GlucoseChartView.swift 3.3 KB

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