From 7a9d23611feaa2023457d9f24d1393e6ca9649e8 Mon Sep 17 00:00:00 2001 From: WandsonDev Date: Thu, 23 Apr 2026 13:55:07 -0300 Subject: [PATCH] fix: Fix missing and incorrect copyWith parameters across chart tooltip data classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several copyWith methods were incomplete or had bugs that silently ignored caller-supplied values, making it impossible to update chart configuration through copyWith. - BarChartRodData: rename parameter `dashArray` → `borderDashArray` and add the missing `?? this.borderDashArray` fallback so the parameter is actually forwarded instead of silently discarded - BarTouchTooltipData: add missing copyWith method; also add `direction` field to props so equality checks reflect direction changes - LineTouchTooltipData: add missing copyWith method - CandlestickTouchTooltipData.copyWith: add missing `showOnTopOfTheChartBoxArea` parameter - ScatterTouchTooltipData.copyWith: add missing `tooltipBorderRadius` parameter - ScatterChartData.props: remove duplicate `rangeAnnotations` entry Regression tests added for each fix. --- lib/src/chart/bar_chart/bar_chart_data.dart | 41 ++++++++++++++++++- .../candlestick_chart_data.dart | 3 ++ lib/src/chart/line_chart/line_chart_data.dart | 37 +++++++++++++++++ .../scatter_chart/scatter_chart_data.dart | 3 +- test/chart/bar_chart/bar_chart_data_test.dart | 38 +++++++++++++++++ .../candlestick_chart_data_test.dart | 12 ++++++ .../line_chart/line_chart_data_test.dart | 18 ++++++++ .../scatter_chart_data_test.dart | 12 ++++++ 8 files changed, 161 insertions(+), 3 deletions(-) diff --git a/lib/src/chart/bar_chart/bar_chart_data.dart b/lib/src/chart/bar_chart/bar_chart_data.dart index b99cdaf2a..be8e824ce 100644 --- a/lib/src/chart/bar_chart/bar_chart_data.dart +++ b/lib/src/chart/bar_chart/bar_chart_data.dart @@ -412,7 +412,7 @@ class BarChartRodData with EquatableMixin { Gradient? gradient, double? width, BorderRadius? borderRadius, - List? dashArray, + List? borderDashArray, BorderSide? borderSide, BackgroundBarChartRodData? backDrawRodData, List? rodStackItems, @@ -426,7 +426,7 @@ class BarChartRodData with EquatableMixin { gradient: gradient ?? this.gradient, width: width ?? this.width, borderRadius: borderRadius ?? this.borderRadius, - borderDashArray: borderDashArray, + borderDashArray: borderDashArray ?? this.borderDashArray, borderSide: borderSide ?? this.borderSide, backDrawRodData: backDrawRodData ?? this.backDrawRodData, rodStackItems: rodStackItems ?? this.rodStackItems, @@ -840,10 +840,47 @@ class BarTouchTooltipData with EquatableMixin { getTooltipItem, fitInsideHorizontally, fitInsideVertically, + direction, rotateAngle, tooltipBorder, getTooltipColor, ]; + + /// Copies current [BarTouchTooltipData] to a new [BarTouchTooltipData], + /// and replaces provided values. + BarTouchTooltipData copyWith({ + BorderRadius? tooltipBorderRadius, + EdgeInsets? tooltipPadding, + double? tooltipMargin, + FLHorizontalAlignment? tooltipHorizontalAlignment, + double? tooltipHorizontalOffset, + double? maxContentWidth, + GetBarTooltipItem? getTooltipItem, + GetBarTooltipColor? getTooltipColor, + bool? fitInsideHorizontally, + bool? fitInsideVertically, + TooltipDirection? direction, + double? rotateAngle, + BorderSide? tooltipBorder, + }) => + BarTouchTooltipData( + tooltipBorderRadius: tooltipBorderRadius ?? _tooltipBorderRadius, + tooltipPadding: tooltipPadding ?? this.tooltipPadding, + tooltipMargin: tooltipMargin ?? this.tooltipMargin, + tooltipHorizontalAlignment: + tooltipHorizontalAlignment ?? this.tooltipHorizontalAlignment, + tooltipHorizontalOffset: + tooltipHorizontalOffset ?? this.tooltipHorizontalOffset, + maxContentWidth: maxContentWidth ?? this.maxContentWidth, + getTooltipItem: getTooltipItem ?? this.getTooltipItem, + getTooltipColor: getTooltipColor ?? this.getTooltipColor, + fitInsideHorizontally: + fitInsideHorizontally ?? this.fitInsideHorizontally, + fitInsideVertically: fitInsideVertically ?? this.fitInsideVertically, + direction: direction ?? this.direction, + rotateAngle: rotateAngle ?? this.rotateAngle, + tooltipBorder: tooltipBorder ?? this.tooltipBorder, + ); } /// Provides a [BarTooltipItem] for showing content inside the [BarTouchTooltipData]. diff --git a/lib/src/chart/candlestick_chart/candlestick_chart_data.dart b/lib/src/chart/candlestick_chart/candlestick_chart_data.dart index b05b642f2..4da6f956b 100644 --- a/lib/src/chart/candlestick_chart/candlestick_chart_data.dart +++ b/lib/src/chart/candlestick_chart/candlestick_chart_data.dart @@ -575,6 +575,7 @@ class CandlestickTouchTooltipData with EquatableMixin { GetCandlestickTooltipItems? getTooltipItems, bool? fitInsideHorizontally, bool? fitInsideVertically, + bool? showOnTopOfTheChartBoxArea, double? rotateAngle, BorderSide? tooltipBorder, GetCandlestickTooltipColor? getTooltipColor, @@ -591,6 +592,8 @@ class CandlestickTouchTooltipData with EquatableMixin { fitInsideHorizontally: fitInsideHorizontally ?? this.fitInsideHorizontally, fitInsideVertically: fitInsideVertically ?? this.fitInsideVertically, + showOnTopOfTheChartBoxArea: + showOnTopOfTheChartBoxArea ?? this.showOnTopOfTheChartBoxArea, rotateAngle: rotateAngle ?? this.rotateAngle, tooltipBorder: tooltipBorder ?? this.tooltipBorder, getTooltipColor: getTooltipColor ?? this.getTooltipColor, diff --git a/lib/src/chart/line_chart/line_chart_data.dart b/lib/src/chart/line_chart/line_chart_data.dart index e42be381c..b5956ddc7 100644 --- a/lib/src/chart/line_chart/line_chart_data.dart +++ b/lib/src/chart/line_chart/line_chart_data.dart @@ -1145,6 +1145,43 @@ class LineTouchTooltipData with EquatableMixin { tooltipBorder, getTooltipColor, ]; + + /// Copies current [LineTouchTooltipData] to a new [LineTouchTooltipData], + /// and replaces provided values. + LineTouchTooltipData copyWith({ + BorderRadius? tooltipBorderRadius, + EdgeInsets? tooltipPadding, + double? tooltipMargin, + FLHorizontalAlignment? tooltipHorizontalAlignment, + double? tooltipHorizontalOffset, + double? maxContentWidth, + GetLineTooltipItems? getTooltipItems, + GetLineTooltipColor? getTooltipColor, + bool? fitInsideHorizontally, + bool? fitInsideVertically, + bool? showOnTopOfTheChartBoxArea, + double? rotateAngle, + BorderSide? tooltipBorder, + }) => + LineTouchTooltipData( + tooltipBorderRadius: tooltipBorderRadius ?? _tooltipBorderRadius, + tooltipPadding: tooltipPadding ?? this.tooltipPadding, + tooltipMargin: tooltipMargin ?? this.tooltipMargin, + tooltipHorizontalAlignment: + tooltipHorizontalAlignment ?? this.tooltipHorizontalAlignment, + tooltipHorizontalOffset: + tooltipHorizontalOffset ?? this.tooltipHorizontalOffset, + maxContentWidth: maxContentWidth ?? this.maxContentWidth, + getTooltipItems: getTooltipItems ?? this.getTooltipItems, + getTooltipColor: getTooltipColor ?? this.getTooltipColor, + fitInsideHorizontally: + fitInsideHorizontally ?? this.fitInsideHorizontally, + fitInsideVertically: fitInsideVertically ?? this.fitInsideVertically, + showOnTopOfTheChartBoxArea: + showOnTopOfTheChartBoxArea ?? this.showOnTopOfTheChartBoxArea, + rotateAngle: rotateAngle ?? this.rotateAngle, + tooltipBorder: tooltipBorder ?? this.tooltipBorder, + ); } /// Provides a [LineTooltipItem] for showing content inside the [LineTouchTooltipData]. diff --git a/lib/src/chart/scatter_chart/scatter_chart_data.dart b/lib/src/chart/scatter_chart/scatter_chart_data.dart index 69aea514f..9df0e040f 100644 --- a/lib/src/chart/scatter_chart/scatter_chart_data.dart +++ b/lib/src/chart/scatter_chart/scatter_chart_data.dart @@ -192,7 +192,6 @@ class ScatterChartData extends AxisChartData with EquatableMixin { minY, maxY, baselineY, - rangeAnnotations, scatterLabelSettings, clipData, backgroundColor, @@ -533,6 +532,7 @@ class ScatterTouchTooltipData with EquatableMixin { /// Copies current [ScatterTouchTooltipData] to a new [ScatterTouchTooltipData], /// and replaces provided values. ScatterTouchTooltipData copyWith({ + BorderRadius? tooltipBorderRadius, EdgeInsets? tooltipPadding, FLHorizontalAlignment? tooltipHorizontalAlignment, double? tooltipHorizontalOffset, @@ -545,6 +545,7 @@ class ScatterTouchTooltipData with EquatableMixin { GetScatterTooltipColor? getTooltipColor, }) => ScatterTouchTooltipData( + tooltipBorderRadius: tooltipBorderRadius ?? _tooltipBorderRadius, tooltipPadding: tooltipPadding ?? this.tooltipPadding, tooltipHorizontalAlignment: tooltipHorizontalAlignment ?? this.tooltipHorizontalAlignment, diff --git a/test/chart/bar_chart/bar_chart_data_test.dart b/test/chart/bar_chart/bar_chart_data_test.dart index 710ae625b..05382c3a3 100644 --- a/test/chart/bar_chart/bar_chart_data_test.dart +++ b/test/chart/bar_chart/bar_chart_data_test.dart @@ -29,6 +29,20 @@ void main() { expect(barChartRodData1 == barChartRodData8, false); }); + test('BarChartRodData copyWith borderDashArray', () { + final base = BarChartRodData(toY: 10, borderDashArray: [4, 4]); + + final unchanged = base.copyWith(toY: 20); + expect(unchanged.borderDashArray, [4, 4]); + + final changed = base.copyWith(borderDashArray: [2, 8]); + expect(changed.borderDashArray, [2, 8]); + + final noArray = BarChartRodData(toY: 10); + final withArray = noArray.copyWith(borderDashArray: [6, 2]); + expect(withArray.borderDashArray, [6, 2]); + }); + test('BarChartRodStackItem equality test', () { expect(barChartRodStackItem1 == barChartRodStackItem1Clone, true); expect( @@ -110,6 +124,30 @@ void main() { expect(barTouchTooltipData1 == barTouchTooltipData11, false); }); + test('BarTouchTooltipData direction in props', () { + const base = BarTouchTooltipData(direction: TooltipDirection.auto); + const different = BarTouchTooltipData(direction: TooltipDirection.bottom); + expect(base == different, false); + }); + + test('BarTouchTooltipData copyWith', () { + const base = BarTouchTooltipData( + tooltipMargin: 8, + direction: TooltipDirection.top, + ); + + final unchanged = base.copyWith(maxContentWidth: 200); + expect(unchanged.tooltipMargin, 8); + expect(unchanged.direction, TooltipDirection.top); + + final changed = base.copyWith( + tooltipMargin: 24, + direction: TooltipDirection.bottom, + ); + expect(changed.tooltipMargin, 24); + expect(changed.direction, TooltipDirection.bottom); + }); + test('BarTooltipItem equality test', () { expect(barTooltipItem1 == barTooltipItem1Clone, true); expect(barTooltipItem1 == barTooltipItem2, false); diff --git a/test/chart/candlestick_chart/candlestick_chart_data_test.dart b/test/chart/candlestick_chart/candlestick_chart_data_test.dart index 8ad006d52..184c72e4c 100644 --- a/test/chart/candlestick_chart/candlestick_chart_data_test.dart +++ b/test/chart/candlestick_chart/candlestick_chart_data_test.dart @@ -372,6 +372,18 @@ void main() { ); }); + test('CandlestickTouchTooltipData copyWith showOnTopOfTheChartBoxArea', () { + final base = CandlestickTouchTooltipData( + showOnTopOfTheChartBoxArea: false, + ); + + final unchanged = base.copyWith(maxContentWidth: 200); + expect(unchanged.showOnTopOfTheChartBoxArea, false); + + final changed = base.copyWith(showOnTopOfTheChartBoxArea: true); + expect(changed.showOnTopOfTheChartBoxArea, true); + }); + test('CandlestickTooltipItem equality test', () { final sample1 = CandlestickTooltipItem( 'aa', diff --git a/test/chart/line_chart/line_chart_data_test.dart b/test/chart/line_chart/line_chart_data_test.dart index 15c84352d..594ddcfcd 100644 --- a/test/chart/line_chart/line_chart_data_test.dart +++ b/test/chart/line_chart/line_chart_data_test.dart @@ -1,4 +1,5 @@ import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import '../data_pool.dart'; @@ -144,6 +145,23 @@ void main() { expect(lineTouchTooltipData1 == lineTouchTooltipData7, false); }); + test('LineTouchTooltipData copyWith', () { + const base = LineTouchTooltipData(tooltipMargin: 8); + + final unchanged = base.copyWith(maxContentWidth: 200); + expect(unchanged.tooltipMargin, 8); + expect(unchanged.showOnTopOfTheChartBoxArea, false); + + final changed = base.copyWith( + tooltipMargin: 24, + showOnTopOfTheChartBoxArea: true, + tooltipBorderRadius: BorderRadius.circular(8), + ); + expect(changed.tooltipMargin, 24); + expect(changed.showOnTopOfTheChartBoxArea, true); + expect(changed.tooltipBorderRadius, BorderRadius.circular(8)); + }); + test('LineBarSpot equality test', () { expect(lineBarSpot1 == lineBarSpot1Clone, true); expect(lineBarSpot1 == lineBarSpot2, false); diff --git a/test/chart/scatter_chart/scatter_chart_data_test.dart b/test/chart/scatter_chart/scatter_chart_data_test.dart index aa6a912bb..d605e2498 100644 --- a/test/chart/scatter_chart/scatter_chart_data_test.dart +++ b/test/chart/scatter_chart/scatter_chart_data_test.dart @@ -451,6 +451,18 @@ void main() { expect(scatterTouchTooltipData1 == scatterTouchTooltipData3, false); }); + test('ScatterTouchTooltipData copyWith tooltipBorderRadius', () { + const base = ScatterTouchTooltipData(maxContentWidth: 100); + + final unchanged = base.copyWith(maxContentWidth: 200); + expect(unchanged.tooltipBorderRadius, BorderRadius.circular(4)); + + final changed = base.copyWith( + tooltipBorderRadius: BorderRadius.circular(12), + ); + expect(changed.tooltipBorderRadius, BorderRadius.circular(12)); + }); + test('ScatterTooltipItem equality test', () { final sample1 = ScatterTooltipItem( 'aa',