Commit aaf964fa authored by Stefan Haslinger's avatar Stefan Haslinger

heart rate zones in activity heart rate diagram

parent 7ca6c8ad
......@@ -16,6 +16,8 @@ import 'package:intl/intl.dart';
import 'package:encrateia/utils/enums.dart';
import 'dart:io';
import 'heart_rate_zone_schema.dart';
class Activity extends ChangeNotifier {
DbActivity db;
List<Event> _records;
......@@ -515,4 +517,12 @@ class Activity extends ChangeNotifier {
);
return powerZoneSchema;
}
getHeartRateZoneSchema() async {
var heartRateZoneSchema = await HeartRateZoneSchema.getBy(
athletesId: db.athletesId,
date: db.timeCreated,
);
return heartRateZoneSchema;
}
}
import 'package:encrateia/models/heart_rate_zone.dart';
import 'package:encrateia/models/lap.dart';
import 'package:charts_flutter/flutter.dart';
import 'package:encrateia/models/power_zone.dart';
......@@ -59,7 +60,7 @@ class GraphUtils {
];
}
static zoneAnnotations({List<PowerZone> powerZones}) {
static powerZoneAnnotations({List<PowerZone> powerZones}) {
List<RangeAnnotationSegment<int>> rangeAnnotationSegmentList = [];
if (powerZones != null) {
......@@ -74,7 +75,24 @@ class GraphUtils {
)
];
}
return rangeAnnotationSegmentList;
}
static heartRateZoneAnnotations({List<HeartRateZone> heartRateZones}) {
List<RangeAnnotationSegment<int>> rangeAnnotationSegmentList = [];
if (heartRateZones != null) {
rangeAnnotationSegmentList = [
for (HeartRateZone heartRateZone in heartRateZones)
RangeAnnotationSegment(
heartRateZone.db.lowerLimit,
heartRateZone.db.upperLimit,
RangeAnnotationAxisType.measure,
startLabel: heartRateZone.db.name,
color: convertedColor(dbColor: heartRateZone.db.color),
)
];
}
return rangeAnnotationSegmentList;
}
......
......@@ -8,6 +8,7 @@ class MyLineChart extends LineChart {
@required maxDomain,
@required laps,
powerZones,
heartRateZones,
@required domainTitle,
measureTitle,
measureTickProviderSpec,
......@@ -26,7 +27,12 @@ class MyLineChart extends LineChart {
behaviors: [
RangeAnnotation(
GraphUtils.rangeAnnotations(laps: laps) +
GraphUtils.zoneAnnotations(powerZones: powerZones),
GraphUtils.powerZoneAnnotations(
powerZones: powerZones,
) +
GraphUtils.heartRateZoneAnnotations(
heartRateZones: heartRateZones,
),
),
ChartTitle(
domainTitle,
......
import 'package:encrateia/models/heart_rate_zone.dart';
import 'package:encrateia/models/heart_rate_zone_schema.dart';
import 'package:encrateia/widgets/charts/actitvity_charts/activity_heart_rate_chart.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
......@@ -5,72 +7,95 @@ import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/lap.dart';
import 'package:encrateia/utils/icon_utils.dart';
class ActivityHeartRateWidget extends StatelessWidget {
class ActivityHeartRateWidget extends StatefulWidget {
final Activity activity;
ActivityHeartRateWidget({this.activity});
@override
_ActivityHeartRateWidgetState createState() =>
_ActivityHeartRateWidgetState();
}
class _ActivityHeartRateWidgetState extends State<ActivityHeartRateWidget> {
List<Event> records = [];
HeartRateZoneSchema heartRateZoneSchema;
List<HeartRateZone> heartRateZones;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(context) {
return FutureBuilder<List<Event>>(
future: activity.records,
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
var heartRateRecords = snapshot.data
.where((value) =>
value.db.heartRate != null && value.db.heartRate > 10)
.toList();
if (records != null) {
var heartRateRecords = records
.where(
(value) => value.db.heartRate != null && value.db.heartRate > 10)
.toList();
if (heartRateRecords.length > 0) {
var records = snapshot.data;
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityHeartRateChart(
records: heartRateRecords,
activity: activity,
),
ListTile(
leading: MyIcon.average,
title: Text(activity.db.avgHeartRate.toString()),
subtitle: Text("average heart rate"),
),
ListTile(
leading: MyIcon.minimum,
title: Text(Lap.minHeartRate(records: records)),
subtitle: Text("minimum heart rate"),
),
ListTile(
leading: MyIcon.maximum,
title: Text(activity.db.maxHeartRate.toString()),
subtitle: Text("maximum heart rate"),
),
ListTile(
leading: MyIcon.standardDeviation,
title: Text(Lap.sdevHeartRate(records: records)),
subtitle: Text("standard deviation heart rate"),
),
ListTile(
leading: MyIcon.amount,
title: Text(heartRateRecords.length.toString()),
subtitle: Text("number of measurements"),
),
],
if (heartRateRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityHeartRateChart(
records: heartRateRecords,
activity: widget.activity,
heartRateZones: heartRateZones,
),
ListTile(
leading: MyIcon.average,
title: Text(widget.activity.db.avgHeartRate.toString()),
subtitle: Text("average heart rate"),
),
);
} else {
return Center(
child: Text("No heart rate data available."),
);
}
} else {
return Center(
child: Text("Loading"),
);
}
},
);
ListTile(
leading: MyIcon.minimum,
title: Text(Lap.minHeartRate(records: records)),
subtitle: Text("minimum heart rate"),
),
ListTile(
leading: MyIcon.maximum,
title: Text(widget.activity.db.maxHeartRate.toString()),
subtitle: Text("maximum heart rate"),
),
ListTile(
leading: MyIcon.standardDeviation,
title: Text(Lap.sdevHeartRate(records: records)),
subtitle: Text("standard deviation heart rate"),
),
ListTile(
leading: MyIcon.amount,
title: Text(heartRateRecords.length.toString()),
subtitle: Text("number of measurements"),
),
],
),
);
} else {
return Center(
child: Text("No heart rate data available."),
);
}
} else {
return Center(
child: Text("Loading"),
);
}
}
getData() async {
Activity activity = widget.activity;
records = await activity.records;
heartRateZoneSchema = await activity.getHeartRateZoneSchema();
if (heartRateZoneSchema != null)
heartRateZones = await heartRateZoneSchema.heartRateZones;
else
heartRateZones = [];
setState(() {});
}
}
......@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/utils/num_utils.dart';
import '../charts/actitvity_charts/activity_power_chart.dart';
import 'package:encrateia/widgets/charts/actitvity_charts/activity_power_chart.dart';
import 'package:encrateia/utils/icon_utils.dart';
import 'package:encrateia/utils/date_time_utils.dart';
......
import 'package:charts_flutter/flutter.dart';
import 'package:encrateia/models/heart_rate_zone.dart';
import 'package:encrateia/models/plot_point.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
......@@ -11,8 +12,13 @@ import 'package:encrateia/utils/enums.dart';
class ActivityHeartRateChart extends StatelessWidget {
final List<Event> records;
final Activity activity;
final List<HeartRateZone> heartRateZones;
ActivityHeartRateChart({this.records, @required this.activity});
ActivityHeartRateChart({
this.records,
@required this.activity,
this.heartRateZones,
});
@override
Widget build(BuildContext context) {
......@@ -23,7 +29,7 @@ class ActivityHeartRateChart extends StatelessWidget {
);
List<Series<dynamic, num>> data = [
Series<IntPlotPoint, int>(
Series<IntPlotPoint, int>(
id: 'Heart Rate',
colorFn: (_, __) => MaterialPalette.red.shadeDefault,
domainFn: (IntPlotPoint point, _) => point.domain,
......@@ -43,6 +49,7 @@ class ActivityHeartRateChart extends StatelessWidget {
data: data,
maxDomain: records.last.db.distance,
laps: laps,
heartRateZones: heartRateZones,
domainTitle: 'Heart Rate (bpm)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
zeroBound: false,
......@@ -52,7 +59,8 @@ class ActivityHeartRateChart extends StatelessWidget {
BasicNumericTickProviderSpec(desiredTickCount: 6),
),
);
} else return GraphUtils.loadingContainer;
} else
return GraphUtils.loadingContainer;
},
);
}
......
......@@ -40,7 +40,7 @@ class LapPowerChart extends StatelessWidget {
animate: false,
behaviors: [
RangeAnnotation(
GraphUtils.zoneAnnotations(powerZones: powerZones),
GraphUtils.powerZoneAnnotations(powerZones: powerZones),
),
ChartTitle(
"Power (W)",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment