Commit 1412051

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-08-22 11:16:16
delete old graph code
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 855d891
Changed files (2)
app
lib
features
screens
app/lib/features/statistics/measurement_graph.dart
@@ -1,284 +0,0 @@
-import 'dart:math';
-
-import 'package:blood_pressure_app/data_util/blood_pressure_builder.dart';
-import 'package:blood_pressure_app/data_util/display_interval_picker.dart';
-import 'package:blood_pressure_app/data_util/repository_builder.dart';
-import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
-import 'package:blood_pressure_app/model/storage/intervall_store.dart';
-import 'package:blood_pressure_app/model/storage/settings_store.dart';
-import 'package:collection/collection.dart';
-import 'package:fl_chart/fl_chart.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:health_data_store/health_data_store.dart';
-import 'package:intl/intl.dart';
-import 'package:provider/provider.dart';
-
-class _LineChart extends StatefulWidget {
-  const _LineChart({this.height = 200});
-
-  final double height;
-
-  @override
-  State<_LineChart> createState() => _LineChartState();
-}
-
-class _LineChartState extends State<_LineChart> {
-  // ๐ŸŸข
-  @override
-  Widget build(BuildContext context) => SizedBox(
-    height: widget.height,
-    child: RepositoryBuilder<MedicineIntake, MedicineIntakeRepository>(
-      rangeType: IntervallStoreManagerLocation.mainPage,
-      onData: (context, List<MedicineIntake> intakes) => Consumer<Settings>(
-      builder: (context, settings, child) => RepositoryBuilder<Note, NoteRepository>(
-        rangeType: IntervallStoreManagerLocation.mainPage,
-        onData: (context, List<Note> notes) => BloodPressureBuilder(
-          rangeType: IntervallStoreManagerLocation.mainPage,
-          onData: (BuildContext context, UnmodifiableListView<BloodPressureRecord> records) {
-            final List<BloodPressureRecord> data = records.toList();
-            data.sort((a, b) => a.time.compareTo(b.time));
-
-            // calculate lines for graph
-            final pulSpots = <FlSpot>[];
-            final diaSpots = <FlSpot>[];
-            final sysSpots = <FlSpot>[];
-            int maxValue = 0;
-            final int minValue = (settings.validateInputs ? 30 : 0);
-            /// Horizontally first value
-            double? graphBegin;
-            /// Horizontally last value
-            double? graphEnd;
-            for (final e in data) {
-              final x = e.time.millisecondsSinceEpoch.toDouble();
-              if (e.dia != null) {
-                diaSpots.add(FlSpot(x, e.dia!.mmHg.toDouble()));
-                maxValue = max(maxValue, e.dia!.mmHg);
-              }
-              if (e.sys != null) {
-                sysSpots.add(FlSpot(x, e.sys!.mmHg.toDouble()));
-                maxValue = max(maxValue, e.sys!.mmHg);
-              }
-              if (e.pul != null) {
-                pulSpots.add(FlSpot(x, e.pul!.toDouble()));
-                maxValue = max(maxValue, e.pul!);
-              }
-              graphBegin ??= x;
-              graphEnd ??= x;
-              if (x < graphBegin) graphBegin = x;
-              if (x > graphEnd) graphEnd = x;
-            }
-
-            if (diaSpots.length < 2 && sysSpots.length < 2 && pulSpots.length < 2 || graphBegin == null || graphEnd == null) {
-              return Text(AppLocalizations.of(context)!.errNotEnoughDataToGraph);
-            }
-
-            // Add padding to avoid overflowing vertical lines.
-            final len = graphEnd - graphBegin;
-            graphBegin -= len / 40;
-            graphEnd += len / 40;
-
-            return TweenAnimationBuilder<double>(
-              duration: Duration(milliseconds: settings.animationSpeed), // interacts with LineChart duration property
-              tween: Tween<double>(begin: 0, end: settings.graphLineThickness),
-              builder: (context, animatedThickness, child) => LineChart(
-                duration: const Duration(milliseconds: 200),
-                LineChartData(
-                  minY: minValue.toDouble(),
-                  maxY: maxValue + 5,
-                  minX: graphBegin,
-                  maxX: graphEnd,
-                  clipData: const FlClipData.all(),
-                  titlesData: _buildFlTitlesData(settings,
-                    DateTimeRange(start: data.first.time, end: data.last.time),),
-                  lineTouchData: const LineTouchData(
-                    touchTooltipData: LineTouchTooltipData(tooltipMargin: -200, tooltipRoundedRadius: 20),
-                  ),
-                  lineBarsData: buildBars(animatedThickness, settings, sysSpots, diaSpots, pulSpots,
-                    maxValue, minValue, graphBegin, graphEnd,
-                    records, intakes, notes,
-                  ),
-                ),
-              ),
-            );
-          },
-        ),
-      ),
-      ),
-    ),
-  );
-
-  // ๐ŸŸข
-  List<LineChartBarData> buildBars(
-      double animatedThickness, 
-      Settings settings, 
-      List<FlSpot> sysSpots, 
-      List<FlSpot> diaSpots,
-      List<FlSpot> pulSpots,
-      int maxValue,
-      int minValue,
-      /// Horizontally earliest value (same as first timestamp).
-      double? graphBegin,
-      /// Horizontally furthest value (same as last timestamp).
-      double? graphEnd, 
-      Iterable<BloodPressureRecord> allRecords,
-      Iterable<MedicineIntake> allIntakes,
-      Iterable<Note> notes,
-      ) {
-    final bars = [
-      _buildBarData(animatedThickness, sysSpots, settings.sysColor, true, settings.sysWarn.toDouble()),
-      _buildBarData(animatedThickness, diaSpots, settings.diaColor, true, settings.diaWarn.toDouble()),
-      _buildBarData(animatedThickness, pulSpots, settings.pulColor, false),
-      for (final horizontalLine in settings.horizontalGraphLines)
-        if (horizontalLine.height < maxValue && horizontalLine.height > minValue)
-          _buildHorizontalLine(horizontalLine, graphBegin!, graphEnd!),
-    ];
-    if (settings.drawRegressionLines) {
-      bars.addAll([
-          _buildRegressionLine(sysSpots),
-          _buildRegressionLine(diaSpots),
-          _buildRegressionLine(pulSpots),
-      ]);
-    }
-    bars.addAll(_buildNeedlePins(notes, minValue, maxValue, settings));
-    for (final intake in allIntakes) {
-      bars.add(LineChartBarData(
-        spots: [
-          FlSpot(intake.time.millisecondsSinceEpoch.toDouble(), minValue.toDouble()),
-          FlSpot(intake.time.millisecondsSinceEpoch.toDouble(), maxValue + 5),
-        ],
-        barWidth: settings.needlePinBarWidth,
-        dotData: const FlDotData(show: false),
-        dashArray: [8,7],
-        color: intake.medicine.color == null ? null : Color(intake.medicine.color!),
-      ),);
-    }
-    return bars;
-  }
-
-  // ๐ŸŸข
-  FlTitlesData _buildFlTitlesData(Settings settings, DateTimeRange graphRange) {
-    const noTitels = AxisTitles(sideTitles: SideTitles(reservedSize: 40));
-    return FlTitlesData(
-      topTitles: noTitels,
-      rightTitles: noTitels,
-      bottomTitles: AxisTitles(
-        sideTitles: SideTitles(
-          showTitles: true,
-          getTitlesWidget: (double pos, TitleMeta meta) {
-            // don't show fixed titles, as they are replaced by long dates below
-            if (meta.axisPosition <= 1 || pos >= meta.max) {
-              return const SizedBox.shrink();
-            }
-
-            // format of titles
-            late final DateFormat formatter;
-            if (graphRange.duration < const Duration(days: 2)) {
-              formatter = DateFormat.Hm();
-            } else if (graphRange.duration < const Duration(days: 15)) {
-              formatter = DateFormat.E();
-            } else if (graphRange.duration < const Duration(days: 30)) {
-              formatter = DateFormat.d();
-            } else if (graphRange.duration < const Duration(days: 500)) {
-              formatter = DateFormat.MMM();
-            } else {
-              formatter = DateFormat.y();
-            }
-              return Text(
-                formatter.format(DateTime.fromMillisecondsSinceEpoch(pos.toInt())),
-              );
-          },
-        ),
-      ),
-    );
-  }
-
-  // ๐ŸŸข
-  List<LineChartBarData> _buildNeedlePins(Iterable<Note> notes, int min, int max, Settings settings,) => [
-    for (final n in notes.where((e) => e.color != null))
-      LineChartBarData(
-        spots: [
-          FlSpot(n.time.millisecondsSinceEpoch.toDouble(), min.toDouble()),
-          FlSpot(n.time.millisecondsSinceEpoch.toDouble(), max + 5),
-        ],
-        barWidth: settings.needlePinBarWidth,
-        dotData: const FlDotData(show: false),
-        color: Color(n.color!).withAlpha(100),
-      ),
-  ];
-
-  // ๐ŸŸข
-  LineChartBarData _buildBarData(double lineThickness, List<FlSpot> spots, Color color, bool hasAreaData, [double? areaDataCutOff]) => LineChartBarData(
-        spots: spots,
-        color: color,
-        barWidth: lineThickness,
-        dotData: const FlDotData(
-          show: false,
-        ),
-          belowBarData: BarAreaData(
-              show: hasAreaData,
-              color: Colors.red.shade400.withAlpha(100),
-              cutOffY: areaDataCutOff ?? 0,
-              applyCutOffY: true,),
-    );
-
-  // ๐ŸŸข
-  LineChartBarData _buildRegressionLine(List<FlSpot> data) {
-    final d = data.length * data.sum((e) => pow(e.x, 2)) - pow(data.sum((e) => e.x), 2);
-    final gradient = (1/d) * (data.length * data.sum((e) => e.x * e.y) - data.sum((e) => e.x) * data.sum((e) => e.y));
-    final yIntercept = (1/d) * (data.sum((e) => pow(e.x,2)) * data.sum((e) => e.y) -
-                                data.sum((e) => (e.x * e.y)) * data.sum((e) => e.x));
-
-    double y(x) => x * gradient + yIntercept;
-    final start = data.map<double>((e) => e.x).min;
-    final end = data.map<double>((e) => e.x).max;
-    return LineChartBarData(
-      color: Colors.grey,
-      spots: [
-        FlSpot(start, y(start)),
-        FlSpot(end, y(end)),
-      ],
-      dotData: const FlDotData(
-        show: false,
-      ),
-    );
-  }
-
-  // ๐ŸŸข
-  LineChartBarData _buildHorizontalLine(HorizontalGraphLine line, double start, double end) => LineChartBarData(
-      color: line.color,
-      spots: [
-        FlSpot(start, line.height.toDouble()),
-        FlSpot(end, line.height.toDouble()),
-      ],
-      barWidth: 1,
-      dotData: const FlDotData(
-        show: false,
-      ),
-      dashArray: [10,5,],
-    );
-}
-
-class MeasurementGraph extends StatelessWidget {
-  const MeasurementGraph({super.key, this.height = 290});
-
-  final double height;
-
-  @override
-  Widget build(BuildContext context) => SizedBox(
-    height: height,
-    child: Padding(
-      padding: const EdgeInsets.only(right: 16, left: 6, top: 22),
-      child: Column(
-        children: [
-          _LineChart(height: height - 100),
-          const IntervalPicker(type: IntervallStoreManagerLocation.mainPage,),
-        ],
-      ),
-    ),
-  );
-}
-
-extension _Sum<T> on List<T> {
-  double sum(num Function(T value) f) => fold<double>(0, (prev, e) => prev + f(e).toDouble());
-}
app/lib/screens/home_screen.dart
@@ -6,7 +6,6 @@ import 'package:blood_pressure_app/data_util/entry_context.dart';
 import 'package:blood_pressure_app/data_util/repository_builder.dart';
 import 'package:blood_pressure_app/features/measurement_list/compact_measurement_list.dart';
 import 'package:blood_pressure_app/features/measurement_list/measurement_list.dart';
