Kaynağa Gözat

Add GMI mmol/mol conversion, fix hint

Deniz Cengiz 1 yıl önce
ebeveyn
işleme
ddc51af173

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

@@ -48336,7 +48336,7 @@
         }
       }
     },
-    "Choose to display eA1c in percent or mmol/mol." : {
+    "Choose to display eA1c and GMI in percent or mmol/mol." : {
 
     },
     "Choose to display HbA1c in percent or mmol/mol." : {
@@ -48640,7 +48640,7 @@
         }
       }
     },
-    "Choose which format you'd prefer the eA1c (estimated A1c) value in the statistics view as a percentage (Example: 6.5%) or mmol/mol (Example: 48 mmol/mol)." : {
+    "Choose which format you'd prefer the eA1c (estimated A1c) and GMI (Glucose Management Index) value in the statistics view as a percentage (Example: eA1c: 6.5%) or mmol/mol (Example: eA1c: 48 mmol/mol)." : {
 
     },
     "Choose which format you'd prefer the HbA1c value in the statistics view as a percentage (Example: 6.5%) or mmol/mol (Example: 48 mmol/mol)." : {
@@ -70973,7 +70973,7 @@
     "eA1c" : {
 
     },
-    "eA1c Display Unit" : {
+    "eA1c/GMI Display Unit" : {
 
     },
     "Edit" : {

+ 19 - 11
Trio/Sources/Modules/Stat/View/ViewElements/Glucose/GlucoseMetricsView.swift

@@ -27,11 +27,13 @@ struct GlucoseMetricsView: View {
         let totalDays = (latestDate - earliestDate).timeInterval / 86400
 
         // Format glucose statistics based on the selected unit
-        let eA1cString = preferredUnit == .mmolL
-            ? glucoseStats.ifcc.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))
-            : glucoseStats.ngsp.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + "%"
+        let eA1cString = preferredUnit == .mgdL
+            ? (glucoseStats.ngsp.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + "%") : glucoseStats
+            .ifcc.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))
 
-        let gmiString = glucoseStats.gmi.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + "%"
+        let gmiString = preferredUnit == .mgdL ?
+            (glucoseStats.gmiPercentage.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1))) + "%") :
+            glucoseStats.gmiMmolMol.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))
 
         // glucoseStats already parsed to units - only format decimals
         let standardDeviationString = units == .mgdL ? glucoseStats.sd.formatted(
@@ -60,14 +62,14 @@ struct GlucoseMetricsView: View {
 
     /// Computes various statistical metrics from stored glucose readings, including:
     /// - Estimated A1c in NGSP (%) and IFCC (mmol/mol)
-    /// - Glucose Management Index (GMI)
+    /// - Glucose Management Index (GMI) in both mmol/mol and percentage
     /// - Average and median glucose levels
     /// - Standard deviation (SD) and coefficient of variation (CV)
     /// - Number of readings per day
     ///
     /// - Returns: A tuple containing glucose statistics.
     func calculateGlucoseStatistics() -> (
-        ifcc: Double, ngsp: Double, gmi: Double, average: Double,
+        ifcc: Double, ngsp: Double, gmiMmolMol: Double, gmiPercentage: Double, average: Double,
         median: Double, sd: Double, cv: Double, readingsPerDay: Double
     ) {
         // Determine the date range of the glucose data
@@ -84,7 +86,7 @@ struct GlucoseMetricsView: View {
 
         // Handle empty dataset case
         guard totalReadings > 1 else {
-            return (ifcc: 0, ngsp: 0, gmi: 0, average: 0, median: 0, sd: 0, cv: 0, readingsPerDay: 0)
+            return (ifcc: 0, ngsp: 0, gmiMmolMol: 0, gmiPercentage: 0, average: 0, median: 0, sd: 0, cv: 0, readingsPerDay: 0)
         }
 
         let sumOfReadings = glucoseValues.reduce(0, +)
@@ -96,7 +98,8 @@ struct GlucoseMetricsView: View {
         // Estimated A1c and Glucose Management Index (GMI) calculations
         var eA1cNGSP = 0.0 // eA1c NGSP (%)
         var eA1cIFCC = 0.0 // eA1c IFCC (mmol/mol)
-        var gmiValue = 0.0 // Glucose Management Index (GMI)
+        var gmiValuePercentage = 0.0 // GMI (%)
+        var gmiValueMmolMol = 0.0 // GMI (mmol/mol)
 
         if totalDays > 0 {
             // **eA1c NGSP Calculation** (CGM-based)
@@ -107,9 +110,13 @@ struct GlucoseMetricsView: View {
             // eA1c IFCC (mmol/mol) = 10.929 * (eA1c NGSP - 2.152)
             eA1cIFCC = 10.929 * (eA1cNGSP - 2.152)
 
-            // **Glucose Management Index (GMI)**
+            // **Glucose Management Index (GMI) in %**
             // GMI = 3.31 + (0.02392 × Average Glucose mg/dL)
-            gmiValue = 3.31 + (0.02392 * meanGlucose)
+            gmiValuePercentage = 3.31 + (0.02392 * meanGlucose)
+
+            // **Glucose Management Index (GMI) in mmol/mol**
+            // GMI mmol/mol = (GMI % - 2.15) * 10.929
+            gmiValueMmolMol = (gmiValuePercentage - 2.152) * 10.929
         }
 
         // Compute Standard Deviation (SD) and Coefficient of Variation (CV)
@@ -123,7 +130,8 @@ struct GlucoseMetricsView: View {
         return (
             ifcc: eA1cIFCC, // eA1c in IFCC (mmol/mol)
             ngsp: eA1cNGSP, // eA1c in NGSP (%)
-            gmi: gmiValue, // Glucose Management Index
+            gmiMmolMol: gmiValueMmolMol, // GMI in mmol/mol
+            gmiPercentage: gmiValuePercentage, // GMI in %
             average: Double(units == .mgdL ? Decimal(meanGlucose) : meanGlucose.asMmolL),
             median: Double(units == .mgdL ? Decimal(medianGlucose) : medianGlucose.asMmolL),
             sd: Double(units == .mgdL ? Decimal(standardDeviation) : standardDeviation.asMmolL),

+ 4 - 4
Trio/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift

@@ -382,7 +382,7 @@ extension UserInterfaceSettings {
                         VStack {
                             Picker(
                                 selection: $state.eA1cDisplayUnit,
-                                label: Text("eA1c Display Unit")
+                                label: Text("eA1c/GMI Display Unit")
                             ) {
                                 ForEach(EstimatedA1cDisplayUnit.allCases) { selection in
                                     Text(selection.displayName).tag(selection)
@@ -391,7 +391,7 @@ extension UserInterfaceSettings {
 
                             HStack(alignment: .center) {
                                 Text(
-                                    "Choose to display eA1c in percent or mmol/mol."
+                                    "Choose to display eA1c and GMI in percent or mmol/mol."
                                 )
                                 .font(.footnote)
                                 .foregroundColor(.secondary)
@@ -399,11 +399,11 @@ extension UserInterfaceSettings {
                                 Spacer()
                                 Button(
                                     action: {
-                                        hintLabel = String(localized: "eA1c Display Unit")
+                                        hintLabel = String(localized: "eA1c/GMI Display Unit")
                                         selectedVerboseHint =
                                             AnyView(
                                                 Text(
-                                                    "Choose which format you'd prefer the eA1c (estimated A1c) value in the statistics view as a percentage (Example: 6.5%) or mmol/mol (Example: 48 mmol/mol)."
+                                                    "Choose which format you'd prefer the eA1c (estimated A1c) and GMI (Glucose Management Index) value in the statistics view as a percentage (Example: eA1c: 6.5%) or mmol/mol (Example: eA1c: 48 mmol/mol)."
                                                 )
                                             )
                                         shouldDisplayHint.toggle()