|
@@ -135,15 +135,17 @@ class TodayHrvChartCard extends StatelessWidget { |
|
@@ -135,15 +135,17 @@ class TodayHrvChartCard extends StatelessWidget { |
|
135
|
fontWeight: FontWeight.w600,
|
135
|
fontWeight: FontWeight.w600,
|
|
136
|
),
|
136
|
),
|
|
137
|
),
|
137
|
),
|
|
138
|
- const SizedBox(width: 4),
|
|
|
|
139
|
GestureDetector(
|
138
|
GestureDetector(
|
|
140
|
behavior: HitTestBehavior.opaque,
|
139
|
behavior: HitTestBehavior.opaque,
|
|
141
|
onTap: () => showHrvPrincipleExplanationBottomSheet(context),
|
140
|
onTap: () => showHrvPrincipleExplanationBottomSheet(context),
|
|
142
|
- child: Image.asset(
|
|
|
|
143
|
- 'assets/images/common/ic_info.png',
|
|
|
|
144
|
- width: 14,
|
|
|
|
145
|
- height: 14,
|
|
|
|
146
|
- color: context.colors.textTertiary,
|
141
|
+ child: Padding(
|
|
|
|
142
|
+ padding: const EdgeInsets.fromLTRB(4, 12, 16, 12),
|
|
|
|
143
|
+ child: Image.asset(
|
|
|
|
144
|
+ 'assets/images/common/ic_info.png',
|
|
|
|
145
|
+ width: 14,
|
|
|
|
146
|
+ height: 14,
|
|
|
|
147
|
+ color: context.colors.textTertiary,
|
|
|
|
148
|
+ ),
|
|
147
|
),
|
149
|
),
|
|
148
|
),
|
150
|
),
|
|
149
|
const Spacer(),
|
151
|
const Spacer(),
|
|
@@ -370,7 +372,32 @@ class TodayHrvChartCard extends StatelessWidget { |
|
@@ -370,7 +372,32 @@ class TodayHrvChartCard extends StatelessWidget { |
|
370
|
final maxSec = _maxChartSeconds();
|
372
|
final maxSec = _maxChartSeconds();
|
|
371
|
final chartWidth = constraints.maxWidth - rightAxisWidth;
|
373
|
final chartWidth = constraints.maxWidth - rightAxisWidth;
|
|
372
|
|
374
|
|
|
373
|
- for (final range in sleepList) {
|
375
|
+ // 1. 过滤并排序睡眠区间
|
|
|
|
376
|
+ final sortedList = List<V2SleepTimeRange>.from(sleepList)
|
|
|
|
377
|
+ ..sort((a, b) => a.fromTime.compareTo(b.fromTime));
|
|
|
|
378
|
+
|
|
|
|
379
|
+ // 2. 合并相邻且间隔小于 2 小时的睡眠区间,避免因短暂醒来分段导致多个床图标或跨天首尾大面积相连
|
|
|
|
380
|
+ final mergedList = <V2SleepTimeRange>[];
|
|
|
|
381
|
+ for (final range in sortedList) {
|
|
|
|
382
|
+ if (mergedList.isEmpty) {
|
|
|
|
383
|
+ mergedList.add(range);
|
|
|
|
384
|
+ } else {
|
|
|
|
385
|
+ final lastRange = mergedList.last;
|
|
|
|
386
|
+ if (range.fromTime - lastRange.toTime <= 2 * 3600) {
|
|
|
|
387
|
+ mergedList[mergedList.length - 1] = V2SleepTimeRange(
|
|
|
|
388
|
+ fromTime: lastRange.fromTime,
|
|
|
|
389
|
+ toTime: range.toTime > lastRange.toTime
|
|
|
|
390
|
+ ? range.toTime
|
|
|
|
391
|
+ : lastRange.toTime,
|
|
|
|
392
|
+ );
|
|
|
|
393
|
+ } else {
|
|
|
|
394
|
+ mergedList.add(range);
|
|
|
|
395
|
+ }
|
|
|
|
396
|
+ }
|
|
|
|
397
|
+ }
|
|
|
|
398
|
+
|
|
|
|
399
|
+ // 3. 渲染合并后的睡眠区间 Positioned widgets
|
|
|
|
400
|
+ for (final range in mergedList) {
|
|
374
|
final fromSec = range.fromTime - todayMidnightSec;
|
401
|
final fromSec = range.fromTime - todayMidnightSec;
|
|
375
|
final toSec = range.toTime - todayMidnightSec;
|
402
|
final toSec = range.toTime - todayMidnightSec;
|
|
376
|
final visibleFrom = fromSec.clamp(0.0, maxSec);
|
403
|
final visibleFrom = fromSec.clamp(0.0, maxSec);
|