Bläddra i källkod

Add chart width calculation

Yakov Karpov 5 år sedan
förälder
incheckning
968e958921

+ 3 - 3
FreeAPS.xcodeproj/project.pbxproj

@@ -1348,8 +1348,8 @@
 			children = (
 				6610FA0525FAED29004781D7 /* Charts */,
 				6610FA0825FAED29004781D7 /* Components */,
-				6610FA0C25FAED29004781D7 /* ChartsConfig.swift */,
 				6610FA0D25FAED29004781D7 /* Points */,
+				6610FA0C25FAED29004781D7 /* ChartsConfig.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -2054,7 +2054,7 @@
 				CODE_SIGN_ENTITLEMENTS = FreeAPS/Resources/FreeAPS.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_ASSET_PATHS = "";
-				DEVELOPMENT_TEAM = BA7ZHP4963;
+				DEVELOPMENT_TEAM = DZTZ7KUUBK;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = FreeAPS/Resources/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -2077,7 +2077,7 @@
 				CODE_SIGN_ENTITLEMENTS = FreeAPS/Resources/FreeAPS.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_ASSET_PATHS = "";
-				DEVELOPMENT_TEAM = BA7ZHP4963;
+				DEVELOPMENT_TEAM = DZTZ7KUUBK;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = FreeAPS/Resources/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;

+ 42 - 36
FreeAPS/Sources/Charts/Views/Charts/PointChartView.swift

@@ -1,19 +1,30 @@
 import SwiftUI
 
 struct PointChartView<PointEntry: View>: View {
+    let minValue: Int
+    let maxValue: Int
     let width: CGFloat
     let showHours: Int
     let glucoseData: [BloodGlucose]
     let pointEntry: (_: Int?) -> PointEntry
 
+    let hoursMultiplier: Double = 14
+    let pointSize: CGFloat = ChartsConfig.glucosePointSize / 2
+
     public var body: some View {
-        GeometryReader { geometry in
+        let firstEntryTime = glucoseData
+            .map(\.date)
+            .first ?? UInt64(Date().timeIntervalSince1970)
+        
+        var width: CGFloat = 0
+        if let lastGlucose = glucoseData.last {
+            width = calculateXPosition(glucose: lastGlucose, firstEntryTime: firstEntryTime)
+        }
+        
+        return GeometryReader { geometry in
             ForEach(
                 getGlucosePoints(
-                    data: glucoseData,
-                    height: geometry.size.height,
-                    width: width,
-                    showHours: showHours
+                    height: geometry.size.height, firstEntryTime: firstEntryTime
                 ),
                 id: \.self
             ) { point in
@@ -21,48 +32,41 @@ struct PointChartView<PointEntry: View>: View {
                     .position(x: point.xPosition, y: point.yPosition ?? 0)
             }
         }
-        .frame(width: 10000)
+        .frame(width: width + pointSize)
     }
 }
 
-private func getGlucosePoints(
-    data: [BloodGlucose],
-    height: CGFloat,
-    width: CGFloat,
-    showHours: Int
-) -> [GlucosePointData] {
-    let values = data.compactMap(\.sgv)
-
-    let maxValue = values.max() ?? 180
-    let minValue = values.min() ?? 60
-    let firstEntryTime = data
-        .map(\.date)
-        .first ?? UInt64(Date().timeIntervalSince1970)
-
-    let pointSize: CGFloat = ChartsConfig.glucosePointSize / 2
+extension PointChartView {
+    func calculateXPosition(glucose: BloodGlucose, firstEntryTime: UInt64) -> CGFloat {
+        let xPositionIndex = CGFloat(glucose.date - firstEntryTime) / CGFloat(300 * showHours)
+        return (xPositionIndex * width / CGFloat(Double(showHours) * hoursMultiplier)) + pointSize
+    }
 
-    /// y = mx + b where m = scalingFactor, b = addendum, x = value, y = mapped value
-    let scalingFactor = Double(height - pointSize * 2) / Double(maxValue - minValue)
-    let addendum = scalingFactor * Double(maxValue)
-    let hoursMultiplier: Double = 14
+    func getGlucosePoints(
+        height: CGFloat,
+        firstEntryTime: UInt64
+    ) -> [GlucosePointData] {
+        /// y = mx + b where m = scalingFactor, b = addendum, x = value, y = mapped value
+        let scalingFactor = Double(height - pointSize * 2) / Double(maxValue - minValue)
+        let addendum = scalingFactor * Double(maxValue)
 
-    return data.map { glucose in
-        let xPositionIndex = CGFloat(glucose.date - firstEntryTime) / CGFloat(300 * showHours)
+        return glucoseData.map { glucose in
 
-        let xPosition = (xPositionIndex * width / CGFloat(Double(showHours) * hoursMultiplier)) + pointSize
+            let xPosition = calculateXPosition(glucose: glucose, firstEntryTime: firstEntryTime)
 
-        guard let value = glucose.sgv else {
+            guard let value = glucose.sgv else {
+                return GlucosePointData(
+                    value: nil,
+                    xPosition: xPosition,
+                    yPosition: nil
+                )
+            }
             return GlucosePointData(
-                value: nil,
+                value: value,
                 xPosition: xPosition,
-                yPosition: nil
+                yPosition: CGFloat(-scalingFactor * Double(value) + addendum) + pointSize
             )
         }
-        return GlucosePointData(
-            value: value,
-            xPosition: xPosition,
-            yPosition: CGFloat(-scalingFactor * Double(value) + addendum) + pointSize
-        )
     }
 }
 
@@ -82,6 +86,8 @@ struct PointChartView_Previews: PreviewProvider {
         Group {
             ScrollView(.horizontal) {
                 PointChartView(
+                    minValue: 3,
+                    maxValue: 8,
                     width: 500,
                     showHours: 1,
                     glucoseData: testingData

+ 2 - 0
FreeAPS/Sources/Charts/Views/Charts/PredictionsChartView.swift

@@ -10,6 +10,8 @@ public struct PredictionsChartView: View {
             if let data = data {
                 ForEach(data, id: \.self) { predictionLine in
                     PointChartView(
+                        minValue: 30,
+                        maxValue: 300,
                         width: 500,
                         showHours: 1,
                         glucoseData: predictionLine.values

+ 1 - 1
FreeAPS/Sources/Modules/Home/HomeDataFlow.swift

@@ -7,5 +7,5 @@ enum Home {
 protocol HomeProvider: Provider {
     var suggestion: Suggestion? { get }
     func fetchAndLoop()
-    func filteredGlucose() -> [BloodGlucose]
+    func filteredGlucose(hours: Int) -> [BloodGlucose]
 }

+ 2 - 2
FreeAPS/Sources/Modules/Home/HomeProvider.swift

@@ -14,9 +14,9 @@ extension Home {
             apsManager.fetchAndLoop()
         }
 
-        func filteredGlucose() -> [BloodGlucose] {
+        func filteredGlucose(hours: Int) -> [BloodGlucose] {
             glucoseStorage.recent().filter {
-                $0.dateString.addingTimeInterval(3.hours.timeInterval) > Date()
+                $0.dateString.addingTimeInterval(hours.hours.timeInterval) > Date()
             }
         }
     }

+ 8 - 2
FreeAPS/Sources/Modules/Home/HomeViewModel.swift

@@ -6,13 +6,15 @@ extension Home {
         @Injected() var broadcaster: Broadcaster!
         @Injected() var settingsManager: SettingsManager!
 
+        private(set) var filteredGlucoseHours = 3
+
         @Published var glucose: [BloodGlucose] = []
         @Published var suggestion: Suggestion?
 
         @Published var allowManualTemp = false
 
         override func subscribe() {
-            glucose = provider.filteredGlucose()
+            glucose = provider.filteredGlucose(hours: filteredGlucoseHours)
             suggestion = provider.suggestion
             allowManualTemp = !settingsManager.settings.closedLoop
             broadcaster.register(GlucoseObserver.self, observer: self)
@@ -43,12 +45,16 @@ extension Home {
         func settings() {
             showModal(for: .settings)
         }
+
+        func setFilteredGlucoseHours(hours: Int) {
+            filteredGlucoseHours = hours
+        }
     }
 }
 
 extension Home.ViewModel: GlucoseObserver, SuggestionObserver, SettingsObserver {
     func glucoseDidUpdate(_: [BloodGlucose]) {
-        glucose = provider.filteredGlucose()
+        glucose = provider.filteredGlucose(hours: filteredGlucoseHours)
     }
 
     func suggestionDidUpdate(_ suggestion: Suggestion) {

+ 4 - 1
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -6,7 +6,8 @@ extension Home {
         @State var showHours = 1
 
         var body: some View {
-            GeometryReader { geo in
+            viewModel.setFilteredGlucoseHours(hours: 24)
+            return GeometryReader { geo in
                 VStack {
                     Group {
                         Text("Header")
@@ -15,6 +16,8 @@ extension Home {
                         HoursPickerView(selectedHour: $showHours)
                         ScrollView(.horizontal, showsIndicators: false) {
                             PointChartView(
+                                minValue: 20,
+                                maxValue: 300,
                                 width: geo.size.width,
                                 showHours: showHours,
                                 glucoseData: SampleData.sampleData