Files
Pulse/Sources/PulseUI/Features/Charts/LoggerStoreSizeChart.swift
2022-09-11 08:17:42 -04:00

93 lines
2.6 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The MIT License (MIT)
//
// Copyright (c) 2020–2022 Alexander Grebenyuk (github.com/kean).
import SwiftUI
import Pulse
#if !os(macOS) && !targetEnvironment(macCatalyst) && swift(>=5.7)
import Charts
#endif
#if !os(macOS) && !targetEnvironment(macCatalyst) && swift(>=5.7)
@available(iOS 16.0, tvOS 16.0, macOS 13.0, watchOS 9.0, *)
struct LoggerStoreSizeChart: View {
let info: LoggerStore.Info
let sizeLimit: Int64?
var body: some View {
VStack {
HStack {
Text("Logger Store")
Spacer()
Text(title).foregroundColor(.secondary)
}
chart
}
}
private var title: String {
let used = ByteCountFormatter.string(fromByteCount: info.totalStoreSize)
let limit = sizeLimit.map(ByteCountFormatter.string)
if let limit = limit {
return "\(used) of \(limit) used"
}
return used
}
private var chart: some View {
Chart(data) {
BarMark(x: .value("Data Size", $0.bytes), stacking: .normalized)
.foregroundStyle(by: .value("Category", $0.category))
}
.chartForegroundStyleScale([
Category.messages: .blue,
Category.responses: .green,
Category.free: .secondaryFill
])
.chartPlotStyle { $0.cornerRadius(8) }
#if os(tvOS)
.chartLegend(position: .bottom, spacing: -20)
.padding(.bottom, 4)
.frame(height: 90)
#else
.chartLegend(position: .bottom, spacing: -8)
.frame(height: 50)
#endif
}
private var data: [Series] {
[Series(category: .messages, bytes: info.totalStoreSize - info.blobsSize),
Series(category: .responses, bytes: info.blobsSize),
sizeLimit.map { Series(category: .free, bytes: max(0, $0 - info.totalStoreSize)) }]
.compactMap { $0 }
}
}
@available(iOS 16.0, tvOS 16.0, macOS 13.0, watchOS 9.0, *)
private enum Category: String, Hashable, Plottable {
case messages = "Logs"
case responses = "Blobs"
case free = "Free"
}
@available(iOS 16.0, tvOS 16.0, macOS 13.0, watchOS 9.0, *)
private struct Series: Identifiable {
let category: Category
let bytes: Int64
var id: Category { category }
}
#if DEBUG
@available(iOS 16.0, tvOS 16.0, macOS 13.0, watchOS 9.0, *)
struct LoggerStoreSizeChart_Previews: PreviewProvider {
static var previews: some View {
LoggerStoreSizeChart(info: try! LoggerStore.mock.info(), sizeLimit: 512 * 1024)
.padding()
.previewLayout(.sizeThatFits)
}
}
#endif
#endif