Commit 58eb882eb2c2de6e197c11e85be5e166304c2edf

Authored by 常守达
1 parent aaf9f668

fix(today):实时压力拖动,首尾吸附

@@ -389,6 +389,9 @@ class TodayHrvChartCard extends StatelessWidget { @@ -389,6 +389,9 @@ class TodayHrvChartCard extends StatelessWidget {
389 fontSize: 14, 389 fontSize: 14,
390 color: _getColorByState(state), 390 color: _getColorByState(state),
391 fontWeight: FontWeight.bold, 391 fontWeight: FontWeight.bold,
  392 + inherit: false,
  393 + fontFamilyFallback: null,
  394 + fontFamily: '',
392 ), 395 ),
393 ), 396 ),
394 TextSpan( 397 TextSpan(
@@ -412,6 +415,9 @@ class TodayHrvChartCard extends StatelessWidget { @@ -412,6 +415,9 @@ class TodayHrvChartCard extends StatelessWidget {
412 color: Color(0xFF78787D), 415 color: Color(0xFF78787D),
413 fontSize: 14, 416 fontSize: 14,
414 fontWeight: FontWeight.bold, 417 fontWeight: FontWeight.bold,
  418 + inherit: false,
  419 + fontFamilyFallback: null,
  420 + fontFamily: '',
415 ), 421 ),
416 ), 422 ),
417 TextSpan( 423 TextSpan(
@@ -430,6 +436,9 @@ class TodayHrvChartCard extends StatelessWidget { @@ -430,6 +436,9 @@ class TodayHrvChartCard extends StatelessWidget {
430 TextSpan( 436 TextSpan(
431 text: '○ ', 437 text: '○ ',
432 style: TextStyle( 438 style: TextStyle(
  439 + inherit: false,
  440 + fontFamilyFallback: null,
  441 + fontFamily: '',
433 color: _getColorByState(state), 442 color: _getColorByState(state),
434 // fontWeight: FontWeight.bold, 443 // fontWeight: FontWeight.bold,
435 fontSize: 14, 444 fontSize: 14,
@@ -453,6 +462,9 @@ class TodayHrvChartCard extends StatelessWidget { @@ -453,6 +462,9 @@ class TodayHrvChartCard extends StatelessWidget {
453 TextSpan( 462 TextSpan(
454 text: '♥ ', 463 text: '♥ ',
455 style: const TextStyle( 464 style: const TextStyle(
  465 + inherit: false,
  466 + fontFamilyFallback: null,
  467 + fontFamily: '',
456 color: Color(0xFF78787D), 468 color: Color(0xFF78787D),
457 fontSize: 14, 469 fontSize: 14,
458 fontWeight: FontWeight.bold, 470 fontWeight: FontWeight.bold,
@@ -953,11 +965,58 @@ class _StressBarChartState extends State<_StressBarChart> { @@ -953,11 +965,58 @@ class _StressBarChartState extends State<_StressBarChart> {
953 event is FlPointerHoverEvent || 965 event is FlPointerHoverEvent ||
954 event is FlPointerEnterEvent) { 966 event is FlPointerEnterEvent) {
955 _stressTooltipTimer?.cancel(); 967 _stressTooltipTimer?.cancel();
956 - if (touchResponse != null &&  
957 - touchResponse.spot != null) { 968 + // 优先用触摸坐标直接定位最近的有数据的柱子
  969 + // 不依赖 fl_chart 的 spot 检测(touchExtraThreshold 会导致总是找到 spot)
  970 + final dx = event.localPosition?.dx;
  971 + if (dx != null && slotStateMap.isNotEmpty) {
  972 + final stepWidth = barWidth + groupsSpace;
  973 + final touchedSlotSec =
  974 + (dx / stepWidth).round() * slotSec;
  975 +
  976 + final sortedSlots = slotStateMap.keys.toList()
  977 + ..sort();
  978 + final firstSlot = sortedSlots.first;
  979 + final lastSlot = sortedSlots.last;
  980 +
  981 + int? targetIndex;
  982 +
  983 + if (touchedSlotSec <= firstSlot) {
  984 + // 超出左侧边界 → 吸附到第一条数据
  985 + targetIndex = (firstSlot / slotSec)
  986 + .round()
  987 + .clamp(0, slotCount - 1);
  988 + } else if (touchedSlotSec >= lastSlot) {
  989 + // 超出右侧边界 → 吸附到最后一条数据(最新)
  990 + targetIndex = (lastSlot / slotSec)
  991 + .round()
  992 + .clamp(0, slotCount - 1);
  993 + } else {
  994 + // 在数据范围内:仅在距最近数据点 ≤ 5 个槽(30min)时才吸附
  995 + const snapThresholdSlots = 5;
  996 + final nearestSlot = sortedSlots.reduce(
  997 + (a, b) => (a - touchedSlotSec).abs() <
  998 + (b - touchedSlotSec).abs()
  999 + ? a
  1000 + : b,
  1001 + );
  1002 + final distanceSlots =
  1003 + (nearestSlot - touchedSlotSec).abs() ~/ slotSec;
  1004 + if (distanceSlots <= snapThresholdSlots) {
  1005 + targetIndex = (nearestSlot / slotSec)
  1006 + .round()
  1007 + .clamp(0, slotCount - 1);
  1008 + }
  1009 + // 超过阈值(大片空白区域)→ targetIndex 保持 null,不显示
  1010 + }
  1011 +
  1012 + setState(() {
  1013 + _stressTouchedGroupIndex = targetIndex;
  1014 + });
  1015 + } else if (touchResponse?.spot != null) {
  1016 + // localPosition 不可用时降级到 fl_chart 的 spot
958 setState(() { 1017 setState(() {
959 _stressTouchedGroupIndex = 1018 _stressTouchedGroupIndex =
960 - touchResponse.spot!.touchedBarGroupIndex; 1019 + touchResponse!.spot!.touchedBarGroupIndex;
961 }); 1020 });
962 } else { 1021 } else {
963 setState(() { 1022 setState(() {