Commit fa7c1fd2 authored by Stefan Haslinger's avatar Stefan Haslinger

zones with alpha channel in activity overview

parent 06e9df75
......@@ -7,6 +7,7 @@ import 'package:strava_flutter/Models/activity.dart' as StravaActivity;
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/lap.dart';
import 'package:encrateia/models/power_zone_schema.dart';
import 'package:fit_parser/fit_parser.dart';
import 'package:path_provider/path_provider.dart';
import 'package:encrateia/utils/date_time_utils.dart';
......@@ -379,7 +380,6 @@ class Activity extends ChangeNotifier {
case "workout_step":
break;
case "session":
var startTime = dateTimeFromStrava(dataMessage.get('start_time'));
if (db.name == "t.b.d.")
......@@ -507,4 +507,12 @@ class Activity extends ChangeNotifier {
.toList();
return activities;
}
getPowerZoneSchema() async {
var powerZoneSchema = await PowerZoneSchema.getBy(
athletesId: db.athletesId,
date: db.timeCreated,
);
return powerZoneSchema;
}
}
......@@ -191,4 +191,23 @@ class PowerZoneSchema extends ChangeNotifier {
.toList();
return powerZoneSchemas;
}
static getBy({
int athletesId,
DateTime date,
}) async {
var dbPowerZoneSchemas = await DbPowerZoneSchema()
.select()
.athletesId
.equals(athletesId)
.and
.date
.lessThanOrEquals(date)
.orderByDesc("date")
.top(1)
.toList();
if (dbPowerZoneSchemas.length != 0)
return PowerZoneSchema.fromDb(dbPowerZoneSchemas.first);
else return null;
}
}
......@@ -173,17 +173,11 @@ class EditAthleteScreen extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Cancel', textScaleFactor: 1.5),
MyButton.cancel(
onPressed: () => Navigator.of(context).pop(),
),
Container(width: 20.0),
RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Save', textScaleFactor: 1.5),
MyButton.save(
onPressed: () => saveStravaUser(context),
),
],
......
import 'package:encrateia/models/lap.dart';
import 'package:charts_flutter/flutter.dart';
import 'package:encrateia/models/power_zone.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as UI;
class GraphUtils {
static rangeAnnotations({List<Lap> laps}) {
......@@ -56,4 +58,29 @@ class GraphUtils {
),
];
}
static zoneAnnotations({List<PowerZone> powerZones}) {
if (powerZones != null) {
return [
for (PowerZone powerZone in powerZones)
RangeAnnotationSegment(
powerZone.db.lowerLimit,
powerZone.db.upperLimit,
RangeAnnotationAxisType.measure,
startLabel: powerZone.db.name,
color: convertedColor(dbColor: powerZone.db.color),
)
];
} else
return [];
}
static convertedColor({int dbColor}) {
return Color(
r: UI.Color(dbColor).red,
g: UI.Color(dbColor).green,
b: UI.Color(dbColor).blue,
a: (UI.Color(dbColor).alpha / 2).round(),
);
}
}
......@@ -3,16 +3,16 @@ import 'package:encrateia/utils/graph_utils.dart';
import 'package:flutter/cupertino.dart';
class MyLineChart extends LineChart {
MyLineChart({
@required data,
@required maxDomain,
@required laps,
@required domainTitle,
measureTitle,
measureTickProviderSpec,
domainTickProviderSpec
}) : super(
MyLineChart(
{@required data,
@required maxDomain,
@required laps,
powerZones,
@required domainTitle,
measureTitle,
measureTickProviderSpec,
domainTickProviderSpec})
: super(
data,
domainAxis: NumericAxisSpec(
viewport: NumericExtents(0, maxDomain + 500),
......@@ -24,7 +24,10 @@ class MyLineChart extends LineChart {
animate: false,
layoutConfig: GraphUtils.layoutConfig,
behaviors: [
RangeAnnotation(GraphUtils.rangeAnnotations(laps: laps)),
RangeAnnotation(
GraphUtils.rangeAnnotations(laps: laps) +
GraphUtils.zoneAnnotations(powerZones: powerZones),
),
ChartTitle(
domainTitle,
titleStyleSpec: TextStyleSpec(fontSize: 13),
......
import 'package:encrateia/models/power_zone.dart';
import 'package:encrateia/models/power_zone_schema.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
......@@ -21,6 +23,8 @@ class _ActivityPowerWidgetState extends State<ActivityPowerWidget> {
String minPowerString = "Loading ...";
String maxPowerString = "Loading ...";
String sdevPowerString = "Loading ...";
PowerZoneSchema powerZoneSchema;
List<PowerZone> powerZones;
@override
void initState() {
......@@ -30,7 +34,7 @@ class _ActivityPowerWidgetState extends State<ActivityPowerWidget> {
@override
Widget build(context) {
if (records.length > 0) {
if (records.length > 0 && powerZones != null) {
var powerRecords = records
.where((value) => value.db.power != null && value.db.power > 100)
.toList();
......@@ -43,7 +47,10 @@ class _ActivityPowerWidgetState extends State<ActivityPowerWidget> {
padding: EdgeInsets.only(left: 25),
children: <Widget>[
ActivityPowerChart(
records: powerRecords, activity: widget.activity),
records: powerRecords,
activity: widget.activity,
powerZones: powerZones,
),
ListTile(
leading: MyIcon.average,
title: Text(avgPowerString),
......@@ -98,6 +105,11 @@ class _ActivityPowerWidgetState extends State<ActivityPowerWidget> {
minPowerString = activity.db.minPower.toString() + " W";
maxPowerString = activity.db.maxPower.toString() + " W";
sdevPowerString = activity.db.sdevPower.toStringOrDashes(2) + " W";
powerZoneSchema = await activity.getPowerZoneSchema();
if (powerZoneSchema != null)
powerZones = await powerZoneSchema.powerZones;
else
powerZones = [];
setState(() {});
}
}
......@@ -45,7 +45,7 @@ class _AthletePowerZoneSchemaWidgetState
DataTable(
headingRowHeight: kMinInteractiveDimension * 0.80,
dataRowHeight: kMinInteractiveDimension * 0.80,
columnSpacing: 20,
columnSpacing: 9,
columns: <DataColumn>[
DataColumn(label: Text("Date")),
DataColumn(label: Text("Name")),
......
import 'package:charts_flutter/flutter.dart';
import 'package:encrateia/models/power_zone.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
......@@ -11,8 +12,13 @@ import 'package:encrateia/utils/enums.dart';
class ActivityPowerChart extends StatelessWidget {
final List<Event> records;
final Activity activity;
final List<PowerZone> powerZones;
ActivityPowerChart({this.records, @required this.activity});
ActivityPowerChart({
this.records,
@required this.activity,
this.powerZones,
});
@override
Widget build(BuildContext context) {
......@@ -23,9 +29,9 @@ class ActivityPowerChart extends StatelessWidget {
);
List<Series<dynamic, num>> data = [
Series<IntPlotPoint, int>(
Series<IntPlotPoint, int>(
id: 'Power',
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
colorFn: (_, __) => MaterialPalette.gray.shade700,
domainFn: (IntPlotPoint record, _) => record.domain,
measureFn: (IntPlotPoint record, _) => record.measure,
data: smoothedRecords,
......@@ -37,12 +43,14 @@ class ActivityPowerChart extends StatelessWidget {
builder: (BuildContext context, AsyncSnapshot<List<Lap>> snapshot) {
if (snapshot.hasData) {
var laps = snapshot.data;
return Container(
height: 300,
child: MyLineChart(
data: data,
maxDomain: records.last.db.distance,
laps: laps,
powerZones: powerZones,
domainTitle: 'Power (W)',
measureTickProviderSpec: BasicNumericTickProviderSpec(
zeroBound: false,
......
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