MainChartView2.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import Charts
  2. import SwiftUI
  3. struct MainChartView2: View {
  4. @Binding var tempBasals: [PumpHistoryEvent]
  5. @Binding var glucose: [BloodGlucose]
  6. @Binding var screenHours: Int16
  7. @Binding var highGlucose: Decimal
  8. @Binding var lowGlucose: Decimal
  9. var body: some View {
  10. VStack(alignment: .center, spacing: 8, content: {
  11. GlucoseChart(glucose: $glucose, screenHours: $screenHours, highGlucose: $highGlucose, lowGlucose: $lowGlucose)
  12. .padding(.bottom, 20)
  13. BasalChart(tempBasals: $tempBasals, screenHours: $screenHours)
  14. .padding(.bottom, 8)
  15. Legend()
  16. })
  17. }
  18. }
  19. // MARK: GLUCOSE FOR CHART
  20. struct GlucoseChart: View {
  21. @Binding var glucose: [BloodGlucose]
  22. @Binding var screenHours: Int16
  23. @Binding var highGlucose: Decimal
  24. @Binding var lowGlucose: Decimal
  25. var body: some View {
  26. VStack {
  27. let filteredGlucose: [BloodGlucose] = filterGlucoseData(for: screenHours)
  28. Chart(filteredGlucose) {
  29. RuleMark(y: .value("High", highGlucose))
  30. .foregroundStyle(Color.loopYellow)
  31. .lineStyle(StrokeStyle(lineWidth: 1, dash: [5]))
  32. RuleMark(y: .value("Low", lowGlucose))
  33. .foregroundStyle(Color.loopRed)
  34. .lineStyle(StrokeStyle(lineWidth: 1, dash: [5]))
  35. PointMark(
  36. x: .value("Time", $0.dateString),
  37. y: .value("Value", $0.value)
  38. )
  39. .foregroundStyle(
  40. $0.value > Double(highGlucose) ? Color.yellow.gradient :
  41. $0.value < Double(lowGlucose) ? Color.red.gradient : Color.green.gradient
  42. )
  43. .symbolSize(12)
  44. }
  45. .frame(height: 250)
  46. .chartXAxis(.hidden)
  47. }
  48. }
  49. private func filterGlucoseData(for hours: Int16) -> [BloodGlucose] {
  50. guard hours > 0 else {
  51. return glucose
  52. }
  53. let currentDate = Date()
  54. let startDate = Calendar.current.date(byAdding: .hour, value: -Int(hours), to: currentDate) ?? currentDate
  55. return glucose.filter { $0.dateString >= startDate }
  56. }
  57. }
  58. // MARK: BASAL FOR CHART
  59. struct BasalChart: View {
  60. @Binding var tempBasals: [PumpHistoryEvent]
  61. @Binding var screenHours: Int16
  62. var body: some View {
  63. VStack {
  64. let filteredBasal: [PumpHistoryEvent] = filterBasalData(for: screenHours)
  65. Chart(filteredBasal) {
  66. BarMark(
  67. x: .value("Time", $0.timestamp),
  68. y: .value("Value", $0.rate ?? 0)
  69. )
  70. .foregroundStyle(Color.blue.gradient)
  71. .cornerRadius(0)
  72. }
  73. .frame(height: 80)
  74. // .rotationEffect(.degrees(180))
  75. // .chartXAxis(.hidden)
  76. .chartYAxis(.hidden)
  77. }
  78. }
  79. private func filterBasalData(for hours: Int16) -> [PumpHistoryEvent] {
  80. guard hours > 0 else {
  81. return tempBasals
  82. }
  83. let currentDate = Date()
  84. let startDate = Calendar.current.date(byAdding: .hour, value: -Int(hours), to: currentDate) ?? currentDate
  85. return tempBasals.filter { $0.timestamp >= startDate }
  86. }
  87. }
  88. // MARK: LEGEND PANEL FOR CHART
  89. struct Legend: View {
  90. var body: some View {
  91. HStack {
  92. Image(systemName: "line.diagonal")
  93. .rotationEffect(Angle(degrees: 45))
  94. .foregroundColor(.green)
  95. Text("BG")
  96. .foregroundColor(.secondary)
  97. Spacer()
  98. Image(systemName: "line.diagonal")
  99. .rotationEffect(Angle(degrees: 45))
  100. .foregroundColor(.insulin)
  101. Text("IOB")
  102. .foregroundColor(.secondary)
  103. Spacer()
  104. Image(systemName: "line.diagonal")
  105. .rotationEffect(Angle(degrees: 45))
  106. .foregroundColor(.purple)
  107. Text("ZT")
  108. .foregroundColor(.secondary)
  109. Spacer()
  110. Image(systemName: "line.diagonal")
  111. .frame(height: 10)
  112. .rotationEffect(Angle(degrees: 45))
  113. .foregroundColor(.loopYellow)
  114. Text("COB")
  115. .foregroundColor(.secondary)
  116. Spacer()
  117. Image(systemName: "line.diagonal")
  118. .rotationEffect(Angle(degrees: 45))
  119. .foregroundColor(.orange)
  120. Text("UAM")
  121. .foregroundColor(.secondary)
  122. }
  123. .font(.caption2)
  124. .padding(.horizontal, 40)
  125. .padding(.vertical, 1)
  126. }
  127. }