Commit 4e4f76f7 authored by Administrator's avatar Administrator

read valid records in widget and transfer only those to chart

parent e2a8aa0b
......@@ -225,6 +225,16 @@ class Lap {
return heartRates.min().toString();
}
static String avgHeartRate({List<Event> records}) {
var heartRates = records.map((record) => record.db.heartRate).nonZeroInts();
return heartRates.mean().toString();
}
static String maxHeartRate({List<Event> records}) {
var heartRates = records.map((record) => record.db.heartRate).nonZeroInts();
return heartRates.max().toString();
}
static double calculateAveragePower({List<Event> records}) {
var powers = records.map((record) => record.db.power).nonZeroInts();
if (powers.length > 0) {
......
extension DurationFormatters on num {
toStringOrDashes(int precision) {
if (this == -1) {
if (this == -1 || this == null) {
return "- - -";
} else {
return this.toStringAsFixed(precision);
......
......@@ -29,8 +29,10 @@ class _ActivityFormPowerWidgetState extends State<ActivityFormPowerWidget> {
@override
Widget build(context) {
if (records.length > 0) {
var formPowerRecords = records.where(
(value) => value.db.formPower != null && value.db.formPower > 0);
var formPowerRecords = records
.where(
(value) => value.db.formPower != null && value.db.formPower > 0)
.toList();
if (formPowerRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......
......@@ -29,8 +29,10 @@ class _ActivityGroundTimeWidgetState extends State<ActivityGroundTimeWidget> {
@override
Widget build(context) {
if (records.length > 0) {
var groundTimeRecords = records.where(
(value) => value.db.groundTime != null && value.db.groundTime > 0);
var groundTimeRecords = records
.where(
(value) => value.db.groundTime != null && value.db.groundTime > 0)
.toList();
if (groundTimeRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......
......@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/lap.dart';
import 'package:encrateia/utils/list_utils.dart';
import '../charts/actitvity_charts/activity_heart_rate_chart.dart';
import 'package:encrateia/utils/icon_utils.dart';
......@@ -18,16 +17,21 @@ class ActivityHeartRateWidget extends StatelessWidget {
future: activity.records,
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
var heartRates =
snapshot.data.map((value) => value.db.heartRate).nonZeroInts();
if (heartRates.length > 0) {
var heartRateRecords = snapshot.data
.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: records, activity: activity),
ActivityHeartRateChart(
records: heartRateRecords,
activity: activity,
),
ListTile(
leading: MyIcon.average,
title: Text(activity.db.avgHeartRate.toString()),
......@@ -50,7 +54,7 @@ class ActivityHeartRateWidget extends StatelessWidget {
),
ListTile(
leading: MyIcon.amount,
title: Text(records.length.toString()),
title: Text(heartRateRecords.length.toString()),
subtitle: Text("number of measurements"),
),
],
......
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/utils/list_utils.dart';
import 'package:encrateia/utils/num_utils.dart';
import '../charts/actitvity_charts/activity_leg_spring_stiffness_chart.dart';
import 'package:encrateia/utils/icon_utils.dart';
......@@ -31,25 +30,30 @@ class _ActivityLegSpringStiffnessWidgetState
@override
Widget build(context) {
if (records.length > 0) {
var powerValues =
records.map((value) => value.db.groundTime).nonZeroDoubles();
if (powerValues.length > 0) {
var legSpringStiffnessRecords = records
.where((value) =>
value.db.legSpringStiffness != null &&
value.db.legSpringStiffness > 0)
.toList();
if (legSpringStiffnessRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityLegSpringStiffnessChart(
records: records, activity: widget.activity),
records: legSpringStiffnessRecords,
activity: widget.activity,
),
ListTile(
leading: MyIcon.average,
title: Text(avgLegSpringStiffnessString),
subtitle: Text("average ground time"),
subtitle: Text("average leg spring stiffness"),
),
ListTile(
leading: MyIcon.standardDeviation,
title: Text(sdevLegSpringStiffnessString),
subtitle: Text("standard deviation ground time"),
subtitle: Text("standard deviation leg spring stiffness"),
),
ListTile(
leading: MyIcon.amount,
......@@ -61,7 +65,7 @@ class _ActivityLegSpringStiffnessWidgetState
);
} else {
return Center(
child: Text("No ground time data available."),
child: Text("No leg spring stiffness data available."),
);
}
} else {
......
......@@ -15,11 +15,12 @@ class ActivityPowerDurationWidget extends StatelessWidget {
future: activity.records,
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
var powerValues =
snapshot.data.map((value) => value.db.power).nonZeroInts();
if (powerValues.length > 0) {
var powerRecords = snapshot.data
.where((value) => value.db.power != null && value.db.power > 100)
.toList();
if (powerRecords.length > 0) {
return SingleChildScrollView(
child: PowerDurationChart(records: snapshot.data),
child: PowerDurationChart(records: powerRecords),
);
} else {
return Center(
......
......@@ -29,12 +29,13 @@ class _ActivityPowerPerHeartRateWidgetState
@override
Widget build(context) {
if (records.length > 0) {
var powerPerHeartRateRecords = records.where((value) =>
value.db.power != null &&
value.db.power > 100 &&
value.db.heartRate != null &&
value.db.heartRate > 0);
var powerPerHeartRateRecords = records
.where((value) =>
value.db.power != null &&
value.db.power > 100 &&
value.db.heartRate != null &&
value.db.heartRate > 0)
.toList();
if (powerPerHeartRateRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/utils/list_utils.dart';
import 'package:encrateia/utils/num_utils.dart';
import 'package:encrateia/widgets/charts/actitvity_charts/activity_power_ratio_chart.dart';
import 'package:encrateia/utils/icon_utils.dart';
......@@ -30,15 +29,19 @@ class _ActivityPowerRatioWidgetState extends State<ActivityPowerRatioWidget> {
@override
Widget build(context) {
if (records.length > 0) {
var powerValues = records.map((value) => value.db.power).nonZeroInts();
if (powerValues.length > 0) {
var powerRecords = records
.where((value) => value.db.power != null && value.db.power > 0)
.toList();
if (powerRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityPowerRatioChart(
records: records, activity: widget.activity),
records: powerRecords,
activity: widget.activity,
),
Text("power ratio (%) = (power - form power) / power * 100"),
ListTile(
leading: MyIcon.formPower,
......@@ -52,7 +55,7 @@ class _ActivityPowerRatioWidgetState extends State<ActivityPowerRatioWidget> {
),
ListTile(
leading: MyIcon.amount,
title: Text(records.length.toString()),
title: Text(powerRecords.length.toString()),
subtitle: Text("number of measurements"),
),
],
......
......@@ -30,14 +30,17 @@ class _ActivityPowerWidgetState extends State<ActivityPowerWidget> {
@override
Widget build(context) {
if (records.length > 0) {
var powerRecords = records.where((value) => value.db.power != null && value.db.power > 100);
var powerRecords = records
.where((value) => value.db.power != null && value.db.power > 100)
.toList();
if (powerRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityPowerChart(records: powerRecords, activity: widget.activity),
ActivityPowerChart(
records: powerRecords, activity: widget.activity),
ListTile(
leading: MyIcon.average,
title: Text(avgPowerString),
......
......@@ -29,11 +29,13 @@ class _ActivitySpeedPerHeartRateWidgetState
@override
Widget build(context) {
if (records.length > 0) {
var heartRateRecords = records.where((value) =>
value.db.power != null &&
value.db.power > 100 &&
value.db.heartRate != null &&
value.db.heartRate > 0);
var heartRateRecords = records
.where((value) =>
value.db.power != null &&
value.db.power > 100 &&
value.db.heartRate != null &&
value.db.heartRate > 0)
.toList();
if (heartRateRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/utils/list_utils.dart';
import 'package:encrateia/utils/num_utils.dart';
import 'package:encrateia/widgets/charts/actitvity_charts/activity_stride_ratio_chart.dart';
import 'package:encrateia/utils/icon_utils.dart';
......@@ -30,16 +29,22 @@ class _ActivityStrideRatioWidgetState extends State<ActivityStrideRatioWidget> {
@override
Widget build(context) {
if (records.length > 0) {
var strideRatioValues =
records.map((value) => value.db.verticalOscillation).nonZeroDoubles();
if (strideRatioValues.length > 0) {
var strideRatioRecords = records
.where((value) =>
value.db.strydCadence != null &&
value.db.verticalOscillation != null &&
value.db.verticalOscillation != 0)
.toList();
if (strideRatioRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
child: ListView(
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityStrideRatioChart(
records: records, activity: widget.activity),
records: strideRatioRecords,
activity: widget.activity,
),
Text(
"stride ratio = \nstride length (cm) / vertical oscillation (cm)\n"),
Text(
......@@ -56,7 +61,7 @@ class _ActivityStrideRatioWidgetState extends State<ActivityStrideRatioWidget> {
),
ListTile(
leading: MyIcon.amount,
title: Text(records.length.toString()),
title: Text(strideRatioRecords.length.toString()),
subtitle: Text("number of measurements"),
),
],
......@@ -64,7 +69,7 @@ class _ActivityStrideRatioWidgetState extends State<ActivityStrideRatioWidget> {
);
} else {
return Center(
child: Text("No power ratio data available."),
child: Text("No stride ratio data available."),
);
}
} else {
......
......@@ -30,7 +30,10 @@ class _ActivityStrydCadenceWidgetState
@override
Widget build(context) {
if (records.length > 0) {
var powerRecords = records.where((value) => value.db.strydCadence != null && value.db.strydCadence > 0);
var powerRecords = records
.where((value) =>
value.db.strydCadence != null && value.db.strydCadence > 0)
.toList();
if (powerRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......@@ -38,7 +41,9 @@ class _ActivityStrydCadenceWidgetState
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityStrydCadenceChart(
records: powerRecords, activity: widget.activity, ),
records: powerRecords,
activity: widget.activity,
),
ListTile(
leading: MyIcon.average,
title: Text(avgStrydCadenceString),
......
......@@ -30,7 +30,9 @@ class _ActivityVerticalOscillationWidgetState
@override
Widget build(context) {
if (records.length > 0) {
var powerRecords = records.where((value) => value.db.power != null && value.db.power > 100);
var powerRecords = records
.where((value) => value.db.power != null && value.db.power > 100)
.toList();
if (powerRecords.length > 0) {
return ListTileTheme(
iconColor: Colors.deepOrange,
......
......@@ -16,11 +16,9 @@ class ActivityHeartRateChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records.where(
(value) => value.db.heartRate != null && value.db.heartRate > 10);
var smoothedRecords = Event.toIntDataPoints(
attribute: LapIntAttr.heartRate,
records: nonZero,
records: records,
amount: 30,
);
......@@ -43,7 +41,7 @@ class ActivityHeartRateChart extends StatelessWidget {
height: 300,
child: MyLineChart(
data: data,
maxDomain: nonZero.last.db.distance,
maxDomain: records.last.db.distance,
laps: laps,
domainTitle: 'Heart Rate (bpm)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
......
......@@ -16,10 +16,9 @@ class ActivityLegSpringStiffnessChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records.where((value) => value.db.groundTime > 0);
var smoothedRecords = Event.toDoubleDataPoints(
attribute: LapDoubleAttr.legSpringStiffness,
records: nonZero,
records: records,
amount: 30,
);
......@@ -42,7 +41,7 @@ class ActivityLegSpringStiffnessChart extends StatelessWidget {
height: 300,
child: MyLineChart(
data: data,
maxDomain: nonZero.last.db.distance,
maxDomain: records.last.db.distance,
laps: laps,
domainTitle: 'Leg Spring Stiffness (kN/m)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
......
......@@ -16,10 +16,9 @@ class ActivityPowerRatioChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records.where((value) => value.db.power > 0);
var smoothedRecords = Event.toDoubleDataPoints(
attribute: LapDoubleAttr.powerRatio,
records: nonZero,
records: records,
amount: 30,
);
......@@ -42,7 +41,7 @@ class ActivityPowerRatioChart extends StatelessWidget {
height: 300,
child: MyLineChart(
data: data,
maxDomain: nonZero.last.db.distance,
maxDomain: records.last.db.distance,
laps: laps,
domainTitle: 'Power Ratio (%)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
......
......@@ -16,13 +16,9 @@ class ActivityStrideRatioChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records.where((value) =>
value.db.strydCadence != null &&
value.db.verticalOscillation != null &&
value.db.verticalOscillation != 0);
var smoothedRecords = Event.toDoubleDataPoints(
attribute: LapDoubleAttr.strideRatio,
records: nonZero,
records: records,
amount: 30,
);
......@@ -45,7 +41,7 @@ class ActivityStrideRatioChart extends StatelessWidget {
height: 300,
child: MyLineChart(
data: data,
maxDomain: nonZero.last.db.distance,
maxDomain: records.last.db.distance,
laps: laps,
domainTitle: 'Stride Ratio (multiple)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
......
......@@ -10,11 +10,7 @@ class LapFormPowerChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where((value) => value.db.formPower != null && value.db.formPower > 0)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -22,7 +18,7 @@ class LapFormPowerChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.formPower,
data: nonZero,
data: records,
)
];
......
......@@ -10,12 +10,7 @@ class LapGroundTimeChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where(
(value) => value.db.groundTime != null && value.db.groundTime > 0)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -23,7 +18,7 @@ class LapGroundTimeChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.groundTime,
data: nonZero,
data: records,
)
];
......
......@@ -10,8 +10,7 @@ class LapHeartRateChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records.where((value) => value.db.heartRate > 0).toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -19,7 +18,7 @@ class LapHeartRateChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.red.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.heartRate,
data: nonZero,
data: records,
)
];
......
......@@ -10,13 +10,7 @@ class LapLegSpringStiffnessChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where((value) =>
value.db.legSpringStiffness != null &&
value.db.legSpringStiffness > 0)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -24,7 +18,7 @@ class LapLegSpringStiffnessChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.groundTime,
data: nonZero,
data: records,
)
];
......
......@@ -10,11 +10,7 @@ class LapPowerChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where((value) => value.db.power != null && value.db.power > 100)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -22,7 +18,7 @@ class LapPowerChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.power,
data: nonZero,
data: records,
)
];
......
......@@ -10,11 +10,7 @@ class LapStrydCadenceChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where((value) => value.db.strydCadence != null && value.db.strydCadence > 0)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -22,7 +18,7 @@ class LapStrydCadenceChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => 2 * record.db.strydCadence,
data: nonZero,
data: records,
)
];
......
......@@ -10,13 +10,7 @@ class LapVerticalOscillationChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
var nonZero = records
.where((value) =>
value.db.verticalOscillation != null &&
value.db.verticalOscillation > 0)
.toList();
var offset = nonZero.first.db.distance.round();
var offset = records.first.db.distance.round();
List<Series<dynamic, num>> data = [
Series<Event, int>(
......@@ -24,7 +18,7 @@ class LapVerticalOscillationChart extends StatelessWidget {
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (Event record, _) => record.db.distance.round() - offset,
measureFn: (Event record, _) => record.db.verticalOscillation,
data: