Explorar o código

Fix percentile formatting; finish section popovers WIP

Deniz Cengiz hai 1 ano
pai
achega
97969bf00b

+ 2 - 2
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -64174,10 +64174,10 @@
     "Dynamically adjust your Carb Ratio (CR)." : {
 
     },
-    "eA1c Display Unit" : {
+    "eA1c" : {
 
     },
-    "ebA1c" : {
+    "eA1c Display Unit" : {
 
     },
     "Edit" : {

+ 1 - 1
Trio/Sources/Modules/Stat/View/ViewElements/BareStatisticsView.swift

@@ -57,7 +57,7 @@ struct BareStatisticsView {
                             + "%"
                     )
                     VStack(spacing: 5) {
-                        Text("ebA1c").font(.subheadline).foregroundColor(.secondary)
+                        Text("eA1c").font(.subheadline).foregroundColor(.secondary)
                         Text(eA1cString)
                     }
                     VStack(spacing: 5) {

+ 35 - 5
Trio/Sources/Modules/Stat/View/ViewElements/GlucosePercentileChart.swift

@@ -210,31 +210,61 @@ struct AGPSelectionPopover: View {
             Grid(alignment: .leading, horizontalSpacing: 8) {
                 GridRow {
                     Text("90%:")
-                    Text(units == .mmolL ? stats.percentile90.asMmolL.formatted(.number) : stats.percentile90.formatted(.number))
+                    Text(units == .mmolL ? stats.percentile90.asMmolL.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(1))
+                    ) : stats.percentile90.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(0))
+                    ))
                     Text(units.rawValue)
                         .foregroundStyle(.secondary)
                 }
                 GridRow {
                     Text("75%:")
-                    Text(units == .mmolL ? stats.percentile75.asMmolL.formatted(.number) : stats.percentile75.formatted(.number))
+                    Text(units == .mmolL ? stats.percentile75.asMmolL.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(1))
+                    ) : stats.percentile75.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(0))
+                    ))
                     Text(units.rawValue)
                         .foregroundStyle(.secondary)
                 }
                 GridRow {
                     Text("Median:")
-                    Text(units == .mmolL ? stats.median.asMmolL.formatted(.number) : stats.median.formatted(.number))
+                    Text(units == .mmolL ? stats.median.asMmolL.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(1))
+                    ) : stats.median.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(0))
+                    ))
                     Text(units.rawValue)
                         .foregroundStyle(.secondary)
                 }
                 GridRow {
                     Text("25%:")
-                    Text(units == .mmolL ? stats.percentile25.asMmolL.formatted(.number) : stats.percentile25.formatted(.number))
+                    Text(units == .mmolL ? stats.percentile25.asMmolL.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(1))
+                    ) : stats.percentile25.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(0))
+                    ))
                     Text(units.rawValue)
                         .foregroundStyle(.secondary)
                 }
                 GridRow {
                     Text("10%:")
-                    Text(units == .mmolL ? stats.percentile10.asMmolL.formatted(.number) : stats.percentile10.formatted(.number))
+                    Text(units == .mmolL ? stats.percentile10.asMmolL.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(1))
+                    ) : stats.percentile10.formatted(
+                        .number.grouping(.never).rounded()
+                            .precision(.fractionLength(0))
+                    ))
                     Text(units.rawValue)
                         .foregroundStyle(.secondary)
                 }

+ 70 - 7
Trio/Sources/Modules/Stat/View/ViewElements/SectorChart.swift

