GlucoseChartView.swift 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import Charts
  2. import Foundation
  3. import SwiftUI
  4. struct GlucoseChartView: ChartContent {
  5. let glucoseData: [GlucoseStored]
  6. let units: GlucoseUnits
  7. let highGlucose: Decimal
  8. let lowGlucose: Decimal
  9. let currentGlucoseTarget: Decimal
  10. let isSmoothingEnabled: Bool
  11. let glucoseColorScheme: GlucoseColorScheme
  12. var body: some ChartContent {
  13. drawGlucoseChart()
  14. }
  15. private func drawGlucoseChart() -> some ChartContent {
  16. ForEach(glucoseData) { item in
  17. let glucoseToDisplay = units == .mgdL ? Decimal(item.glucose) : Decimal(item.glucose).asMmolL
  18. // low glucose and high glucose is parsed in state to mmol/L; parse it back to mg/dL here for comparison
  19. let lowGlucose = units == .mgdL ? lowGlucose : lowGlucose.asMgdL
  20. let highGlucose = units == .mgdL ? highGlucose : highGlucose.asMgdL
  21. let pointMarkColor: Color = FreeAPS.getDynamicGlucoseColor(
  22. glucoseValue: Decimal(item.glucose),
  23. highGlucoseColorValue: highGlucose,
  24. lowGlucoseColorValue: lowGlucose,
  25. targetGlucose: currentGlucoseTarget,
  26. glucoseColorScheme: glucoseColorScheme,
  27. offset: 20
  28. )
  29. if !isSmoothingEnabled {
  30. PointMark(
  31. x: .value("Time", item.date ?? Date(), unit: .second),
  32. y: .value("Value", glucoseToDisplay)
  33. )
  34. .foregroundStyle(pointMarkColor)
  35. .symbolSize(20)
  36. .symbol {
  37. if item.isManual {
  38. Image(systemName: "drop.fill")
  39. .font(.system(size: 10))
  40. .symbolRenderingMode(.monochrome)
  41. .bold()
  42. .foregroundStyle(.red)
  43. } else {
  44. Image(systemName: "circle.fill")
  45. .font(.system(size: 5))
  46. .bold()
  47. .foregroundStyle(pointMarkColor)
  48. }
  49. }
  50. } else {
  51. PointMark(
  52. x: .value("Time", item.date ?? Date(), unit: .second),
  53. y: .value("Value", glucoseToDisplay)
  54. )
  55. .symbol {
  56. if item.isManual {
  57. Image(systemName: "drop.fill")
  58. .font(.system(size: 10))
  59. .symbolRenderingMode(.monochrome)
  60. .bold()
  61. .foregroundStyle(.red)
  62. } else {
  63. Image(systemName: "record.circle.fill")
  64. .font(.system(size: 8))
  65. .bold()
  66. .foregroundStyle(pointMarkColor)
  67. }
  68. }
  69. }
  70. }
  71. }
  72. }