Graphs.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  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. }
  18. func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat) {
  19. if chartView == BGChart {
  20. let currentMatrix = chartView.viewPortHandler.touchMatrix
  21. //BGChartFull.viewPortHandler.refresh(newMatrix: currentMatrix, chart: BGChartFull, invalidate: true)
  22. //BGChartFull.highlightValue(x: Double(currentMatrix.tx), y: Double(currentMatrix.ty), dataSetIndex: 0)
  23. }
  24. }
  25. func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat) {
  26. print("Chart Scaled: \(BGChart.scaleX), \(BGChart.scaleY)")
  27. // dont store huge values
  28. var scale: Float = Float(BGChart.scaleX)
  29. if(scale > ScaleXMax ) {
  30. scale = ScaleXMax
  31. }
  32. UserDefaultsRepository.chartScaleX.value = Float(scale)
  33. }
  34. func createGraph(){
  35. self.BGChart.clear()
  36. // Create the BG Graph Data
  37. let entries = bgData
  38. var bgChartEntry = [ChartDataEntry]()
  39. var colors = [NSUIColor]()
  40. var maxBG: Float = UserDefaultsRepository.minBGScale.value
  41. // Setup BG line details
  42. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  43. lineBG.circleRadius = 3
  44. lineBG.circleColors = [NSUIColor.systemGreen]
  45. lineBG.drawCircleHoleEnabled = false
  46. lineBG.axisDependency = YAxis.AxisDependency.right
  47. lineBG.highlightEnabled = true
  48. lineBG.drawValuesEnabled = false
  49. if UserDefaultsRepository.showLines.value {
  50. lineBG.lineWidth = 2
  51. } else {
  52. lineBG.lineWidth = 0
  53. }
  54. if UserDefaultsRepository.showDots.value {
  55. lineBG.drawCirclesEnabled = true
  56. } else {
  57. lineBG.drawCirclesEnabled = false
  58. }
  59. lineBG.setDrawHighlightIndicators(false)
  60. lineBG.valueFont.withSize(50)
  61. // Setup Prediction line details
  62. var predictionChartEntry = [ChartDataEntry]()
  63. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  64. linePrediction.circleRadius = 3
  65. linePrediction.circleColors = [NSUIColor.systemPurple]
  66. linePrediction.colors = [NSUIColor.systemPurple]
  67. linePrediction.drawCircleHoleEnabled = false
  68. linePrediction.axisDependency = YAxis.AxisDependency.right
  69. linePrediction.highlightEnabled = true
  70. linePrediction.drawValuesEnabled = false
  71. if UserDefaultsRepository.showLines.value {
  72. linePrediction.lineWidth = 2
  73. } else {
  74. linePrediction.lineWidth = 0
  75. }
  76. if UserDefaultsRepository.showDots.value {
  77. linePrediction.drawCirclesEnabled = true
  78. } else {
  79. linePrediction.drawCirclesEnabled = false
  80. }
  81. linePrediction.setDrawHighlightIndicators(false)
  82. linePrediction.valueFont.withSize(50)
  83. // create Basal graph data
  84. var chartEntry = [ChartDataEntry]()
  85. var maxBasal = UserDefaultsRepository.minBasalScale.value
  86. let lineBasal = LineChartDataSet(entries:chartEntry, label: "")
  87. lineBasal.setDrawHighlightIndicators(false)
  88. lineBasal.setColor(NSUIColor.systemBlue, alpha: 0.5)
  89. lineBasal.lineWidth = 0
  90. lineBasal.drawFilledEnabled = true
  91. lineBasal.fillColor = NSUIColor.systemBlue.withAlphaComponent(0.8)
  92. lineBasal.drawCirclesEnabled = false
  93. lineBasal.axisDependency = YAxis.AxisDependency.left
  94. lineBasal.highlightEnabled = true
  95. lineBasal.drawValuesEnabled = false
  96. lineBasal.fillFormatter = basalFillFormatter()
  97. // Boluses
  98. var chartEntryBolus = [ChartDataEntry]()
  99. let lineBolus = LineChartDataSet(entries:chartEntryBolus, label: "")
  100. lineBolus.circleRadius = 5
  101. lineBolus.circleColors = [NSUIColor.systemBlue.withAlphaComponent(0.75)]
  102. lineBolus.drawCircleHoleEnabled = false
  103. lineBolus.setDrawHighlightIndicators(false)
  104. lineBolus.setColor(NSUIColor.systemBlue, alpha: 1.0)
  105. lineBolus.drawCirclesEnabled = true
  106. lineBolus.lineWidth = 0
  107. lineBolus.highlightEnabled = false
  108. lineBolus.axisDependency = YAxis.AxisDependency.right
  109. lineBolus.valueFormatter = ChartYDataValueFormatter()
  110. lineBolus.drawValuesEnabled = true
  111. lineBolus.valueTextColor = NSUIColor.label
  112. // Carbs
  113. var chartEntryCarbs = [ChartDataEntry]()
  114. let lineCarbs = LineChartDataSet(entries:chartEntryCarbs, label: "")
  115. lineCarbs.circleRadius = 5
  116. lineCarbs.circleColors = [NSUIColor.systemOrange.withAlphaComponent(0.75)]
  117. lineCarbs.drawCircleHoleEnabled = false
  118. lineCarbs.setDrawHighlightIndicators(false)
  119. lineCarbs.setColor(NSUIColor.systemBlue, alpha: 1.0)
  120. lineCarbs.drawCirclesEnabled = true
  121. lineCarbs.lineWidth = 0
  122. lineCarbs.highlightEnabled = false
  123. lineCarbs.axisDependency = YAxis.AxisDependency.right
  124. lineCarbs.valueFormatter = ChartYDataValueFormatter()
  125. lineCarbs.drawValuesEnabled = true
  126. lineCarbs.valueTextColor = NSUIColor.label
  127. // create Scheduled Basal graph data
  128. var chartBasalScheduledEntry = [ChartDataEntry]()
  129. let lineBasalScheduled = LineChartDataSet(entries:chartBasalScheduledEntry, label: "")
  130. lineBasalScheduled.setDrawHighlightIndicators(false)
  131. lineBasalScheduled.setColor(NSUIColor.systemBlue, alpha: 0.8)
  132. lineBasalScheduled.lineWidth = 2
  133. lineBasalScheduled.drawFilledEnabled = false
  134. lineBasalScheduled.drawCirclesEnabled = false
  135. lineBasalScheduled.axisDependency = YAxis.AxisDependency.left
  136. lineBasalScheduled.highlightEnabled = false
  137. lineBasalScheduled.drawValuesEnabled = false
  138. lineBasalScheduled.lineDashLengths = [10.0, 5.0]
  139. // create Override graph data
  140. var chartOverrideEntry = [ChartDataEntry]()
  141. let lineOverride = LineChartDataSet(entries:chartOverrideEntry, label: "")
  142. lineOverride.setDrawHighlightIndicators(false)
  143. lineOverride.lineWidth = 0
  144. lineOverride.drawFilledEnabled = true
  145. lineOverride.fillFormatter = OverrideFillFormatter()
  146. lineOverride.fillColor = NSUIColor.systemTeal.withAlphaComponent(0.8)
  147. lineOverride.drawCirclesEnabled = false
  148. lineOverride.axisDependency = YAxis.AxisDependency.right
  149. lineOverride.highlightEnabled = true
  150. lineOverride.drawValuesEnabled = false
  151. // BG Check
  152. var chartEntryBGCheck = [ChartDataEntry]()
  153. let lineBGCheck = LineChartDataSet(entries:chartEntryBGCheck, label: "")
  154. lineBGCheck.circleRadius = 5
  155. lineBGCheck.circleColors = [NSUIColor.systemRed.withAlphaComponent(0.75)]
  156. lineBGCheck.drawCircleHoleEnabled = false
  157. lineBGCheck.setDrawHighlightIndicators(false)
  158. lineBGCheck.setColor(NSUIColor.systemRed, alpha: 1.0)
  159. lineBGCheck.drawCirclesEnabled = true
  160. lineBGCheck.lineWidth = 0
  161. lineBGCheck.highlightEnabled = false
  162. lineBGCheck.axisDependency = YAxis.AxisDependency.right
  163. lineBGCheck.valueFormatter = ChartYDataValueFormatter()
  164. lineBGCheck.drawValuesEnabled = false
  165. // Setup the chart data of all lines
  166. let data = LineChartData()
  167. data.addDataSet(lineBG) // Dataset 0
  168. data.addDataSet(linePrediction) // Dataset 1
  169. data.addDataSet(lineBasal) // Dataset 2
  170. data.addDataSet(lineBolus) // Dataset 3
  171. data.addDataSet(lineCarbs) // Dataset 4
  172. data.addDataSet(lineBasalScheduled) // Dataset 5
  173. data.addDataSet(lineOverride) // Dataset 6
  174. data.addDataSet(lineBGCheck) // Dataset 7
  175. data.setValueFont(UIFont.systemFont(ofSize: 12))
  176. // Add marker popups for bolus and carbs
  177. let marker = PillMarker(color: .secondarySystemBackground, font: UIFont.boldSystemFont(ofSize: 14), textColor: .label)
  178. BGChart.marker = marker
  179. // Clear limit lines so they don't add multiples when changing the settings
  180. BGChart.rightAxis.removeAllLimitLines()
  181. //Add lower red line based on low alert value
  182. let ll = ChartLimitLine()
  183. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  184. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  185. BGChart.rightAxis.addLimitLine(ll)
  186. //Add upper yellow line based on low alert value
  187. let ul = ChartLimitLine()
  188. ul.limit = Double(UserDefaultsRepository.highLine.value)
  189. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  190. BGChart.rightAxis.addLimitLine(ul)
  191. // Add Now Line
  192. createNowLine()
  193. startGraphNowTimer()
  194. // Setup the main graph overall details
  195. BGChart.xAxis.valueFormatter = ChartXValueFormatter()
  196. BGChart.xAxis.granularity = 1800
  197. BGChart.xAxis.labelTextColor = NSUIColor.label
  198. BGChart.xAxis.labelPosition = XAxis.LabelPosition.bottom
  199. BGChart.xAxis.drawGridLinesEnabled = false
  200. BGChart.leftAxis.enabled = true
  201. BGChart.leftAxis.labelPosition = YAxis.LabelPosition.insideChart
  202. BGChart.leftAxis.axisMaximum = maxBasal
  203. BGChart.leftAxis.axisMinimum = -1
  204. BGChart.leftAxis.drawGridLinesEnabled = false
  205. BGChart.rightAxis.labelTextColor = NSUIColor.label
  206. BGChart.rightAxis.labelPosition = YAxis.LabelPosition.insideChart
  207. BGChart.rightAxis.axisMinimum = Double(UserDefaultsRepository.minBGValue.value)
  208. BGChart.rightAxis.axisMaximum = Double(maxBG)
  209. BGChart.rightAxis.gridLineDashLengths = [5.0, 5.0]
  210. BGChart.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
  211. BGChart.legend.enabled = false
  212. BGChart.scaleYEnabled = false
  213. BGChart.drawGridBackgroundEnabled = false
  214. //BGChart.gridBackgroundColor = NSUIColor.secondarySystemBackground
  215. BGChart.data = data
  216. BGChart.setExtraOffsets(left: 10, top: 10, right: 10, bottom: 10)
  217. }
  218. func createNowLine() {
  219. BGChart.xAxis.removeAllLimitLines()
  220. let ul = ChartLimitLine()
  221. ul.limit = Double(dateTimeUtils.getNowTimeIntervalUTC())
  222. ul.lineColor = NSUIColor.systemGray.withAlphaComponent(0.5)
  223. ul.lineWidth = 1
  224. BGChart.xAxis.addLimitLine(ul)
  225. }
  226. func updateBGGraphSettings() {
  227. let dataIndex = 0
  228. let dataIndexPrediction = 1
  229. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  230. let linePrediction = BGChart.lineData!.dataSets[dataIndexPrediction] as! LineChartDataSet
  231. if UserDefaultsRepository.showLines.value {
  232. lineBG.lineWidth = 2
  233. linePrediction.lineWidth = 2
  234. } else {
  235. lineBG.lineWidth = 0
  236. linePrediction.lineWidth = 0
  237. }
  238. if UserDefaultsRepository.showDots.value {
  239. lineBG.drawCirclesEnabled = true
  240. linePrediction.drawCirclesEnabled = true
  241. } else {
  242. lineBG.drawCirclesEnabled = false
  243. linePrediction.drawCirclesEnabled = false
  244. }
  245. BGChart.rightAxis.axisMinimum = Double(UserDefaultsRepository.minBGValue.value)
  246. // Clear limit lines so they don't add multiples when changing the settings
  247. BGChart.rightAxis.removeAllLimitLines()
  248. //Add lower red line based on low alert value
  249. let ll = ChartLimitLine()
  250. ll.limit = Double(UserDefaultsRepository.lowLine.value)
  251. ll.lineColor = NSUIColor.systemRed.withAlphaComponent(0.5)
  252. BGChart.rightAxis.addLimitLine(ll)
  253. //Add upper yellow line based on low alert value
  254. let ul = ChartLimitLine()
  255. ul.limit = Double(UserDefaultsRepository.highLine.value)
  256. ul.lineColor = NSUIColor.systemYellow.withAlphaComponent(0.5)
  257. BGChart.rightAxis.addLimitLine(ul)
  258. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  259. BGChart.data?.notifyDataChanged()
  260. BGChart.notifyDataSetChanged()
  261. }
  262. func updateBGGraph() {
  263. let dataIndex = 0
  264. let entries = bgData
  265. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  266. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  267. mainChart.clear()
  268. smallChart.clear()
  269. var maxBG = UserDefaultsRepository.minBGScale.value
  270. var maxBGOffset: Float = 0.0
  271. if UserDefaultsRepository.offsetCarbsBolus.value {
  272. maxBGOffset = 40.0
  273. }
  274. var colors = [NSUIColor]()
  275. for i in 0..<entries.count{
  276. if Float(entries[i].sgv) > maxBG - maxBGOffset {
  277. maxBG = Float(entries[i].sgv) + maxBGOffset
  278. }
  279. let value = ChartDataEntry(x: Double(entries[i].date), y: Double(entries[i].sgv), data: bgUnits.toDisplayUnits(String(entries[i].sgv)))
  280. mainChart.addEntry(value)
  281. smallChart.addEntry(value)
  282. if Double(entries[i].sgv) >= Double(UserDefaultsRepository.highLine.value) {
  283. colors.append(NSUIColor.systemYellow)
  284. } else if Double(entries[i].sgv) <= Double(UserDefaultsRepository.lowLine.value) {
  285. colors.append(NSUIColor.systemRed)
  286. } else {
  287. colors.append(NSUIColor.systemGreen)
  288. }
  289. }
  290. // Set Colors
  291. let lineBG = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  292. let lineBGSmall = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  293. lineBG.colors.removeAll()
  294. lineBG.circleColors.removeAll()
  295. lineBGSmall.colors.removeAll()
  296. lineBGSmall.circleColors.removeAll()
  297. if colors.count > 0 {
  298. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: colors") }
  299. for i in 0..<colors.count{
  300. mainChart.addColor(colors[i])
  301. mainChart.circleColors.append(colors[i])
  302. smallChart.addColor(colors[i])
  303. smallChart.circleColors.append(colors[i])
  304. }
  305. }
  306. BGChart.rightAxis.axisMaximum = Double(maxBG)
  307. BGChart.setVisibleXRangeMinimum(600)
  308. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  309. BGChart.data?.notifyDataChanged()
  310. BGChart.notifyDataSetChanged()
  311. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  312. BGChartFull.data?.notifyDataChanged()
  313. BGChartFull.notifyDataSetChanged()
  314. if firstGraphLoad {
  315. var scaleX = CGFloat(UserDefaultsRepository.chartScaleX.value)
  316. print("Scale: \(scaleX)")
  317. if( scaleX > CGFloat(ScaleXMax) ) {
  318. scaleX = CGFloat(ScaleXMax)
  319. UserDefaultsRepository.chartScaleX.value = ScaleXMax
  320. }
  321. BGChart.zoom(scaleX: scaleX, scaleY: 1, x: 1, y: 1)
  322. firstGraphLoad = false
  323. }
  324. if BGChart.chartXMax > dateTimeUtils.getNowTimeIntervalUTC() {
  325. BGChart.moveViewToAnimated(xValue: dateTimeUtils.getNowTimeIntervalUTC() - (BGChart.visibleXRange * 0.7), yValue: 0.0, axis: .right, duration: 1, easingOption: .easeInBack)
  326. }
  327. }
  328. func updatePredictionGraph() {
  329. let dataIndex = 1
  330. var mainChart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  331. var smallChart = BGChartFull.lineData!.dataSets[dataIndex] as! LineChartDataSet
  332. mainChart.clear()
  333. smallChart.clear()
  334. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: print prediction") }
  335. var colors = [NSUIColor]()
  336. for i in 0..<predictionData.count {
  337. var predictionVal = Double(predictionData[i].sgv)
  338. // Below can be turned on to prevent out of range on the graph if desired.
  339. // It currently just drops them out of view
  340. if predictionVal > 400 {
  341. predictionVal = 400
  342. colors.append(NSUIColor.systemYellow)
  343. } else if predictionVal < 0 {
  344. predictionVal = 0
  345. colors.append(NSUIColor.systemRed)
  346. } else {
  347. colors.append(NSUIColor.systemPurple)
  348. }
  349. let value = ChartDataEntry(x: predictionData[i].date, y: predictionVal)
  350. mainChart.addEntry(value)
  351. smallChart.addEntry(value)
  352. }
  353. smallChart.circleColors.removeAll()
  354. smallChart.colors.removeAll()
  355. mainChart.colors.removeAll()
  356. mainChart.circleColors.removeAll()
  357. if colors.count > 0 {
  358. if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: prediction colors") }
  359. for i in 0..<colors.count{
  360. mainChart.addColor(colors[i])
  361. mainChart.circleColors.append(colors[i])
  362. smallChart.addColor(colors[i])
  363. smallChart.circleColors.append(colors[i])
  364. }
  365. }
  366. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  367. BGChart.data?.notifyDataChanged()
  368. BGChart.notifyDataSetChanged()
  369. BGChartFull.data?.dataSets[dataIndex].notifyDataSetChanged()
  370. BGChartFull.data?.notifyDataChanged()
  371. BGChartFull.notifyDataSetChanged()
  372. }
  373. func updateBasalGraph() {
  374. var dataIndex = 2
  375. BGChart.lineData?.dataSets[dataIndex].clear()
  376. var maxBasal = UserDefaultsRepository.minBasalScale.value
  377. for i in 0..<basalData.count{
  378. let value = ChartDataEntry(x: Double(basalData[i].date), y: Double(basalData[i].basalRate))
  379. BGChart.data?.dataSets[dataIndex].addEntry(value)
  380. if basalData[i].basalRate > maxBasal {
  381. maxBasal = basalData[i].basalRate
  382. }
  383. }
  384. BGChart.leftAxis.axisMaximum = maxBasal
  385. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  386. BGChart.data?.notifyDataChanged()
  387. BGChart.notifyDataSetChanged()
  388. }
  389. func updateBasalScheduledGraph() {
  390. var dataIndex = 5
  391. BGChart.lineData?.dataSets[dataIndex].clear()
  392. for i in 0..<basalScheduleData.count{
  393. let value = ChartDataEntry(x: Double(basalScheduleData[i].date), y: Double(basalScheduleData[i].basalRate))
  394. BGChart.data?.dataSets[dataIndex].addEntry(value)
  395. }
  396. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  397. BGChart.data?.notifyDataChanged()
  398. BGChart.notifyDataSetChanged()
  399. }
  400. func updateBolusGraph() {
  401. var dataIndex = 3
  402. BGChart.lineData?.dataSets[dataIndex].clear()
  403. for i in 0..<bolusData.count{
  404. let formatter = NumberFormatter()
  405. formatter.minimumFractionDigits = 0
  406. formatter.maximumFractionDigits = 2
  407. formatter.minimumIntegerDigits = 1
  408. var offset = 0
  409. if UserDefaultsRepository.offsetCarbsBolus.value {
  410. offset = 10
  411. }
  412. //let value = ChartDataEntry(x: Double(bolusData[i].date), y: Double(bolusData[i].sgv + offset), data: formatter.string(from: NSNumber(value: bolusData[i].value)))
  413. let value = ChartDataEntry(x: Double(bolusData[i].date), y: -5, data: formatter.string(from: NSNumber(value: bolusData[i].value)))
  414. BGChart.data?.dataSets[dataIndex].addEntry(value)
  415. }
  416. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  417. BGChart.data?.notifyDataChanged()
  418. BGChart.notifyDataSetChanged()
  419. }
  420. func updateCarbGraph() {
  421. var dataIndex = 4
  422. BGChart.lineData?.dataSets[dataIndex].clear()
  423. for i in 0..<carbData.count{
  424. let formatter = NumberFormatter()
  425. formatter.minimumFractionDigits = 0
  426. formatter.maximumFractionDigits = 2
  427. formatter.minimumIntegerDigits = 1
  428. var offset = 0
  429. if UserDefaultsRepository.offsetCarbsBolus.value {
  430. offset = 30
  431. }
  432. // let value = ChartDataEntry(x: Double(carbData[i].date), y: Double(carbData[i].sgv + offset), data: formatter.string(from: NSNumber(value: carbData[i].value)))
  433. let value = ChartDataEntry(x: Double(carbData[i].date), y: -25, data: formatter.string(from: NSNumber(value: carbData[i].value)))
  434. BGChart.data?.dataSets[dataIndex].addEntry(value)
  435. }
  436. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  437. BGChart.data?.notifyDataChanged()
  438. BGChart.notifyDataSetChanged()
  439. }
  440. func updateBGCheckGraph() {
  441. var dataIndex = 7
  442. BGChart.lineData?.dataSets[dataIndex].clear()
  443. for i in 0..<bgCheckData.count{
  444. let formatter = NumberFormatter()
  445. formatter.minimumFractionDigits = 0
  446. formatter.maximumFractionDigits = 2
  447. formatter.minimumIntegerDigits = 1
  448. let value = ChartDataEntry(x: Double(bgCheckData[i].date), y: Double(bgCheckData[i].sgv), data: formatter.string(from: NSNumber(value: bgCheckData[i].sgv)))
  449. BGChart.data?.dataSets[dataIndex].addEntry(value)
  450. }
  451. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  452. BGChart.data?.notifyDataChanged()
  453. BGChart.notifyDataSetChanged()
  454. }
  455. func createSmallBGGraph(){
  456. let entries = bgData
  457. var bgChartEntry = [ChartDataEntry]()
  458. var colors = [NSUIColor]()
  459. let lineBG = LineChartDataSet(entries:bgChartEntry, label: "")
  460. lineBG.drawCirclesEnabled = false
  461. //line2.setDrawHighlightIndicators(false)
  462. lineBG.highlightEnabled = true
  463. lineBG.drawHorizontalHighlightIndicatorEnabled = false
  464. lineBG.drawVerticalHighlightIndicatorEnabled = false
  465. lineBG.highlightColor = NSUIColor.label
  466. lineBG.drawValuesEnabled = false
  467. lineBG.lineWidth = 2
  468. // Setup Prediction line details
  469. var predictionChartEntry = [ChartDataEntry]()
  470. let linePrediction = LineChartDataSet(entries:predictionChartEntry, label: "")
  471. linePrediction.drawCirclesEnabled = false
  472. //line2.setDrawHighlightIndicators(false)
  473. linePrediction.setColor(NSUIColor.systemPurple)
  474. linePrediction.highlightEnabled = true
  475. linePrediction.drawHorizontalHighlightIndicatorEnabled = false
  476. linePrediction.drawVerticalHighlightIndicatorEnabled = false
  477. linePrediction.highlightColor = NSUIColor.label
  478. linePrediction.drawValuesEnabled = false
  479. linePrediction.lineWidth = 2
  480. let data = LineChartData()
  481. data.addDataSet(lineBG)
  482. data.addDataSet(linePrediction)
  483. BGChartFull.highlightPerDragEnabled = true
  484. BGChartFull.leftAxis.enabled = false
  485. BGChartFull.rightAxis.enabled = false
  486. BGChartFull.xAxis.enabled = false
  487. BGChartFull.legend.enabled = false
  488. BGChartFull.scaleYEnabled = false
  489. BGChartFull.scaleXEnabled = false
  490. BGChartFull.drawGridBackgroundEnabled = false
  491. BGChartFull.data = data
  492. }
  493. func updateOverrideGraph() {
  494. var dataIndex = 6
  495. var chart = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  496. chart.clear()
  497. var colors = [NSUIColor]()
  498. for i in 0..<overrideGraphData.count{
  499. let multiplier = overrideGraphData[i].insulNeedsScaleFactor as! Double * 100.0
  500. //let labelText = String(format: "%.0f%%", multiplier)
  501. let labelText = overrideGraphData[i].reason
  502. // Start Dot
  503. let value = ChartDataEntry(x: Double(overrideGraphData[i].date), y: Double(overrideGraphData[i].sgv), data: labelText)
  504. BGChart.data?.dataSets[dataIndex].addEntry(value)
  505. if Double(overrideGraphData[i].insulNeedsScaleFactor) == 1.0 {
  506. colors.append(NSUIColor.systemGray.withAlphaComponent(0.0))
  507. } else if i >= overrideGraphData.count - 2 {
  508. colors.append(NSUIColor.systemGreen)
  509. } else {
  510. colors.append(NSUIColor.systemGray.withAlphaComponent(CGFloat(overrideGraphData[i].insulNeedsScaleFactor / 2)))
  511. }
  512. // End Dot
  513. let endDot = ChartDataEntry(x: Double(overrideGraphData[i].endDate), y: Double(overrideGraphData[i].sgv), data: labelText)
  514. BGChart.data?.dataSets[dataIndex].addEntry(endDot)
  515. if Double(overrideGraphData[i].insulNeedsScaleFactor) == 1.0 {
  516. colors.append(NSUIColor.systemGray.withAlphaComponent(0.0))
  517. } else if i >= overrideGraphData.count - 2 {
  518. colors.append(NSUIColor.systemGreen)
  519. } else {
  520. colors.append(NSUIColor.systemGray.withAlphaComponent(CGFloat(overrideGraphData[i].insulNeedsScaleFactor / 2)))
  521. }
  522. }
  523. // Set Colors
  524. let line = BGChart.lineData!.dataSets[dataIndex] as! LineChartDataSet
  525. line.colors.removeAll()
  526. line.circleColors.removeAll()
  527. if colors.count > 0 {
  528. for i in 0..<colors.count{
  529. chart.addColor(colors[i])
  530. chart.circleColors.append(colors[i])
  531. }
  532. }
  533. BGChart.data?.dataSets[dataIndex].notifyDataSetChanged()
  534. BGChart.data?.notifyDataChanged()
  535. BGChart.notifyDataSetChanged()
  536. }
  537. }