@@ -31,7 +31,7 @@ struct SectorChart: View {
             // Count readings between low limit and 140 mg/dL (tight control)
             let tight = glucose.filter { $0.glucose >= Int(lowLimit) && $0.glucose <= 140 }.count
             // Count readings between 140 and high limit (normal range)
-            let normal = glucose.filter { $0.glucose > 140 && $0.glucose <= Int(highLimit) }.count
+            let normal = glucose.filter { $0.glucose >= Int(lowLimit) && $0.glucose <= Int(highLimit) }.count
             // Count readings between 54 and low limit (low)
             let low = glucose.filter { $0.glucose < Int(lowLimit) }.count
 
@@ -248,24 +248,55 @@ struct SectorChart: View {
             // Count readings between low limit and 140 mg/dL (tight control)
             let tight = glucose.filter { $0.glucose >= Int(lowLimit) && $0.glucose <= 140 }.count
             // Count readings between 140 and high limit (normal range)
-            let normal = glucose.filter { $0.glucose > 140 && $0.glucose <= Int(highLimit) }.count
+            let glucoseValues = glucose.filter { $0.glucose >= Int(lowLimit) && $0.glucose <= Int(highLimit) }
 
             // Format glucose values
             let lowLimitTreshold = units == .mmolL ? Decimal(Int(lowLimit)).asMmolL : lowLimit
             let highLimitTreshold = units == .mmolL ? Decimal(Int(highLimit)).asMmolL : highLimit
             let tightThresholdTreshold = units == .mmolL ? Decimal(140).asMmolL : 140
 
+            let glucoseValuesAsInt = glucoseValues.compactMap({ each in Int(each.glucose as Int16) })
+            let glucoseTotal = glucoseValuesAsInt.reduce(0, +)
+
+            let average = Decimal(glucoseTotal / glucoseValues.count)
+            let median = Decimal(BareStatisticsView.medianCalculation(array: glucoseValuesAsInt))
+
+            var sumOfSquares = 0.0
+            glucoseValuesAsInt.forEach { value in
+                sumOfSquares += pow(Double(value) - Double(average), 2)
+            }
+
+            var standardDeviation = 0.0
+
+            if average > 0 {
+                standardDeviation = sqrt(sumOfSquares / Double(glucoseValues.count))
+            }
+
             return RangeDetail(
                 title: "In Range",
                 color: .green,
                 items: [
                     (
-                        "Tight (\(lowLimitTreshold)-\(tightThresholdTreshold) \(units.rawValue))",
+                        "Normal (\(lowLimitTreshold)-\(highLimitTreshold))",
+                        formatPercentage(Decimal(glucoseValues.count) / total * 100)
+                    ),
+                    (
+                        "Tight (\(lowLimitTreshold)-\(tightThresholdTreshold))",
                         formatPercentage(Decimal(tight) / total * 100)
                     ),
+                    ("Avergage", units == .mgdL ? average.description : average.formattedAsMmolL),
+                    ("Median", units == .mgdL ? median.description : median.formattedAsMmolL),
                     (
-                        "Normal (\(tightThresholdTreshold)-\(highLimitTreshold) \(units.rawValue))",
-                        formatPercentage(Decimal(normal) / total * 100)
+                        "SD",
+                        units == .mgdL ? standardDeviation.formatted(
+                            .number.grouping(.never).rounded()
+                                .precision(.fractionLength(0))
+                        ) : standardDeviation.asMmolL.formatted(
+                            .number.grouping(.never).rounded()
+                                .precision(
+                                    .fractionLength(1)
+                                )
+                        )
                     )
                 ]
             )
@@ -279,17 +310,49 @@ struct SectorChart: View {
             let lowLimitTreshold = units == .mmolL ? Decimal(Int(lowLimit)).asMmolL : lowLimit
             let veryLowThresholdTreshold = units == .mmolL ? Decimal(54).asMmolL : 54
 
+            let lowGlucoseValues = glucose.filter { $0.glucose < Int(lowLimit) }
+            let lowGlucoseValuesAsInt = lowGlucoseValues.compactMap({ each in Int(each.glucose as Int16) })
+            let lowGlucoseTotal = lowGlucoseValuesAsInt.reduce(0, +)
+
+            let average = Decimal(lowGlucoseTotal / lowGlucoseValues.count)
+            let median = Decimal(BareStatisticsView.medianCalculation(array: lowGlucoseValuesAsInt))
+
+            var sumOfSquares = 0.0
+            lowGlucoseValuesAsInt.forEach { value in
+                sumOfSquares += pow(Double(value) - Double(average), 2)
+            }
+
+            var standardDeviation = 0.0
+
+            if average > 0 {
+                standardDeviation = sqrt(sumOfSquares / Double(lowGlucoseValues.count))
+            }
+
             return RangeDetail(
                 title: "Low Glucose",
                 color: .red,
                 items: [
                     (
-                        "Low (\(veryLowThresholdTreshold)-\(lowLimitTreshold) \(units.rawValue))",
+                        "Low (\(veryLowThresholdTreshold)-\(lowLimitTreshold))",
                         formatPercentage(Decimal(low) / total * 100)
                     ),
                     (
-                        "Very Low (<\(veryLowThresholdTreshold) \(units.rawValue))",
+                        "Very Low (<\(veryLowThresholdTreshold))",
                         formatPercentage(Decimal(veryLow) / total * 100)
+                    ),
+                    ("Avergage", units == .mgdL ? average.description : average.formattedAsMmolL),
+                    ("Median", units == .mgdL ? median.description : median.formattedAsMmolL),
+                    (
+                        "SD",
+                        units == .mgdL ? standardDeviation.formatted(
+                            .number.grouping(.never).rounded()
+                                .precision(.fractionLength(0))
+                        ) : standardDeviation.asMmolL.formatted(
+                            .number.grouping(.never).rounded()
+                                .precision(
+                                    .fractionLength(1)
+                                )
+                        )
                     )
                 ]
             )