Graphs.swift 69 KB

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