Commit 7b9b017

derdilla <derdilla06@gmail.com>
2023-05-01 16:43:06
FEAT: graph time intervall selection
1 parent 5c30bac
Changed files (10)
android
app
src
main
res
drawable
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
lib
android/app/src/main/res/drawable/icon.png
Binary file
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary file
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary file
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary file
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary file
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary file
android/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.derdilla.blood_pressure_app">
    <application
-        android:label="blood_pressure_app"
+        android:label="blood pressure app"
         android:name="${applicationName}"
         android:icon="@mipmap/ic_launcher">
         <activity
android/app/build.gradle
@@ -54,8 +54,8 @@ android {
         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
         minSdkVersion 19
         targetSdkVersion flutter.targetSdkVersion
-        versionCode flutterVersionCode.toInteger()
-        versionName flutterVersionName
+        versionCode 3
+        versionName "0.2"
     }
 
     signingConfigs {
lib/components/measurement_graph.dart
@@ -8,166 +8,210 @@ import 'dart:math';
 import 'package:intl/intl.dart';
 
 class _LineChart extends StatefulWidget {
-
   @override
   State<StatefulWidget> createState() {
     return _LineChartState();
   }
-
 }
 
 class _LineChartState extends State<_LineChart> {
-  static const _recordsCount = 50;
   var _displayMode = DisplayModes.day;
 
   @override
   Widget build(BuildContext context) {
-    const _pulseColor = Colors.red;
-    const _diaColor = Colors.green;
-    const _sysColor = Colors.teal;
-
-
-    return Consumer<BloodPressureModel>(
-      builder: (context, model, child) {
-        late final _dataFuture;
-        DateTime now = DateTime.now();
-        switch (_displayMode) {
-          case DisplayModes.day:
-            _dataFuture = model.getInTimeRange(DateTime(now.year, now.month, now.day), now);
-            break;
-          case DisplayModes.month:
-            _dataFuture = model.getInTimeRange(DateTime(now.year, now.month), now);
-            break;
-          case DisplayModes.year:
-            _dataFuture = model.getInTimeRange(DateTime(now.year), now);
-            break;
-          case DisplayModes.lifetime:
-            _dataFuture = model.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(0), now);
-            break;
-        }
-
-
-        return FutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
-          future: _dataFuture,
-          builder: (BuildContext context, AsyncSnapshot<UnmodifiableListView<BloodPressureRecord>> snapshot) {
-            Widget res;
-            switch (snapshot.connectionState) {
-              case ConnectionState.none:
-                res = const Text('not started');
-                break;
-              case ConnectionState.waiting:
-                res = const Text('loading...');
-                break;
-              default:
-                if (snapshot.hasError) {
-                  res = Text('ERROR: ${snapshot.error}');
-                } else {
-                  assert(snapshot.hasData);
-                  final data = snapshot.data ?? [];
-
-                  List<FlSpot> pulseSpots = [];
-                  List<FlSpot> diastolicSpots = [];
-                  List<FlSpot> systolicSpots = [];
-                  int pulMax = 0;
-                  int diaMax = 0;
-                  int sysMax = 0;
-                  for (var element in data) {
-                    final x = element.creationTime.millisecondsSinceEpoch.toDouble();
-                    diastolicSpots.add(FlSpot(x, element.diastolic.toDouble()));
-                    systolicSpots.add(FlSpot(x, element.systolic.toDouble()));
-                    pulseSpots.add(FlSpot(x, element.pulse.toDouble()));
-                    pulMax = max(pulMax, element.pulse);
-                    diaMax = max(diaMax, element.diastolic);
-                    sysMax = max(sysMax, element.systolic);
-                  }
-
-
-                  final noTitels = AxisTitles(sideTitles: SideTitles(reservedSize: 40, showTitles: false));
-                  res = LineChart(
-                      swapAnimationDuration: const Duration(milliseconds: 250),
-                      LineChartData(
-                          minY: 30,
-                          maxY: max(pulMax.toDouble(), max(diaMax.toDouble(), sysMax.toDouble())) + 5,
-                          titlesData: FlTitlesData(topTitles: noTitels, rightTitles:  noTitels,
-                              bottomTitles: AxisTitles(
-                                sideTitles: SideTitles(
-                                    showTitles: true,
-                                    getTitlesWidget: (double pos, TitleMeta meta) {
-                                      late final DateFormat formater;
-                                      switch (_displayMode) {
-                                        case DisplayModes.day:
-                                          formater = DateFormat('H:mm');
-                                          break;
-                                        case DisplayModes.month:
-                                          formater = DateFormat('d');
-                                          break;
-                                        case DisplayModes.year:
-                                          formater = DateFormat('MMM');
-                                          break;
-                                        case DisplayModes.lifetime:
-                                          formater = DateFormat('yyyy');
-                                      }
-                                      return Text(
-                                          formater.format(DateTime.fromMillisecondsSinceEpoch(pos.toInt()))
-                                      );
-                                    }
-                                ),
-                              )
-                          ),
-                          lineBarsData: [
-                            // high blood pressure marking acordning to https://www.texasheart.org/heart-health/heart-information-center/topics/high-blood-pressure-hypertension/
-                            LineChartBarData(
-                                spots: pulseSpots,
-                                color: _pulseColor,
-                                barWidth: 4,
-                                isCurved: true,
-                                preventCurveOverShooting: true
-                            ),
-                            LineChartBarData(
-                                spots: diastolicSpots,
-                                color: _diaColor,
-                                barWidth: 4,
-                                isCurved: true,
-                                preventCurveOverShooting: true,
-                                belowBarData: BarAreaData(
-                                    show: true,
-                                    color: Colors.red.shade400.withAlpha(100),
-                                    cutOffY: 80,
-                                    applyCutOffY: true
-                                )
-                            ),
-                            LineChartBarData(
-                                spots: systolicSpots,
-                                color: _sysColor,
-                                barWidth: 4,
-                                isCurved: true,
-                                preventCurveOverShooting: true,
-                                belowBarData: BarAreaData(
-                                    show: true,
-                                    color: Colors.red.shade400.withAlpha(100),
-                                    cutOffY: 130,
-                                    applyCutOffY: true
-                                )
-                            )
-                          ]
-                      )
-                  );
+    const pulseColor = Colors.red;
+    const diaColor = Colors.green;
+    const sysColor = Colors.teal;
+
+
+    return Stack(
+      children: [
+        Container(
+          height: 200,
+          child: Consumer<BloodPressureModel>(
+              builder: (context, model, child) {
+                late final Future<UnmodifiableListView<BloodPressureRecord>> dataFuture;
+                DateTime now = DateTime.now();
+                switch (_displayMode) {
+                  case DisplayModes.day:
+                    dataFuture = model.getInTimeRange(DateTime(now.year, now.month, now.day), now);
+                    break;
+                  case DisplayModes.month:
+                    dataFuture = model.getInTimeRange(DateTime(now.year, now.month), now);
+                    break;
+                  case DisplayModes.year:
+                    dataFuture = model.getInTimeRange(DateTime(now.year), now);
+                    break;
+                  case DisplayModes.lifetime:
+                    dataFuture = model.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(0), now);
+                    break;
                 }
-            }
-            return res;
-          }
-      );
-      },
+
+
+                return FutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
+                    future: dataFuture,
+                    builder: (BuildContext context, AsyncSnapshot<UnmodifiableListView<BloodPressureRecord>> snapshot) {
+                      Widget res;
+                      switch (snapshot.connectionState) {
+                        case ConnectionState.none:
+                          res = const Text('not started');
+                          break;
+                        case ConnectionState.waiting:
+                          res = const Text('loading...');
+                          break;
+                        default:
+                          if (snapshot.hasError) {
+                            res = Text('ERROR: ${snapshot.error}');
+                          } else {
+                            assert(snapshot.hasData);
+                            final data = snapshot.data ?? [];
+
+                            List<FlSpot> pulseSpots = [];
+                            List<FlSpot> diastolicSpots = [];
+                            List<FlSpot> systolicSpots = [];
+                            int pulMax = 0;
+                            int diaMax = 0;
+                            int sysMax = 0;
+                            for (var element in data) {
+                              final x = element.creationTime.millisecondsSinceEpoch.toDouble();
+                              diastolicSpots.add(FlSpot(x, element.diastolic.toDouble()));
+                              systolicSpots.add(FlSpot(x, element.systolic.toDouble()));
+                              pulseSpots.add(FlSpot(x, element.pulse.toDouble()));
+                              pulMax = max(pulMax, element.pulse);
+                              diaMax = max(diaMax, element.diastolic);
+                              sysMax = max(sysMax, element.systolic);
+                            }
+
+
+                            final noTitels = AxisTitles(sideTitles: SideTitles(reservedSize: 40, showTitles: false));
+                            res = LineChart(
+                                swapAnimationDuration: const Duration(milliseconds: 250),
+                                LineChartData(
+                                    minY: 30,
+                                    maxY: max(pulMax.toDouble(), max(diaMax.toDouble(), sysMax.toDouble())) + 5,
+                                    titlesData: FlTitlesData(topTitles: noTitels, rightTitles:  noTitels,
+                                        bottomTitles: AxisTitles(
+                                          sideTitles: SideTitles(
+                                              showTitles: true,
+                                              getTitlesWidget: (double pos, TitleMeta meta) {
+                                                late final DateFormat formater;
+                                                switch (_displayMode) {
+                                                  case DisplayModes.day:
+                                                    formater = DateFormat('H:mm');
+                                                    break;
+                                                  case DisplayModes.month:
+                                                    formater = DateFormat('d');
+                                                    break;
+                                                  case DisplayModes.year:
+                                                    formater = DateFormat('MMM');
+                                                    break;
+                                                  case DisplayModes.lifetime:
+                                                    formater = DateFormat('yyyy');
+                                                }
+                                                return Text(
+                                                    formater.format(DateTime.fromMillisecondsSinceEpoch(pos.toInt()))
+                                                );
+                                              }
+                                          ),
+                                        )
+                                    ),
+                                    lineBarsData: [
+                                      // high blood pressure marking acordning to https://www.texasheart.org/heart-health/heart-information-center/topics/high-blood-pressure-hypertension/
+                                      LineChartBarData(
+                                          spots: pulseSpots,
+                                          color: pulseColor,
+                                          barWidth: 4,
+                                          isCurved: true,
+                                          preventCurveOverShooting: true
+                                      ),
+                                      LineChartBarData(
+                                          spots: diastolicSpots,
+                                          color: diaColor,
+                                          barWidth: 4,
+                                          isCurved: true,
+                                          preventCurveOverShooting: true,
+                                          belowBarData: BarAreaData(
+                                              show: true,
+                                              color: Colors.red.shade400.withAlpha(100),
+                                              cutOffY: 80,
+                                              applyCutOffY: true
+                                          )
+                                      ),
+                                      LineChartBarData(
+                                          spots: systolicSpots,
+                                          color: sysColor,
+                                          barWidth: 4,
+                                          isCurved: true,
+                                          preventCurveOverShooting: true,
+                                          belowBarData: BarAreaData(
+                                              show: true,
+                                              color: Colors.red.shade400.withAlpha(100),
+                                              cutOffY: 130,
+                                              applyCutOffY: true
+                                          )
+                                      )
+                                    ]
+                                )
+                            );
+                          }
+                      }
+                      return res;
+                    }
+                );
+              },
+        )
+        ),
+        Align(
+          alignment: Alignment.topRight,
+          child: Container(
+            color: Colors.white,
+            child: DropdownButton<int>(
+              value: _displayMode,
+              onChanged: (int? value) {
+                setState(() {
+                  _displayMode = value ?? 1;
+                });
+              },
+              dropdownColor: Colors.white,
+              items: DisplayModes.options.map<DropdownMenuItem<int>>((v) {
+                return DropdownMenuItem(
+                    value: v,
+                    child: Text(
+                        DisplayModes.getName(v)
+                    )
+                );
+              }).toList(),
+            ),
+          )
+        )
+      ],
     );
+
   }
 
 }
 
 class DisplayModes {
+  static const options = [0, 1, 2, 3];
+
   static const day = 0;
   static const month = 1;
   static const year = 2;
   static const lifetime = 3;
+
+  static String getName(int opt) {
+    switch (opt) {
+      case day:
+        return 'day';
+      case month:
+        return 'month';
+      case year:
+        return 'year';
+      case lifetime:
+        return 'lifetime';
+    }
+    return 'invalid';
+  }
 }
 
 class MeasurementGraph extends StatelessWidget {
@@ -176,10 +220,10 @@ class MeasurementGraph extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     // TODO: implement build
-    return Container(
+    return SizedBox(
       height: 100,
       child: Padding(
-        padding: const EdgeInsets.only(right: 16, left: 6),
+        padding: const EdgeInsets.only(right: 16, left: 6, top: 10),
         child: _LineChart(),
       ),
     );
lib/components/measurement_list.dart
@@ -52,12 +52,12 @@ class MeasurementList extends StatelessWidget {
   Widget buildListItem(BloodPressureRecord record) {
     final DateFormat formater = DateFormat('yy-MM-dd H:mm:s');
     return Container(
-      margin: EdgeInsets.only(bottom: 5),
+      margin: const EdgeInsets.only(bottom: 5),
       child: Row(
           children: [
             Expanded(
               flex: _sideFlex,
-              child: SizedBox(),
+              child: const SizedBox(),
             ),
             Expanded(
                 flex: _tableElementsSizes[0],