ChartAxisSetup.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import Foundation
  2. extension Home.StateModel {
  3. func yAxisChartData(glucoseValues: [GlucoseStored]) {
  4. // Capture the forecast values from `preprocessedData` on the main thread
  5. Task { @MainActor in
  6. let forecastValues = self.preprocessedData.map { Decimal($0.forecastValue.value) }
  7. // Perform the glucose processing on the background context
  8. glucoseFetchContext.perform {
  9. let glucoseMapped = glucoseValues.map { Decimal($0.glucose) }
  10. // Calculate min and max values for glucose and forecast
  11. let minGlucose = glucoseMapped.min()
  12. let maxGlucose = glucoseMapped.max()
  13. let minForecast = forecastValues.min()
  14. let maxForecast = forecastValues.max()
  15. // Ensure all values exist, otherwise set default values
  16. guard let minGlucose = minGlucose, let maxGlucose = maxGlucose else {
  17. Task {
  18. await self.updateChartBounds(minValue: 39, maxValue: 200)
  19. }
  20. return
  21. }
  22. // Adjust max forecast to be no more than 50 over max glucose
  23. let adjustedMaxForecast = min(maxForecast ?? maxGlucose + 50, maxGlucose + 50)
  24. let minOverall = min(minGlucose, minForecast ?? minGlucose)
  25. let maxOverall = max(maxGlucose, adjustedMaxForecast)
  26. var maxYValue = Decimal(200)
  27. if maxOverall > 200, maxOverall <= 225 {
  28. maxYValue = Decimal(250)
  29. } else if maxOverall > 225, maxOverall <= 275 {
  30. maxYValue = Decimal(300)
  31. } else if maxOverall > 275, maxOverall <= 325 {
  32. maxYValue = Decimal(350)
  33. } else if maxOverall > 325 {
  34. maxYValue = Decimal(400)
  35. }
  36. // Update the chart bounds on the main thread
  37. Task {
  38. await self.updateChartBounds(minValue: minOverall, maxValue: maxYValue)
  39. }
  40. }
  41. }
  42. }
  43. @MainActor private func updateChartBounds(minValue: Decimal, maxValue: Decimal) async {
  44. minYAxisValue = minValue
  45. maxYAxisValue = maxValue
  46. }
  47. func yAxisChartDataCobChart(determinations: [[String: Any]]) {
  48. determinationFetchContext.perform {
  49. // Map the COB values from the dictionary results
  50. let cobMapped = determinations.compactMap { entry in
  51. // First cast to Int16, then convert to Decimal
  52. if let cobValue = entry["cob"] as? Int16 {
  53. return Decimal(cobValue)
  54. }
  55. return nil
  56. }
  57. let maxCob = cobMapped.max()
  58. // Ensure the result exists or set default values
  59. if let maxCob = maxCob {
  60. let calculatedMax = maxCob == 0 ? 20 : maxCob + 20
  61. Task {
  62. await self.updateCobChartBounds(minValue: 0, maxValue: calculatedMax)
  63. }
  64. } else {
  65. Task {
  66. await self.updateCobChartBounds(minValue: 0, maxValue: 20)
  67. }
  68. }
  69. }
  70. }
  71. @MainActor private func updateCobChartBounds(minValue: Decimal, maxValue: Decimal) {
  72. minValueCobChart = minValue
  73. maxValueCobChart = maxValue
  74. }
  75. func yAxisChartDataIobChart(determinations: [[String: Any]]) {
  76. determinationFetchContext.perform {
  77. // Map the IOB values from the fetched dictionaries
  78. let iobMapped = determinations.compactMap { ($0["iob"] as? NSDecimalNumber)?.decimalValue }
  79. let minIob = iobMapped.min()
  80. let maxIob = iobMapped.max()
  81. // Ensure min and max IOB values exist, or set defaults
  82. if let minIob = minIob, let maxIob = maxIob {
  83. let adjustedMin = minIob < 0 ? minIob - 2 : 0
  84. Task {
  85. await self.updateIobChartBounds(minValue: adjustedMin, maxValue: maxIob + 2)
  86. }
  87. } else {
  88. Task {
  89. await self.updateIobChartBounds(minValue: 0, maxValue: 5)
  90. }
  91. }
  92. }
  93. }
  94. @MainActor private func updateIobChartBounds(minValue: Decimal, maxValue: Decimal) async {
  95. minValueIobChart = minValue
  96. maxValueIobChart = maxValue
  97. }
  98. }