ChartLegendView.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import SwiftUI
  2. struct ChartLegendView: View {
  3. @Environment(AppState.self) var appState
  4. @Environment(\.colorScheme) var colorScheme
  5. var state: Home.StateModel
  6. @State var legendSheetDetent = PresentationDetent.large
  7. var body: some View {
  8. NavigationStack {
  9. VStack(alignment: .leading) {
  10. Text(
  11. "The main chart in Trio is made up of various elements and shapes. Find their meanings below."
  12. )
  13. .font(.subheadline)
  14. .foregroundColor(.secondary)
  15. .padding(.top, 50)
  16. List {
  17. VStack(alignment: .leading) {
  18. Text("Forecasts").bold().padding(.bottom, 5).textCase(.uppercase)
  19. Text(
  20. "The oref algorithm determines insulin dosing based on a number of scenarios that it estimates with different types of forecasts."
  21. )
  22. .font(.subheadline)
  23. .foregroundColor(.primary)
  24. if state.forecastDisplayType == .lines {
  25. legendLinesView
  26. } else {
  27. legendConeOfUncertaintyView
  28. }
  29. }.listRowBackground(Color.gray.opacity(0.1))
  30. VStack(alignment: .leading) {
  31. Text("Other Elements & Shapes").bold().padding(.bottom, 5).textCase(.uppercase)
  32. DefinitionRow(
  33. term: "Scheduled Basal Rate",
  34. definition: VStack(alignment: .leading, spacing: 10) {
  35. Text("This dotted line represents the hourly insulin rate of your scheduled basal insulin.")
  36. Text("To review or change your scheduled basal rates, go to Settings > Therapy > Basal Rates.")
  37. },
  38. color: Color.insulin,
  39. iconString: "ellipsis"
  40. )
  41. DefinitionRow(
  42. term: "Temporary Basal Rate (TBR)",
  43. definition: Text(
  44. "Shows current or past TBRs, which can be set by the oref algorithm or manually."
  45. ),
  46. color: Color.insulin,
  47. iconString: "square"
  48. )
  49. DefinitionRow(
  50. term: "Pump Suspension",
  51. definition: Text("Indicates when insulin delivery was paused, i.e. pump is suspended."),
  52. color: Color.loopGray.opacity(colorScheme == .dark ? 0.3 : 0.8),
  53. iconString: "square.fill"
  54. )
  55. DefinitionRow(
  56. term: "CGM Glucose Value",
  57. definition: VStack(alignment: .leading, spacing: 10) {
  58. if state.settingsManager.settings.smoothGlucose {
  59. Text(
  60. "Displays real-time glucose readings from your CGM that were smoothed using the Savatzky-Golay filter. The displayed glucose readings may not match the actual readings from your CGM."
  61. )
  62. Text(
  63. "Depending on your user interface settings, this may be displayed in a static (red, green, orange) or dynamic (full color spectrum) coloring scheme."
  64. )
  65. } else {
  66. Text(
  67. "Displays real-time glucose readings from your CGM. Depending on your user interface settings, this may be displayed in a static (red, green, orange) or dynamic (full color spectrum) coloring scheme."
  68. )
  69. }
  70. Text(
  71. "To modify how glucose readings are displayed, go to Settings > Features > User Interface > Glucose Color Scheme."
  72. )
  73. if state.settingsManager.settings.smoothGlucose {
  74. Text(
  75. "To disable smoothing, go to Settings > Devices > Continuous Glucose Monitor > Smooth Glucose Value and toggle off the setting."
  76. )
  77. }
  78. },
  79. color: Color.green,
  80. iconString: state.settingsManager.settings.smoothGlucose ? "record.circle.fill" : "circle.fill"
  81. )
  82. DefinitionRow(
  83. term: "Manual Glucose Measurement",
  84. definition: Text("Manually entered blood glucose, such as a fingerstick test."),
  85. color: Color.red,
  86. iconString: "drop.fill"
  87. )
  88. DefinitionRow(
  89. term: "Bolus",
  90. definition: Text(
  91. "Shows an insulin dose, which can be a small automated dose (super-micro-bolus), a manually entered dose, or one given externally (e.g., a pen shot)."
  92. ),
  93. color: Color.insulin,
  94. iconString: "arrowtriangle.down.fill"
  95. )
  96. DefinitionRow(
  97. term: "Carb Entry",
  98. definition: Text("Tracks the carbohydrates you eat, entered to guide insulin dosing."),
  99. color: Color.orange,
  100. iconString: "arrowtriangle.down.fill",
  101. shouldRotateIcon: true
  102. )
  103. DefinitionRow(
  104. term: "Fat-Protein Carb Equivalent",
  105. definition: VStack(alignment: .leading, spacing: 10) {
  106. Text(
  107. "Represents carb equivalent for fat and protein, calculated using the Warsaw Method."
  108. )
  109. Text(
  110. "To enable or configure Warsaw Method application in Trio, go to Settings > Features > Meal Settings."
  111. )
  112. },
  113. color: Color.brown,
  114. iconString: "circle.fill"
  115. )
  116. DefinitionRow(
  117. term: "Override",
  118. definition: Text(
  119. "Indicates when an override is or was active, temporarily changing therapy settings (e.g., basal rate, insulin sensitivity, carb ratio, target glucose, or whether Trio can dose SMBs)."
  120. ),
  121. color: Color.purple.opacity(0.4),
  122. iconString: "button.horizontal.fill"
  123. )
  124. DefinitionRow(
  125. term: "Temporary Target",
  126. definition: Text(
  127. "Marks when a short-term temporary glucose target is or was active, (potentially) altering when or how much insulin is delivered."
  128. ),
  129. color: Color.green.opacity(0.4),
  130. iconString: "button.horizontal.fill"
  131. )
  132. DefinitionRow(
  133. term: "Past Insulin-on-Board (IOB)",
  134. definition: Text(
  135. "Shows the IOB value calculated by the algorithm at a specific time in the past. These values are snapshots and won’t change if insulin is added or removed after the fact."
  136. ),
  137. color: Color.darkerBlue.opacity(0.8),
  138. iconString: "line.diagonal"
  139. )
  140. DefinitionRow(
  141. term: "Past Carbs-on-Board (COB)",
  142. definition: Text(
  143. "Shows the COB value calculated by the algorithm at a specific time in the past. These values are snapshots and won’t change if carbs are added or removed after the fact."
  144. ),
  145. color: Color.orange.opacity(0.8),
  146. iconString: "line.diagonal"
  147. )
  148. }.listRowBackground(Color.gray.opacity(0.1))
  149. }
  150. .scrollContentBackground(.hidden)
  151. .navigationBarTitle("Chart Legend", displayMode: .inline)
  152. .padding(.trailing, 10)
  153. .padding(.bottom, 15)
  154. Button {
  155. state.isLegendPresented.toggle()
  156. } label: {
  157. Text("Got it!").bold().frame(maxWidth: .infinity, minHeight: 30, alignment: .center)
  158. }
  159. .buttonStyle(.bordered)
  160. .padding(.top)
  161. }
  162. .padding([.horizontal, .bottom])
  163. .listSectionSpacing(10)
  164. .ignoresSafeArea(edges: .top)
  165. .presentationDetents(
  166. [.fraction(0.9), .large],
  167. selection: $legendSheetDetent
  168. )
  169. }
  170. }
  171. var legendLinesView: some View {
  172. Group {
  173. DefinitionRow(
  174. term: "IOB (Insulin on Board)",
  175. definition: Text(
  176. "Forecasts future glucose readings based on the amount of insulin still active in the body."
  177. ),
  178. color: .insulin
  179. )
  180. DefinitionRow(
  181. term: "ZT (Zero-Temp)",
  182. definition: Text(
  183. "Forecasts the worst-case future glucose reading scenario if no carbs are absorbed and insulin delivery is stopped until glucose starts rising."
  184. ),
  185. color: .zt
  186. )
  187. DefinitionRow(
  188. term: "COB (Carbs on Board)",
  189. definition: Text(
  190. "Forecasts future glucose reading changes by considering the amount of carbohydrates still being absorbed in the body."
  191. ),
  192. color: .loopYellow
  193. )
  194. DefinitionRow(
  195. term: "UAM (Unannounced Meal)",
  196. definition: Text(
  197. "Forecasts future glucose levels and insulin dosing needs for unexpected meals or other causes of glucose reading increases without prior notice."
  198. ),
  199. color: .uam
  200. )
  201. }
  202. }
  203. var legendConeOfUncertaintyView: some View {
  204. DefinitionRow(
  205. term: "Cone of Uncertainty",
  206. definition: VStack(alignment: .leading, spacing: 10) {
  207. Text(
  208. "For simplicity reasons, oref's various forecast curves are displayed as a \"Cone of Uncertainty\" that depicts a possible, forecasted range of future glucose fluctuation based on the current data and the algothim's result."
  209. )
  210. Text(
  211. "To modify how the forecast is displayed, go to Settings > Features > User Interface > Forecast Display Type."
  212. )
  213. },
  214. color: Color.blue.opacity(0.5)
  215. )
  216. }
  217. }