Graphs.swift 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  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. self.BGChart.clear()
  32. // Create the BG Graph Data
  33. let entries = bgData
  34. var bgChartEntry = [ChartDataEntry]()
  35. var colors = [NSUIColor]()
  36. var maxBG: Float = UserDefaultsRepository.minBGScale.value
  37. // Setup BG line details
  38. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  39. lineBG.circleRadius = CGFloat(globalVariables.dotBG)
  40. lineBG.circleColors = [NSUIColor.systemGreen]
  41. lineBG.drawCircleHoleEnabled = false
  42. lineBG.axisDependency = YAxis.AxisDependency.right
  43. lineBG.highlightEnabled = true
  44. lineBG.drawValuesEnabled = false
  45. if UserDefaultsRepository.showLines.value {
  46. lineBG.lineWidth = 2
  47. } else {
  48. lineBG.lineWidth = 0
  49. }
  50. if UserDefaultsRepository.showDots.value {
  51. lineBG.drawCirclesEnabled = true
  52. } else {
  53. lineBG.drawCirclesEnabled = false
  54. }
  55. lineBG.setDrawHighlightIndicators(false)
  56. lineBG.valueFont.withSize(50)
  57. // Setup Prediction line details
  58. var predictionChartEntry = [ChartDataEntry]()
  59. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  60. linePrediction.circleRadius = CGFloat(globalVariables.dotBG)
  61. linePrediction.circleColors = [NSUIColor.systemPurple]
  62. linePrediction.colors = [NSUIColor.systemPurple]
  63. linePrediction.drawCircleHoleEnabled = false
  64. linePrediction.axisDependency = YAxis.AxisDependency.right
  65. linePrediction.highlightEnabled = true
  66. linePrediction.drawValuesEnabled = false
  67. if UserDefaultsRepository.showLines.value {
  68. linePrediction.lineWidth = 2
  69. } else {
  70. linePrediction.lineWidth = 0
  71. }
  72. if UserDefaultsRepository.showDots.value {
  73. linePrediction.drawCirclesEnabled = true
  74. } else {
  75. linePrediction.drawCirclesEnabled = false
  76. }
  77. linePrediction.setDrawHighlightIndicators(false)
  78. linePrediction.valueFont.withSize(50)
  79. // create Basal graph data
  80. var chartEntry = [ChartDataEntry]()
  81. var maxBasal = UserDefaultsRepository.minBasalScale.value
  82. let lineBasal = LineChartDataSet(entries:chartEntry, label: "")
  83. lineBasal.setDrawHighlightIndicators(false)
  84. lineBasal.setColor(NSUIColor.systemBlue, alpha: 0.5)
  85. lineBasal.lineWidth = 0
  86. lineBasal.drawFilledEnabled = true
  87. lineBasal.fillColor = NSUIColor.systemBlue
  88. lineBasal.fillAlpha = 0.5
  89. lineBasal.drawCirclesEnabled = false
  90. lineBasal.axisDependency = YAxis.AxisDependency.left
  91. lineBasal.highlightEnabled = true
  92. lineBasal.drawValuesEnabled = false
  93. lineBasal.fillFormatter = basalFillFormatter()
  94. // Boluses
  95. var chartEntryBolus = [ChartDataEntry]()
  96. let lineBolus = LineChartDataSet(entries:chartEntryBolus, label: "")
  97. lineBolus.circleRadius = CGFloat(globalVariables.dotBolus)
  98. lineBolus.circleColors = [NSUIColor.systemBlue.withAlphaComponent(0.75)]
  99. lineBolus.drawCircleHoleEnabled = false
  100. lineBolus.setDrawHighlightIndicators(false)
  101. lineBolus.setColor(NSUIColor.systemBlue, alpha: 1.0)
  102. lineBolus.lineWidth = 0
  103. lineBolus.axisDependency = YAxis.AxisDependency.right
  104. lineBolus.valueFormatter = ChartYDataValueFormatter()
  105. lineBolus.valueTextColor = NSUIColor.label
  106. lineBolus.fillColor = NSUIColor.systemBlue
  107. lineBolus.fillAlpha = 0.6
  108. lineBolus.drawCirclesEnabled = true
  109. lineBolus.drawFilledEnabled = false
  110. if UserDefaultsRepository.showValues.value {
  111. lineBolus.drawValuesEnabled = true
  112. lineBolus.highlightEnabled = false
  113. } else {
  114. lineBolus.drawValuesEnabled = false
  115. lineBolus.highlightEnabled = true
  116. }
  117. // Carbs
  118. var chartEntryCarbs = [ChartDataEntry]()
  119. let lineCarbs = LineChartDataSet(entries:chartEntryCarbs, label: "")
  120. lineCarbs.circleRadius = CGFloat(globalVariables.dotCarb)
  121. lineCarbs.circleColors = [NSUIColor.systemOrange.withAlphaComponent(0.75)]
  122. lineCarbs.drawCircleHoleEnabled = false
  123. lineCarbs.setDrawHighlightIndicators(false)
  124. lineCarbs.setColor(NSUIColor.systemBlue, alpha: 1.0)
  125. lineCarbs.lineWidth = 0
  126. lineCarbs.axisDependency = YAxis.AxisDependency.right
  127. lineCarbs.valueFormatter = ChartYDataValueFormatter()
  128. lineCarbs.valueTextColor = NSUIColor.label
  129. lineCarbs.fillColor = NSUIColor.systemOrange
  130. lineCarbs.fillAlpha = 0.6
  131. lineCarbs.drawCirclesEnabled = true
  132. lineCarbs.drawFilledEnabled = false
  133. if UserDefaultsRepository.showValues.value {
  134. lineCarbs.drawValuesEnabled = true
  135. lineCarbs.highlightEnabled = false
  136. } else {
  137. lineCarbs.drawValuesEnabled = false
  138. lineCarbs.highlightEnabled = true
  139. }
  140. // create Scheduled Basal graph data
  141. var chartBasalScheduledEntry = [ChartDataEntry]()
  142. let lineBasalScheduled = LineChartDataSet(entries:chartBasalScheduledEntry, label: "")
  143. lineBasalScheduled.setDrawHighlightIndicators(false)
  144. lineBasalScheduled.setColor(NSUIColor.systemBlue, alpha: 0.8)
  145. lineBasalScheduled.lineWidth = 2
  146. lineBasalScheduled.drawFilledEnabled = false
  147. lineBasalScheduled.drawCirclesEnabled = false
  148. lineBasalScheduled.axisDependency = YAxis.AxisDependency.left
  149. lineBasalScheduled.highlightEnabled = false
  150. lineBasalScheduled.drawValuesEnabled = false
  151. lineBasalScheduled.lineDashLengths = [10.0, 5.0]
  152. // create Override graph data
  153. var chartOverrideEntry = [ChartDataEntry]()
  154. let lineOverride = LineChartDataSet(entries:chartOverrideEntry, label: "")
  155. lineOverride.setDrawHighlightIndicators(false)
  156. lineOverride.lineWidth = 0
  157. lineOverride.drawFilledEnabled = true
  158. lineOverride.fillFormatter = OverrideFillFormatter()
  159. lineOverride.fillColor = NSUIColor.systemGreen
  160. lineOverride.fillAlpha = 0.6
  161. lineOverride.drawCirclesEnabled = false
  162. lineOverride.axisDependency = YAxis.AxisDependency.right
  163. lineOverride.highlightEnabled = true
  164. lineOverride.drawValuesEnabled = false
  165. // BG Check
  166. var chartEntryBGCheck = [ChartDataEntry]()
  167. let lineBGCheck = LineChartDataSet(entries:chartEntryBGCheck, label: "")
  168. lineBGCheck.circleRadius = CGFloat(globalVariables.dotOther)
  169. lineBGCheck.circleColors = [NSUIColor.systemRed.withAlphaComponent(0.75)]
  170. lineBGCheck.drawCircleHoleEnabled = false
  171. lineBGCheck.setDrawHighlightIndicators(false)
  172. lineBGCheck.setColor(NSUIColor.systemRed, alpha: 1.0)
  173. lineBGCheck.drawCirclesEnabled = true
  174. lineBGCheck.lineWidth = 0
  175. lineBGCheck.highlightEnabled = true
  176. lineBGCheck.axisDependency = YAxis.AxisDependency.right
  177. lineBGCheck.valueFormatter = ChartYDataValueFormatter()
  178. lineBGCheck.drawValuesEnabled = false
  179. // Suspend Pump
  180. var chartEntrySuspend = [ChartDataEntry]()
  181. let lineSuspend = LineChartDataSet(entries:chartEntrySuspend, label: "")
  182. lineSuspend.circleRadius = CGFloat(globalVariables.dotOther)
  183. lineSuspend.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  184. lineSuspend.drawCircleHoleEnabled = false
  185. lineSuspend.setDrawHighlightIndicators(false)
  186. lineSuspend.setColor(NSUIColor.systemGray2, alpha: 1.0)
  187. lineSuspend.drawCirclesEnabled = true
  188. lineSuspend.lineWidth = 0
  189. lineSuspend.highlightEnabled = true
  190. lineSuspend.axisDependency = YAxis.AxisDependency.right
  191. lineSuspend.valueFormatter = ChartYDataValueFormatter()
  192. lineSuspend.drawValuesEnabled = false
  193. // Resume Pump
  194. var chartEntryResume = [ChartDataEntry]()
  195. let lineResume = LineChartDataSet(entries:chartEntryResume, label: "")
  196. lineResume.circleRadius = CGFloat(globalVariables.dotOther)
  197. lineResume.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  198. lineResume.drawCircleHoleEnabled = false
  199. lineResume.setDrawHighlightIndicators(false)
  200. lineResume.setColor(NSUIColor.systemGray4, alpha: 1.0)
  201. lineResume.drawCirclesEnabled = true
  202. lineResume.lineWidth = 0
  203. lineResume.highlightEnabled = true
  204. lineResume.axisDependency = YAxis.AxisDependency.right
  205. lineResume.valueFormatter = ChartYDataValueFormatter()
  206. lineResume.drawValuesEnabled = false
  207. // Sensor Start
  208. var chartEntrySensor = [ChartDataEntry]()
  209. let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
  210. lineSensor.circleRadius = CGFloat(globalVariables.dotOther)
  211. lineSensor.circleColors = [NSUIColor.systemIndigo.withAlphaComponent(0.75)]
  212. lineSensor.drawCircleHoleEnabled = false
  213. lineSensor.setDrawHighlightIndicators(false)
  214. lineSensor.setColor(NSUIColor.systemGray3, alpha: 1.0)
  215. lineSensor.drawCirclesEnabled = true
  216. lineSensor.lineWidth = 0
  217. lineSensor.highlightEnabled = true
  218. lineSensor.axisDependency = YAxis.AxisDependency.right
  219. lineSensor.valueFormatter = ChartYDataValueFormatter()
  220. lineSensor.drawValuesEnabled = false
  221. // Notes
  222. var chartEntryNote = [ChartDataEntry]()
  223. let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
  224. lineNote.circleRadius = CGFloat(globalVariables.dotOther)
  225. lineNote.circleColors = [NSUIColor.systemGray.withAlphaComponent(0.75)]
  226. lineNote.drawCircleHoleEnabled = false
  227. lineNote.setDrawHighlightIndicators(false)
  228. lineNote.setColor(NSUIColor.systemGray3, alpha: 1.0)
  229. lineNote.drawCirclesEnabled = true
  230. lineNote.lineWidth = 0
  231. lineNote.highlightEnabled = true
  232. lineNote.axisDependency = YAxis.AxisDependency.right
  233. lineNote.valueFormatter = ChartYDataValueFormatter()
  234. lineNote.drawValuesEnabled = false
  235. // Setup the chart data of all lines
  236. let data = LineChartData()
  237. data.addDataSet(lineBG) // Dataset 0
  238. data.addDataSet(linePrediction) // Dataset 1
  239. data.addDataSet(lineBasal) // Dataset 2
  240. data.addDataSet(lineBolus) // Dataset 3
  241. data.addDataSet(lineCarbs) // Dataset 4
  242. data.addDataSet(lineBasalScheduled) // Dataset 5
  243. data.addDataSet(lineOverride) // Dataset 6
  244. data.addDataSet(lineBGCheck) // Dataset 7
  245. data.addDataSet(lineSuspend) // Dataset 8
  246. data.addDataSet(lineResume) // Dataset 9
  247. data.addDataSet(lineSensor) // Dataset 10
  248. data.addDataSet(lineNote) // Dataset 11
  249. data.setValueFont(UIFont.systemFont(ofSize: 12))
  250. // Add marker popups for bolus and carbs
  251. let marker = PillMarker(color: .secondarySystemBackground, font: UIFont.boldSystemFont(ofSize: 14), textColor: .label)
  252. BGChart.marker = marker
  253. // Clear limit lines so they don't add multiples when changing the settings
  254. BGChart.rightAxis.removeAllLimitLines()
  255. //Add lower red line based on low alert value
  256. let ll = ChartLimitLine()
  257. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  258. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  259. BGChart.rightAxis.addLimitLine(ll)
  260. //Add upper yellow line based on low alert value
  261. let ul = ChartLimitLine()
  262. ul.limit = Double(UserDefaultsRepository.highLine.value)
  263. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  264. BGChart.rightAxis.addLimitLine(ul)
  265. // Add Now Line
  266. createNowAndDIALines()
  267. startGraphNowTimer()
  268. // Setup the main graph overall details
  269. BGChart.xAxis.valueFormatter = ChartXValueFormatter()
  270. BGChart.xAxis.granularity = 1800
  271. BGChart.xAxis.labelTextColor = NSUIColor.label
  272. BGChart.xAxis.labelPosition = XAxis.LabelPosition.bottom
  273. BGChart.xAxis.drawGridLinesEnabled = false
  274. BGChart.leftAxis.enabled = true
  275. BGChart.leftAxis.labelPosition = YAxis.LabelPosition.insideChart
  276. BGChart.leftAxis.axisMaximum = maxBasal
  277. BGChart.leftAxis.axisMinimum = 0
  278. BGChart.leftAxis.drawGridLinesEnabled = false
  279. BGChart.leftAxis.granularityEnabled = true
  280. BGChart.leftAxis.granularity = 0.5
  281. BGChart.rightAxis.labelTextColor = NSUIColor.label
  282. BGChart.rightAxis.labelPosition = YAxis.LabelPosition.insideChart
  283. BGChart.rightAxis.axisMinimum = 0.0
  284. BGChart.rightAxis.axisMaximum = Double(maxBG)
  285. BGChart.rightAxis.gridLineDashLengths = [5.0, 5.0]
  286. BGChart.rightAxis.drawGridLinesEnabled = false
  287. BGChart.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
  288. BGChart.rightAxis.granularityEnabled = true
  289. BGChart.rightAxis.granularity = 50
  290. BGChart.maxHighlightDistance = 15.0
  291. BGChart.legend.enabled = false
  292. BGChart.scaleYEnabled = false
  293. BGChart.drawGridBackgroundEnabled = true
  294. BGChart.gridBackgroundColor = NSUIColor.secondarySystemBackground
  295. BGChart.highlightValue(nil, callDelegate: false)
  296. BGChart.data = data
  297. BGChart.setExtraOffsets(left: 10, top: 10, right: 10, bottom: 10)
  298. }
  299. func createNowAndDIALines() {
  300. BGChart.xAxis.removeAllLimitLines()
  301. let ul = ChartLimitLine()
  302. ul.limit = Double(dateTimeUtils.getNowTimeIntervalUTC())
  303. ul.lineColor = NSUIColor.systemGray.withAlphaComponent(0.5)
  304. ul.lineWidth = 1
  305. BGChart.xAxis.addLimitLine(ul)
  306. if UserDefaultsRepository.showDIALines.value {
  307. for i in 1..<7 {
  308. let ul = ChartLimitLine()
  309. ul.limit = Double(dateTimeUtils.getNowTimeIntervalUTC() - Double(i * 60 * 60))
  310. ul.lineColor = NSUIColor.systemGray.withAlphaComponent(0.3)
  311. let dash = 10.0 - Double(i)
  312. let space = 5.0 + Double(i)
  313. ul.lineDashLengths = [CGFloat(dash), CGFloat(space)]
  314. ul.lineWidth = 1
  315. BGChart.xAxis.addLimitLine(ul)
  316. }
  317. }
  318. }
  319. func updateBGGraphSettings() {
  320. let dataIndex = 0
  321. let dataIndexPrediction = 1
  322. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  323. let linePrediction = BGChart.lineData!.dataSets[dataIndexPrediction] as! LineChartDataSet
  324. if UserDefaultsRepository.showLines.value {
  325. lineBG.lineWidth = 2
  326. linePrediction.lineWidth = 2
  327. } else {
  328. lineBG.lineWidth = 0
  329. linePrediction.lineWidth = 0
  330. }
  331. if UserDefaultsRepository.showDots.value {
  332. lineBG.drawCirclesEnabled = true
  333. linePrediction.drawCirclesEnabled = true
  334. } else {
  335. lineBG.drawCirclesEnabled = false
  336. linePrediction.drawCirclesEnabled = false
  337. }
  338. BGChart.rightAxis.axisMinimum = 0
  339. // Clear limit lines so they don't add multiples when changing the settings
  340. BGChart.rightAxis.removeAllLimitLines()
  341. //Add lower red line based on low alert value
  342. let ll = ChartLimitLine()
  343. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  344. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  345. BGChart.rightAxis.addLimitLine(ll)
  346. //Add upper yellow line based on low alert value
  347. let ul = ChartLimitLine()
  348. ul.limit = Double(UserDefaultsRepository.highLine.value)
  349. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  350. BGChart.rightAxis.addLimitLine(ul)
  351. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  352. BGChart.data?.notifyDataChanged()
  353. BGChart.notifyDataSetChanged()
  354. }
  355. func updateBGGraph() {
  356. let dataIndex = 0
  357. let entries = bgData
  358. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  359. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  360. mainChart.clear()
  361. smallChart.clear()
  362. var maxBGOffset: Float = 50
  363. var colors = [NSUIColor]()
  364. for i in 0..<entries.count{
  365. if Float(entries[i].sgv) > topBG - maxBGOffset {
  366. topBG = Float(entries[i].sgv) + maxBGOffset
  367. }
  368. 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))
  369. mainChart.addEntry(value)
  370. smallChart.addEntry(value)
  371. if Double(entries[i].sgv) >= Double(UserDefaultsRepository.highLine.value) {
  372. colors.append(NSUIColor.systemYellow)
  373. } else if Double(entries[i].sgv) <= Double(UserDefaultsRepository.lowLine.value) {
  374. colors.append(NSUIColor.systemRed)
  375. } else {
  376. colors.append(NSUIColor.systemGreen)
  377. }
  378. }
  379. // Set Colors
  380. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  381. let lineBGSmall = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  382. lineBG.colors.removeAll()
  383. lineBG.circleColors.removeAll()
  384. lineBGSmall.colors.removeAll()
  385. lineBGSmall.circleColors.removeAll()
  386. if colors.count > 0 {
  387. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: colors") }
  388. for i in 0..<colors.count{
  389. mainChart.addColor(colors[i])
  390. mainChart.circleColors.append(colors[i])
  391. smallChart.addColor(colors[i])
  392. smallChart.circleColors.append(colors[i])
  393. }
  394. }
  395. BGChart.rightAxis.axisMaximum = Double(topBG)
  396. BGChart.setVisibleXRangeMinimum(600)
  397. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  398. BGChart.data?.notifyDataChanged()
  399. BGChart.notifyDataSetChanged()
  400. BGChartFull.rightAxis.axisMaximum = Double(topBG)
  401. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  402. BGChartFull.data?.notifyDataChanged()
  403. BGChartFull.notifyDataSetChanged()
  404. if firstGraphLoad {
  405. var scaleX = CGFloat(UserDefaultsRepository.chartScaleX.value)
  406. print("Scale: \(scaleX)")
  407. if( scaleX > CGFloat(ScaleXMax) ) {
  408. scaleX = CGFloat(ScaleXMax)
  409. UserDefaultsRepository.chartScaleX.value = ScaleXMax
  410. }
  411. BGChart.zoom(scaleX: scaleX, scaleY: 1, x: 1, y: 1)
  412. firstGraphLoad = false
  413. }
  414. // Move to current reading everytime new readings load
  415. BGChart.moveViewToAnimated(xValue: dateTimeUtils.getNowTimeIntervalUTC() - (BGChart.visibleXRange * 0.7), yValue: 0.0, axis: .right, duration: 1, easingOption: .easeInBack)
  416. }
  417. func updatePredictionGraph() {
  418. let dataIndex = 1
  419. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  420. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  421. mainChart.clear()
  422. smallChart.clear()
  423. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: print prediction") }
  424. var colors = [NSUIColor]()
  425. let maxBGOffset: Float = 20
  426. for i in 0..<predictionData.count {
  427. var predictionVal = Double(predictionData[i].sgv)
  428. if Float(predictionVal) > topBG - maxBGOffset {
  429. topBG = Float(predictionVal) + maxBGOffset
  430. }
  431. if i == 0 {
  432. if UserDefaultsRepository.showDots.value {
  433. colors.append(NSUIColor.systemPurple.withAlphaComponent(0.0))
  434. } else {
  435. colors.append(NSUIColor.systemPurple.withAlphaComponent(1.0))
  436. }
  437. } else if predictionVal > 400 {
  438. predictionVal = 400
  439. colors.append(NSUIColor.systemYellow)
  440. } else if predictionVal < 0 {
  441. predictionVal = 0
  442. colors.append(NSUIColor.systemRed)
  443. } else {
  444. colors.append(NSUIColor.systemPurple)
  445. }
  446. let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal, data: formatPillText(line1: bgUnits.toDisplayUnits(String(predictionData[i].sgv)), time: predictionData[i].date))
  447. mainChart.addEntry(value)
  448. smallChart.addEntry(value)
  449. }
  450. smallChart.circleColors.removeAll()
  451. smallChart.colors.removeAll()
  452. mainChart.colors.removeAll()
  453. mainChart.circleColors.removeAll()
  454. if colors.count > 0 {
  455. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: prediction colors") }
  456. for i in 0..<colors.count{
  457. mainChart.addColor(colors[i])
  458. mainChart.circleColors.append(colors[i])
  459. smallChart.addColor(colors[i])
  460. smallChart.circleColors.append(colors[i])
  461. }
  462. }
  463. BGChart.rightAxis.axisMaximum = Double(topBG)
  464. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  465. BGChart.data?.notifyDataChanged()
  466. BGChart.notifyDataSetChanged()
  467. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  468. BGChartFull.data?.notifyDataChanged()
  469. BGChartFull.notifyDataSetChanged()
  470. }
  471. func updateBasalGraph() {
  472. var dataIndex = 2
  473. BGChart.lineData?.dataSets[dataIndex].clear()
  474. BGChartFull.lineData?.dataSets[dataIndex].clear()
  475. var maxBasal = UserDefaultsRepository.minBasalScale.value
  476. var maxBasalSmall: Double = 0.0
  477. for i in 0..<basalData.count{
  478. let value = ChartDataEntry(x: Double(basalData[i].date), y: Double(basalData[i].basalRate), data: formatPillText(line1: String(basalData[i].basalRate), time: basalData[i].date))
  479. BGChart.data?.dataSets[dataIndex].addEntry(value)
  480. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  481. if basalData[i].basalRate > maxBasal {
  482. maxBasal = basalData[i].basalRate
  483. }
  484. if basalData[i].basalRate > maxBasalSmall {
  485. maxBasalSmall = basalData[i].basalRate
  486. }
  487. }
  488. BGChart.leftAxis.axisMaximum = maxBasal
  489. BGChartFull.leftAxis.axisMaximum = maxBasalSmall
  490. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  491. BGChart.data?.notifyDataChanged()
  492. BGChart.notifyDataSetChanged()
  493. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  494. BGChartFull.data?.notifyDataChanged()
  495. BGChartFull.notifyDataSetChanged()
  496. }
  497. func updateBasalScheduledGraph() {
  498. var dataIndex = 5
  499. BGChart.lineData?.dataSets[dataIndex].clear()
  500. BGChartFull.lineData?.dataSets[dataIndex].clear()
  501. for i in 0..<basalScheduleData.count{
  502. let value = ChartDataEntry(x: Double(basalScheduleData[i].date), y: Double(basalScheduleData[i].basalRate))
  503. BGChart.data?.dataSets[dataIndex].addEntry(value)
  504. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  505. }
  506. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  507. BGChart.data?.notifyDataChanged()
  508. BGChart.notifyDataSetChanged()
  509. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  510. BGChartFull.data?.notifyDataChanged()
  511. BGChartFull.notifyDataSetChanged()
  512. }
  513. func updateBolusGraph() {
  514. var dataIndex = 3
  515. var yTop: Double = 370
  516. var yBottom: Double = 345
  517. BGChart.lineData?.dataSets[dataIndex].clear()
  518. BGChartFull.lineData?.dataSets[dataIndex].clear()
  519. for i in 0..<bolusData.count{
  520. let formatter = NumberFormatter()
  521. formatter.minimumFractionDigits = 0
  522. formatter.maximumFractionDigits = 2
  523. formatter.minimumIntegerDigits = 0
  524. // Check overlapping carbs to shift left if needed
  525. let bolusShift = findNextBolusTime(timeWithin: 240, needle: bolusData[i].date, haystack: bolusData, startingIndex: i)
  526. var dateTimeStamp = bolusData[i].date
  527. if bolusShift {
  528. // Move it half the distance between BG readings
  529. dateTimeStamp = dateTimeStamp - 150
  530. }
  531. // skip if > 24 hours old
  532. if dateTimeStamp < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  533. let dot = ChartDataEntry(x: Double(dateTimeStamp), y: Double(bolusData[i].sgv), data: formatter.string(from: NSNumber(value: bolusData[i].value)))
  534. BGChart.data?.dataSets[dataIndex].addEntry(dot)
  535. BGChartFull.data?.dataSets[dataIndex].addEntry(dot)
  536. }
  537. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  538. BGChart.data?.notifyDataChanged()
  539. BGChart.notifyDataSetChanged()
  540. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  541. BGChartFull.data?.notifyDataChanged()
  542. BGChartFull.notifyDataSetChanged()
  543. }
  544. func updateCarbGraph() {
  545. var dataIndex = 4
  546. BGChart.lineData?.dataSets[dataIndex].clear()
  547. BGChartFull.lineData?.dataSets[dataIndex].clear()
  548. for i in 0..<carbData.count{
  549. let formatter = NumberFormatter()
  550. formatter.minimumFractionDigits = 0
  551. formatter.maximumFractionDigits = 2
  552. formatter.minimumIntegerDigits = 1
  553. var valueString: String = formatter.string(from: NSNumber(value: carbData[i].value))!
  554. if carbData[i].absorptionTime > 0 && UserDefaultsRepository.showAbsorption.value {
  555. let hours = carbData[i].absorptionTime / 60
  556. valueString += " " + String(hours) + "h"
  557. }
  558. // Check overlapping carbs to shift left if needed
  559. let carbShift = findNextCarbTime(timeWithin: 250, needle: carbData[i].date, haystack: carbData, startingIndex: i)
  560. var dateTimeStamp = carbData[i].date
  561. // skip if > 24 hours old
  562. if dateTimeStamp < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  563. if carbShift {
  564. dateTimeStamp = dateTimeStamp - 250
  565. }
  566. let dot = ChartDataEntry(x: Double(dateTimeStamp), y: Double(carbData[i].sgv), data: valueString)
  567. BGChart.data?.dataSets[dataIndex].addEntry(dot)
  568. BGChartFull.data?.dataSets[dataIndex].addEntry(dot)
  569. }
  570. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  571. BGChart.data?.notifyDataChanged()
  572. BGChart.notifyDataSetChanged()
  573. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  574. BGChartFull.data?.notifyDataChanged()
  575. BGChartFull.notifyDataSetChanged()
  576. }
  577. func updateBGCheckGraph() {
  578. var dataIndex = 7
  579. BGChart.lineData?.dataSets[dataIndex].clear()
  580. BGChartFull.lineData?.dataSets[dataIndex].clear()
  581. for i in 0..<bgCheckData.count{
  582. let formatter = NumberFormatter()
  583. formatter.minimumFractionDigits = 0
  584. formatter.maximumFractionDigits = 2
  585. formatter.minimumIntegerDigits = 1
  586. // skip if > 24 hours old
  587. if bgCheckData[i].date < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  588. 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))
  589. BGChart.data?.dataSets[dataIndex].addEntry(value)
  590. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  591. }
  592. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  593. BGChart.data?.notifyDataChanged()
  594. BGChart.notifyDataSetChanged()
  595. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  596. BGChartFull.data?.notifyDataChanged()
  597. BGChartFull.notifyDataSetChanged()
  598. }
  599. func updateSuspendGraph() {
  600. var dataIndex = 8
  601. BGChart.lineData?.dataSets[dataIndex].clear()
  602. BGChartFull.lineData?.dataSets[dataIndex].clear()
  603. let thisData = suspendGraphData
  604. for i in 0..<thisData.count{
  605. // skip if > 24 hours old
  606. if thisData[i].date < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  607. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Suspend Pump", time: thisData[i].date))
  608. BGChart.data?.dataSets[dataIndex].addEntry(value)
  609. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  610. }
  611. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  612. BGChart.data?.notifyDataChanged()
  613. BGChart.notifyDataSetChanged()
  614. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  615. BGChartFull.data?.notifyDataChanged()
  616. BGChartFull.notifyDataSetChanged()
  617. }
  618. func updateResumeGraph() {
  619. var dataIndex = 9
  620. BGChart.lineData?.dataSets[dataIndex].clear()
  621. BGChartFull.lineData?.dataSets[dataIndex].clear()
  622. let thisData = resumeGraphData
  623. for i in 0..<thisData.count{
  624. // skip if > 24 hours old
  625. if thisData[i].date < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  626. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Resume Pump", time: thisData[i].date))
  627. BGChart.data?.dataSets[dataIndex].addEntry(value)
  628. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  629. }
  630. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  631. BGChart.data?.notifyDataChanged()
  632. BGChart.notifyDataSetChanged()
  633. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  634. BGChartFull.data?.notifyDataChanged()
  635. BGChartFull.notifyDataSetChanged()
  636. }
  637. func updateSensorStart() {
  638. var dataIndex = 10
  639. BGChart.lineData?.dataSets[dataIndex].clear()
  640. BGChartFull.lineData?.dataSets[dataIndex].clear()
  641. let thisData = sensorStartGraphData
  642. for i in 0..<thisData.count{
  643. // skip if > 24 hours old
  644. if thisData[i].date < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  645. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: "Start Sensor", time: thisData[i].date))
  646. BGChart.data?.dataSets[dataIndex].addEntry(value)
  647. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  648. }
  649. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  650. BGChart.data?.notifyDataChanged()
  651. BGChart.notifyDataSetChanged()
  652. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  653. BGChartFull.data?.notifyDataChanged()
  654. BGChartFull.notifyDataSetChanged()
  655. }
  656. func updateNotes() {
  657. var dataIndex = 11
  658. BGChart.lineData?.dataSets[dataIndex].clear()
  659. BGChartFull.lineData?.dataSets[dataIndex].clear()
  660. let thisData = noteGraphData
  661. for i in 0..<thisData.count{
  662. // skip if > 24 hours old
  663. if thisData[i].date < dateTimeUtils.getTimeInterval24HoursAgo() { continue }
  664. let value = ChartDataEntry(x: Double(thisData[i].date), y: Double(thisData[i].sgv), data: formatPillText(line1: thisData[i].note, time: thisData[i].date))
  665. BGChart.data?.dataSets[dataIndex].addEntry(value)
  666. BGChartFull.data?.dataSets[dataIndex].addEntry(value)
  667. }
  668. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  669. BGChart.data?.notifyDataChanged()
  670. BGChart.notifyDataSetChanged()
  671. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  672. BGChartFull.data?.notifyDataChanged()
  673. BGChartFull.notifyDataSetChanged()
  674. }
  675. func createSmallBGGraph(){
  676. let entries = bgData
  677. var bgChartEntry = [ChartDataEntry]()
  678. var colors = [NSUIColor]()
  679. var maxBG: Float = UserDefaultsRepository.minBGScale.value
  680. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  681. lineBG.drawCirclesEnabled = false
  682. //line2.setDrawHighlightIndicators(false)
  683. lineBG.highlightEnabled = true
  684. lineBG.drawHorizontalHighlightIndicatorEnabled = false
  685. lineBG.drawVerticalHighlightIndicatorEnabled = false
  686. lineBG.highlightColor = NSUIColor.label
  687. lineBG.drawValuesEnabled = false
  688. lineBG.lineWidth = 1.5
  689. lineBG.axisDependency = YAxis.AxisDependency.right
  690. // Setup Prediction line details
  691. var predictionChartEntry = [ChartDataEntry]()
  692. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  693. linePrediction.drawCirclesEnabled = false
  694. //line2.setDrawHighlightIndicators(false)
  695. linePrediction.setColor(NSUIColor.systemPurple)
  696. linePrediction.highlightEnabled = true
  697. linePrediction.drawHorizontalHighlightIndicatorEnabled = false
  698. linePrediction.drawVerticalHighlightIndicatorEnabled = false
  699. linePrediction.highlightColor = NSUIColor.label
  700. linePrediction.drawValuesEnabled = false
  701. linePrediction.lineWidth = 1.5
  702. linePrediction.axisDependency = YAxis.AxisDependency.right
  703. // create Basal graph data
  704. var chartEntry = [ChartDataEntry]()
  705. var maxBasal = UserDefaultsRepository.minBasalScale.value
  706. let lineBasal = LineChartDataSet(entries:chartEntry, label: "")
  707. lineBasal.setDrawHighlightIndicators(false)
  708. lineBasal.setColor(NSUIColor.systemBlue, alpha: 0.5)
  709. lineBasal.lineWidth = 0
  710. lineBasal.drawFilledEnabled = true
  711. lineBasal.fillColor = NSUIColor.systemBlue
  712. lineBasal.fillAlpha = 0.35
  713. lineBasal.drawCirclesEnabled = false
  714. lineBasal.axisDependency = YAxis.AxisDependency.left
  715. lineBasal.highlightEnabled = false
  716. lineBasal.drawValuesEnabled = false
  717. lineBasal.fillFormatter = basalFillFormatter()
  718. // Boluses
  719. var chartEntryBolus = [ChartDataEntry]()
  720. let lineBolus = LineChartDataSet(entries:chartEntryBolus, label: "")
  721. lineBolus.circleRadius = 2
  722. lineBolus.circleColors = [NSUIColor.systemBlue.withAlphaComponent(0.75)]
  723. lineBolus.drawCircleHoleEnabled = false
  724. lineBolus.setDrawHighlightIndicators(false)
  725. lineBolus.setColor(NSUIColor.systemBlue, alpha: 1.0)
  726. lineBolus.lineWidth = 0
  727. lineBolus.axisDependency = YAxis.AxisDependency.right
  728. lineBolus.valueFormatter = ChartYDataValueFormatter()
  729. lineBolus.valueTextColor = NSUIColor.label
  730. lineBolus.fillColor = NSUIColor.systemBlue
  731. lineBolus.fillAlpha = 0.6
  732. lineBolus.drawCirclesEnabled = true
  733. lineBolus.drawFilledEnabled = false
  734. lineBolus.drawValuesEnabled = false
  735. lineBolus.highlightEnabled = false
  736. // Carbs
  737. var chartEntryCarbs = [ChartDataEntry]()
  738. let lineCarbs = LineChartDataSet(entries:chartEntryCarbs, label: "")
  739. lineCarbs.circleRadius = 2
  740. lineCarbs.circleColors = [NSUIColor.systemOrange.withAlphaComponent(0.75)]
  741. lineCarbs.drawCircleHoleEnabled = false
  742. lineCarbs.setDrawHighlightIndicators(false)
  743. lineCarbs.setColor(NSUIColor.systemBlue, alpha: 1.0)
  744. lineCarbs.lineWidth = 0
  745. lineCarbs.axisDependency = YAxis.AxisDependency.right
  746. lineCarbs.valueFormatter = ChartYDataValueFormatter()
  747. lineCarbs.valueTextColor = NSUIColor.label
  748. lineCarbs.fillColor = NSUIColor.systemOrange
  749. lineCarbs.fillAlpha = 0.6
  750. lineCarbs.drawCirclesEnabled = true
  751. lineCarbs.drawFilledEnabled = false
  752. lineCarbs.drawValuesEnabled = false
  753. lineCarbs.highlightEnabled = false
  754. // create Scheduled Basal graph data
  755. var chartBasalScheduledEntry = [ChartDataEntry]()
  756. let lineBasalScheduled = LineChartDataSet(entries:chartBasalScheduledEntry, label: "")
  757. lineBasalScheduled.setDrawHighlightIndicators(false)
  758. lineBasalScheduled.setColor(NSUIColor.systemBlue, alpha: 0.8)
  759. lineBasalScheduled.lineWidth = 0.5
  760. lineBasalScheduled.drawFilledEnabled = false
  761. lineBasalScheduled.drawCirclesEnabled = false
  762. lineBasalScheduled.axisDependency = YAxis.AxisDependency.left
  763. lineBasalScheduled.highlightEnabled = false
  764. lineBasalScheduled.drawValuesEnabled = false
  765. lineBasalScheduled.lineDashLengths = [2, 1]
  766. // create Override graph data
  767. var chartOverrideEntry = [ChartDataEntry]()
  768. let lineOverride = LineChartDataSet(entries:chartOverrideEntry, label: "")
  769. lineOverride.setDrawHighlightIndicators(false)
  770. lineOverride.lineWidth = 0
  771. lineOverride.drawFilledEnabled = true
  772. lineOverride.fillFormatter = OverrideFillFormatter()
  773. lineOverride.fillColor = NSUIColor.systemGreen
  774. lineOverride.fillAlpha = 0.6
  775. lineOverride.drawCirclesEnabled = false
  776. lineOverride.axisDependency = YAxis.AxisDependency.right
  777. lineOverride.highlightEnabled = true
  778. lineOverride.drawValuesEnabled = false
  779. // BG Check
  780. var chartEntryBGCheck = [ChartDataEntry]()
  781. let lineBGCheck = LineChartDataSet(entries:chartEntryBGCheck, label: "")
  782. lineBGCheck.circleRadius = 2
  783. lineBGCheck.circleColors = [NSUIColor.systemRed.withAlphaComponent(0.75)]
  784. lineBGCheck.drawCircleHoleEnabled = false
  785. lineBGCheck.setDrawHighlightIndicators(false)
  786. lineBGCheck.setColor(NSUIColor.systemRed, alpha: 1.0)
  787. lineBGCheck.drawCirclesEnabled = true
  788. lineBGCheck.lineWidth = 0
  789. lineBGCheck.highlightEnabled = false
  790. lineBGCheck.axisDependency = YAxis.AxisDependency.right
  791. lineBGCheck.valueFormatter = ChartYDataValueFormatter()
  792. lineBGCheck.drawValuesEnabled = false
  793. // Suspend Pump
  794. var chartEntrySuspend = [ChartDataEntry]()
  795. let lineSuspend = LineChartDataSet(entries:chartEntrySuspend, label: "")
  796. lineSuspend.circleRadius = 2
  797. lineSuspend.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  798. lineSuspend.drawCircleHoleEnabled = false
  799. lineSuspend.setDrawHighlightIndicators(false)
  800. lineSuspend.setColor(NSUIColor.systemGray2, alpha: 1.0)
  801. lineSuspend.drawCirclesEnabled = true
  802. lineSuspend.lineWidth = 0
  803. lineSuspend.highlightEnabled = false
  804. lineSuspend.axisDependency = YAxis.AxisDependency.right
  805. lineSuspend.valueFormatter = ChartYDataValueFormatter()
  806. lineSuspend.drawValuesEnabled = false
  807. // Resume Pump
  808. var chartEntryResume = [ChartDataEntry]()
  809. let lineResume = LineChartDataSet(entries:chartEntryResume, label: "")
  810. lineResume.circleRadius = 2
  811. lineResume.circleColors = [NSUIColor.systemTeal.withAlphaComponent(0.75)]
  812. lineResume.drawCircleHoleEnabled = false
  813. lineResume.setDrawHighlightIndicators(false)
  814. lineResume.setColor(NSUIColor.systemGray4, alpha: 1.0)
  815. lineResume.drawCirclesEnabled = true
  816. lineResume.lineWidth = 0
  817. lineResume.highlightEnabled = false
  818. lineResume.axisDependency = YAxis.AxisDependency.right
  819. lineResume.valueFormatter = ChartYDataValueFormatter()
  820. lineResume.drawValuesEnabled = false
  821. // Sensor Start
  822. var chartEntrySensor = [ChartDataEntry]()
  823. let lineSensor = LineChartDataSet(entries:chartEntrySensor, label: "")
  824. lineSensor.circleRadius = 2
  825. lineSensor.circleColors = [NSUIColor.systemIndigo.withAlphaComponent(0.75)]
  826. lineSensor.drawCircleHoleEnabled = false
  827. lineSensor.setDrawHighlightIndicators(false)
  828. lineSensor.setColor(NSUIColor.systemGray3, alpha: 1.0)
  829. lineSensor.drawCirclesEnabled = true
  830. lineSensor.lineWidth = 0
  831. lineSensor.highlightEnabled = false
  832. lineSensor.axisDependency = YAxis.AxisDependency.right
  833. lineSensor.valueFormatter = ChartYDataValueFormatter()
  834. lineSensor.drawValuesEnabled = false
  835. // Notes
  836. var chartEntryNote = [ChartDataEntry]()
  837. let lineNote = LineChartDataSet(entries:chartEntryNote, label: "")
  838. lineNote.circleRadius = 2
  839. lineNote.circleColors = [NSUIColor.systemGray.withAlphaComponent(0.75)]
  840. lineNote.drawCircleHoleEnabled = false
  841. lineNote.setDrawHighlightIndicators(false)
  842. lineNote.setColor(NSUIColor.systemGray3, alpha: 1.0)
  843. lineNote.drawCirclesEnabled = true
  844. lineNote.lineWidth = 0
  845. lineNote.highlightEnabled = false
  846. lineNote.axisDependency = YAxis.AxisDependency.right
  847. lineNote.valueFormatter = ChartYDataValueFormatter()
  848. lineNote.drawValuesEnabled = false
  849. // Setup the chart data of all lines
  850. let data = LineChartData()
  851. data.addDataSet(lineBG) // Dataset 0
  852. data.addDataSet(linePrediction) // Dataset 1
  853. data.addDataSet(lineBasal) // Dataset 2
  854. data.addDataSet(lineBolus) // Dataset 3
  855. data.addDataSet(lineCarbs) // Dataset 4
  856. data.addDataSet(lineBasalScheduled) // Dataset 5
  857. data.addDataSet(lineOverride) // Dataset 6
  858. data.addDataSet(lineBGCheck) // Dataset 7
  859. data.addDataSet(lineSuspend) // Dataset 8
  860. data.addDataSet(lineResume) // Dataset 9
  861. data.addDataSet(lineSensor) // Dataset 10
  862. data.addDataSet(lineNote) // Dataset 11
  863. BGChartFull.highlightPerDragEnabled = true
  864. BGChartFull.leftAxis.enabled = false
  865. BGChartFull.leftAxis.axisMaximum = maxBasal
  866. BGChartFull.leftAxis.axisMinimum = 0
  867. BGChartFull.rightAxis.enabled = false
  868. BGChartFull.rightAxis.axisMinimum = 0.0
  869. BGChartFull.rightAxis.axisMaximum = Double(maxBG)
  870. BGChartFull.xAxis.enabled = false
  871. BGChartFull.legend.enabled = false
  872. BGChartFull.scaleYEnabled = false
  873. BGChartFull.scaleXEnabled = false
  874. BGChartFull.drawGridBackgroundEnabled = false
  875. BGChartFull.data = data
  876. }
  877. func updateOverrideGraph() {
  878. var dataIndex = 6
  879. var yTop: Double = Double(topBG - 1)
  880. var yBottom: Double = Double(topBG - 25)
  881. var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  882. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  883. chart.clear()
  884. smallChart.clear()
  885. let thisData = overrideGraphData
  886. var colors = [NSUIColor]()
  887. for i in 0..<thisData.count{
  888. let thisItem = thisData[i]
  889. let multiplier = thisItem.insulNeedsScaleFactor as! Double * 100.0
  890. var labelText = thisItem.reason + "\r\n"
  891. labelText += String(Int(thisItem.insulNeedsScaleFactor * 100)) + "% "
  892. if thisItem.correctionRange.count == 2 {
  893. labelText += String(thisItem.correctionRange[0]) + "-" + String(thisItem.correctionRange[1])
  894. }
  895. // Start Dot
  896. // Shift dots 30 seconds to create an empty 0 space between consecutive temps
  897. let preStartDot = ChartDataEntry(x: Double(thisItem.date), y: yBottom, data: "hide")
  898. BGChart.data?.dataSets[dataIndex].addEntry(preStartDot)
  899. BGChartFull.data?.dataSets[dataIndex].addEntry(preStartDot)
  900. let startDot = ChartDataEntry(x: Double(thisItem.date + 1), y: yTop, data: labelText)
  901. BGChart.data?.dataSets[dataIndex].addEntry(startDot)
  902. BGChartFull.data?.dataSets[dataIndex].addEntry(startDot)
  903. // End Dot
  904. let endDot = ChartDataEntry(x: Double(thisItem.endDate - 1), y: yTop, data: labelText)
  905. BGChart.data?.dataSets[dataIndex].addEntry(endDot)
  906. BGChartFull.data?.dataSets[dataIndex].addEntry(endDot)
  907. // Post end dot
  908. let postEndDot = ChartDataEntry(x: Double(thisItem.endDate), y: yBottom, data: "hide")
  909. BGChart.data?.dataSets[dataIndex].addEntry(postEndDot)
  910. BGChartFull.data?.dataSets[dataIndex].addEntry(postEndDot)
  911. }
  912. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  913. BGChart.data?.notifyDataChanged()
  914. BGChart.notifyDataSetChanged()
  915. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  916. BGChartFull.data?.notifyDataChanged()
  917. BGChartFull.notifyDataSetChanged()
  918. }
  919. func formatPillText(line1: String, time: TimeInterval) -> String {
  920. let dateFormatter = DateFormatter()
  921. //let timezoneOffset = TimeZone.current.secondsFromGMT()
  922. //let epochTimezoneOffset = value + Double(timezoneOffset)
  923. if dateTimeUtils.is24Hour() {
  924. dateFormatter.setLocalizedDateFormatFromTemplate("HH:mm")
  925. } else {
  926. dateFormatter.setLocalizedDateFormatFromTemplate("hh:mm")
  927. }
  928. //let date = Date(timeIntervalSince1970: epochTimezoneOffset)
  929. let date = Date(timeIntervalSince1970: time)
  930. let formattedDate = dateFormatter.string(from: date)
  931. return line1 + "\r\n" + formattedDate
  932. }
  933. }