-import 'package:blood_pressure_app/features/statistics/measurement_graph.dart';
 import 'package:blood_pressure_app/features/statistics/value_graph.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
@@ -28,6 +27,38 @@ class AppHome extends StatelessWidget {
   /// Create a home screen.
   const AppHome({super.key});
 
+  Widget _buildValueGraph(BuildContext context) => SizedBox(
+     height: 290,
+     child: Padding(
+       padding: const EdgeInsets.only(right: 16, left: 6, top: 22),
+       child: Column(
+         children: [
+           SizedBox(
+             height: 190,
+             width: MediaQuery.of(context).size.width,
+             child: RepositoryBuilder<MedicineIntake, MedicineIntakeRepository>(
+               rangeType: IntervallStoreManagerLocation.mainPage,
+               onData: (context, List<MedicineIntake> intakes) => RepositoryBuilder<Note, NoteRepository>(
+                 rangeType: IntervallStoreManagerLocation.mainPage,
+                 onData: (context, List<Note> notes) => BloodPressureBuilder(
+                   rangeType: IntervallStoreManagerLocation.mainPage,
+                   onData: (BuildContext context, UnmodifiableListView<BloodPressureRecord> records) => BloodPressureValueGraph(
+                     records: records,
+                     colors: notes,
+                     intakes: intakes,
+                   ),
+                 ),
+               ),
+             ),
+           ),
+           const IntervalPicker(
+             type: IntervallStoreManagerLocation.mainPage,
+           ),
+         ],
+       ),
+     ),
+   );
+
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
@@ -42,47 +73,13 @@ class AppHome extends StatelessWidget {
     return Scaffold(
       body: OrientationBuilder(
         builder: (context, orientation) {
-        if (orientation == Orientation.landscape) {
-          return MeasurementGraph(
-            height: MediaQuery.of(context).size.height,
-          );
-        }
+        if (orientation == Orientation.landscape) return _buildValueGraph(context);
         return Center(
           child: Padding(
             padding: const EdgeInsets.only(top: 20),
             child: Consumer<IntervallStoreManager>(builder: (context, intervalls, child) =>
               Column(children: [
-                SizedBox(
-                  height: 290,
-                  child: Padding(
-                    padding: const EdgeInsets.only(right: 16, left: 6, top: 22),
-                    child: Column(
-                      children: [
-                        SizedBox(
-                          height: 190,
-                          width: MediaQuery.of(context).size.width,
-                          child: RepositoryBuilder<MedicineIntake, MedicineIntakeRepository>(
-                            rangeType: IntervallStoreManagerLocation.mainPage,
-                            onData: (context, List<MedicineIntake> intakes) => RepositoryBuilder<Note, NoteRepository>(
-                              rangeType: IntervallStoreManagerLocation.mainPage,
-                              onData: (context, List<Note> notes) => BloodPressureBuilder(
-                                rangeType: IntervallStoreManagerLocation.mainPage,
-                                onData: (BuildContext context, UnmodifiableListView<BloodPressureRecord> records) => BloodPressureValueGraph(
-                                  records: records,
-                                  colors: notes,
-                                  intakes: intakes,
-                                ),
-                              ),
-                            ),
-                          ),
-                        ),
-                        const IntervalPicker(
-                          type: IntervallStoreManagerLocation.mainPage,
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
+                _buildValueGraph(context),
                 Expanded(
                   child: BloodPressureBuilder(
                     rangeType: IntervallStoreManagerLocation.mainPage,
@@ -159,7 +156,8 @@ class AppHome extends StatelessWidget {
               ),
             ],
           ),);
-        },),
+        },
+      ),
     );
   }
 }