| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import Charts
- import CoreData
- import SwiftDate
- import SwiftUI
- struct SectorChart: View {
- private enum Constants {
- static let chartHeight: CGFloat = 200
- static let spacing: CGFloat = 8
- static let labelSpacing: CGFloat = 4
- }
- let highLimit: Decimal
- let lowLimit: Decimal
- let units: GlucoseUnits
- let hbA1cDisplayUnit: HbA1cDisplayUnit
- let timeInRangeChartStyle: TimeInRangeChartStyle
- let glucose: [GlucoseStored]
- @Environment(\.colorScheme) var colorScheme
- var body: some View {
- HStack(spacing: 20) {
- Chart {
- ForEach(timeInRangeData, id: \.string) { data in
- SectorMark(
- angle: .value("Percentage", data.decimal),
- innerRadius: .ratio(0.618), // Golden ratio
- angularInset: 1.5
- )
- .foregroundStyle(data.color.gradient)
- }
- }
- .frame(height: Constants.chartHeight)
- // Legend
- VStack(spacing: Constants.spacing) {
- ForEach(timeInRangeData, id: \.string) { data in
- HStack(spacing: Constants.spacing) {
- Circle()
- .fill(data.color)
- .frame(width: 12, height: 12)
- Text(data.string)
- .font(.subheadline)
- Spacer()
- Text(formatPercentage(data.decimal))
- .font(.subheadline)
- .bold()
- }
- }
- }
- .padding(.top, Constants.spacing)
- }
- }
- // MARK: - Data Processing
- private var timeInRangeData: [(decimal: Decimal, string: String, color: Color)] {
- let total = glucose.count
- guard total > 0 else { return [] }
- let hyperArray = glucose.filter { $0.glucose >= Int(highLimit) }
- let hyperReadings = hyperArray.count
- let hyperPercentage = Decimal(hyperReadings) / Decimal(total) * 100
- let hypoArray = glucose.filter { $0.glucose <= Int(lowLimit) }
- let hypoReadings = hypoArray.count
- let hypoPercentage = Decimal(hypoReadings) / Decimal(total) * 100
- let normalPercentage = 100 - (hypoPercentage + hyperPercentage)
- return [
- (normalPercentage, "In Range", .green),
- (hyperPercentage, "High", .yellow),
- (hypoPercentage, "Low", .red)
- ]
- }
- private func formatPercentage(_ value: Decimal) -> String {
- let formatter = NumberFormatter()
- formatter.numberStyle = .percent
- formatter.maximumFractionDigits = 1
- return formatter.string(from: NSDecimalNumber(decimal: value / 100)) ?? "0%"
- }
- }
|