GradientStops.swift 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import Foundation
  2. import SwiftUI
  3. struct GradientStops {
  4. static func calculateGradientStops(
  5. lowGlucose: Decimal,
  6. highGlucose: Decimal,
  7. glucoseValues: [Decimal]
  8. ) async -> [Gradient.Stop] {
  9. let low = Double(lowGlucose)
  10. let high = Double(highGlucose)
  11. let minimum = glucoseValues.min() ?? 0.0
  12. let maximum = glucoseValues.max() ?? 0.0
  13. // Handle edge case where minimum and maximum are equal
  14. guard minimum != maximum else {
  15. return [
  16. Gradient.Stop(color: .green, location: 0.0),
  17. Gradient.Stop(color: .green, location: 1.0)
  18. ]
  19. }
  20. // Calculate positions for gradient
  21. let lowPosition = (low - Double(truncating: minimum as NSNumber)) /
  22. (Double(truncating: maximum as NSNumber) - Double(truncating: minimum as NSNumber))
  23. let highPosition = (high - Double(truncating: minimum as NSNumber)) /
  24. (Double(truncating: maximum as NSNumber) - Double(truncating: minimum as NSNumber))
  25. // Ensure positions are in bounds [0, 1]
  26. let clampedLowPosition = max(0.0, min(lowPosition, 1.0))
  27. let clampedHighPosition = max(0.0, min(highPosition, 1.0))
  28. // Ensure lowPosition is less than highPosition
  29. let epsilon: CGFloat = 0.0001
  30. let sortedPositions = [clampedLowPosition, clampedHighPosition].sorted()
  31. var adjustedHighPosition = sortedPositions[1]
  32. if adjustedHighPosition - sortedPositions[0] < epsilon {
  33. adjustedHighPosition = min(1.0, sortedPositions[0] + epsilon)
  34. }
  35. return [
  36. Gradient.Stop(color: .red, location: 0.0),
  37. Gradient.Stop(color: .red, location: sortedPositions[0]), // draw red gradient till lowGlucose
  38. Gradient.Stop(color: .green, location: sortedPositions[0] + epsilon),
  39. // draw green above lowGlucose till highGlucose
  40. Gradient.Stop(color: .green, location: adjustedHighPosition),
  41. Gradient.Stop(color: .orange, location: adjustedHighPosition + epsilon), // draw orange above highGlucose
  42. Gradient.Stop(color: .orange, location: 1.0)
  43. ]
  44. }
  45. }