Showing
1 changed file
with
48 additions
and
23 deletions
| @@ -905,6 +905,9 @@ class _BedtimeChart extends StatefulWidget { | @@ -905,6 +905,9 @@ class _BedtimeChart extends StatefulWidget { | ||
| 905 | } | 905 | } |
| 906 | 906 | ||
| 907 | class _BedtimeChartState extends State<_BedtimeChart> { | 907 | class _BedtimeChartState extends State<_BedtimeChart> { |
| 908 | + static const _xAxisLeftInset = 10.0; | ||
| 909 | + static const _xAxisRightInset = 40.0; | ||
| 910 | + | ||
| 908 | int? _selectedDayIndex; | 911 | int? _selectedDayIndex; |
| 909 | Timer? _tooltipTimer; | 912 | Timer? _tooltipTimer; |
| 910 | 913 | ||
| @@ -985,12 +988,12 @@ class _BedtimeChartState extends State<_BedtimeChart> { | @@ -985,12 +988,12 @@ class _BedtimeChartState extends State<_BedtimeChart> { | ||
| 985 | } | 988 | } |
| 986 | 989 | ||
| 987 | double _lineXForDay(double width, int dayIndex) { | 990 | double _lineXForDay(double width, int dayIndex) { |
| 988 | - return _barCenterForIndex( | ||
| 989 | - dayIndex, | ||
| 990 | - width, | ||
| 991 | - widget.days.length, | ||
| 992 | - widget.compact, | ||
| 993 | - ); | 991 | + final count = widget.days.length; |
| 992 | + if (count <= 1 || width <= _xAxisLeftInset + _xAxisRightInset) { | ||
| 993 | + return width / 2; | ||
| 994 | + } | ||
| 995 | + final dataWidth = width - _xAxisLeftInset - _xAxisRightInset; | ||
| 996 | + return _xAxisLeftInset + dataWidth * dayIndex / (count - 1); | ||
| 994 | } | 997 | } |
| 995 | 998 | ||
| 996 | LineChartData _chartData( | 999 | LineChartData _chartData( |
| @@ -1044,18 +1047,11 @@ class _BedtimeChartState extends State<_BedtimeChart> { | @@ -1044,18 +1047,11 @@ class _BedtimeChartState extends State<_BedtimeChart> { | ||
| 1044 | } | 1047 | } |
| 1045 | 1048 | ||
| 1046 | final count = widget.days.length; | 1049 | final count = widget.days.length; |
| 1047 | - final dataMaxX = count <= 1 ? 0.0 : (count - 1).toDouble(); | ||
| 1048 | - final horizontalInset = count <= 1 | ||
| 1049 | - ? chartWidth / 2 | ||
| 1050 | - : _barCenterForIndex(0, chartWidth, count, widget.compact); | ||
| 1051 | - final dataWidth = chartWidth - horizontalInset * 2; | ||
| 1052 | - final xPadding = count <= 1 || dataWidth <= 0 | ||
| 1053 | - ? 0.5 | ||
| 1054 | - : horizontalInset * (count - 1) / dataWidth; | 1050 | + final xBounds = _xBounds(chartWidth, count); |
| 1055 | 1051 | ||
| 1056 | return LineChartData( | 1052 | return LineChartData( |
| 1057 | - minX: -xPadding, | ||
| 1058 | - maxX: dataMaxX + xPadding, | 1053 | + minX: xBounds.minX, |
| 1054 | + maxX: xBounds.maxX, | ||
| 1059 | minY: 0, | 1055 | minY: 0, |
| 1060 | maxY: _tooltipChartMaxY, | 1056 | maxY: _tooltipChartMaxY, |
| 1061 | gridData: const FlGridData(show: false), | 1057 | gridData: const FlGridData(show: false), |
| @@ -1084,12 +1080,7 @@ class _BedtimeChartState extends State<_BedtimeChart> { | @@ -1084,12 +1080,7 @@ class _BedtimeChartState extends State<_BedtimeChart> { | ||
| 1084 | 1080 | ||
| 1085 | void _selectSpotAt(double dx, double chartWidth) { | 1081 | void _selectSpotAt(double dx, double chartWidth) { |
| 1086 | _tooltipTimer?.cancel(); | 1082 | _tooltipTimer?.cancel(); |
| 1087 | - final index = _barIndexForTouch( | ||
| 1088 | - dx, | ||
| 1089 | - chartWidth, | ||
| 1090 | - widget.days.length, | ||
| 1091 | - widget.compact, | ||
| 1092 | - ); | 1083 | + final index = _dayIndexForTouch(dx, chartWidth); |
| 1093 | final hasData = index != null && | 1084 | final hasData = index != null && |
| 1094 | widget.days[index].hasSleepData && | 1085 | widget.days[index].hasSleepData && |
| 1095 | widget.days[index].heartRate.sleepStart != null; | 1086 | widget.days[index].heartRate.sleepStart != null; |
| @@ -1098,6 +1089,38 @@ class _BedtimeChartState extends State<_BedtimeChart> { | @@ -1098,6 +1089,38 @@ class _BedtimeChartState extends State<_BedtimeChart> { | ||
| 1098 | setState(() => _selectedDayIndex = nextIndex); | 1089 | setState(() => _selectedDayIndex = nextIndex); |
| 1099 | } | 1090 | } |
| 1100 | 1091 | ||
| 1092 | + ({double minX, double maxX}) _xBounds(double width, int count) { | ||
| 1093 | + if (count <= 1 || width <= _xAxisLeftInset + _xAxisRightInset) { | ||
| 1094 | + return (minX: -0.5, maxX: 0.5); | ||
| 1095 | + } | ||
| 1096 | + final scale = (count - 1) / (width - _xAxisLeftInset - _xAxisRightInset); | ||
| 1097 | + return ( | ||
| 1098 | + minX: -_xAxisLeftInset * scale, | ||
| 1099 | + maxX: count - 1 + _xAxisRightInset * scale, | ||
| 1100 | + ); | ||
| 1101 | + } | ||
| 1102 | + | ||
| 1103 | + int? _dayIndexForTouch(double? dx, double width) { | ||
| 1104 | + final count = widget.days.length; | ||
| 1105 | + if (dx == null || width <= 0 || count <= 0) return null; | ||
| 1106 | + if (count == 1 || width <= _xAxisLeftInset + _xAxisRightInset) { | ||
| 1107 | + return dx <= width - _xAxisRightInset ? 0 : null; | ||
| 1108 | + } | ||
| 1109 | + final dataWidth = width - _xAxisLeftInset - _xAxisRightInset; | ||
| 1110 | + final firstX = _xAxisLeftInset; | ||
| 1111 | + final lastX = width - _xAxisRightInset; | ||
| 1112 | + final step = dataWidth / (count - 1); | ||
| 1113 | + final minTouchX = (firstX - step / 2).clamp(0, width).toDouble(); | ||
| 1114 | + final maxTouchX = (lastX + step / 2) | ||
| 1115 | + .clamp(0, width - _ChartPlotFrame.rightAxisWidth) | ||
| 1116 | + .toDouble(); | ||
| 1117 | + if (dx < minTouchX || dx > maxTouchX) return null; | ||
| 1118 | + return ((dx - _xAxisLeftInset) / dataWidth * (count - 1)) | ||
| 1119 | + .round() | ||
| 1120 | + .clamp(0, count - 1) | ||
| 1121 | + .toInt(); | ||
| 1122 | + } | ||
| 1123 | + | ||
| 1101 | void _scheduleTooltipDismissal() { | 1124 | void _scheduleTooltipDismissal() { |
| 1102 | if (_selectedDayIndex == null || widget.tooltipAutoDismissMs <= 0) return; | 1125 | if (_selectedDayIndex == null || widget.tooltipAutoDismissMs <= 0) return; |
| 1103 | _tooltipTimer?.cancel(); | 1126 | _tooltipTimer?.cancel(); |
| @@ -1588,7 +1611,9 @@ class _ChartPlotFrame extends StatelessWidget { | @@ -1588,7 +1611,9 @@ class _ChartPlotFrame extends StatelessWidget { | ||
| 1588 | padding: EdgeInsets.only( | 1611 | padding: EdgeInsets.only( |
| 1589 | top: topInset, | 1612 | top: topInset, |
| 1590 | left: insetChildHorizontally ? horizontalInset : 0, | 1613 | left: insetChildHorizontally ? horizontalInset : 0, |
| 1591 | - right: insetChildHorizontally ? rightAxisWidth : 0, | 1614 | + right: insetChildHorizontally |
| 1615 | + ? rightAxisWidth | ||
| 1616 | + : 0, | ||
| 1592 | ), | 1617 | ), |
| 1593 | child: child, | 1618 | child: child, |
| 1594 | ), | 1619 | ), |
-
Please register or login to post a comment