This repository has been archived on 2024-03-27. You can view files and clone it, but cannot push or open issues/pull-requests.
encrateia/lib/widgets/activity_widgets/activity_bargraph_widget.dart

208 lines
7.0 KiB
Dart

import 'dart:math';
import 'package:flutter/material.dart';
import '/models/activity.dart';
import '/models/athlete.dart';
import '/models/bar_zone.dart';
import '/models/heart_rate_zone.dart';
import '/models/heart_rate_zone_schema.dart';
import '/models/lap.dart';
import '/models/power_zone.dart';
import '/models/power_zone_schema.dart';
import '/utils/PQText.dart';
import '/utils/enums.dart';
import '/utils/my_bar_chart.dart';
class ActivityBarGraphWidget extends StatefulWidget {
const ActivityBarGraphWidget({
@required this.activity,
@required this.athlete,
});
final Activity activity;
final Athlete athlete;
@override
_ActivityBarGraphWidgetState createState() => _ActivityBarGraphWidgetState();
}
class _ActivityBarGraphWidgetState extends State<ActivityBarGraphWidget> {
PowerZoneSchema _powerZoneSchema;
HeartRateZoneSchema _heartRateZoneSchema;
List<PowerZone> _powerZones = <PowerZone>[];
List<HeartRateZone> _heartRateZones = <HeartRateZone>[];
List<Lap> _laps = <Lap>[];
List<BarZone> _heartRateDistributions = <BarZone>[];
List<BarZone> _powerDistributions = <BarZone>[];
bool loading = true;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
if (_powerZones.isNotEmpty && _laps.isNotEmpty) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 500,
child: ListView(padding: const EdgeInsets.all(20), children: <Widget>[
Table(columnWidths: const <int, TableColumnWidth>{
0: FixedColumnWidth(60),
1: FixedColumnWidth(160),
2: FixedColumnWidth(60),
3: FixedColumnWidth(160),
4: FixedColumnWidth(60),
}, children: <TableRow>[
const TableRow(children: <Widget>[
Text('Title\n'),
Text('Average Power'),
Text('Watts'),
Text('Average Heart Rate'),
Text('bpm'),
]),
TableRow(children: <Widget>[
const Text('Activity'),
MyBarChart(
width: 150,
height: 20,
value: widget.activity.avgPower,
powerZones: _powerZones,
),
Text((widget.activity.avgPower > 0)
? widget.activity.avgPower.toStringAsFixed(1)
: ''),
MyBarChart(
width: 150,
height: 20,
value: widget.activity.avgHeartRate,
heartRateZones: _heartRateZones,
),
Text(widget.activity.avgHeartRate.toString()),
]),
for (Lap lap in _laps)
TableRow(children: <Widget>[
Text('Lap ' + lap.index.toString()),
MyBarChart(
width: 150,
height: 20,
value: lap.avgPower,
powerZones: _powerZones,
),
Text((lap.avgPower > 0)
? lap.avgPower.toStringAsFixed(1)
: ''),
MyBarChart(
width: 150,
height: 20,
value: lap.avgHeartRate,
heartRateZones: _heartRateZones,
),
Text(lap.avgHeartRate.toString()),
]),
]),
const SizedBox(height: 40),
Table(columnWidths: const <int, TableColumnWidth>{
0: FixedColumnWidth(60),
1: FixedColumnWidth(210),
2: FixedColumnWidth(210),
}, children: <TableRow>[
const TableRow(children: <Widget>[
Text('Title\n'),
Text('Power Zone Distribution'),
Text('Heart Rate Zone Distribution'),
]),
TableRow(children: <Widget>[
const Text('Activity'),
MyBarChart.visualizeDistributions(
height: 20,
distributions: _heartRateDistributions,
),
MyBarChart.visualizeDistributions(
height: 20,
distributions: _powerDistributions,
),
]),
for (Lap lap in _laps)
TableRow(children: <Widget>[
Text('Lap ' + lap.index.toString()),
MyBarChart.visualizeDistributions(
height: 20,
distributions: lap.powerDistributions,
),
MyBarChart.visualizeDistributions(
height: 20,
distributions: lap.heartRateDistributions,
),
]),
]),
const SizedBox(height: 40),
Table(columnWidths: const <int, TableColumnWidth>{
0: FixedColumnWidth(60),
1: FixedColumnWidth(210),
2: FixedColumnWidth(60),
}, children: <TableRow>[
const TableRow(children: <Widget>[
Text('Title\n'),
Text('Average Pace'),
Text('min/km'),
]),
TableRow(children: <Widget>[
const Text('Activity'),
MyBarChart(
height: 20,
value: widget.activity.avgSpeed,
maximum: _laps.map((Lap lap) => lap.avgSpeed).reduce(max),
),
PQText(value: widget.activity.avgSpeed, pq: PQ.paceFromSpeed),
]),
for (Lap lap in _laps)
TableRow(children: <Widget>[
Text('Lap ' + lap.index.toString()),
MyBarChart(
height: 20,
value: lap.avgSpeed,
maximum: _laps.map((Lap lap) => lap.avgSpeed).reduce(max),
),
PQText(value: lap.avgSpeed, pq: PQ.paceFromSpeed),
]),
]),
]),
),
);
} else {
return Center(
child: Text(loading ? 'Loading' : 'No data available'),
);
}
}
Future<void> getData() async {
final Activity activity = widget.activity;
_laps = await activity.laps;
for (final Lap _lap in _laps) {
_lap.powerDistributions = await _lap.powerZoneCounts();
_lap.heartRateDistributions = await _lap.heartRateZoneCounts();
}
_powerZoneSchema = await activity.powerZoneSchema;
if (_powerZoneSchema != null) {
_powerZones = await _powerZoneSchema.powerZones;
}
_heartRateDistributions = await activity.powerZoneCounts();
_powerDistributions = await activity.heartRateZoneCounts();
_heartRateZoneSchema = await activity.heartRateZoneSchema;
if (_heartRateZoneSchema != null) {
_heartRateZones = await _heartRateZoneSchema.heartRateZones;
}
setState(() => loading = false);
}
}