Showing 1 changed files with 105 additions and 16 deletions
+105 -16
USB Meter/Views/Meter/Components/MeasurementChartView.swift
@@ -224,14 +224,42 @@ struct MeasurementChartView: View {
224 224
         let maximumSampleValue: Double?
225 225
     }
226 226
 
227
+    private enum LegendStatistic: CaseIterable, Hashable {
228
+        case minimum
229
+        case average
230
+        case maximum
231
+        case last
232
+        case total
233
+
234
+        var title: String {
235
+            switch self {
236
+            case .minimum: return "Min"
237
+            case .average: return "Avg"
238
+            case .maximum: return "Max"
239
+            case .last: return "Last"
240
+            case .total: return "Total"
241
+            }
242
+        }
243
+    }
244
+
245
+    private struct SeriesLegendValue: Identifiable {
246
+        let statistic: LegendStatistic
247
+        let text: String
248
+
249
+        var id: LegendStatistic {
250
+            statistic
251
+        }
252
+    }
253
+
227 254
     private struct SeriesLegendEntry: Identifiable {
228 255
         let id: SeriesKind
229 256
         let name: String
230 257
         let tint: Color
231
-        let minimumText: String
232
-        let averageText: String
233
-        let maximumText: String
234
-        let lastText: String
258
+        let values: [SeriesLegendValue]
259
+
260
+        func text(for statistic: LegendStatistic) -> String? {
261
+            values.first { $0.statistic == statistic }?.text
262
+        }
235 263
     }
236 264
 
237 265
     private let minimumTimeSpan: TimeInterval = 1
@@ -771,34 +799,90 @@ struct MeasurementChartView: View {
771 799
         }
772 800
 
773 801
         let averageValue = samples.reduce(0) { $0 + $1.value } / Double(samples.count)
802
+        let values = legendValues(
803
+            for: series.kind,
804
+            minimumValue: minimumValue,
805
+            averageValue: averageValue,
806
+            maximumValue: maximumValue,
807
+            lastValue: lastValue
808
+        )
774 809
 
775 810
         return [
776 811
             SeriesLegendEntry(
777 812
                 id: series.kind,
778 813
                 name: series.kind.displayName,
779 814
                 tint: series.kind.tint,
780
-                minimumText: legendValueText(minimumValue, for: series.kind),
781
-                averageText: legendValueText(averageValue, for: series.kind),
782
-                maximumText: legendValueText(maximumValue, for: series.kind),
783
-                lastText: legendValueText(lastValue, for: series.kind)
815
+                values: values
784 816
             )
785 817
         ]
786 818
     }
787 819
 
820
+    private func legendValues(
821
+        for kind: SeriesKind,
822
+        minimumValue: Double,
823
+        averageValue: Double,
824
+        maximumValue: Double,
825
+        lastValue: Double
826
+    ) -> [SeriesLegendValue] {
827
+        switch kind {
828
+        case .energy:
829
+            return [
830
+                SeriesLegendValue(
831
+                    statistic: .total,
832
+                    text: legendValueText(lastValue, for: kind)
833
+                )
834
+            ]
835
+        case .batteryPercent:
836
+            return [
837
+                SeriesLegendValue(
838
+                    statistic: .minimum,
839
+                    text: legendValueText(minimumValue, for: kind)
840
+                ),
841
+                SeriesLegendValue(
842
+                    statistic: .maximum,
843
+                    text: legendValueText(maximumValue, for: kind)
844
+                ),
845
+                SeriesLegendValue(
846
+                    statistic: .last,
847
+                    text: legendValueText(lastValue, for: kind)
848
+                )
849
+            ]
850
+        case .power, .voltage, .current, .temperature:
851
+            return [
852
+                SeriesLegendValue(
853
+                    statistic: .minimum,
854
+                    text: legendValueText(minimumValue, for: kind)
855
+                ),
856
+                SeriesLegendValue(
857
+                    statistic: .average,
858
+                    text: legendValueText(averageValue, for: kind)
859
+                ),
860
+                SeriesLegendValue(
861
+                    statistic: .maximum,
862
+                    text: legendValueText(maximumValue, for: kind)
863
+                ),
864
+                SeriesLegendValue(
865
+                    statistic: .last,
866
+                    text: legendValueText(lastValue, for: kind)
867
+                )
868
+            ]
869
+        }
870
+    }
871
+
788 872
     @ViewBuilder
789 873
     private func chartLegend(entries: [SeriesLegendEntry]) -> some View {
790 874
         if !entries.isEmpty {
791 875
             let nameWidth: CGFloat = compactLayout ? 88 : (isLargeDisplay ? 128 : 108)
792 876
             let valueWidth: CGFloat = compactLayout ? 78 : (isLargeDisplay ? 108 : 92)
877
+            let statistics = legendStatistics(for: entries)
793 878
 
794 879
             ScrollView(.horizontal, showsIndicators: false) {
795 880
                 VStack(alignment: .leading, spacing: compactLayout ? 5 : 7) {
796 881
                     HStack(spacing: compactLayout ? 8 : 10) {
797 882
                         legendHeaderText("Measurement", width: nameWidth, alignment: .leading)
798
-                        legendHeaderText("Min", width: valueWidth)
799
-                        legendHeaderText("Avg", width: valueWidth)
800
-                        legendHeaderText("Max", width: valueWidth)
801
-                        legendHeaderText("Last", width: valueWidth)
883
+                        ForEach(statistics, id: \.self) { statistic in
884
+                            legendHeaderText(statistic.title, width: valueWidth)
885
+                        }
802 886
                     }
803 887
 
804 888
                     ForEach(entries) { entry in
@@ -814,10 +898,9 @@ struct MeasurementChartView: View {
814 898
                             }
815 899
                             .frame(width: nameWidth, alignment: .leading)
816 900
 
817
-                            legendValueText(entry.minimumText, width: valueWidth)
818
-                            legendValueText(entry.averageText, width: valueWidth)
819
-                            legendValueText(entry.maximumText, width: valueWidth)
820
-                            legendValueText(entry.lastText, width: valueWidth)
901
+                            ForEach(statistics, id: \.self) { statistic in
902
+                                legendValueText(entry.text(for: statistic) ?? "-", width: valueWidth)
903
+                            }
821 904
                         }
822 905
                     }
823 906
                 }
@@ -835,6 +918,12 @@ struct MeasurementChartView: View {
835 918
         }
836 919
     }
837 920
 
921
+    private func legendStatistics(for entries: [SeriesLegendEntry]) -> [LegendStatistic] {
922
+        LegendStatistic.allCases.filter { statistic in
923
+            entries.contains { $0.text(for: statistic) != nil }
924
+        }
925
+    }
926
+
838 927
     private func legendHeaderText(
839 928
         _ text: String,
840 929
         width: CGFloat,