Commit ef503062f3aeb733cffffe82b0c7602b7ea14c7b

Authored by 刘宏哲
1 parent 57589833

feat(app): update ui

@@ -423,9 +423,9 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> { @@ -423,9 +423,9 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> {
423 @override 423 @override
424 Widget build(BuildContext context) { 424 Widget build(BuildContext context) {
425 final hasData = widget.report.hasData; 425 final hasData = widget.report.hasData;
  426 + final hasChartData = _hasChartData;
426 final maxY = _maxY; 427 final maxY = _maxY;
427 final comparisonPercent = widget.report.activeEnergyComparisonPercent; 428 final comparisonPercent = widget.report.activeEnergyComparisonPercent;
428 - final hasChartReference = _hasChartReference;  
429 return Container( 429 return Container(
430 height: 344, 430 height: 344,
431 padding: const EdgeInsets.fromLTRB(20, 20, 14, 40), 431 padding: const EdgeInsets.fromLTRB(20, 20, 14, 40),
@@ -541,16 +541,19 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> { @@ -541,16 +541,19 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> {
541 }, 541 },
542 ), 542 ),
543 ), 543 ),
544 - if (!hasChartReference)  
545 - Positioned.fill( 544 + if (!hasChartData)
  545 + Positioned(
  546 + left: ActivityBurnTrendPlotFrame.horizontalInset,
  547 + right: ActivityBurnTrendPlotFrame.rightAxisWidth,
546 top: _chartTopInset, 548 top: _chartTopInset,
547 bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight, 549 bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight,
548 child: Center( 550 child: Center(
549 child: Text( 551 child: Text(
550 context.l10n.reportWaitingForData, 552 context.l10n.reportWaitingForData,
551 style: const TextStyle( 553 style: const TextStyle(
552 - color: ActivityBurnMonthReportView._h3, 554 + color: Color(0xFFA1A0A5),
553 fontSize: 12, 555 fontSize: 12,
  556 + fontWeight: FontWeight.w400,
554 ), 557 ),
555 ), 558 ),
556 ), 559 ),
@@ -573,9 +576,8 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> { @@ -573,9 +576,8 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> {
573 .toDouble(); 576 .toDouble();
574 } 577 }
575 578
576 - bool get _hasChartReference =>  
577 - widget.report.days.any((day) => (day.activeEnergy?.value ?? 0) > 0) ||  
578 - widget.report.activeEnergyGoal > 0; 579 + bool get _hasChartData =>
  580 + widget.report.days.any((day) => (day.activeEnergy?.value ?? 0) > 0);
579 581
580 String _comparisonText(BuildContext context, int? percent) { 582 String _comparisonText(BuildContext context, int? percent) {
581 if (percent == null || !widget.report.hasData) { 583 if (percent == null || !widget.report.hasData) {
@@ -713,9 +715,7 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> { @@ -713,9 +715,7 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> {
713 interval: 5, 715 interval: 5,
714 getTitlesWidget: (value, meta) { 716 getTitlesWidget: (value, meta) {
715 final day = value.toInt() + 1; 717 final day = value.toInt() + 1;
716 - if (day != 1 &&  
717 - day % 5 != 0 &&  
718 - day != widget.report.monthEnd.day) { 718 + if (!_shouldShowBottomTitle(day)) {
719 return const SizedBox.shrink(); 719 return const SizedBox.shrink();
720 } 720 }
721 return Padding( 721 return Padding(
@@ -762,6 +762,13 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> { @@ -762,6 +762,13 @@ class _MonthEnergyTrendCardState extends State<_MonthEnergyTrendCard> {
762 reportWeekdayLabel(date.weekday), 762 reportWeekdayLabel(date.weekday),
763 ); 763 );
764 } 764 }
  765 +
  766 + bool _shouldShowBottomTitle(int day) {
  767 + final lastDay = widget.report.monthEnd.day;
  768 + if (day == 1 || day == lastDay) return true;
  769 + if (day == lastDay - 1 && lastDay % 5 == 1) return false;
  770 + return day % 5 == 0;
  771 + }
765 } 772 }
766 773
767 double _barGroupsSpace(double plotWidth, int count, double barWidth) { 774 double _barGroupsSpace(double plotWidth, int count, double barWidth) {
@@ -400,9 +400,10 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> { @@ -400,9 +400,10 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> {
400 400
401 @override 401 @override
402 Widget build(BuildContext context) { 402 Widget build(BuildContext context) {
  403 + final hasData = widget.report.hasData;
  404 + final hasChartData = _hasChartData;
403 final maxY = _maxY; 405 final maxY = _maxY;
404 final comparisonPercent = widget.report.activeEnergyComparisonPercent; 406 final comparisonPercent = widget.report.activeEnergyComparisonPercent;
405 - final hasChartReference = _hasChartReference;  
406 return Container( 407 return Container(
407 height: 344, 408 height: 344,
408 padding: const EdgeInsets.fromLTRB(20, 20, 14, 32), 409 padding: const EdgeInsets.fromLTRB(20, 20, 14, 32),
@@ -427,7 +428,7 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> { @@ -427,7 +428,7 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> {
427 crossAxisAlignment: CrossAxisAlignment.end, 428 crossAxisAlignment: CrossAxisAlignment.end,
428 children: [ 429 children: [
429 Text( 430 Text(
430 - widget.report.hasData 431 + hasData
431 ? widget.report.averageDailyActiveEnergy.toString() 432 ? widget.report.averageDailyActiveEnergy.toString()
432 : '-', 433 : '-',
433 style: const TextStyle( 434 style: const TextStyle(
@@ -518,8 +519,10 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> { @@ -518,8 +519,10 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> {
518 }, 519 },
519 ), 520 ),
520 ), 521 ),
521 - if (!hasChartReference)  
522 - Positioned.fill( 522 + if (!hasChartData)
  523 + Positioned(
  524 + left: ActivityBurnTrendPlotFrame.horizontalInset,
  525 + right: ActivityBurnTrendPlotFrame.rightAxisWidth,
523 top: _chartTopInset, 526 top: _chartTopInset,
524 bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight, 527 bottom: ActivityBurnTrendPlotFrame.bottomTitleHeight,
525 child: Center( 528 child: Center(
@@ -528,6 +531,7 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> { @@ -528,6 +531,7 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> {
528 style: const TextStyle( 531 style: const TextStyle(
529 color: Color(0xFFA1A0A5), 532 color: Color(0xFFA1A0A5),
530 fontSize: 12, 533 fontSize: 12,
  534 + fontWeight: FontWeight.w400,
531 ), 535 ),
532 ), 536 ),
533 ), 537 ),
@@ -550,9 +554,8 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> { @@ -550,9 +554,8 @@ class _EnergyTrendCardState extends State<_EnergyTrendCard> {
550 .toDouble(); 554 .toDouble();
551 } 555 }
552 556
553 - bool get _hasChartReference =>  
554 - widget.report.days.any((day) => (day.activeEnergy?.value ?? 0) > 0) ||  
555 - widget.report.activeEnergyGoal > 0; 557 + bool get _hasChartData =>
  558 + widget.report.days.any((day) => (day.activeEnergy?.value ?? 0) > 0);
556 559
557 String _comparisonText(BuildContext context, int? percent) { 560 String _comparisonText(BuildContext context, int? percent) {
558 if (percent == null || !widget.report.hasData) { 561 if (percent == null || !widget.report.hasData) {
@@ -25,12 +25,13 @@ class SleepHeartRateCard extends StatelessWidget { @@ -25,12 +25,13 @@ class SleepHeartRateCard extends StatelessWidget {
25 static const _red = Color(0xFFFF5279); 25 static const _red = Color(0xFFFF5279);
26 static const _chartLeftInset = 0.0; 26 static const _chartLeftInset = 0.0;
27 static const _chartRightInset = 20.0; 27 static const _chartRightInset = 20.0;
  28 + static const _chartTopInset = 16.0;
28 29
29 @override 30 @override
30 Widget build(BuildContext context) { 31 Widget build(BuildContext context) {
31 return Container( 32 return Container(
32 height: 358, 33 height: 358,
33 - padding: EdgeInsets.fromLTRB(20, 20.h, 20, 16), 34 + padding: EdgeInsets.fromLTRB(20, 20.h, 20, 16),
34 decoration: BoxDecoration( 35 decoration: BoxDecoration(
35 color: Colors.white, 36 color: Colors.white,
36 borderRadius: BorderRadius.circular(16), 37 borderRadius: BorderRadius.circular(16),
@@ -66,6 +67,7 @@ class SleepHeartRateCard extends StatelessWidget { @@ -66,6 +67,7 @@ class SleepHeartRateCard extends StatelessWidget {
66 children: [ 67 children: [
67 if (hasChartData) ...[ 68 if (hasChartData) ...[
68 Positioned.fill( 69 Positioned.fill(
  70 + top: _chartTopInset,
69 bottom: 20, 71 bottom: 20,
70 child: LayoutBuilder( 72 child: LayoutBuilder(
71 builder: (context, constraints) => LineChart( 73 builder: (context, constraints) => LineChart(
@@ -77,7 +79,13 @@ class SleepHeartRateCard extends StatelessWidget { @@ -77,7 +79,13 @@ class SleepHeartRateCard extends StatelessWidget {
77 ), 79 ),
78 ), 80 ),
79 ), 81 ),
  82 + const Positioned.fill(
  83 + top: _chartTopInset,
  84 + bottom: 20,
  85 + child: _HeartRateBoundaryGridLine(),
  86 + ),
80 Positioned.fill( 87 Positioned.fill(
  88 + top: _chartTopInset,
81 bottom: 20, 89 bottom: 20,
82 child: _HeartRateAxisLabels( 90 child: _HeartRateAxisLabels(
83 range: _HeartRateYAxisRange.fromPoints(chartPoints), 91 range: _HeartRateYAxisRange.fromPoints(chartPoints),
@@ -86,7 +94,42 @@ class SleepHeartRateCard extends StatelessWidget { @@ -86,7 +94,42 @@ class SleepHeartRateCard extends StatelessWidget {
86 Positioned.fill( 94 Positioned.fill(
87 child: _HeartRateTimeLabels(axis: xAxis), 95 child: _HeartRateTimeLabels(axis: xAxis),
88 ), 96 ),
89 - ] else 97 + ] else ...[
  98 + Positioned.fill(
  99 + top: _chartTopInset,
  100 + bottom: 20,
  101 + child: LayoutBuilder(
  102 + builder: (context, constraints) => LineChart(
  103 + _chartData(
  104 + xAxis: xAxis,
  105 + chartPoints: chartPoints,
  106 + chartWidth: constraints.maxWidth,
  107 + ),
  108 + ),
  109 + ),
  110 + ),
  111 + const Positioned.fill(
  112 + top: _chartTopInset,
  113 + bottom: 20,
  114 + child: _HeartRateBoundaryGridLine(
  115 + drawTop: true,
  116 + ),
  117 + ),
  118 + Positioned.fill(
  119 + top: _chartTopInset,
  120 + bottom: 20,
  121 + child: _HeartRateAxisLabels(
  122 + range: _HeartRateYAxisRange.fromPoints(
  123 + chartPoints,
  124 + ),
  125 + ),
  126 + ),
  127 + Positioned.fill(
  128 + child: _HeartRateTimeLabels(
  129 + axis: xAxis,
  130 + tickCount: 4,
  131 + ),
  132 + ),
90 Positioned.fill( 133 Positioned.fill(
91 bottom: 20, 134 bottom: 20,
92 child: Center( 135 child: Center(
@@ -100,6 +143,7 @@ class SleepHeartRateCard extends StatelessWidget { @@ -100,6 +143,7 @@ class SleepHeartRateCard extends StatelessWidget {
100 ), 143 ),
101 ), 144 ),
102 ), 145 ),
  146 + ],
103 ], 147 ],
104 ); 148 );
105 }, 149 },
@@ -138,7 +182,7 @@ class SleepHeartRateCard extends StatelessWidget { @@ -138,7 +182,7 @@ class SleepHeartRateCard extends StatelessWidget {
138 gridData: FlGridData( 182 gridData: FlGridData(
139 show: true, 183 show: true,
140 drawVerticalLine: false, 184 drawVerticalLine: false,
141 - horizontalInterval: _HeartRateYAxisRange.interval, 185 + horizontalInterval: yRange.interval,
142 getDrawingHorizontalLine: (_) => const FlLine( 186 getDrawingHorizontalLine: (_) => const FlLine(
143 color: _grid, 187 color: _grid,
144 strokeWidth: 1, 188 strokeWidth: 1,
@@ -208,10 +252,21 @@ class SleepHeartRateCard extends StatelessWidget { @@ -208,10 +252,21 @@ class SleepHeartRateCard extends StatelessWidget {
208 _HeartRateXAxis get _heartRateXAxis { 252 _HeartRateXAxis get _heartRateXAxis {
209 final points = _visibleDatePoints; 253 final points = _visibleDatePoints;
210 if (points.isEmpty) { 254 if (points.isEmpty) {
211 - final start = _chartDayStart; 255 + final sleepStart = summary.sleepStart;
  256 + final sleepEnd = summary.sleepEnd;
  257 + if (sleepStart != null &&
  258 + sleepEnd != null &&
  259 + sleepEnd.isAfter(sleepStart)) {
  260 + return _HeartRateXAxis(
  261 + start: sleepStart,
  262 + end: sleepEnd,
  263 + );
  264 + }
  265 +
  266 + final start = _chartDayStart.add(const Duration(hours: 22));
212 return _HeartRateXAxis( 267 return _HeartRateXAxis(
213 start: start, 268 start: start,
214 - end: start.add(const Duration(hours: 1)), 269 + end: start.add(const Duration(hours: 8, minutes: 59)),
215 ); 270 );
216 } 271 }
217 272
@@ -274,6 +329,65 @@ class SleepHeartRateCard extends StatelessWidget { @@ -274,6 +329,65 @@ class SleepHeartRateCard extends StatelessWidget {
274 } 329 }
275 } 330 }
276 331
  332 +class _HeartRateBoundaryGridLine extends StatelessWidget {
  333 + const _HeartRateBoundaryGridLine({
  334 + this.drawTop = false,
  335 + });
  336 +
  337 + final bool drawTop;
  338 +
  339 + @override
  340 + Widget build(BuildContext context) {
  341 + return IgnorePointer(
  342 + child: CustomPaint(
  343 + painter: _HeartRateBoundaryGridLinePainter(drawTop: drawTop),
  344 + ),
  345 + );
  346 + }
  347 +}
  348 +
  349 +class _HeartRateBoundaryGridLinePainter extends CustomPainter {
  350 + const _HeartRateBoundaryGridLinePainter({
  351 + required this.drawTop,
  352 + });
  353 +
  354 + final bool drawTop;
  355 +
  356 + @override
  357 + void paint(Canvas canvas, Size size) {
  358 + final paint = Paint()
  359 + ..color = SleepHeartRateCard._grid
  360 + ..strokeWidth = 1;
  361 + final right = size.width;
  362 + _drawDashedLine(canvas, paint, y: size.height - 0.5, width: right);
  363 + if (drawTop) {
  364 + _drawDashedLine(canvas, paint, y: 0.5, width: right);
  365 + }
  366 + }
  367 +
  368 + void _drawDashedLine(
  369 + Canvas canvas,
  370 + Paint paint, {
  371 + required double y,
  372 + required double width,
  373 + }) {
  374 + const dashWidth = 2.0;
  375 + const dashSpace = 2.0;
  376 + var x = 0.0;
  377 +
  378 + while (x < width) {
  379 + final end = (x + dashWidth).clamp(0.0, width);
  380 + canvas.drawLine(Offset(x, y), Offset(end, y), paint);
  381 + x += dashWidth + dashSpace;
  382 + }
  383 + }
  384 +
  385 + @override
  386 + bool shouldRepaint(covariant _HeartRateBoundaryGridLinePainter oldDelegate) {
  387 + return drawTop != oldDelegate.drawTop;
  388 + }
  389 +}
  390 +
277 class _HeartRateXAxis { 391 class _HeartRateXAxis {
278 const _HeartRateXAxis({ 392 const _HeartRateXAxis({
279 required this.start, 393 required this.start,
@@ -325,18 +439,23 @@ class _HeartRateAxisLabels extends StatelessWidget { @@ -325,18 +439,23 @@ class _HeartRateAxisLabels extends StatelessWidget {
325 class _HeartRateTimeLabels extends StatelessWidget { 439 class _HeartRateTimeLabels extends StatelessWidget {
326 const _HeartRateTimeLabels({ 440 const _HeartRateTimeLabels({
327 required this.axis, 441 required this.axis,
  442 + this.tickCount = 3,
328 }); 443 });
329 444
330 final _HeartRateXAxis axis; 445 final _HeartRateXAxis axis;
  446 + final int tickCount;
331 447
332 @override 448 @override
333 Widget build(BuildContext context) { 449 Widget build(BuildContext context) {
334 final totalMinutes = axis.end.difference(axis.start).inMinutes; 450 final totalMinutes = axis.end.difference(axis.start).inMinutes;
335 - final ticks = <DateTime>[  
336 - axis.start,  
337 - axis.start.add(Duration(minutes: totalMinutes ~/ 2)),  
338 - axis.end,  
339 - ]; 451 + final count = tickCount < 2 ? 2 : tickCount;
  452 + final ticks = List.generate(count, (index) {
  453 + if (index == 0) return axis.start;
  454 + if (index == count - 1) return axis.end;
  455 + return axis.start.add(
  456 + Duration(minutes: (totalMinutes * index / (count - 1)).round()),
  457 + );
  458 + });
340 459
341 return IgnorePointer( 460 return IgnorePointer(
342 child: LayoutBuilder( 461 child: LayoutBuilder(
@@ -371,7 +490,8 @@ class _HeartRateTimeLabels extends StatelessWidget { @@ -371,7 +490,8 @@ class _HeartRateTimeLabels extends StatelessWidget {
371 final plotWidth = 490 final plotWidth =
372 (plotRight - plotLeft).clamp(0, double.infinity).toDouble(); 491 (plotRight - plotLeft).clamp(0, double.infinity).toDouble();
373 final tickX = plotLeft + plotWidth * progress; 492 final tickX = plotLeft + plotWidth * progress;
374 - final left = tickX - labelWidth / 2; 493 + final isFirstTick = index == 0;
  494 + final left = isFirstTick ? tickX : tickX - labelWidth / 2;
375 495
376 return Positioned( 496 return Positioned(
377 left: left, 497 left: left,
@@ -379,7 +499,7 @@ class _HeartRateTimeLabels extends StatelessWidget { @@ -379,7 +499,7 @@ class _HeartRateTimeLabels extends StatelessWidget {
379 width: labelWidth, 499 width: labelWidth,
380 child: _TimeLabel( 500 child: _TimeLabel(
381 _tickLabel(tick), 501 _tickLabel(tick),
382 - textAlign: TextAlign.center, 502 + textAlign: isFirstTick ? TextAlign.left : TextAlign.center,
383 ), 503 ),
384 ); 504 );
385 } 505 }
@@ -417,12 +537,12 @@ class _HeartRateYAxisRange { @@ -417,12 +537,12 @@ class _HeartRateYAxisRange {
417 const _HeartRateYAxisRange({ 537 const _HeartRateYAxisRange({
418 required this.minY, 538 required this.minY,
419 required this.maxY, 539 required this.maxY,
  540 + this.interval = 20.0,
420 }); 541 });
421 542
422 - static const interval = 20.0;  
423 -  
424 final double minY; 543 final double minY;
425 final double maxY; 544 final double maxY;
  545 + final double interval;
426 546
427 double get span => maxY - minY <= 0 ? interval : maxY - minY; 547 double get span => maxY - minY <= 0 ? interval : maxY - minY;
428 548
@@ -439,19 +559,24 @@ class _HeartRateYAxisRange { @@ -439,19 +559,24 @@ class _HeartRateYAxisRange {
439 559
440 factory _HeartRateYAxisRange.fromPoints(List<SleepHeartRatePoint> points) { 560 factory _HeartRateYAxisRange.fromPoints(List<SleepHeartRatePoint> points) {
441 if (points.isEmpty) { 561 if (points.isEmpty) {
442 - return const _HeartRateYAxisRange(minY: 50, maxY: 80); 562 + return const _HeartRateYAxisRange(
  563 + minY: 50,
  564 + maxY: 80,
  565 + interval: 10,
  566 + );
443 } 567 }
444 568
445 final values = points.map((point) => point.bpm); 569 final values = points.map((point) => point.bpm);
446 final minBpm = values.reduce((min, bpm) => bpm < min ? bpm : min); 570 final minBpm = values.reduce((min, bpm) => bpm < min ? bpm : min);
447 final maxBpm = values.reduce((max, bpm) => bpm > max ? bpm : max); 571 final maxBpm = values.reduce((max, bpm) => bpm > max ? bpm : max);
448 - final minY = minBpm;  
449 - var maxY = (maxBpm / 5).ceil() * 5.0;  
450 - if (minY == maxY) maxY += interval; 572 + final minY = (minBpm / 10).floor() * 10.0;
  573 + var maxY = (maxBpm / 10).ceil() * 10.0;
  574 + if (minY == maxY) maxY += 10;
451 575
452 return _HeartRateYAxisRange( 576 return _HeartRateYAxisRange(
453 minY: minY, 577 minY: minY,
454 maxY: maxY, 578 maxY: maxY,
  579 + interval: 10,
455 ); 580 );
456 } 581 }
457 } 582 }
@@ -700,6 +700,7 @@ class _BedtimeChart extends StatelessWidget { @@ -700,6 +700,7 @@ class _BedtimeChart extends StatelessWidget {
700 maxY: axis.maxHour.toDouble(), 700 maxY: axis.maxHour.toDouble(),
701 minY: axis.minHour.toDouble(), 701 minY: axis.minHour.toDouble(),
702 interval: 1, 702 interval: 1,
  703 + topInset: 16,
703 rightLabel: _timeAxisLabel, 704 rightLabel: _timeAxisLabel,
704 child: LineChart(_chartData(axis)), 705 child: LineChart(_chartData(axis)),
705 ), 706 ),
@@ -1175,6 +1176,7 @@ class _ChartPlotFrame extends StatelessWidget { @@ -1175,6 +1176,7 @@ class _ChartPlotFrame extends StatelessWidget {
1175 required this.interval, 1176 required this.interval,
1176 required this.rightLabel, 1177 required this.rightLabel,
1177 this.minY = 0, 1178 this.minY = 0,
  1179 + this.topInset = 0,
1178 this.referenceLines = const [], 1180 this.referenceLines = const [],
1179 }); 1181 });
1180 1182
@@ -1186,6 +1188,7 @@ class _ChartPlotFrame extends StatelessWidget { @@ -1186,6 +1188,7 @@ class _ChartPlotFrame extends StatelessWidget {
1186 final double minY; 1188 final double minY;
1187 final double maxY; 1189 final double maxY;
1188 final double interval; 1190 final double interval;
  1191 + final double topInset;
1189 final String Function(double value) rightLabel; 1192 final String Function(double value) rightLabel;
1190 final List<_ChartReferenceLine> referenceLines; 1193 final List<_ChartReferenceLine> referenceLines;
1191 1194
@@ -1195,6 +1198,7 @@ class _ChartPlotFrame extends StatelessWidget { @@ -1195,6 +1198,7 @@ class _ChartPlotFrame extends StatelessWidget {
1195 clipBehavior: Clip.none, 1198 clipBehavior: Clip.none,
1196 children: [ 1199 children: [
1197 Positioned.fill( 1200 Positioned.fill(
  1201 + top: topInset,
1198 bottom: bottomTitleHeight, 1202 bottom: bottomTitleHeight,
1199 child: CustomPaint( 1203 child: CustomPaint(
1200 painter: _HorizontalDashedGridPainter( 1204 painter: _HorizontalDashedGridPainter(
@@ -1205,6 +1209,7 @@ class _ChartPlotFrame extends StatelessWidget { @@ -1205,6 +1209,7 @@ class _ChartPlotFrame extends StatelessWidget {
1205 ), 1209 ),
1206 ), 1210 ),
1207 Positioned.fill( 1211 Positioned.fill(
  1212 + top: topInset,
1208 bottom: bottomTitleHeight, 1213 bottom: bottomTitleHeight,
1209 child: CustomPaint( 1214 child: CustomPaint(
1210 painter: _ReferenceLinePainter( 1215 painter: _ReferenceLinePainter(
@@ -1215,13 +1220,15 @@ class _ChartPlotFrame extends StatelessWidget { @@ -1215,13 +1220,15 @@ class _ChartPlotFrame extends StatelessWidget {
1215 ), 1220 ),
1216 ), 1221 ),
1217 Padding( 1222 Padding(
1218 - padding: const EdgeInsets.only( 1223 + padding: EdgeInsets.only(
  1224 + top: topInset,
1219 left: horizontalInset, 1225 left: horizontalInset,
1220 right: rightAxisWidth, 1226 right: rightAxisWidth,
1221 ), 1227 ),
1222 child: child, 1228 child: child,
1223 ), 1229 ),
1224 Positioned.fill( 1230 Positioned.fill(
  1231 + top: topInset,
1225 bottom: bottomTitleHeight, 1232 bottom: bottomTitleHeight,
1226 child: _RightAxisLabels( 1233 child: _RightAxisLabels(
1227 minY: minY, 1234 minY: minY,