|
@@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; |
|
@@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; |
|
6
|
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
|
6
|
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
|
|
7
|
import 'package:intl/intl.dart';
|
7
|
import 'package:intl/intl.dart';
|
|
8
|
|
8
|
|
|
9
|
-import '../../../../r.dart';
|
|
|
|
10
|
import '../../report_common/widgets/health_report_subject_scope.dart';
|
9
|
import '../../report_common/widgets/health_report_subject_scope.dart';
|
|
11
|
import '../models/activity_burn_report_models.dart';
|
10
|
import '../models/activity_burn_report_models.dart';
|
|
12
|
import 'activity_burn_trend_lines.dart';
|
11
|
import 'activity_burn_trend_lines.dart';
|
|
@@ -21,7 +20,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -21,7 +20,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
21
|
|
20
|
|
|
22
|
static const _h1 = Color(0xFF0F0F11);
|
21
|
static const _h1 = Color(0xFF0F0F11);
|
|
23
|
static const _h3 = Color(0xFFB0B0B6);
|
22
|
static const _h3 = Color(0xFFB0B0B6);
|
|
24
|
- static const _brand = Color(0xFF845EEE);
|
|
|
|
25
|
static const _active = Color(0xFFFF5279);
|
23
|
static const _active = Color(0xFFFF5279);
|
|
26
|
static const _warm = Color(0xFFFF9A6E);
|
24
|
static const _warm = Color(0xFFFF9A6E);
|
|
27
|
static const _stand = Color(0xFF7B9BFB);
|
25
|
static const _stand = Color(0xFF7B9BFB);
|
|
@@ -41,8 +39,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -41,8 +39,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
41
|
Widget build(BuildContext context) {
|
39
|
Widget build(BuildContext context) {
|
|
42
|
final start = _startTime;
|
40
|
final start = _startTime;
|
|
43
|
final axis = _HeartRateAxis.fromSummary(summary, start);
|
41
|
final axis = _HeartRateAxis.fromSummary(summary, start);
|
|
44
|
- final sleepRange = summary.hasData ? _sleepRange(start, axis.maxX) : null;
|
|
|
|
45
|
-
|
|
|
|
46
|
return Container(
|
42
|
return Container(
|
|
47
|
height: 273,
|
43
|
height: 273,
|
|
48
|
padding: const EdgeInsets.fromLTRB(20, 20, 14, 16),
|
44
|
padding: const EdgeInsets.fromLTRB(20, 20, 14, 16),
|
|
@@ -69,7 +65,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -69,7 +65,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
69
|
SizedBox(
|
65
|
SizedBox(
|
|
70
|
height: _chartHeight,
|
66
|
height: _chartHeight,
|
|
71
|
child: LayoutBuilder(
|
67
|
child: LayoutBuilder(
|
|
72
|
- builder: (context, constraints) {
|
68
|
+ builder: (_, __) {
|
|
73
|
return Stack(
|
69
|
return Stack(
|
|
74
|
fit: StackFit.expand,
|
70
|
fit: StackFit.expand,
|
|
75
|
alignment: Alignment.center,
|
71
|
alignment: Alignment.center,
|
|
@@ -89,20 +85,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -89,20 +85,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
89
|
top: 0,
|
85
|
top: 0,
|
|
90
|
child: LineChart(_chartData()),
|
86
|
child: LineChart(_chartData()),
|
|
91
|
),
|
87
|
),
|
|
92
|
- if (sleepRange != null)
|
|
|
|
93
|
- Positioned(
|
|
|
|
94
|
- top: 0,
|
|
|
|
95
|
- left: _sleepIconLeft(
|
|
|
|
96
|
- sleepRange,
|
|
|
|
97
|
- axis.maxX,
|
|
|
|
98
|
- constraints.maxWidth,
|
|
|
|
99
|
- ),
|
|
|
|
100
|
- child: Image.asset(
|
|
|
|
101
|
- R.assetsImagesHealthBedIcon,
|
|
|
|
102
|
- width: 12,
|
|
|
|
103
|
- height: 12,
|
|
|
|
104
|
- ),
|
|
|
|
105
|
- ),
|
|
|
|
106
|
if (!summary.hasData)
|
88
|
if (!summary.hasData)
|
|
107
|
Positioned(
|
89
|
Positioned(
|
|
108
|
left: 0,
|
90
|
left: 0,
|
|
@@ -130,25 +112,10 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -130,25 +112,10 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
130
|
);
|
112
|
);
|
|
131
|
}
|
113
|
}
|
|
132
|
|
114
|
|
|
133
|
- double _sleepIconLeft(
|
|
|
|
134
|
- _SleepRange range,
|
|
|
|
135
|
- double maxX,
|
|
|
|
136
|
- double chartWidth,
|
|
|
|
137
|
- ) {
|
|
|
|
138
|
- const rightTitleWidth = 28.0;
|
|
|
|
139
|
- const iconWidth = 12.0;
|
|
|
|
140
|
- final plotWidth = math.max(0, chartWidth - rightTitleWidth);
|
|
|
|
141
|
- final centerX = (range.startX + range.endX) / 2;
|
|
|
|
142
|
- return (centerX / maxX * plotWidth - iconWidth / 2)
|
|
|
|
143
|
- .clamp(0, math.max(0, chartWidth - iconWidth))
|
|
|
|
144
|
- .toDouble();
|
|
|
|
145
|
- }
|
|
|
|
146
|
-
|
|
|
|
147
|
LineChartData _chartData() {
|
115
|
LineChartData _chartData() {
|
|
148
|
final start = _startTime;
|
116
|
final start = _startTime;
|
|
149
|
final axis = _HeartRateAxis.fromSummary(summary, start);
|
117
|
final axis = _HeartRateAxis.fromSummary(summary, start);
|
|
150
|
final points = _points(start, axis.endTime);
|
118
|
final points = _points(start, axis.endTime);
|
|
151
|
- final sleepRange = _sleepRange(start, axis.maxX);
|
|
|
|
152
|
|
119
|
|
|
153
|
return LineChartData(
|
120
|
return LineChartData(
|
|
154
|
minX: 0,
|
121
|
minX: 0,
|
|
@@ -219,11 +186,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -219,11 +186,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
219
|
),
|
186
|
),
|
|
220
|
lineBarsData: points.isEmpty
|
187
|
lineBarsData: points.isEmpty
|
|
221
|
? [_emptyPlaceholderBar(axis)]
|
188
|
? [_emptyPlaceholderBar(axis)]
|
|
222
|
- : [
|
|
|
|
223
|
- if (sleepRange != null)
|
|
|
|
224
|
- _sleepRangeBar(sleepRange, axis.maxY, axis.minY),
|
|
|
|
225
|
- ..._lineSegments(points, start),
|
|
|
|
226
|
- ],
|
189
|
+ : _lineSegments(points, start),
|
|
227
|
);
|
190
|
);
|
|
228
|
}
|
191
|
}
|
|
229
|
|
192
|
|
|
@@ -240,47 +203,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
@@ -240,47 +203,6 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { |
|
240
|
);
|
203
|
);
|
|
241
|
}
|
204
|
}
|
|
242
|
|
205
|
|
|
243
|
- LineChartBarData _sleepRangeBar(
|
|
|
|
244
|
- _SleepRange range,
|
|
|
|
245
|
- double maxY,
|
|
|
|
246
|
- double minY,
|
|
|
|
247
|
- ) {
|
|
|
|
248
|
- return LineChartBarData(
|
|
|
|
249
|
- spots: [FlSpot(range.startX, maxY), FlSpot(range.endX, maxY)],
|
|
|
|
250
|
- color: _brand,
|
|
|
|
251
|
- barWidth: 2,
|
|
|
|
252
|
- isCurved: false,
|
|
|
|
253
|
- dotData: const FlDotData(show: false),
|
|
|
|
254
|
- belowBarData: BarAreaData(
|
|
|
|
255
|
- show: true,
|
|
|
|
256
|
- cutOffY: minY,
|
|
|
|
257
|
- applyCutOffY: true,
|
|
|
|
258
|
- gradient: const LinearGradient(
|
|
|
|
259
|
- begin: Alignment.topCenter,
|
|
|
|
260
|
- end: Alignment.bottomCenter,
|
|
|
|
261
|
- colors: [Color(0x4D845EEE), Color(0x00845EEE)],
|
|
|
|
262
|
- ),
|
|
|
|
263
|
- ),
|
|
|
|
264
|
- );
|
|
|
|
265
|
- }
|
|
|
|
266
|
-
|
|
|
|
267
|
- _SleepRange? _sleepRange(DateTime start, double maxX) {
|
|
|
|
268
|
- final sleepStart = summary.sleepStartTime;
|
|
|
|
269
|
- final sleepEnd = summary.sleepEndTime;
|
|
|
|
270
|
- if (sleepStart == null ||
|
|
|
|
271
|
- sleepEnd == null ||
|
|
|
|
272
|
- !sleepEnd.isAfter(sleepStart)) {
|
|
|
|
273
|
- return null;
|
|
|
|
274
|
- }
|
|
|
|
275
|
-
|
|
|
|
276
|
- final startX = sleepStart.difference(start).inMinutes.toDouble();
|
|
|
|
277
|
- final endX = sleepEnd.difference(start).inMinutes.toDouble();
|
|
|
|
278
|
- final visibleStart = startX.clamp(0, maxX).toDouble();
|
|
|
|
279
|
- final visibleEnd = endX.clamp(0, maxX).toDouble();
|
|
|
|
280
|
- if (visibleEnd <= visibleStart) return null;
|
|
|
|
281
|
- return _SleepRange(visibleStart, visibleEnd);
|
|
|
|
282
|
- }
|
|
|
|
283
|
-
|
|
|
|
284
|
DateTime get _startTime {
|
206
|
DateTime get _startTime {
|
|
285
|
if (summary.startTime != null) return _dayStart(summary.startTime!);
|
207
|
if (summary.startTime != null) return _dayStart(summary.startTime!);
|
|
286
|
if (summary.points.isNotEmpty) return _dayStart(summary.points.first.time);
|
208
|
if (summary.points.isNotEmpty) return _dayStart(summary.points.first.time);
|
|
@@ -531,10 +453,3 @@ class _HeartRateSegment { |
|
@@ -531,10 +453,3 @@ class _HeartRateSegment { |
|
531
|
final Color color;
|
453
|
final Color color;
|
|
532
|
final List<FlSpot> spots;
|
454
|
final List<FlSpot> spots;
|
|
533
|
} |
455
|
} |
|
534
|
-
|
|
|
|
535
|
-class _SleepRange {
|
|
|
|
536
|
- const _SleepRange(this.startX, this.endX);
|
|
|
|
537
|
-
|
|
|
|
538
|
- final double startX;
|
|
|
|
539
|
- final double endX;
|
|
|
|
540
|
-} |
|
|