Predictions.swift 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import Charts
  2. import CoreData
  3. import SwiftUI
  4. import Swinject
  5. struct PredictionView: View {
  6. @Binding var predictions: Predictions?
  7. @Binding var units: GlucoseUnits
  8. @Binding var eventualBG: Int
  9. @Binding var target: Decimal
  10. var body: some View {
  11. chart()
  12. }
  13. func chart() -> some View {
  14. // Data Source
  15. let iob = predictions?.iob ?? [Int]()
  16. let cob = predictions?.cob ?? [Int]()
  17. let uam = predictions?.uam ?? [Int]()
  18. let zt = predictions?.zt ?? [Int]()
  19. let count = max(iob.count, cob.count, uam.count, zt.count)
  20. var now = Date.now
  21. var startIndex = 0
  22. let conversion = units == .mmolL ? 0.0555 : 1
  23. let eventualRounded: String = (Double(eventualBG) * conversion)
  24. .formatted(.number.grouping(.never).rounded().precision(.fractionLength(units == .mmolL ? 1 : 0)))
  25. // Organize the data needed for prediction chart.
  26. var data = [ChartData]()
  27. repeat {
  28. now = now.addingTimeInterval(5.minutes.timeInterval)
  29. if startIndex < count {
  30. let addedData = ChartData(
  31. date: now,
  32. iob: startIndex < iob.count ? Double(iob[startIndex]) * conversion : 0,
  33. zt: startIndex < zt.count ? Double(zt[startIndex]) * conversion : 0,
  34. cob: startIndex < cob.count ? Double(cob[startIndex]) * conversion : 0,
  35. uam: startIndex < uam.count ? Double(uam[startIndex]) * conversion : 0,
  36. id: UUID()
  37. )
  38. data.append(addedData)
  39. }
  40. startIndex += 1
  41. } while startIndex < count
  42. // Chart
  43. return Chart(data) {
  44. // Remove 0 (empty) values
  45. if $0.iob != 0 {
  46. LineMark(
  47. x: .value("Time", $0.date),
  48. y: .value("IOB", $0.iob),
  49. series: .value("IOB", "A")
  50. )
  51. .foregroundStyle(Color(.insulin))
  52. .lineStyle(StrokeStyle(lineWidth: 2))
  53. }
  54. if $0.uam != 0 {
  55. LineMark(
  56. x: .value("Time", $0.date),
  57. y: .value("UAM", $0.uam),
  58. series: .value("UAM", "B")
  59. )
  60. .foregroundStyle(Color(.UAM))
  61. .lineStyle(StrokeStyle(lineWidth: 2))
  62. }
  63. if $0.cob != 0 {
  64. LineMark(
  65. x: .value("Time", $0.date),
  66. y: .value("COB", $0.cob),
  67. series: .value("COB", "C")
  68. )
  69. .foregroundStyle(Color(.loopYellow))
  70. .lineStyle(StrokeStyle(lineWidth: 2))
  71. }
  72. if $0.zt != 0 {
  73. LineMark(
  74. x: .value("Time", $0.date),
  75. y: .value("ZT", $0.zt),
  76. series: .value("ZT", "D")
  77. )
  78. .foregroundStyle(Color(.ZT))
  79. .lineStyle(StrokeStyle(lineWidth: 2))
  80. }
  81. }
  82. .frame(minHeight: 150)
  83. .chartForegroundStyleScale([
  84. "IOB": Color(.insulin),
  85. "UAM": Color(.UAM),
  86. "COB": Color(.loopYellow),
  87. "ZT": Color(.ZT)
  88. ])
  89. .chartYAxisLabel("Eventual Glucose: " + eventualRounded + " " + units.rawValue, alignment: .center)
  90. }
  91. }