ChartAxisSetup.swift 3.9 KB

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