Commit 338edb02 authored by Administrator's avatar Administrator

work diagramm on activity level

parent 177bfbc5
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.10/","dependencies":[]}],"android":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.10/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]},{"name":"shared_preferences_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+8/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"url_launcher_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+5/","dependencies":[]},{"name":"url_launcher_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.1+5/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"uni_links","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]}],"date_created":"2020-07-17 13:11:33.186953","version":"1.17.3"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.10/","dependencies":[]}],"android":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.10/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]},{"name":"shared_preferences_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+8/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"url_launcher_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+5/","dependencies":[]},{"name":"url_launcher_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.1+5/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"uni_links","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]}],"date_created":"2020-07-17 15:31:52.307110","version":"1.17.3"}
\ No newline at end of file
......@@ -27,8 +27,7 @@ class PowerDuration {
for (int durationIndex = newDuration;
durationIndex > 0;
durationIndex--) {
if (newPower <= (powerMap[durationIndex] ?? 0))
break;
if (newPower <= (powerMap[durationIndex] ?? 0)) break;
powerMap[durationIndex] = newPower;
}
}
......@@ -41,8 +40,7 @@ class PowerDuration {
if (power > (powerMap[duration] ?? 0)) {
for (int durationIndex = duration; durationIndex > 0; durationIndex--) {
if (power <= (powerMap[durationIndex] ?? 0))
break;
if (power <= (powerMap[durationIndex] ?? 0)) break;
powerMap[durationIndex] = power.toDouble();
}
}
......@@ -66,11 +64,33 @@ class PowerDuration {
return plotPoints;
}
List<DoublePlotPoint> asWorkList() {
final List<DoublePlotPoint> plotPoints = <DoublePlotPoint>[];
powerMap.forEach((int duration, double power) {
if (duration > 60 && duration < 1200)
plotPoints.add(DoublePlotPoint(
domain: duration,
measure: power,
));
});
plotPoints.sort(
(DoublePlotPoint a, DoublePlotPoint b) => a.domain.compareTo(b.domain));
return plotPoints;
}
PowerDuration normalize() {
powerMap.forEach((int duration, double power) =>
powerMap[duration] = power * pow(3600 / duration, -0.07));
return this;
}
PowerDuration workify() {
powerMap.forEach(
(int duration, double power) => powerMap[duration] = power * duration);
return this;
}
static int scaled({int seconds}) => (200 * log(seconds)).round();
}
......@@ -8,6 +8,7 @@ import 'package:encrateia/widgets/activity_widgets/activity_pace_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_power_ratio_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_speed_per_heart_rate_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_tag_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_work_widget.dart';
import 'package:encrateia/widgets/laps_list_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_heart_rate_widget.dart';
import 'package:encrateia/widgets/activity_widgets/activity_path_widget.dart';
......@@ -240,6 +241,16 @@ class _ShowActivityScreenState extends State<ShowActivityScreen> {
athlete: widget.athlete,
),
),
navigationButton(
title: 'Work / CP',
color: MyColor.navigate,
icon: MyIcon.work,
context: context,
nextWidget: ActivityWorkWidget(
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
title: 'Metadata',
color: MyColor.settings,
......
......@@ -113,4 +113,5 @@ class MyIcon {
static final Icon warning = Icon(Icons.warning);
static final Icon website = Icon(Icons.web);
static final Icon weight = Icon(Icons.restaurant_menu);
static final Icon work = Icon(Icons.landscape);
}
import 'package:encrateia/models/athlete.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/widgets/charts/work_chart.dart';
class ActivityWorkWidget extends StatelessWidget {
const ActivityWorkWidget({
@required this.activity,
@required this.athlete,
});
final Activity activity;
final Athlete athlete;
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Event>>(
future: activity.records,
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
final List<Event> powerRecords = snapshot.data
.where((Event value) =>
value.power != null && value.power > 100)
.toList();
if (powerRecords.isNotEmpty) {
return SingleChildScrollView(
child: WorkChart(records: powerRecords),
);
} else {
return const Center(
child: Text('No power data available.'),
);
}
} else {
return Container(
height: 100,
child: const Center(
child: Text('Loading'),
),
);
}
},
);
}
}
import 'package:encrateia/models/power_duration.dart';
import 'package:charts_flutter/flutter.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/plot_point.dart';
class WorkChart extends StatelessWidget {
const WorkChart({this.records});
final List<Event> records;
@override
Widget build(BuildContext context) {
final PowerDuration powerDuration = PowerDuration(records: records);
final PowerDuration workCurve = powerDuration.workify();
final List<Series<DoublePlotPoint, num>> data = <Series<DoublePlotPoint, num>>[
Series<DoublePlotPoint, int>(
id: 'Work',
colorFn: (_, __) => MaterialPalette.green.shadeDefault,
domainFn: (DoublePlotPoint record, _) => record.domain,
measureFn: (DoublePlotPoint record, _) => record.measure,
data: workCurve.asWorkList(),
)
];
const StaticNumericTickProviderSpec staticTicks =
StaticNumericTickProviderSpec(<TickSpec<int>>[
TickSpec<int>(60, label: '1min'),
TickSpec<int>(600, label: '10min'),
TickSpec<int>(1200, label: '20min'),
]);
final List<ChartTitle> chartTitles = <ChartTitle>[
ChartTitle(
'Work (J)',
titleStyleSpec: const TextStyleSpec(fontSize: 13),
behaviorPosition: BehaviorPosition.start,
titleOutsideJustification: OutsideJustification.end,
),
ChartTitle(
'Time',
titleStyleSpec: const TextStyleSpec(fontSize: 13),
behaviorPosition: BehaviorPosition.bottom,
titleOutsideJustification: OutsideJustification.end,
),
ChartTitle(
'Work diagram created with Encrateia https://encreteia.informatom.com',
titleStyleSpec: const TextStyleSpec(fontSize: 10),
behaviorPosition: BehaviorPosition.top,
titleOutsideJustification: OutsideJustification.endDrawArea,
),
];
return Container(
height: 300,
padding: const EdgeInsets.all(2),
child: LineChart(
data,
defaultRenderer: LineRendererConfig<num>(
includeArea: true,
),
primaryMeasureAxis: const NumericAxisSpec(
tickProviderSpec: BasicNumericTickProviderSpec(
zeroBound: false,
dataIsInWholeNumbers: true,
desiredTickCount: 10,
desiredMinTickCount: 6),
),
domainAxis: const NumericAxisSpec(tickProviderSpec: staticTicks),
animate: false,
behaviors: chartTitles,
),
);
}
}
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