From b7ddb152806798dc80432ff18503e43790676017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Sun, 26 Jul 2026 20:09:42 +0200 Subject: [PATCH] Fix Advanced Settings graph toggles not hiding chart elements The old chart only drew what the gated update calls pushed into it, but the Swift Charts model reads the data arrays directly, so Graph Basal, Graph Bolus, Graph Carbs and Graph Other Treatments were never consulted. Skip the corresponding data during rebuild when a toggle is off, and mark the chart dirty when a toggle changes so it redraws on return to the home screen. Restore two settings-change behaviors dropped in the migration: changing the prediction style re-routes the stored predBGs again, and toggling Show Yesterday's BG reloads the BG window so the overlay updates right away instead of at the next scheduled fetch. --- LoopFollow/Charts/BGChartModel.swift | 32 ++++++++++++------- LoopFollow/Charts/BGChartStubs.swift | 9 ++++++ .../Settings/AdvancedSettingsViewModel.swift | 4 +++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/LoopFollow/Charts/BGChartModel.swift b/LoopFollow/Charts/BGChartModel.swift index a08bab90f..f4f697a2f 100644 --- a/LoopFollow/Charts/BGChartModel.swift +++ b/LoopFollow/Charts/BGChartModel.swift @@ -408,6 +408,14 @@ final class BGChartModel: ObservableObject { showMidnight = Storage.shared.showMidnightLines.value smallGraphTreatments = Storage.shared.smallGraphTreatments.value + // Advanced-settings visibility toggles. The Nightscout controllers + // collect the data regardless (it also feeds the info rows), so hidden + // kinds are dropped here at render time. + let showBasal = Storage.shared.graphBasal.value + let showBolus = Storage.shared.graphBolus.value + let showCarbs = Storage.shared.graphCarbs.value + let showOtherTreatments = Storage.shared.graphOtherTreatments.value + let isLoop = Storage.shared.device.value == "Loop" overrideColor = isLoop ? .green : .purple tempTargetColor = isLoop ? .purple : .green @@ -436,7 +444,7 @@ final class BGChartModel: ObservableObject { cobPrediction = vc.cobPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) } uamPrediction = vc.uamPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) } - let bolusPoints = vc.bolusData.map { + let bolusPoints = (showBolus ? vc.bolusData : []).map { let dose = self.formatDose($0.value) return TreatmentPoint( date: Date(timeIntervalSince1970: $0.date), @@ -446,7 +454,7 @@ final class BGChartModel: ObservableObject { pillText: "Bolus\n\(dose)U\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))" ) } - carbs = Self.spread(vc.carbData.map { + carbs = Self.spread((showCarbs ? vc.carbData : []).map { let grams = Int($0.value) var label = "\(grams)" if $0.absorptionTime > 0, Storage.shared.showAbsorption.value { @@ -460,7 +468,7 @@ final class BGChartModel: ObservableObject { pillText: "Carbs\n\(grams)g\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))" ) }, minGap: Spread.carbGap, maxShift: Spread.carbShift) - let smbPoints = vc.smbData.map { + let smbPoints = (showBolus ? vc.smbData : []).map { let dose = self.formatDose($0.value) return TreatmentPoint( date: Date(timeIntervalSince1970: $0.date), @@ -471,7 +479,7 @@ final class BGChartModel: ObservableObject { ) } (boluses, smbs) = Self.spreadTogether(bolusPoints, smbPoints, minGap: Spread.bolusGap, maxShift: Spread.bolusShift) - bgChecks = vc.bgCheckData.map { + bgChecks = (showOtherTreatments ? vc.bgCheckData : []).map { TreatmentPoint( date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), @@ -480,16 +488,16 @@ final class BGChartModel: ObservableObject { pillText: "BG Check\n\(Localizer.toDisplayUnits(String($0.sgv)))\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))" ) } - suspends = vc.suspendGraphData.map { + suspends = (showOtherTreatments ? vc.suspendGraphData : []).map { TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Suspend\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))") } - resumes = vc.resumeGraphData.map { + resumes = (showOtherTreatments ? vc.resumeGraphData : []).map { TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Resume\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))") } - sensorStarts = vc.sensorStartGraphData.map { + sensorStarts = (showOtherTreatments ? vc.sensorStartGraphData : []).map { TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Sensor Start\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))") } - notes = vc.noteGraphData.map { + notes = (showOtherTreatments ? vc.noteGraphData : []).map { TreatmentPoint( date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), @@ -499,12 +507,12 @@ final class BGChartModel: ObservableObject { ) } - basalScheduled = vc.basalScheduleData.map { + basalScheduled = (showBasal ? vc.basalScheduleData : []).map { ScheduledBasalPoint(date: Date(timeIntervalSince1970: $0.date), rate: $0.basalRate) } var steps: [BasalStep] = [] - let sortedBasal = vc.basalData.sorted { $0.date < $1.date } + let sortedBasal = (showBasal ? vc.basalData : []).sorted { $0.date < $1.date } for i in 0 ..< sortedBasal.count { let start = sortedBasal[i].date let end = i + 1 < sortedBasal.count @@ -523,7 +531,7 @@ final class BGChartModel: ObservableObject { let yTop = maxBG - 5 let yBottom = maxBG - 25 - overrides = vc.overrideGraphData.map { + overrides = (showOtherTreatments ? vc.overrideGraphData : []).map { let overrideName = $0.reason.trimmingCharacters(in: .whitespacesAndNewlines) let displayName = overrideName.isEmpty ? "Override" : overrideName return BandRect( @@ -535,7 +543,7 @@ final class BGChartModel: ObservableObject { pillText: "Override\n\(displayName)\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))" ) } - tempTargets = vc.tempTargetGraphData.map { + tempTargets = (showOtherTreatments ? vc.tempTargetGraphData : []).map { let target = $0.correctionRange.first.map { String($0) } ?? "" // Temp targets render at the BG level they target (±5 mg/dL); // only overrides live in the top strip. diff --git a/LoopFollow/Charts/BGChartStubs.swift b/LoopFollow/Charts/BGChartStubs.swift index ba8714a82..700821a66 100644 --- a/LoopFollow/Charts/BGChartStubs.swift +++ b/LoopFollow/Charts/BGChartStubs.swift @@ -22,6 +22,15 @@ extension MainViewController { func updateBGGraphSettings() { chartModel.rebuild() + + // Re-route the stored predBGs in case the prediction style + // (cone/lines) changed; rebuild() alone only redraws what was + // already routed. + updateOpenAPSPredictionDisplay() + + // The yesterday overlay is built during the BG fetch and needs an + // extra day of history, so reload the BG window when it's toggled. + TaskScheduler.shared.rescheduleTask(id: .fetchBG, to: Date()) } private func recomputeTopBG() { diff --git a/LoopFollow/Settings/AdvancedSettingsViewModel.swift b/LoopFollow/Settings/AdvancedSettingsViewModel.swift index 307d91e69..078e62288 100644 --- a/LoopFollow/Settings/AdvancedSettingsViewModel.swift +++ b/LoopFollow/Settings/AdvancedSettingsViewModel.swift @@ -19,24 +19,28 @@ class AdvancedSettingsViewModel: ObservableObject { @Published var graphBasal: Bool { didSet { Storage.shared.graphBasal.value = graphBasal + Observable.shared.chartSettingsChanged.value = true } } @Published var graphBolus: Bool { didSet { Storage.shared.graphBolus.value = graphBolus + Observable.shared.chartSettingsChanged.value = true } } @Published var graphCarbs: Bool { didSet { Storage.shared.graphCarbs.value = graphCarbs + Observable.shared.chartSettingsChanged.value = true } } @Published var graphOtherTreatments: Bool { didSet { Storage.shared.graphOtherTreatments.value = graphOtherTreatments + Observable.shared.chartSettingsChanged.value = true } }