ChartAxisSetup.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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,
  17. let minForecast = minForecast, let maxForecast = maxForecast
  18. else {
  19. Task {
  20. await self.updateChartBounds(minValue: 39, maxValue: 300)
  21. }
  22. return
  23. }
  24. // Adjust max forecast to be no more than 100 over max glucose
  25. let adjustedMaxForecast = min(maxForecast, maxGlucose + 100)
  26. let minOverall = min(minGlucose, minForecast)
  27. let maxOverall = max(maxGlucose, adjustedMaxForecast)
  28. // Update the chart bounds on the main thread
  29. Task {
  30. await self.updateChartBounds(minValue: minOverall - 50, maxValue: maxOverall + 80)
  31. }
  32. }
  33. }
  34. }
  35. @MainActor private func updateChartBounds(minValue: Decimal, maxValue: Decimal) async {
  36. minYAxisValue = minValue
  37. maxYAxisValue = maxValue
  38. }
  39. func yAxisChartDataCobChart(determinations: [[String: Any]]) {
  40. determinationFetchContext.perform {
  41. // Map the COB values from the dictionary results
  42. let cobMapped = determinations.compactMap { entry in
  43. // First cast to Int16, then convert to Decimal
  44. if let cobValue = entry["cob"] as? Int16 {
  45. return Decimal(cobValue)
  46. }
  47. return nil
  48. }
  49. let maxCob = cobMapped.max()
  50. // Ensure the result exists or set default values
  51. if let maxCob = maxCob {
  52. let calculatedMax = maxCob == 0 ? 20 : maxCob + 20
  53. Task {
  54. await self.updateCobChartBounds(minValue: 0, maxValue: calculatedMax)
  55. }
  56. } else {
  57. Task {
  58. await self.updateCobChartBounds(minValue: 0, maxValue: 20)
  59. }
  60. }
  61. }
  62. }
  63. @MainActor private func updateCobChartBounds(minValue: Decimal, maxValue: Decimal) {
  64. minValueCobChart = minValue
  65. maxValueCobChart = maxValue
  66. }
  67. func yAxisChartDataIobChart(determinations: [[String: Any]]) {
  68. determinationFetchContext.perform {
  69. // Map the IOB values from the fetched dictionaries
  70. let iobMapped = determinations.compactMap { ($0["iob"] as? NSDecimalNumber)?.decimalValue }
  71. let minIob = iobMapped.min()
  72. let maxIob = iobMapped.max()
  73. // Ensure min and max IOB values exist, or set defaults
  74. if let minIob = minIob, let maxIob = maxIob {
  75. let adjustedMin = minIob < 0 ? minIob - 2 : 0
  76. Task {
  77. await self.updateIobChartBounds(minValue: adjustedMin, maxValue: maxIob + 2)
  78. }
  79. } else {
  80. Task {
  81. await self.updateIobChartBounds(minValue: 0, maxValue: 5)
  82. }
  83. }
  84. }
  85. }
  86. @MainActor private func updateIobChartBounds(minValue: Decimal, maxValue: Decimal) async {
  87. minValueIobChart = minValue
  88. maxValueIobChart = maxValue
  89. }
  90. }