Просмотр исходного кода

fix glucose target line mark logic ....wip

polscm32 aka Marvout 1 год назад
Родитель
Сommit
fc4e09789b

+ 47 - 33
FreeAPS/Sources/Modules/Home/View/Chart/ChartElements/GlucoseTargetsView.swift

@@ -12,56 +12,70 @@ struct GlucoseTargetsView: ChartContent {
         drawGlucoseTargets()
     }
 
+    /**
+     Draws glucose target ranges on the chart
+
+     - Returns: A ChartContent containing line marks representing target glucose ranges
+
+     The function:
+     - Creates target profiles for two consecutive days
+     - Converts values between mg/dL and mmol/L based on user settings
+     - Draws green lines to visualize the target ranges
+     */
     private func drawGlucoseTargets() -> some ChartContent {
+        // Array to store target profiles for visualization
         var targetProfiles: [TargetProfile] = []
         let targets = bgTargets.targets
 
-        for (index, target) in targets.enumerated() {
-            let startTime = max(TimeInterval(target.offset * 60), startMarker.timeIntervalSinceReferenceDate)
-            let endTime: TimeInterval = {
-                if index + 1 < targets.count {
-                    return min(TimeInterval(targets[index + 1].offset * 60), endMarker.timeIntervalSinceReferenceDate)
-                } else {
-                    return endMarker.timeIntervalSinceReferenceDate
-                }
-            }()
+        // Generate profiles for today and tomorrow, because otherwise the targets would be cut off at midnight
+        // TODO: maybe theres a better solution than introducing a second for loop?
+        let days = [0, 1]
+
+        for dayOffset in days {
+            // Calculate base date for current day offset
+            // it should be the start of the day of the startMarker
+            let baseDate = Calendar.current.startOfDay(for: startMarker)
+                .addingTimeInterval(TimeInterval(dayOffset * 24 * 60 * 60))
+
+            for (index, target) in targets.enumerated() {
+                // Calculate start time by adding target offset
+                let startTime = baseDate.addingTimeInterval(TimeInterval(target.offset * 60))
 
-            if startTime < endTime { // Ensure valid range
+                // Calculate end time - either next target or end of day
+                let endTime: Date = {
+                    if index + 1 < targets.count {
+                        return baseDate.addingTimeInterval(TimeInterval(targets[index + 1].offset * 60))
+                    } else {
+                        return baseDate.addingTimeInterval(24 * 60 * 60)
+                    }
+                }()
+
+                // append target profile to array
                 targetProfiles.append(
                     TargetProfile(
                         value: units == .mgdL ? target.low : target.low.asMmolL,
-                        startTime: startTime,
-                        endTime: endTime
+                        startTime: startTime.timeIntervalSinceReferenceDate,
+                        endTime: endTime.timeIntervalSinceReferenceDate
                     )
                 )
             }
         }
 
-        // Draw Target Lines
+        // Draw target lines for each profile
         return ForEach(targetProfiles, id: \.self) { profile in
-            // Horizontal Line for Target Range
             LineMark(
-                x: .value("Time", Date(timeIntervalSince1970: profile.startTime)),
-                y: .value("Value", profile.value)
-            ).lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.green.gradient)
+                x: .value("Time", Date(timeIntervalSinceReferenceDate: profile.startTime)),
+                y: .value("Target", profile.value)
+            )
+            .lineStyle(.init(lineWidth: 0.5))
+            .foregroundStyle(Color.green.opacity(0.8))
 
             LineMark(
-                x: .value("Time", Date(timeIntervalSince1970: profile.endTime)),
-                y: .value("Value", profile.value)
-            ).lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.green.gradient)
-
-            // Vertical Transition Line to the Next Profile (if exists)
-            if let nextProfile = targetProfiles.first(where: { $0.startTime == profile.endTime }) {
-                LineMark(
-                    x: .value("Time", Date(timeIntervalSince1970: profile.endTime)),
-                    y: .value("Value", profile.value)
-                ).lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.green.gradient)
-
-                LineMark(
-                    x: .value("Time", Date(timeIntervalSince1970: profile.endTime)),
-                    y: .value("Value", nextProfile.value)
-                ).lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.green.gradient)
-            }
+                x: .value("Time", Date(timeIntervalSinceReferenceDate: profile.endTime)),
+                y: .value("Target", profile.value)
+            )
+            .lineStyle(.init(lineWidth: 0.5))
+            .foregroundStyle(Color.green.opacity(0.8))
         }
     }
 }