GlucoseChartView.swift 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. // TODO: workaround for now: set low value to 55, to have dynamic color shades between 55 and user-set low (approx. 70); same for high glucose
  22. let hardCodedLow = Decimal(55)
  23. let hardCodedHigh = Decimal(220)
  24. let pointMarkColor: Color = FreeAPS.getDynamicGlucoseColor(
  25. glucoseValue: Decimal(item.glucose),
  26. highGlucoseColorValue: hardCodedHigh,
  27. lowGlucoseColorValue: hardCodedLow,
  28. targetGlucose: currentGlucoseTarget,
  29. glucoseColorScheme: glucoseColorScheme
  30. )
  31. if !isSmoothingEnabled {
  32. PointMark(
  33. x: .value("Time", item.date ?? Date(), unit: .second),
  34. y: .value("Value", glucoseToDisplay)
  35. )
  36. .foregroundStyle(pointMarkColor)
  37. .symbolSize(20)
  38. .symbol {
  39. if item.isManual {
  40. Image(systemName: "drop.fill")
  41. .font(.system(size: 10))
  42. .symbolRenderingMode(.monochrome)
  43. .bold()
  44. .foregroundStyle(.red)
  45. } else {
  46. Image(systemName: "circle.fill")
  47. .font(.system(size: 5))
  48. .bold()
  49. .foregroundStyle(pointMarkColor)
  50. }
  51. }
  52. } else {
  53. PointMark(
  54. x: .value("Time", item.date ?? Date(), unit: .second),
  55. y: .value("Value", glucoseToDisplay)
  56. )
  57. .symbol {
  58. if item.isManual {
  59. Image(systemName: "drop.fill")
  60. .font(.system(size: 10))
  61. .symbolRenderingMode(.monochrome)
  62. .bold()
  63. .foregroundStyle(.red)
  64. } else {
  65. Image(systemName: "record.circle.fill")
  66. .font(.system(size: 8))
  67. .bold()
  68. .foregroundStyle(pointMarkColor)
  69. }
  70. }
  71. }
  72. }
  73. }
  74. }