Graphs.swift 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  1. //
  2. // Graphs.swift
  3. // LoopFollow
  4. //
  5. // Created by Jon Fawcett on 6/16/20.
  6. // Copyright © 2020 Jon Fawcett. All rights reserved.
  7. //
  8. import Foundation
  9. import Charts
  10. import UIKit
  11. let ScaleXMax:Float = 150.0
  12. extension MainViewController {
  13. func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
  14. if chartView == BGChartFull {
  15. BGChart.moveViewToX(entry.x)
  16. }
  17. if entry.data as? String == "hide"{
  18. BGChart.highlightValue(nil, callDelegate: false)
  19. }
  20. }
  21. func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat) {
  22. print("Chart Scaled: \(BGChart.scaleX), \(BGChart.scaleY)")
  23. // dont store huge values
  24. var scale: Float = Float(BGChart.scaleX)
  25. if(scale > ScaleXMax ) {
  26. scale = ScaleXMax
  27. }
  28. UserDefaultsRepository.chartScaleX.value = Float(scale)
  29. }
  30. func createGraph(){
  31. // Create the BG Graph Data
  32. let bgChartEntry = [ChartDataEntry]()
  33. let maxBG: Float = UserDefaultsRepository.minBGScale.value
  34. // Setup BG line details
  35. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  36. lineBG.circleRadius = CGFloat(globalVariables.dotBG)
  37. lineBG.circleColors = [NSUIColor.systemGreen]
  38. lineBG.drawCircleHoleEnabled = false
  39. lineBG.axisDependency = YAxis.AxisDependency.right
  40. lineBG.highlightEnabled = true
  41. lineBG.drawValuesEnabled = false
  42. if UserDefaultsRepository.showLines.value {
  43. lineBG.lineWidth = 2
  44. } else {
  45. lineBG.lineWidth = 0
  46. }
  47. if UserDefaultsRepository.showDots.value {
  48. lineBG.drawCirclesEnabled = true
  49. } else {
  50. lineBG.drawCirclesEnabled = false
  51. }
  52. lineBG.setDrawHighlightIndicators(false)
  53. lineBG.valueFont.withSize(50)
  54. // Setup Prediction line details
  55. let predictionChartEntry = [ChartDataEntry]()
  56. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  57. linePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  58. linePrediction.circleColors = [NSUIColor.systemPurple]
  59. linePrediction.colors = [NSUIColor.systemPurple]
  60. linePrediction.drawCircleHoleEnabled = false
  61. linePrediction.axisDependency = YAxis.AxisDependency.right
  62. linePrediction.highlightEnabled = true
  63. linePrediction.drawValuesEnabled = false
  64. if UserDefaultsRepository.showLines.value {
  65. linePrediction.lineWidth = 2
  66. } else {
  67. linePrediction.lineWidth = 0
  68. }
  69. if UserDefaultsRepository.showDots.value {
  70. linePrediction.drawCirclesEnabled = true
  71. } else {
  72. linePrediction.drawCirclesEnabled = false
  73. }
  74. linePrediction.setDrawHighlightIndicators(false)
  75. linePrediction.valueFont.withSize(50)
  76. // create Basal graph data
  77. let chartEntry = [ChartDataEntry]()
  78. let maxBasal = UserDefaultsRepository.minBasalScale.value
  79. let lineBasal = LineChartDataSet(entries:chartEntry, label: "")
  80. lineBasal.setDrawHighlightIndicators(false)
  81. lineBasal.setColor(NSUIColor.systemBlue, alpha: 0.5)
  82. lineBasal.lineWidth = 0
  83. lineBasal.drawFilledEnabled = true
  84. lineBasal.fillColor = NSUIColor.systemBlue
  85. lineBasal.fillAlpha = 0.5
  86. lineBasal.drawCirclesEnabled = false
  87. lineBasal.axisDependency = YAxis.AxisDependency.left
  88. lineBasal.highlightEnabled = true
  89. lineBasal.drawValuesEnabled = false
  90. lineBasal.fillFormatter = basalFillFormatter()
  91. // Boluses
  92. let chartEntryBolus = [ChartDataEntry]()
  93. let lineBolus = LineChartDataSet(entries:chartEntryBolus, label: "")
  94. lineBolus.circleRadius = CGFloat(globalVariables.dotBolus)
  95. lineBolus.circleColors = [NSUIColor.systemBlue.withAlphaComponent(0.75)]
  96. lineBolus.drawCircleHoleEnabled = false
  97. lineBolus.setDrawHighlightIndicators(false)
  98. lineBolus.setColor(NSUIColor.systemBlue, alpha: 1.0)
  99. lineBolus.lineWidth = 0
  100. lineBolus.axisDependency = YAxis.AxisDependency.right
  101. lineBolus.valueFormatter = ChartYDataValueFormatter()
  102. lineBolus.valueTextColor = NSUIColor.label
  103. lineBolus.fillColor = NSUIColor.systemBlue
  104. lineBolus.fillAlpha = 0.6
  105. lineBolus.drawCirclesEnabled = true
  106. lineBolus.drawFilledEnabled = false
  107. if UserDefaultsRepository.showValues.value {
  108. lineBolus.drawValuesEnabled = true
  109. lineBolus.highlightEnabled = false
  110. } else {
  111. lineBolus.drawValuesEnabled = false
  112. lineBolus.highlightEnabled = true
  113. }
  114. // Carbs
  115. let chartEntryCarbs = [ChartDataEntry]()
  116. let lineCarbs = LineChartDataSet(entries:chartEntryCarbs, label: "")
  117. lineCarbs.circleRadius = CGFloat(globalVariables.dotCarb)
  118. lineCarbs.circleColors = [NSUIColor.systemOrange.withAlphaComponent(0.75)]
  119. lineCarbs.drawCircleHoleEnabled = false
  120. lineCarbs.setDrawHighlightIndicators(false)
  121. lineCarbs.setColor(NSUIColor.systemBlue, alpha: 1.0)
  122. lineCarbs.lineWidth = 0
  123. lineCarbs.axisDependency = YAxis.AxisDependency.right
  124. lineCarbs.valueFormatter = ChartYDataValueFormatter()
  125. lineCarbs.valueTextColor = NSUIColor.label
  126. lineCarbs.fillColor = NSUIColor.systemOrange
  127. lineCarbs.fillAlpha = 0.6
  128. lineCarbs.drawCirclesEnabled = true
  129. lineCarbs.drawFilledEnabled = false
  130. if UserDefaultsRepository.showValues.value {
  131. lineCarbs.drawValuesEnabled = true
  132. lineCarbs.highlightEnabled = false
  133. } else {
  134. lineCarbs.drawValuesEnabled = false
  135. lineCarbs.highlightEnabled = true
  136. }
  137. // create Scheduled Basal graph data
  138. let chartBasalScheduledEntry = [ChartDataEntry]()
  139. let lineBasalScheduled = LineChartDataSet(entries:chartBasalScheduledEntry, label: "")
  140. lineBasalScheduled.setDrawHighlightIndicators(false)
  141. lineBasalScheduled.setColor(NSUIColor.systemBlue, alpha: 0.8)
  142. lineBasalScheduled.lineWidth = 2
  143. lineBasalScheduled.drawFilledEnabled = false
  144. lineBasalScheduled.drawCirclesEnabled = false
  145. lineBasalScheduled.axisDependency = YAxis.AxisDependency.left
  146. lineBasalScheduled.highlightEnabled = false
  147. lineBasalScheduled.drawValuesEnabled = false
  148. lineBasalScheduled.lineDashLengths = [10.0, 5.0]
  149. // create Override graph data
  150. let chartOverrideEntry = [ChartDataEntry]()
  151. let lineOverride = LineChartDataSet(entries:chartOverrideEntry, label: "")
  152. lineOverride.setDrawHighlightIndicators(false)
  153. lineOverride.lineWidth = 0
  154. lineOverride.drawFilledEnabled = true
  155. lineOverride.fillFormatter = OverrideFillFormatter()
  156. lineOverride.fillColor = NSUIColor.systemGreen
  157. lineOverride.fillAlpha = 0.6
  158. lineOverride.drawCirclesEnabled = false
  159. lineOverride.axisDependency = YAxis.AxisDependency.right
  160. lineOverride.highlightEnabled = true
  161. lineOverride.drawValuesEnabled = false
  162. // BG Check
  163. let chartEntryBGCheck = [ChartDataEntry]()
  164. let lineBGCheck = LineChartDataSet(entries:chartEntryBGCheck, label: "")
  165. lineBGCheck.circleRadius = CGFloat(globalVariables.dotOther)
  166. lineBGCheck.circleColors = [NSUIColor.systemRed.withAlphaComponent(0.75)]
  167. lineBGCheck.drawCircleHoleEnabled = false
  168. lineBGCheck.setDrawHighlightIndicators(false)
  169. lineBGCheck.setColor(NSUIColor.systemRed, alpha: 1.0)
  170. lineBGCheck.drawCirclesEnabled = true
  171. lineBGCheck.lineWidth = 0
  172. lineBGCheck.highlightEnabled = true
  173. lineBGCheck.axisDependency = YAxis.AxisDependency.right
  174. lineBGCheck.valueFormatter = ChartYDataValueFormatter()
  175. lineBGCheck.drawValuesEnabled = false
  176. // Suspend Pump
  177. let chartEntrySuspend = [ChartDataEntry]()
  178. let lineSuspend = LineChartDataSet(entries:chartEntrySuspend, label: "")
  179. lineSuspend.circleRadius = CGFloat(globalVariables.dotOther)
  180. lineSuspend.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  181. lineSuspend.drawCircleHoleEnabled = false
  182. lineSuspend.setDrawHighlightIndicators(false)
  183. lineSuspend.setColor(NSUIColor.systemGray2, alpha: 1.0)
  184. lineSuspend.drawCirclesEnabled = true
  185. lineSuspend.lineWidth = 0
  186. lineSuspend.highlightEnabled = true
  187. lineSuspend.axisDependency = YAxis.AxisDependency.right
  188. lineSuspend.valueFormatter = ChartYDataValueFormatter()
  189. lineSuspend.drawValuesEnabled = false
  190. // Resume Pump
  191. let chartEntryResume = [ChartDataEntry]()
  192. let lineResume = LineChartDataSet(entries:chartEntryResume, label: "")
  193. lineResume.circleRadius = CGFloat(globalVariables.dotOther)
  194. lineResume.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  195. lineResume.drawCircleHoleEnabled = false
  196. lineResume.setDrawHighlightIndicators(false)
  197. lineResume.setColor(NSUIColor.systemGray4, alpha: 1.0)
  198. lineResume.drawCirclesEnabled = true
  199. lineResume.lineWidth = 0
  200. lineResume.highlightEnabled = true
  201. lineResume.axisDependency = YAxis.AxisDependency.right
  202. lineResume.valueFormatter = ChartYDataValueFormatter()
  203. lineResume.drawValuesEnabled = false
  204. // Sensor Start
  205. let chartEntrySensor = [ChartDataEntry]()
  206. let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
  207. lineSensor.circleRadius = CGFloat(globalVariables.dotOther)
  208. lineSensor.circleColors = [NSUIColor.systemIndigo.withAlphaComponent(0.75)]
  209. lineSensor.drawCircleHoleEnabled = false
  210. lineSensor.setDrawHighlightIndicators(false)
  211. lineSensor.setColor(NSUIColor.systemGray3, alpha: 1.0)
  212. lineSensor.drawCirclesEnabled = true
  213. lineSensor.lineWidth = 0
  214. lineSensor.highlightEnabled = true
  215. lineSensor.axisDependency = YAxis.AxisDependency.right
  216. lineSensor.valueFormatter = ChartYDataValueFormatter()
  217. lineSensor.drawValuesEnabled = false
  218. // Notes
  219. let chartEntryNote = [ChartDataEntry]()
  220. let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
  221. lineNote.circleRadius = CGFloat(globalVariables.dotOther)
  222. lineNote.circleColors = [NSUIColor.systemGray.withAlphaComponent(0.75)]
  223. lineNote.drawCircleHoleEnabled = false
  224. lineNote.setDrawHighlightIndicators(false)
  225. lineNote.setColor(NSUIColor.systemGray3, alpha: 1.0)
  226. lineNote.drawCirclesEnabled = true
  227. lineNote.lineWidth = 0
  228. lineNote.highlightEnabled = true
  229. lineNote.axisDependency = YAxis.AxisDependency.right
  230. lineNote.valueFormatter = ChartYDataValueFormatter()
  231. lineNote.drawValuesEnabled = false
  232. // Setup COB Prediction line details
  233. let COBpredictionChartEntry = [ChartDataEntry]()
  234. let COBlinePrediction = LineChartDataSet(entries:COBpredictionChartEntry, label: "")
  235. COBlinePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  236. COBlinePrediction.circleColors = [NSUIColor.systemPurple]
  237. COBlinePrediction.colors = [NSUIColor.systemPurple]
  238. COBlinePrediction.drawCircleHoleEnabled = false
  239. COBlinePrediction.axisDependency = YAxis.AxisDependency.right
  240. COBlinePrediction.highlightEnabled = true
  241. COBlinePrediction.drawValuesEnabled = false
  242. if UserDefaultsRepository.showLines.value {
  243. COBlinePrediction.lineWidth = 2
  244. } else {
  245. COBlinePrediction.lineWidth = 0
  246. }
  247. if UserDefaultsRepository.showDots.value {
  248. COBlinePrediction.drawCirclesEnabled = true
  249. } else {
  250. COBlinePrediction.drawCirclesEnabled = false
  251. }
  252. COBlinePrediction.setDrawHighlightIndicators(false)
  253. COBlinePrediction.valueFont.withSize(50)
  254. // Setup IOB Prediction line details
  255. let IOBpredictionChartEntry = [ChartDataEntry]()
  256. let IOBlinePrediction = LineChartDataSet(entries:IOBpredictionChartEntry, label: "")
  257. IOBlinePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  258. IOBlinePrediction.circleColors = [NSUIColor.systemPurple]
  259. IOBlinePrediction.colors = [NSUIColor.systemPurple]
  260. IOBlinePrediction.drawCircleHoleEnabled = false
  261. IOBlinePrediction.axisDependency = YAxis.AxisDependency.right
  262. IOBlinePrediction.highlightEnabled = true
  263. IOBlinePrediction.drawValuesEnabled = false
  264. if UserDefaultsRepository.showLines.value {
  265. IOBlinePrediction.lineWidth = 2
  266. } else {
  267. IOBlinePrediction.lineWidth = 0
  268. }
  269. if UserDefaultsRepository.showDots.value {
  270. IOBlinePrediction.drawCirclesEnabled = true
  271. } else {
  272. IOBlinePrediction.drawCirclesEnabled = false
  273. }
  274. IOBlinePrediction.setDrawHighlightIndicators(false)
  275. IOBlinePrediction.valueFont.withSize(50)
  276. // Setup UAM Prediction line details
  277. let UAMpredictionChartEntry = [ChartDataEntry]()
  278. let UAMlinePrediction = LineChartDataSet(entries:UAMpredictionChartEntry, label: "")
  279. UAMlinePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  280. UAMlinePrediction.circleColors = [NSUIColor.systemPurple]
  281. UAMlinePrediction.colors = [NSUIColor.systemPurple]
  282. UAMlinePrediction.drawCircleHoleEnabled = false
  283. UAMlinePrediction.axisDependency = YAxis.AxisDependency.right
  284. UAMlinePrediction.highlightEnabled = true
  285. UAMlinePrediction.drawValuesEnabled = false
  286. if UserDefaultsRepository.showLines.value {
  287. UAMlinePrediction.lineWidth = 2
  288. } else {
  289. UAMlinePrediction.lineWidth = 0
  290. }
  291. if UserDefaultsRepository.showDots.value {
  292. UAMlinePrediction.drawCirclesEnabled = true
  293. } else {
  294. UAMlinePrediction.drawCirclesEnabled = false
  295. }
  296. linePrediction.setDrawHighlightIndicators(false)
  297. linePrediction.valueFont.withSize(50)
  298. // Setup ZT Prediction line details
  299. let ZTpredictionChartEntry = [ChartDataEntry]()
  300. let ZTlinePrediction = LineChartDataSet(entries:ZTpredictionChartEntry, label: "")
  301. ZTlinePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  302. ZTlinePrediction.circleColors = [NSUIColor.systemPurple]
  303. ZTlinePrediction.colors = [NSUIColor.systemPurple]
  304. ZTlinePrediction.drawCircleHoleEnabled = false
  305. ZTlinePrediction.axisDependency = YAxis.AxisDependency.right
  306. ZTlinePrediction.highlightEnabled = true
  307. ZTlinePrediction.drawValuesEnabled = false
  308. if UserDefaultsRepository.showLines.value {
  309. ZTlinePrediction.lineWidth = 2
  310. } else {
  311. ZTlinePrediction.lineWidth = 0
  312. }
  313. if UserDefaultsRepository.showDots.value {
  314. ZTlinePrediction.drawCirclesEnabled = true
  315. } else {
  316. ZTlinePrediction.drawCirclesEnabled = false
  317. }
  318. ZTlinePrediction.setDrawHighlightIndicators(false)
  319. ZTlinePrediction.valueFont.withSize(50)
  320. // Setup the chart data of all lines
  321. let data = LineChartData()
  322. data.append(lineBG) // Dataset 0
  323. data.append(linePrediction) // Dataset 1
  324. data.append(lineBasal) // Dataset 2
  325. data.append(lineBolus) // Dataset 3
  326. data.append(lineCarbs) // Dataset 4
  327. data.append(lineBasalScheduled) // Dataset 5
  328. data.append(lineOverride) // Dataset 6
  329. data.append(lineBGCheck) // Dataset 7
  330. data.append(lineSuspend) // Dataset 8
  331. data.append(lineResume) // Dataset 9
  332. data.append(lineSensor) // Dataset 10
  333. data.append(lineNote) // Dataset 11
  334. data.append(ZTlinePrediction) // Dataset 12
  335. data.append(IOBlinePrediction) // Dataset 13
  336. data.append(COBlinePrediction) // Dataset 14
  337. data.append(UAMlinePrediction) // Dataset 15
  338. data.setValueFont(UIFont.systemFont(ofSize: 12))
  339. // Add marker popups for bolus and carbs
  340. let marker = PillMarker(color: .secondarySystemBackground, font: UIFont.boldSystemFont(ofSize: 14), textColor: .label)
  341. BGChart.marker = marker
  342. // Clear limit lines so they don't add multiples when changing the settings
  343. BGChart.rightAxis.removeAllLimitLines()
  344. //Add lower red line based on low alert value
  345. let ll = ChartLimitLine()
  346. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  347. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  348. BGChart.rightAxis.addLimitLine(ll)
  349. //Add upper yellow line based on low alert value
  350. let ul = ChartLimitLine()
  351. ul.limit = Double(UserDefaultsRepository.highLine.value)
  352. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  353. BGChart.rightAxis.addLimitLine(ul)
  354. // Add vertical lines as configured
  355. createVerticalLines()
  356. startGraphNowTimer()
  357. // Setup the main graph overall details
  358. BGChart.xAxis.valueFormatter = ChartXValueFormatter()
  359. BGChart.xAxis.granularity = 1800
  360. BGChart.xAxis.labelTextColor = NSUIColor.label
  361. BGChart.xAxis.labelPosition = XAxis.LabelPosition.bottom
  362. BGChart.xAxis.drawGridLinesEnabled = false
  363. BGChart.leftAxis.enabled = true
  364. BGChart.leftAxis.labelPosition = YAxis.LabelPosition.insideChart
  365. BGChart.leftAxis.axisMaximum = maxBasal
  366. BGChart.leftAxis.axisMinimum = 0
  367. BGChart.leftAxis.drawGridLinesEnabled = false
  368. BGChart.leftAxis.granularityEnabled = true
  369. BGChart.leftAxis.granularity = 0.5
  370. BGChart.rightAxis.labelTextColor = NSUIColor.label
  371. BGChart.rightAxis.labelPosition = YAxis.LabelPosition.insideChart
  372. BGChart.rightAxis.axisMinimum = 0.0
  373. BGChart.rightAxis.axisMaximum = Double(maxBG)
  374. BGChart.rightAxis.gridLineDashLengths = [5.0, 5.0]
  375. BGChart.rightAxis.drawGridLinesEnabled = false
  376. BGChart.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
  377. BGChart.rightAxis.granularityEnabled = true
  378. BGChart.rightAxis.granularity = 50
  379. BGChart.maxHighlightDistance = 15.0
  380. BGChart.legend.enabled = false
  381. BGChart.scaleYEnabled = false
  382. BGChart.drawGridBackgroundEnabled = true
  383. BGChart.gridBackgroundColor = NSUIColor.secondarySystemBackground
  384. BGChart.highlightValue(nil, callDelegate: false)
  385. BGChart.data = data
  386. BGChart.setExtraOffsets(left: 5, top: 10, right: 5, bottom: 10)
  387. }
  388. func createVerticalLines() {
  389. BGChart.xAxis.removeAllLimitLines()
  390. BGChartFull.xAxis.removeAllLimitLines()
  391. createNowAndDIALines()
  392. createMidnightLines()
  393. }
  394. func createNowAndDIALines() {
  395. let ul = ChartLimitLine()
  396. ul.limit = Double(dateTimeUtils.getNowTimeIntervalUTC())
  397. ul.lineColor = NSUIColor.systemGray.withAlphaComponent(0.5)
  398. ul.lineWidth = 1
  399. BGChart.xAxis.addLimitLine(ul)
  400. if UserDefaultsRepository.show30MinLine.value {
  401. let ul2 = ChartLimitLine()
  402. ul2.limit = Double(dateTimeUtils.getNowTimeIntervalUTC().advanced(by: -30 * 60))
  403. ul2.lineColor = NSUIColor.systemBlue.withAlphaComponent(0.5)
  404. ul2.lineWidth = 1
  405. BGChart.xAxis.addLimitLine(ul2)
  406. }
  407. if UserDefaultsRepository.showDIALines.value {
  408. for i in 1..<7 {
  409. let ul = ChartLimitLine()
  410. ul.limit = Double(dateTimeUtils.getNowTimeIntervalUTC() - Double(i * 60 * 60))
  411. ul.lineColor = NSUIColor.systemGray.withAlphaComponent(0.3)
  412. let dash = 10.0 - Double(i)
  413. let space = 5.0 + Double(i)
  414. ul.lineDashLengths = [CGFloat(dash), CGFloat(space)]
  415. ul.lineWidth = 1
  416. BGChart.xAxis.addLimitLine(ul)
  417. }
  418. }
  419. if UserDefaultsRepository.show90MinLine.value {
  420. let ul3 = ChartLimitLine()
  421. ul3.limit = Double(dateTimeUtils.getNowTimeIntervalUTC().advanced(by: -90 * 60))
  422. ul3.lineColor = NSUIColor.systemOrange.withAlphaComponent(0.5)
  423. ul3.lineWidth = 1
  424. BGChart.xAxis.addLimitLine(ul3)
  425. }
  426. }
  427. func createMidnightLines() {
  428. // Draw a line at midnight: useful when showing multiple days of data
  429. if UserDefaultsRepository.showMidnightLines.value {
  430. var midnightTimeInterval = dateTimeUtils.getTimeIntervalMidnightToday()
  431. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  432. let graphStart = dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours)
  433. while midnightTimeInterval > graphStart {
  434. // Large chart
  435. let ul = ChartLimitLine()
  436. ul.limit = Double(midnightTimeInterval)
  437. ul.lineColor = NSUIColor.systemTeal.withAlphaComponent(0.5)
  438. ul.lineDashLengths = [CGFloat(2), CGFloat(5)]
  439. ul.lineWidth = 1
  440. BGChart.xAxis.addLimitLine(ul)
  441. // Small chart
  442. let sl = ChartLimitLine()
  443. sl.limit = Double(midnightTimeInterval)
  444. sl.lineColor = NSUIColor.systemTeal
  445. sl.lineDashLengths = [CGFloat(2), CGFloat(2)]
  446. sl.lineWidth = 1
  447. BGChartFull.xAxis.addLimitLine(sl)
  448. midnightTimeInterval = midnightTimeInterval.advanced(by: -24*60*60)
  449. }
  450. }
  451. }
  452. func updateBGGraphSettings() {
  453. let dataIndex = 0
  454. let dataIndexPrediction = 1
  455. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  456. let linePrediction = BGChart.lineData!.dataSets[dataIndexPrediction] as! LineChartDataSet
  457. if UserDefaultsRepository.showLines.value {
  458. lineBG.lineWidth = 2
  459. linePrediction.lineWidth = 2
  460. } else {
  461. lineBG.lineWidth = 0
  462. linePrediction.lineWidth = 0
  463. }
  464. if UserDefaultsRepository.showDots.value {
  465. lineBG.drawCirclesEnabled = true
  466. linePrediction.drawCirclesEnabled = true
  467. } else {
  468. lineBG.drawCirclesEnabled = false
  469. linePrediction.drawCirclesEnabled = false
  470. }
  471. BGChart.rightAxis.axisMinimum = 0
  472. // Clear limit lines so they don't add multiples when changing the settings
  473. BGChart.rightAxis.removeAllLimitLines()
  474. //Add lower red line based on low alert value
  475. let ll = ChartLimitLine()
  476. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  477. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  478. BGChart.rightAxis.addLimitLine(ll)
  479. //Add upper yellow line based on low alert value
  480. let ul = ChartLimitLine()
  481. ul.limit = Double(UserDefaultsRepository.highLine.value)
  482. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  483. BGChart.rightAxis.addLimitLine(ul)
  484. // Re-create vertical markers in case their settings changed
  485. createVerticalLines()
  486. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  487. BGChart.data?.notifyDataChanged()
  488. BGChart.notifyDataSetChanged()
  489. }
  490. func updateBGGraph() {
  491. if UserDefaultsRepository.debugLog.value { writeDebugLog(value: "##### Start BG Graph #####") }
  492. let dataIndex = 0
  493. let entries = bgData
  494. guard !entries.isEmpty else {
  495. return
  496. }
  497. let mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  498. let smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  499. mainChart.removeAll(keepingCapacity: false)
  500. smallChart.removeAll(keepingCapacity: false)
  501. let maxBGOffset: Float = 50
  502. var colors = [NSUIColor]()
  503. for i in 0..<entries.count{
  504. if Float(entries[i].sgv) > topBG - maxBGOffset {
  505. topBG = Float(entries[i].sgv) + maxBGOffset
  506. }
  507. let value = ChartDataEntry(x: Double(entries[i].date), y: Double(entries[i].sgv), data: formatPillText(line1: bgUnits.toDisplayUnits(String(entries[i].sgv)), time: entries[i].date))
  508. if UserDefaultsRepository.debugLog.value { writeDebugLog(value: "BG: " + value.description) }
  509. mainChart.append(value)
  510. smallChart.append(value)
  511. if Double(entries[i].sgv) >= Double(UserDefaultsRepository.highLine.value) {
  512. colors.append(NSUIColor.systemYellow)
  513. } else if Double(entries[i].sgv) <= Double(UserDefaultsRepository.lowLine.value) {
  514. colors.append(NSUIColor.systemRed)
  515. } else {
  516. colors.append(NSUIColor.systemGreen)
  517. }
  518. }
  519. if UserDefaultsRepository.debugLog.value { writeDebugLog(value: "Total Graph BGs: " + mainChart.entries.count.description) }
  520. // Set Colors
  521. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  522. let lineBGSmall = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  523. lineBG.colors.removeAll()
  524. lineBG.circleColors.removeAll()
  525. lineBGSmall.colors.removeAll()
  526. lineBGSmall.circleColors.removeAll()
  527. if colors.count > 0 {
  528. for i in 0..<colors.count{
  529. mainChart.addColor(colors[i])
  530. mainChart.circleColors.append(colors[i])
  531. smallChart.addColor(colors[i])
  532. smallChart.circleColors.append(colors[i])
  533. }
  534. }
  535. if UserDefaultsRepository.debugLog.value { writeDebugLog(value: "Total Colors: " + mainChart.colors.count.description) }
  536. BGChart.rightAxis.axisMaximum = Double(topBG)
  537. BGChart.setVisibleXRangeMinimum(600)
  538. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  539. BGChart.data?.notifyDataChanged()
  540. BGChart.notifyDataSetChanged()
  541. BGChartFull.rightAxis.axisMaximum = Double(topBG)
  542. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  543. BGChartFull.data?.notifyDataChanged()
  544. BGChartFull.notifyDataSetChanged()
  545. if firstGraphLoad {
  546. var scaleX = CGFloat(UserDefaultsRepository.chartScaleX.value)
  547. print("Scale: \(scaleX)")
  548. if( scaleX > CGFloat(ScaleXMax) ) {
  549. scaleX = CGFloat(ScaleXMax)
  550. UserDefaultsRepository.chartScaleX.value = ScaleXMax
  551. }
  552. BGChart.zoom(scaleX: scaleX, scaleY: 1, x: 1, y: 1)
  553. firstGraphLoad = false
  554. }
  555. // Move to current reading everytime new readings load
  556. // Check if auto-scrolling should be performed
  557. if autoScrollPauseUntil == nil || Date() > autoScrollPauseUntil! {
  558. BGChart.moveViewToAnimated(xValue: dateTimeUtils.getNowTimeIntervalUTC() - (BGChart.visibleXRange * 0.7), yValue: 0.0, axis: .right, duration: 1, easingOption: .easeInBack)
  559. }
  560. }
  561. func updatePredictionGraph(color: UIColor? = nil) {
  562. let dataIndex = 1
  563. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  564. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  565. mainChart.clear()
  566. smallChart.clear()
  567. var colors = [NSUIColor]()
  568. let maxBGOffset: Float = 20
  569. for i in 0..<predictionData.count {
  570. var predictionVal = Double(predictionData[i].sgv)
  571. if Float(predictionVal) > topBG - maxBGOffset {
  572. topBG = Float(predictionVal) + maxBGOffset
  573. }
  574. if i == 0 {
  575. if UserDefaultsRepository.showDots.value {
  576. colors.append((color ?? NSUIColor.systemPurple).withAlphaComponent(0.0))
  577. } else {
  578. colors.append((color ?? NSUIColor.systemPurple).withAlphaComponent(1.0))
  579. }
  580. } else if predictionVal > 400 {
  581. colors.append(color ?? NSUIColor.systemYellow)
  582. } else if predictionVal < 0 {
  583. colors.append(color ?? NSUIColor.systemRed)
  584. } else {
  585. colors.append(color ?? NSUIColor.systemPurple)
  586. }
  587. let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal, data: formatPillText(line1: bgUnits.toDisplayUnits(String(predictionData[i].sgv)), time: predictionData[i].date))
  588. mainChart.addEntry(value)
  589. smallChart.addEntry(value)
  590. }
  591. smallChart.circleColors.removeAll()
  592. smallChart.colors.removeAll()
  593. mainChart.colors.removeAll()
  594. mainChart.circleColors.removeAll()
  595. if colors.count > 0 {
  596. for i in 0..<colors.count {
  597. mainChart.addColor(colors[i])
  598. mainChart.circleColors.append(colors[i])
  599. smallChart.addColor(colors[i])
  600. smallChart.circleColors.append(colors[i])
  601. }
  602. }
  603. BGChart.rightAxis.axisMaximum = Double(topBG)
  604. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  605. BGChart.data?.notifyDataChanged()
  606. BGChart.notifyDataSetChanged()
  607. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  608. BGChartFull.data?.notifyDataChanged()
  609. BGChartFull.notifyDataSetChanged()
  610. }
  611. func updateBasalGraph() {
  612. var dataIndex = 2
  613. BGChart.lineData?.dataSets[dataIndex].clear()
  614. BGChartFull.lineData?.dataSets[dataIndex].clear()
  615. var maxBasal = UserDefaultsRepository.minBasalScale.value
  616. var maxBasalSmall: Double = 0.0
  617. for i in 0..<basalData.count{
  618. let value = ChartDataEntry(x: Double(basalData[i].date), y: Double(basalData[i].basalRate), data: formatPillText(line1: String(basalData[i].basalRate), time: basalData[i].date))
  619. BGChart.data?.dataSets[dataIndex].addEntry(value)
  620. if UserDefaultsRepository.smallGraphTreatments.value {
  621. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  622. }
  623. if basalData[i].basalRate > maxBasal {
  624. maxBasal = basalData[i].basalRate
  625. }
  626. if basalData[i].basalRate > maxBasalSmall {
  627. maxBasalSmall = basalData[i].basalRate
  628. }
  629. }
  630. BGChart.leftAxis.axisMaximum = maxBasal
  631. BGChartFull.leftAxis.axisMaximum = maxBasalSmall
  632. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  633. BGChart.data?.notifyDataChanged()
  634. BGChart.notifyDataSetChanged()
  635. if UserDefaultsRepository.smallGraphTreatments.value {
  636. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  637. BGChartFull.data?.notifyDataChanged()
  638. BGChartFull.notifyDataSetChanged()
  639. }
  640. }
  641. func updateBasalScheduledGraph() {
  642. var dataIndex = 5
  643. BGChart.lineData?.dataSets[dataIndex].clear()
  644. BGChartFull.lineData?.dataSets[dataIndex].clear()
  645. for i in 0..<basalScheduleData.count{
  646. let value = ChartDataEntry(x: Double(basalScheduleData[i].date), y: Double(basalScheduleData[i].basalRate))
  647. BGChart.data?.dataSets[dataIndex].addEntry(value)
  648. if UserDefaultsRepository.smallGraphTreatments.value {
  649. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  650. }
  651. }
  652. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  653. BGChart.data?.notifyDataChanged()
  654. BGChart.notifyDataSetChanged()
  655. if UserDefaultsRepository.smallGraphTreatments.value {
  656. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  657. BGChartFull.data?.notifyDataChanged()
  658. BGChartFull.notifyDataSetChanged()
  659. }
  660. }
  661. func updateBolusGraph() {
  662. var dataIndex = 3
  663. var yTop: Double = 370
  664. var yBottom: Double = 345
  665. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  666. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  667. mainChart.clear()
  668. smallChart.clear()
  669. var colors = [NSUIColor]()
  670. for i in 0..<bolusData.count{
  671. let formatter = NumberFormatter()
  672. formatter.minimumFractionDigits = 0
  673. formatter.maximumFractionDigits = 2
  674. formatter.minimumIntegerDigits = 0
  675. // Check overlapping carbs to shift left if needed
  676. let bolusShift = findNextBolusTime(timeWithin: 240, needle: bolusData[i].date, haystack: bolusData, startingIndex: i)
  677. var dateTimeStamp = bolusData[i].date
  678. // Alpha colors for DIA
  679. let nowTime = dateTimeUtils.getNowTimeIntervalUTC()
  680. let diffTimeHours = (nowTime - dateTimeStamp) / 60 / 60
  681. if diffTimeHours <= 1 {
  682. colors.append(NSUIColor.systemBlue.withAlphaComponent(1.0))
  683. } else if diffTimeHours > 6 {
  684. colors.append(NSUIColor.systemBlue.withAlphaComponent(0.25))
  685. } else {
  686. let thisAlpha = 1.0 - (0.15 * diffTimeHours)
  687. colors.append(NSUIColor.systemBlue.withAlphaComponent(CGFloat(thisAlpha)))
  688. }
  689. if bolusShift {
  690. // Move it half the distance between BG readings
  691. dateTimeStamp = dateTimeStamp - 150
  692. }
  693. // skip if outside of visible area
  694. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  695. if dateTimeStamp < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  696. let dot = ChartDataEntry(x: Double(dateTimeStamp), y: Double(bolusData[i].sgv), data: formatter.string(from: NSNumber(value: bolusData[i].value)))
  697. mainChart.addEntry(dot)
  698. if UserDefaultsRepository.smallGraphTreatments.value {
  699. smallChart.addEntry(dot)
  700. }
  701. }
  702. // Set Colors
  703. let lineBolus = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  704. let lineBolusSmall = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  705. lineBolus.colors.removeAll()
  706. lineBolus.circleColors.removeAll()
  707. lineBolusSmall.colors.removeAll()
  708. lineBolusSmall.circleColors.removeAll()
  709. if colors.count > 0 {
  710. for i in 0..<colors.count{
  711. mainChart.addColor(colors[i])
  712. mainChart.circleColors.append(colors[i])
  713. smallChart.addColor(colors[i])
  714. smallChart.circleColors.append(colors[i])
  715. }
  716. }
  717. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  718. BGChart.data?.notifyDataChanged()
  719. BGChart.notifyDataSetChanged()
  720. if UserDefaultsRepository.smallGraphTreatments.value {
  721. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  722. BGChartFull.data?.notifyDataChanged()
  723. BGChartFull.notifyDataSetChanged()
  724. }
  725. }
  726. func updateCarbGraph() {
  727. var dataIndex = 4
  728. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  729. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  730. mainChart.clear()
  731. smallChart.clear()
  732. var colors = [NSUIColor]()
  733. for i in 0..<carbData.count{
  734. let formatter = NumberFormatter()
  735. formatter.minimumFractionDigits = 0
  736. formatter.maximumFractionDigits = 2
  737. formatter.minimumIntegerDigits = 1
  738. var valueString: String = formatter.string(from: NSNumber(value: carbData[i].value))!
  739. var hours = 3
  740. if carbData[i].absorptionTime > 0 && UserDefaultsRepository.showAbsorption.value {
  741. hours = carbData[i].absorptionTime / 60
  742. valueString += " " + String(hours) + "h"
  743. }
  744. // Check overlapping carbs to shift left if needed
  745. let carbShift = findNextCarbTime(timeWithin: 250, needle: carbData[i].date, haystack: carbData, startingIndex: i)
  746. var dateTimeStamp = carbData[i].date
  747. // Alpha colors for DIA
  748. let nowTime = dateTimeUtils.getNowTimeIntervalUTC()
  749. let diffTimeHours = (nowTime - dateTimeStamp) / 60 / 60
  750. if diffTimeHours <= 0.5 {
  751. colors.append(NSUIColor.systemOrange.withAlphaComponent(1.0))
  752. } else if diffTimeHours > Double(hours) {
  753. colors.append(NSUIColor.systemOrange.withAlphaComponent(0.25))
  754. } else {
  755. let thisAlpha = 1.0 - ((0.75 / Double(hours)) * diffTimeHours)
  756. colors.append(NSUIColor.systemOrange.withAlphaComponent(CGFloat(thisAlpha)))
  757. }
  758. // skip if outside of visible area
  759. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  760. if dateTimeStamp < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  761. if carbShift {
  762. dateTimeStamp = dateTimeStamp - 250
  763. }
  764. let dot = ChartDataEntry(x: Double(dateTimeStamp), y: Double(carbData[i].sgv), data: valueString)
  765. BGChart.data?.dataSets[dataIndex].addEntry(dot)
  766. if UserDefaultsRepository.smallGraphTreatments.value {
  767. BGChartFull.data?.dataSets[dataIndex].addEntry(dot)
  768. }
  769. }
  770. // Set Colors
  771. let lineCarbs = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  772. let lineCarbsSmall = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  773. lineCarbs.colors.removeAll()
  774. lineCarbs.circleColors.removeAll()
  775. lineCarbsSmall.colors.removeAll()
  776. lineCarbsSmall.circleColors.removeAll()
  777. if colors.count > 0 {
  778. for i in 0..<colors.count{
  779. mainChart.addColor(colors[i])
  780. mainChart.circleColors.append(colors[i])
  781. smallChart.addColor(colors[i])
  782. smallChart.circleColors.append(colors[i])
  783. }
  784. }
  785. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  786. BGChart.data?.notifyDataChanged()
  787. BGChart.notifyDataSetChanged()
  788. if UserDefaultsRepository.smallGraphTreatments.value {
  789. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  790. BGChartFull.data?.notifyDataChanged()
  791. BGChartFull.notifyDataSetChanged()
  792. }
  793. }
  794. func updateBGCheckGraph() {
  795. var dataIndex = 7
  796. BGChart.lineData?.dataSets[dataIndex].clear()
  797. BGChartFull.lineData?.dataSets[dataIndex].clear()
  798. for i in 0..<bgCheckData.count{
  799. let formatter = NumberFormatter()
  800. formatter.minimumFractionDigits = 0
  801. formatter.maximumFractionDigits = 2
  802. formatter.minimumIntegerDigits = 1
  803. // skip if outside of visible area
  804. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  805. if bgCheckData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  806. let value = ChartDataEntry(x: Double(bgCheckData[i].date), y: Double(bgCheckData[i].sgv), data: formatPillText(line1: bgUnits.toDisplayUnits(String(bgCheckData[i].sgv)), time: bgCheckData[i].date))
  807. BGChart.data?.dataSets[dataIndex].addEntry(value)
  808. if UserDefaultsRepository.smallGraphTreatments.value {
  809. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  810. }
  811. }
  812. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  813. BGChart.data?.notifyDataChanged()
  814. BGChart.notifyDataSetChanged()
  815. if UserDefaultsRepository.smallGraphTreatments.value {
  816. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  817. BGChartFull.data?.notifyDataChanged()
  818. BGChartFull.notifyDataSetChanged()
  819. }
  820. }
  821. func updateSuspendGraph() {
  822. var dataIndex = 8
  823. BGChart.lineData?.dataSets[dataIndex].clear()
  824. BGChartFull.lineData?.dataSets[dataIndex].clear()
  825. let thisData = suspendGraphData
  826. for i in 0..<thisData.count{
  827. // skip if outside of visible area
  828. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  829. if thisData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  830. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Suspend Pump", time: thisData[i].date))
  831. BGChart.data?.dataSets[dataIndex].addEntry(value)
  832. if UserDefaultsRepository.smallGraphTreatments.value {
  833. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  834. }
  835. }
  836. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  837. BGChart.data?.notifyDataChanged()
  838. BGChart.notifyDataSetChanged()
  839. if UserDefaultsRepository.smallGraphTreatments.value {
  840. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  841. BGChartFull.data?.notifyDataChanged()
  842. BGChartFull.notifyDataSetChanged()
  843. }
  844. }
  845. func updateResumeGraph() {
  846. var dataIndex = 9
  847. BGChart.lineData?.dataSets[dataIndex].clear()
  848. BGChartFull.lineData?.dataSets[dataIndex].clear()
  849. let thisData = resumeGraphData
  850. for i in 0..<thisData.count{
  851. // skip if outside of visible area
  852. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  853. if thisData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  854. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Resume Pump", time: thisData[i].date))
  855. BGChart.data?.dataSets[dataIndex].addEntry(value)
  856. if UserDefaultsRepository.smallGraphTreatments.value {
  857. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  858. }
  859. }
  860. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  861. BGChart.data?.notifyDataChanged()
  862. BGChart.notifyDataSetChanged()
  863. if UserDefaultsRepository.smallGraphTreatments.value {
  864. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  865. BGChartFull.data?.notifyDataChanged()
  866. BGChartFull.notifyDataSetChanged()
  867. }
  868. }
  869. func updateSensorStart() {
  870. var dataIndex = 10
  871. BGChart.lineData?.dataSets[dataIndex].clear()
  872. BGChartFull.lineData?.dataSets[dataIndex].clear()
  873. let thisData = sensorStartGraphData
  874. for i in 0..<thisData.count{
  875. // skip if outside of visible area
  876. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  877. if thisData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  878. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Start Sensor", time: thisData[i].date))
  879. BGChart.data?.dataSets[dataIndex].addEntry(value)
  880. if UserDefaultsRepository.smallGraphTreatments.value {
  881. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  882. }
  883. }
  884. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  885. BGChart.data?.notifyDataChanged()
  886. BGChart.notifyDataSetChanged()
  887. if UserDefaultsRepository.smallGraphTreatments.value {
  888. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  889. BGChartFull.data?.notifyDataChanged()
  890. BGChartFull.notifyDataSetChanged()
  891. }
  892. }
  893. func updateNotes() {
  894. var dataIndex = 11
  895. BGChart.lineData?.dataSets[dataIndex].clear()
  896. BGChartFull.lineData?.dataSets[dataIndex].clear()
  897. let thisData = noteGraphData
  898. for i in 0..<thisData.count{
  899. // skip if outside of visible area
  900. let graphHours = 24 * UserDefaultsRepository.downloadDays.value
  901. if thisData[i].date < dateTimeUtils.getTimeIntervalNHoursAgo(N: graphHours) { continue }
  902. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: thisData[i].note, time: thisData[i].date))
  903. BGChart.data?.dataSets[dataIndex].addEntry(value)
  904. if UserDefaultsRepository.smallGraphTreatments.value {
  905. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  906. }
  907. }
  908. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  909. BGChart.data?.notifyDataChanged()
  910. BGChart.notifyDataSetChanged()
  911. if UserDefaultsRepository.smallGraphTreatments.value {
  912. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  913. BGChartFull.data?.notifyDataChanged()
  914. BGChartFull.notifyDataSetChanged()
  915. }
  916. }
  917. func createSmallBGGraph(){
  918. let entries = bgData
  919. var bgChartEntry = [ChartDataEntry]()
  920. var colors = [NSUIColor]()
  921. var maxBG: Float = UserDefaultsRepository.minBGScale.value
  922. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  923. lineBG.drawCirclesEnabled = false
  924. //line2.setDrawHighlightIndicators(false)
  925. lineBG.highlightEnabled = true
  926. lineBG.drawHorizontalHighlightIndicatorEnabled = false
  927. lineBG.drawVerticalHighlightIndicatorEnabled = false
  928. lineBG.highlightColor = NSUIColor.label
  929. lineBG.drawValuesEnabled = false
  930. lineBG.lineWidth = 1.5
  931. lineBG.axisDependency = YAxis.AxisDependency.right
  932. // Setup Prediction line details
  933. var predictionChartEntry = [ChartDataEntry]()
  934. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  935. linePrediction.drawCirclesEnabled = false
  936. //line2.setDrawHighlightIndicators(false)
  937. linePrediction.setColor(NSUIColor.systemPurple)
  938. linePrediction.highlightEnabled = true
  939. linePrediction.drawHorizontalHighlightIndicatorEnabled = false
  940. linePrediction.drawVerticalHighlightIndicatorEnabled = false
  941. linePrediction.highlightColor = NSUIColor.label
  942. linePrediction.drawValuesEnabled = false
  943. linePrediction.lineWidth = 1.5
  944. linePrediction.axisDependency = YAxis.AxisDependency.right
  945. // create Basal graph data
  946. var chartEntry = [ChartDataEntry]()
  947. var maxBasal = UserDefaultsRepository.minBasalScale.value
  948. let lineBasal = LineChartDataSet(entries:chartEntry, label: "")
  949. lineBasal.setDrawHighlightIndicators(false)
  950. lineBasal.setColor(NSUIColor.systemBlue, alpha: 0.5)
  951. lineBasal.lineWidth = 0
  952. lineBasal.drawFilledEnabled = true
  953. lineBasal.fillColor = NSUIColor.systemBlue
  954. lineBasal.fillAlpha = 0.35
  955. lineBasal.drawCirclesEnabled = false
  956. lineBasal.axisDependency = YAxis.AxisDependency.left
  957. lineBasal.highlightEnabled = false
  958. lineBasal.drawValuesEnabled = false
  959. lineBasal.fillFormatter = basalFillFormatter()
  960. // Boluses
  961. var chartEntryBolus = [ChartDataEntry]()
  962. let lineBolus = LineChartDataSet(entries:chartEntryBolus, label: "")
  963. lineBolus.circleRadius = 2
  964. lineBolus.circleColors = [NSUIColor.systemBlue.withAlphaComponent(0.75)]
  965. lineBolus.drawCircleHoleEnabled = false
  966. lineBolus.setDrawHighlightIndicators(false)
  967. lineBolus.setColor(NSUIColor.systemBlue, alpha: 1.0)
  968. lineBolus.lineWidth = 0
  969. lineBolus.axisDependency = YAxis.AxisDependency.right
  970. lineBolus.valueFormatter = ChartYDataValueFormatter()
  971. lineBolus.valueTextColor = NSUIColor.label
  972. lineBolus.fillColor = NSUIColor.systemBlue
  973. lineBolus.fillAlpha = 0.6
  974. lineBolus.drawCirclesEnabled = true
  975. lineBolus.drawFilledEnabled = false
  976. lineBolus.drawValuesEnabled = false
  977. lineBolus.highlightEnabled = false
  978. // Carbs
  979. var chartEntryCarbs = [ChartDataEntry]()
  980. let lineCarbs = LineChartDataSet(entries:chartEntryCarbs, label: "")
  981. lineCarbs.circleRadius = 2
  982. lineCarbs.circleColors = [NSUIColor.systemOrange.withAlphaComponent(0.75)]
  983. lineCarbs.drawCircleHoleEnabled = false
  984. lineCarbs.setDrawHighlightIndicators(false)
  985. lineCarbs.setColor(NSUIColor.systemBlue, alpha: 1.0)
  986. lineCarbs.lineWidth = 0
  987. lineCarbs.axisDependency = YAxis.AxisDependency.right
  988. lineCarbs.valueFormatter = ChartYDataValueFormatter()
  989. lineCarbs.valueTextColor = NSUIColor.label
  990. lineCarbs.fillColor = NSUIColor.systemOrange
  991. lineCarbs.fillAlpha = 0.6
  992. lineCarbs.drawCirclesEnabled = true
  993. lineCarbs.drawFilledEnabled = false
  994. lineCarbs.drawValuesEnabled = false
  995. lineCarbs.highlightEnabled = false
  996. // create Scheduled Basal graph data
  997. var chartBasalScheduledEntry = [ChartDataEntry]()
  998. let lineBasalScheduled = LineChartDataSet(entries:chartBasalScheduledEntry, label: "")
  999. lineBasalScheduled.setDrawHighlightIndicators(false)
  1000. lineBasalScheduled.setColor(NSUIColor.systemBlue, alpha: 0.8)
  1001. lineBasalScheduled.lineWidth = 0.5
  1002. lineBasalScheduled.drawFilledEnabled = false
  1003. lineBasalScheduled.drawCirclesEnabled = false
  1004. lineBasalScheduled.axisDependency = YAxis.AxisDependency.left
  1005. lineBasalScheduled.highlightEnabled = false
  1006. lineBasalScheduled.drawValuesEnabled = false
  1007. lineBasalScheduled.lineDashLengths = [2, 1]
  1008. // create Override graph data
  1009. var chartOverrideEntry = [ChartDataEntry]()
  1010. let lineOverride = LineChartDataSet(entries:chartOverrideEntry, label: "")
  1011. lineOverride.setDrawHighlightIndicators(false)
  1012. lineOverride.lineWidth = 0
  1013. lineOverride.drawFilledEnabled = true
  1014. lineOverride.fillFormatter = OverrideFillFormatter()
  1015. lineOverride.fillColor = NSUIColor.systemGreen
  1016. lineOverride.fillAlpha = 0.6
  1017. lineOverride.drawCirclesEnabled = false
  1018. lineOverride.axisDependency = YAxis.AxisDependency.right
  1019. lineOverride.highlightEnabled = true
  1020. lineOverride.drawValuesEnabled = false
  1021. // BG Check
  1022. var chartEntryBGCheck = [ChartDataEntry]()
  1023. let lineBGCheck = LineChartDataSet(entries:chartEntryBGCheck, label: "")
  1024. lineBGCheck.circleRadius = 2
  1025. lineBGCheck.circleColors = [NSUIColor.systemRed.withAlphaComponent(0.75)]
  1026. lineBGCheck.drawCircleHoleEnabled = false
  1027. lineBGCheck.setDrawHighlightIndicators(false)
  1028. lineBGCheck.setColor(NSUIColor.systemRed, alpha: 1.0)
  1029. lineBGCheck.drawCirclesEnabled = true
  1030. lineBGCheck.lineWidth = 0
  1031. lineBGCheck.highlightEnabled = false
  1032. lineBGCheck.axisDependency = YAxis.AxisDependency.right
  1033. lineBGCheck.valueFormatter = ChartYDataValueFormatter()
  1034. lineBGCheck.drawValuesEnabled = false
  1035. // Suspend Pump
  1036. var chartEntrySuspend = [ChartDataEntry]()
  1037. let lineSuspend = LineChartDataSet(entries:chartEntrySuspend, label: "")
  1038. lineSuspend.circleRadius = 2
  1039. lineSuspend.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  1040. lineSuspend.drawCircleHoleEnabled = false
  1041. lineSuspend.setDrawHighlightIndicators(false)
  1042. lineSuspend.setColor(NSUIColor.systemGray2, alpha: 1.0)
  1043. lineSuspend.drawCirclesEnabled = true
  1044. lineSuspend.lineWidth = 0
  1045. lineSuspend.highlightEnabled = false
  1046. lineSuspend.axisDependency = YAxis.AxisDependency.right
  1047. lineSuspend.valueFormatter = ChartYDataValueFormatter()
  1048. lineSuspend.drawValuesEnabled = false
  1049. // Resume Pump
  1050. var chartEntryResume = [ChartDataEntry]()
  1051. let lineResume = LineChartDataSet(entries:chartEntryResume, label: "")
  1052. lineResume.circleRadius = 2
  1053. lineResume.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  1054. lineResume.drawCircleHoleEnabled = false
  1055. lineResume.setDrawHighlightIndicators(false)
  1056. lineResume.setColor(NSUIColor.systemGray4, alpha: 1.0)
  1057. lineResume.drawCirclesEnabled = true
  1058. lineResume.lineWidth = 0
  1059. lineResume.highlightEnabled = false
  1060. lineResume.axisDependency = YAxis.AxisDependency.right
  1061. lineResume.valueFormatter = ChartYDataValueFormatter()
  1062. lineResume.drawValuesEnabled = false
  1063. // Sensor Start
  1064. var chartEntrySensor = [ChartDataEntry]()
  1065. let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
  1066. lineSensor.circleRadius = 2
  1067. lineSensor.circleColors = [NSUIColor.systemIndigo.withAlphaComponent(0.75)]
  1068. lineSensor.drawCircleHoleEnabled = false
  1069. lineSensor.setDrawHighlightIndicators(false)
  1070. lineSensor.setColor(NSUIColor.systemGray3, alpha: 1.0)
  1071. lineSensor.drawCirclesEnabled = true
  1072. lineSensor.lineWidth = 0
  1073. lineSensor.highlightEnabled = false
  1074. lineSensor.axisDependency = YAxis.AxisDependency.right
  1075. lineSensor.valueFormatter = ChartYDataValueFormatter()
  1076. lineSensor.drawValuesEnabled = false
  1077. // Notes
  1078. var chartEntryNote = [ChartDataEntry]()
  1079. let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
  1080. lineNote.circleRadius = 2
  1081. lineNote.circleColors = [NSUIColor.systemGray.withAlphaComponent(0.75)]
  1082. lineNote.drawCircleHoleEnabled = false
  1083. lineNote.setDrawHighlightIndicators(false)
  1084. lineNote.setColor(NSUIColor.systemGray3, alpha: 1.0)
  1085. lineNote.drawCirclesEnabled = true
  1086. lineNote.lineWidth = 0
  1087. lineNote.highlightEnabled = false
  1088. lineNote.axisDependency = YAxis.AxisDependency.right
  1089. lineNote.valueFormatter = ChartYDataValueFormatter()
  1090. lineNote.drawValuesEnabled = false
  1091. // Setup COB Prediction line details
  1092. var COBpredictionChartEntry = [ChartDataEntry]()
  1093. let COBlinePrediction = LineChartDataSet(entries:COBpredictionChartEntry, label: "")
  1094. COBlinePrediction.drawCirclesEnabled = false
  1095. COBlinePrediction.setColor(NSUIColor.systemPurple)
  1096. COBlinePrediction.highlightEnabled = true
  1097. COBlinePrediction.drawHorizontalHighlightIndicatorEnabled = false
  1098. COBlinePrediction.drawVerticalHighlightIndicatorEnabled = false
  1099. COBlinePrediction.highlightColor = NSUIColor.label
  1100. COBlinePrediction.drawValuesEnabled = false
  1101. COBlinePrediction.lineWidth = 1.5
  1102. COBlinePrediction.axisDependency = YAxis.AxisDependency.right
  1103. // Setup IOB Prediction line details
  1104. var IOBpredictionChartEntry = [ChartDataEntry]()
  1105. let IOBlinePrediction = LineChartDataSet(entries:IOBpredictionChartEntry, label: "")
  1106. IOBlinePrediction.drawCirclesEnabled = false
  1107. IOBlinePrediction.setColor(NSUIColor.systemPurple)
  1108. IOBlinePrediction.highlightEnabled = true
  1109. IOBlinePrediction.drawHorizontalHighlightIndicatorEnabled = false
  1110. IOBlinePrediction.drawVerticalHighlightIndicatorEnabled = false
  1111. IOBlinePrediction.highlightColor = NSUIColor.label
  1112. IOBlinePrediction.drawValuesEnabled = false
  1113. IOBlinePrediction.lineWidth = 1.5
  1114. IOBlinePrediction.axisDependency = YAxis.AxisDependency.right
  1115. // Setup UAM Prediction line details
  1116. var UAMpredictionChartEntry = [ChartDataEntry]()
  1117. let UAMlinePrediction = LineChartDataSet(entries:UAMpredictionChartEntry, label: "")
  1118. UAMlinePrediction.drawCirclesEnabled = false
  1119. UAMlinePrediction.setColor(NSUIColor.systemPurple)
  1120. UAMlinePrediction.highlightEnabled = true
  1121. UAMlinePrediction.drawHorizontalHighlightIndicatorEnabled = false
  1122. UAMlinePrediction.drawVerticalHighlightIndicatorEnabled = false
  1123. UAMlinePrediction.highlightColor = NSUIColor.label
  1124. UAMlinePrediction.drawValuesEnabled = false
  1125. UAMlinePrediction.lineWidth = 1.5
  1126. UAMlinePrediction.axisDependency = YAxis.AxisDependency.right
  1127. // Setup ZT Prediction line details
  1128. var ZTpredictionChartEntry = [ChartDataEntry]()
  1129. let ZTlinePrediction = LineChartDataSet(entries:ZTpredictionChartEntry, label: "")
  1130. ZTlinePrediction.drawCirclesEnabled = false
  1131. ZTlinePrediction.setColor(NSUIColor.systemPurple)
  1132. ZTlinePrediction.highlightEnabled = true
  1133. ZTlinePrediction.drawHorizontalHighlightIndicatorEnabled = false
  1134. ZTlinePrediction.drawVerticalHighlightIndicatorEnabled = false
  1135. ZTlinePrediction.highlightColor = NSUIColor.label
  1136. ZTlinePrediction.drawValuesEnabled = false
  1137. ZTlinePrediction.lineWidth = 1.5
  1138. ZTlinePrediction.axisDependency = YAxis.AxisDependency.right
  1139. // Setup the chart data of all lines
  1140. let data = LineChartData()
  1141. data.append(lineBG) // Dataset 0
  1142. data.append(linePrediction) // Dataset 1
  1143. data.append(lineBasal) // Dataset 2
  1144. data.append(lineBolus) // Dataset 3
  1145. data.append(lineCarbs) // Dataset 4
  1146. data.append(lineBasalScheduled) // Dataset 5
  1147. data.append(lineOverride) // Dataset 6
  1148. data.append(lineBGCheck) // Dataset 7
  1149. data.append(lineSuspend) // Dataset 8
  1150. data.append(lineResume) // Dataset 9
  1151. data.append(lineSensor) // Dataset 10
  1152. data.append(lineNote) // Dataset 11
  1153. data.append(ZTlinePrediction) // Dataset 12
  1154. data.append(IOBlinePrediction) // Dataset 13
  1155. data.append(COBlinePrediction) // Dataset 14
  1156. data.append(UAMlinePrediction) // Dataset 15
  1157. BGChartFull.highlightPerDragEnabled = true
  1158. BGChartFull.leftAxis.enabled = false
  1159. BGChartFull.leftAxis.axisMaximum = maxBasal
  1160. BGChartFull.leftAxis.axisMinimum = 0
  1161. BGChartFull.rightAxis.enabled = false
  1162. BGChartFull.rightAxis.axisMinimum = 0.0
  1163. BGChartFull.rightAxis.axisMaximum = Double(maxBG)
  1164. BGChartFull.xAxis.drawLabelsEnabled = false
  1165. BGChartFull.xAxis.drawGridLinesEnabled = false
  1166. BGChartFull.xAxis.drawAxisLineEnabled = false
  1167. BGChartFull.legend.enabled = false
  1168. BGChartFull.scaleYEnabled = false
  1169. BGChartFull.scaleXEnabled = false
  1170. BGChartFull.drawGridBackgroundEnabled = false
  1171. BGChartFull.data = data
  1172. }
  1173. func updateOverrideGraph() {
  1174. var dataIndex = 6
  1175. var yTop: Double = Double(topBG - 5)
  1176. var yBottom: Double = Double(topBG - 25)
  1177. var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  1178. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  1179. chart.clear()
  1180. smallChart.clear()
  1181. let thisData = overrideGraphData
  1182. var colors = [NSUIColor]()
  1183. for i in 0..<thisData.count{
  1184. let thisItem = thisData[i]
  1185. let multiplier = thisItem.insulNeedsScaleFactor as! Double * 100.0
  1186. var labelText = thisItem.reason + "\r\n"
  1187. labelText += String(Int(thisItem.insulNeedsScaleFactor * 100)) + "% "
  1188. if thisItem.correctionRange.count == 2 {
  1189. labelText += String(thisItem.correctionRange[0]) + "-" + String(thisItem.correctionRange[1])
  1190. }
  1191. if thisItem.enteredBy.count > 0 {
  1192. labelText += "\r\nEntered By: " + thisItem.enteredBy
  1193. }
  1194. // Start Dot
  1195. // Shift dots 30 seconds to create an empty 0 space between consecutive temps
  1196. let preStartDot = ChartDataEntry(x: Double(thisItem.date), y: yBottom, data: labelText)
  1197. BGChart.data?.dataSets[dataIndex].addEntry(preStartDot)
  1198. if UserDefaultsRepository.smallGraphTreatments.value {
  1199. BGChartFull.data?.dataSets[dataIndex].addEntry(preStartDot)
  1200. }
  1201. let startDot = ChartDataEntry(x: Double(thisItem.date + 1), y: yTop, data: labelText)
  1202. BGChart.data?.dataSets[dataIndex].addEntry(startDot)
  1203. if UserDefaultsRepository.smallGraphTreatments.value {
  1204. BGChartFull.data?.dataSets[dataIndex].addEntry(startDot)
  1205. }
  1206. // End Dot
  1207. let endDot = ChartDataEntry(x: Double(thisItem.endDate - 2), y: yTop, data: labelText)
  1208. BGChart.data?.dataSets[dataIndex].addEntry(endDot)
  1209. if UserDefaultsRepository.smallGraphTreatments.value {
  1210. BGChartFull.data?.dataSets[dataIndex].addEntry(endDot)
  1211. }
  1212. // Post end dot
  1213. let postEndDot = ChartDataEntry(x: Double(thisItem.endDate - 1), y: yBottom, data: labelText)
  1214. BGChart.data?.dataSets[dataIndex].addEntry(postEndDot)
  1215. if UserDefaultsRepository.smallGraphTreatments.value {
  1216. BGChartFull.data?.dataSets[dataIndex].addEntry(postEndDot)
  1217. }
  1218. }
  1219. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  1220. BGChart.data?.notifyDataChanged()
  1221. BGChart.notifyDataSetChanged()
  1222. if UserDefaultsRepository.smallGraphTreatments.value {
  1223. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  1224. BGChartFull.data?.notifyDataChanged()
  1225. BGChartFull.notifyDataSetChanged()
  1226. }
  1227. }
  1228. func formatPillText(line1: String, time: TimeInterval, line2: String? = nil) -> String {
  1229. let dateFormatter = DateFormatter()
  1230. if dateTimeUtils.is24Hour() {
  1231. dateFormatter.setLocalizedDateFormatFromTemplate("HH:mm")
  1232. } else {
  1233. dateFormatter.setLocalizedDateFormatFromTemplate("hh:mm")
  1234. }
  1235. let date = Date(timeIntervalSince1970: time)
  1236. let formattedDate = dateFormatter.string(from: date)
  1237. if let line2 = line2 {
  1238. return line1 + "\r\n" + line2 + "\r\n" + formattedDate
  1239. } else {
  1240. return line1 + "\r\n" + formattedDate
  1241. }
  1242. }
  1243. func updatePredictionGraphGeneric(
  1244. dataIndex: Int,
  1245. predictionData: [ShareGlucoseData],
  1246. chartLabel: String,
  1247. color: UIColor
  1248. ) {
  1249. let mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  1250. let smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  1251. mainChart.clear()
  1252. smallChart.clear()
  1253. var colors = [NSUIColor]()
  1254. let maxBGOffset: Float = 20
  1255. for i in 0..<predictionData.count {
  1256. let predictionVal = Double(predictionData[i].sgv)
  1257. if Float(predictionVal) > topBG - maxBGOffset {
  1258. topBG = Float(predictionVal) + maxBGOffset
  1259. }
  1260. if i == 0 {
  1261. if UserDefaultsRepository.showDots.value {
  1262. colors.append((color).withAlphaComponent(0.0))
  1263. } else {
  1264. colors.append((color).withAlphaComponent(1.0))
  1265. }
  1266. } else {
  1267. colors.append(color)
  1268. }
  1269. let value = ChartDataEntry(
  1270. x: predictionData[i].date,
  1271. y: predictionVal,
  1272. data: formatPillText(
  1273. line1: chartLabel,
  1274. time: predictionData[i].date,
  1275. line2: bgUnits.toDisplayUnits(String(predictionVal))
  1276. )
  1277. )
  1278. mainChart.addEntry(value)
  1279. smallChart.addEntry(value)
  1280. }
  1281. smallChart.circleColors.removeAll()
  1282. smallChart.colors.removeAll()
  1283. mainChart.colors.removeAll()
  1284. mainChart.circleColors.removeAll()
  1285. if colors.count > 0 {
  1286. for color in colors {
  1287. mainChart.addColor(color)
  1288. mainChart.circleColors.append(color)
  1289. smallChart.addColor(color)
  1290. smallChart.circleColors.append(color)
  1291. }
  1292. }
  1293. BGChart.rightAxis.axisMaximum = Double(topBG)
  1294. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  1295. BGChart.data?.notifyDataChanged()
  1296. BGChart.notifyDataSetChanged()
  1297. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  1298. BGChartFull.data?.notifyDataChanged()
  1299. BGChartFull.notifyDataSetChanged()
  1300. }
  1301. }