diff --git a/LoopFollow/Charts/BGChartModel.swift b/LoopFollow/Charts/BGChartModel.swift index 9b451ac6a..37091fb68 100644 --- a/LoopFollow/Charts/BGChartModel.swift +++ b/LoopFollow/Charts/BGChartModel.swift @@ -157,6 +157,7 @@ final class BGChartModel: ObservableObject { @Published var now: Date = .init() @Published var diaMarkers: [Date] = [] @Published var midnightMarkers: [Date] = [] + @Published var priorDayTimeMarkers: [Date] = [] @Published var thirtyMinMark: Date? = nil @Published var ninetyMinMark: Date? = nil @@ -179,6 +180,7 @@ final class BGChartModel: ObservableObject { @Published var show90Min: Bool = false @Published var showMidnight: Bool = false @Published var smallGraphTreatments: Bool = true + @Published var showPriorDayTime: Bool = false private static let doseFormatter: NumberFormatter = { let nf = NumberFormatter() @@ -411,6 +413,7 @@ final class BGChartModel: ObservableObject { show90Min = Storage.shared.show90MinLine.value showMidnight = Storage.shared.showMidnightLines.value smallGraphTreatments = Storage.shared.smallGraphTreatments.value + showPriorDayTime = Storage.shared.showPriorDayTimeLines.value // Advanced-settings visibility toggles. The Nightscout controllers // collect the data regardless (it also feeds the info rows), so hidden @@ -596,6 +599,17 @@ final class BGChartModel: ObservableObject { } return cal }() + + // Mark the current local time on each prior day. Calendar arithmetic + // preserves the displayed time of day across daylight-saving changes. + var priorDayTimes: [Date] = [] + var priorDayTime = calendar.date(byAdding: .day, value: -1, to: currentNow) + while let marker = priorDayTime, marker > domainStart { + priorDayTimes.append(marker) + priorDayTime = calendar.date(byAdding: .day, value: -1, to: marker) + } + priorDayTimeMarkers = priorDayTimes + var cursor = calendar.startOfDay(for: domainStart) while cursor <= domainEnd { if cursor >= domainStart { diff --git a/LoopFollow/Charts/BGChartView.swift b/LoopFollow/Charts/BGChartView.swift index 9098bd123..1b7dc9407 100644 --- a/LoopFollow/Charts/BGChartView.swift +++ b/LoopFollow/Charts/BGChartView.swift @@ -1095,6 +1095,9 @@ private struct BGChartCanvas: View, Equatable { if showTreatments { treatmentMarks } + if model.showPriorDayTime { + priorDayTimeRuleMarks + } if !isSmall { ruleMarks } else if model.showMidnight { @@ -1462,6 +1465,15 @@ private struct BGChartCanvas: View, Equatable { } } + @ChartContentBuilder + private var priorDayTimeRuleMarks: some ChartContent { + ForEach(model.priorDayTimeMarkers.filter { $0 >= windowStart && $0 <= windowEnd }, id: \.self) { d in + RuleMark(x: .value("same time on prior day", d)) + .lineStyle(StrokeStyle(lineWidth: 1, dash: isSmall ? [2, 2] : [2, 5])) + .foregroundStyle(Color.orange.opacity(isSmall ? 1 : 0.5)) + } + } + @ChartContentBuilder private var ruleMarks: some ChartContent { RuleMark(y: .value("low", model.lowLine)) diff --git a/LoopFollow/Settings/GraphSettingsView.swift b/LoopFollow/Settings/GraphSettingsView.swift index 07d9d8d91..7efb38c40 100644 --- a/LoopFollow/Settings/GraphSettingsView.swift +++ b/LoopFollow/Settings/GraphSettingsView.swift @@ -12,6 +12,7 @@ struct GraphSettingsView: View { @ObservedObject private var show30MinLine = Storage.shared.show30MinLine @ObservedObject private var show90MinLine = Storage.shared.show90MinLine @ObservedObject private var showMidnightLines = Storage.shared.showMidnightLines + @ObservedObject private var showPriorDayTimeLines = Storage.shared.showPriorDayTimeLines @ObservedObject private var showYesterdayLine = Storage.shared.showYesterdayLine @ObservedObject private var smallGraphTreatments = Storage.shared.smallGraphTreatments @@ -50,6 +51,9 @@ struct GraphSettingsView: View { Toggle("Show Midnight Lines", isOn: $showMidnightLines.value) .onChange(of: showMidnightLines.value) { _ in markDirty() } + + Toggle("Show Prior Day Time Lines", isOn: $showPriorDayTimeLines.value) + .onChange(of: showPriorDayTimeLines.value) { _ in markDirty() } } // ── Treatments ─────────────────────────────────────────────── diff --git a/LoopFollow/Settings/SettingsMenuView.swift b/LoopFollow/Settings/SettingsMenuView.swift index 38fb991fb..93fd0fd93 100644 --- a/LoopFollow/Settings/SettingsMenuView.swift +++ b/LoopFollow/Settings/SettingsMenuView.swift @@ -176,6 +176,7 @@ enum SettingsRoute: Hashable, Identifiable { SettingsLeaf("Show −90 min Line", ["-90"]), SettingsLeaf("Show Yesterday's BG", ["yesterday"]), SettingsLeaf("Show Midnight Lines"), + SettingsLeaf("Show Prior Day Time Lines", ["prior day", "same time", "yesterday"]), SettingsLeaf("Show Carb/Bolus Values", ["carbs"]), SettingsLeaf("Show Carb Absorption"), SettingsLeaf("Treatments on Small Graph"), diff --git a/LoopFollow/Storage/Storage.swift b/LoopFollow/Storage/Storage.swift index 4876924e2..32f099148 100644 --- a/LoopFollow/Storage/Storage.swift +++ b/LoopFollow/Storage/Storage.swift @@ -128,6 +128,7 @@ class Storage { var show30MinLine = StorageValue(key: "show30MinLine", defaultValue: false) var show90MinLine = StorageValue(key: "show90MinLine", defaultValue: false) var showMidnightLines = StorageValue(key: "showMidnightMarkers", defaultValue: false) + var showPriorDayTimeLines = StorageValue(key: "showPriorDayTimeMarkers", defaultValue: false) var showYesterdayLine = StorageValue(key: "showYesterdayLine", defaultValue: false) var smallGraphTreatments = StorageValue(key: "smallGraphTreatments", defaultValue: true)