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

Format TIR Chart.
Check for empty loops

Jon Mårtensson 2 лет назад
Родитель
Сommit
ff7c4a765f

+ 16 - 7
FreeAPS/Sources/Modules/Stat/View/ChartsView.swift

@@ -161,20 +161,24 @@ struct ChartsView: View {
         let fetched = tir()
         let low = lowLimit * (units == .mmolL ? Decimal(conversionFactor) : 1)
         let high = highLimit * (units == .mmolL ? Decimal(conversionFactor) : 1)
+        let fraction = units == .mmolL ? 1 : 0
         let data: [ShapeModel] = [
             .init(
                 type: NSLocalizedString(
                     "Low",
                     comment: ""
-                ) + " (≤ \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))))",
+                ) + " (≤ \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))))",
                 percent: fetched[0].decimal
             ),
-            .init(type: NSLocalizedString("In Range", comment: ""), percent: fetched[1].decimal),
+            .init(
+                type: "> \(low.formatted(.number.precision(.fractionLength(fraction)))) - < \(high.formatted(.number.precision(.fractionLength(fraction))))",
+                percent: fetched[1].decimal
+            ),
             .init(
                 type: NSLocalizedString(
                     "High",
                     comment: ""
-                ) + " (≥ \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))))",
+                ) + " (≥ \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))))",
                 percent: fetched[2].decimal
             )
         ]
@@ -184,21 +188,26 @@ struct ChartsView: View {
                 y: .value("Percentage", shape.percent)
             )
             .foregroundStyle(by: .value("Group", shape.type))
-            .annotation(position: .automatic, alignment: .center) {
+            .annotation(position: shape.percent > 19 ? .overlay : .automatic, alignment: .center) {
                 Text(shape.percent == 0 ? "" : "\(shape.percent, format: .number.precision(.fractionLength(0)))")
             }
         }
         .chartXAxis(.hidden)
+        .chartYAxis {
+            AxisMarks(
+                format: Decimal.FormatStyle.Percent.percent.scale(1)
+            )
+        }
         .chartForegroundStyleScale([
             NSLocalizedString(
                 "Low",
                 comment: ""
-            ) + " (≤ \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))))": .red,
-            NSLocalizedString("In Range", comment: ""): .green,
+            ) + " (≤ \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))))": .red,
+            "> \(low.formatted(.number.precision(.fractionLength(fraction)))) - < \(high.formatted(.number.precision(.fractionLength(fraction))))": .green,
             NSLocalizedString(
                 "High",
                 comment: ""
-            ) + " (≥ \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))))": .orange
+            ) + " (≥ \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))))": .orange
         ])
     }
 

+ 48 - 47
FreeAPS/Sources/Modules/Stat/View/StatsView.swift

@@ -57,53 +57,54 @@ struct StatsView: View {
     var loops: some View {
         VStack(spacing: 10) {
             let loops = fetchRequest
-
-            // First date
-            let previous = loops.last?.end ?? Date()
-            // Last date (recent)
-            let current = loops.first?.start ?? Date()
-
-            // Total time in days
-            let totalTime = (current - previous).timeInterval / 8.64E4
-
-            let durationArray = loops.compactMap({ each in each.duration })
-            let durationArrayCount = durationArray.count
-            // var durationAverage = durationArray.reduce(0, +) / Double(durationArrayCount)
-            let medianDuration = medianCalculationDouble(array: durationArray)
-            let successsNR = loops.compactMap({ each in each.loopStatus }).filter({ each in each!.contains("Success") })
-                .count
-            let errorNR = durationArrayCount - successsNR
-            let successRate: Double? = (Double(successsNR) / Double(successsNR + errorNR)) * 100
-
-            let loopNr = totalTime <= 1 ? Double(successsNR + errorNR) : round(Double(successsNR + errorNR) / totalTime)
-
-            let intervalArray = loops.compactMap({ each in each.interval as Double })
-            let intervalAverage = intervalArray.reduce(0, +) / Double(intervalArray.count)
-            // let maximumInterval = intervalArray.max()
-            // let minimumInterval = intervalArray.min()
-
-            HStack(spacing: 35) {
-                VStack(spacing: 5) {
-                    Text("Loops").font(.subheadline).foregroundColor(headline)
-                    Text(loopNr.formatted())
-                }
-                VStack(spacing: 5) {
-                    Text("Interval").font(.subheadline).foregroundColor(headline)
-                    Text(intervalAverage.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + " min")
-                }
-                VStack(spacing: 5) {
-                    Text("Duration").font(.subheadline).foregroundColor(headline)
-                    Text(
-                        (medianDuration * 60)
-                            .formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + " s"
-                    )
-                }
-                VStack(spacing: 5) {
-                    Text("Sucess").font(.subheadline).foregroundColor(headline)
-                    Text(
-                        ((successRate ?? 100) / 100)
-                            .formatted(.percent.grouping(.never).rounded().precision(.fractionLength(1)))
-                    )
+            if !loops.isEmpty {
+                // First date
+                let previous = loops.last?.end ?? Date()
+                // Last date (recent)
+                let current = loops.first?.start ?? Date()
+
+                // Total time in days
+                let totalTime = (current - previous).timeInterval / 8.64E4
+
+                let durationArray = loops.compactMap({ each in each.duration })
+                let durationArrayCount = durationArray.count
+                // var durationAverage = durationArray.reduce(0, +) / Double(durationArrayCount)
+                let medianDuration = medianCalculationDouble(array: durationArray)
+                let successsNR = loops.compactMap({ each in each.loopStatus }).filter({ each in each!.contains("Success") })
+                    .count
+                let errorNR = durationArrayCount - successsNR
+                let successRate: Double? = (Double(successsNR) / Double(successsNR + errorNR)) * 100
+
+                let loopNr = totalTime <= 1 ? Double(successsNR + errorNR) : round(Double(successsNR + errorNR) / totalTime)
+
+                let intervalArray = loops.compactMap({ each in each.interval as Double })
+                let intervalAverage = intervalArray.reduce(0, +) / Double(intervalArray.count)
+                // let maximumInterval = intervalArray.max()
+                // let minimumInterval = intervalArray.min()
+
+                HStack(spacing: 35) {
+                    VStack(spacing: 5) {
+                        Text("Loops").font(.subheadline).foregroundColor(headline)
+                        Text(loopNr.formatted())
+                    }
+                    VStack(spacing: 5) {
+                        Text("Interval").font(.subheadline).foregroundColor(headline)
+                        Text(intervalAverage.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + " min")
+                    }
+                    VStack(spacing: 5) {
+                        Text("Duration").font(.subheadline).foregroundColor(headline)
+                        Text(
+                            (medianDuration * 60)
+                                .formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + " s"
+                        )
+                    }
+                    VStack(spacing: 5) {
+                        Text("Sucess").font(.subheadline).foregroundColor(headline)
+                        Text(
+                            ((successRate ?? 100) / 100)
+                                .formatted(.percent.grouping(.never).rounded().precision(.fractionLength(1)))
+                        )
+                    }
                 }
             }
         }