Repository: imaNNeo/fl_chart

Issue:
Memory leaking with changing spot list

**Describe the bug**
When chaning the complete FLSpot list instance/reference e.g. calculating it based on another list whenever the list changes the `LineChart` is leaking a ton of `FlSpots`

Here is a DevTool-measurement within seconds the Spots grows to 100k+ instances ( Example code used to measure can be found below)
<img width="705" alt="Bildschirmfoto 2022-07-29 um 19 27 23" src="https://user-images.githubusercontent.com/10357775/181812733-a93e3061-1586-4a69-8d9a-d6ea2bcf99c8.png">


**To Reproduce**
To debug the behavior I had a look at the [Sample#10](https://github.com/imaNNeoFighT/fl_chart/blob/master/example/lib/line_chart/samples/line_chart_sample10.dart) which does not leak any memory. However, I edited and also managed to reproduce the FLSpot leaking I encountered in my own app.
Instead of using an instance of `final sinePoints=<FlSpot>[]` ([src](https://github.com/imaNNeoFighT/fl_chart/blob/d9d3aa81073b3b3f6029a4fd88388bf02477bce2/example/lib/line_chart/samples/line_chart_sample10.dart#L19)) I am using a `final sinPoints = <double>[];` list which I later map to `FlSpots` using the `_convertToPlotSpots` method.
Also to verify that the issue is caused by the chart I replaced the `LineChart` widget with an `Text('Test:${_convertToPlotSpots(sinPoints).last.x}');` widget that uses also the FlSpot list just to see if the leaking is caused by the code in `_convertToPlotSpots` which is not the case.
Finaly I found a workaround for me by using a single instance of `List<FlSpot>`that does not change/only swapps elements using this code for the `_convertToPlotSpots` method:
```dart
// Workaround that uses again a fixed instance of List<FlSpot> and just replace the elements of it
List<FlSpot> l = [];
List<FlSpot> _convertToPlotSpots(List<double>? doubles) {
  if (doubles == null) return const [];
  List<double> sublist = doubles.sublist(max(0, doubles.length - 300));
  l.clear();
  double i = 0;
  l.addAll(sublist
      .map((e) => FlSpot(i++, e)));
  return l;
}
```




Sample#10 leaking Memory:
```dart
// Widget that leaks memory 
class LineChartSample10 extends StatefulWidget {
  const LineChartSample10({Key? key}) : super(key: key);

  @override
  _LineChartSample10State createState() => _LineChartSample10State();
}

class _LineChartSample10State extends State<LineChartSample10> {
  final Color sinColor = Colors.redAccent;
  final Color cosColor = Colors.blueAccent;

  final limitCount = 300;
  final sinPoints = <double>[];

  double xValue = 0;
  double step = 0.05;

  late Timer timer;

  @override
  void initState() {
    super.initState();
    timer = Timer.periodic(const Duration(milliseconds: 40), (timer) {
      if (sinPoints.length > 1200) sinPoints.removeAt(0);
      setState(() {
        sinPoints.add(math.sin(xValue));
      });
      xValue += step;
    });
  }

  @override
  Widget build(BuildContext context) {
    return sinPoints.isNotEmpty
        ? Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'x: ${xValue.toStringAsFixed(1)}',
                style: const TextStyle(
                  color: Colors.black,
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Text(
                'sin: ${sinPoints.last.toStringAsFixed(1)}',
                style: TextStyle(
                  color: sinColor,
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(
                height: 12,
              ),
              SizedBox(
                width: 300,
                height: 300,
                child: _Chartextends(
                  sinPoints: sinPoints,
                ),
              )
            ],
          )
        : Container();
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }
}

class _Chartextends extends StatelessWidget {
  static const Color sinColor = Colors.redAccent;
  static const Color cosColor = Colors.blueAccent;

  final List<double> sinPoints;

  const _Chartextends({Key? key, required this.sinPoints}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Enable to test if its caused by the method and not by the LineChart
    // return Text('Test:${_convertToPlotSpots(sinPoints).last.x}');


    return LineChart(
      LineChartData(
        minY: -1,
        maxY: 1,
        lineTouchData: LineTouchData(enabled: false),
        clipData: FlClipData.all(),
        gridData: FlGridData(
          show: true,
          drawVerticalLine: false,
        ),
        lineBarsData: [
          sinLine(_convertToPlotSpots(sinPoints)),
        ],
        titlesData: FlTitlesData(
          show: false,
        ),
      ),
    );
  }

  LineChartBarData sinLine(List<FlSpot> points) {
    return LineChartBarData(
      spots: points,
      dotData: FlDotData(
        show: false,
      ),
      gradient: LinearGradient(
          colors: [sinColor.withOpacity(0), sinColor],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          stops: const [0.1, 1.0]),
      barWidth: 4,
      isCurved: false,
    );
  }

  LineChartBarData cosLine(List<FlSpot> points) {
    return LineChartBarData(
      spots: points,
      dotData: FlDotData(
        show: false,
      ),
      gradient: LinearGradient(
          colors: [sinColor.withOpacity(0), sinColor],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          stops: const [0.1, 1.0]),
      barWidth: 4,
      isCurved: false,
    );
  }
}

List<FlSpot> _convertToPlotSpots(List<double>? doubles) {
  if (doubles == null) return const [];
  List<double> sublist = doubles.sublist(max(0, doubles.length - 300));
  double i = 0;
  return sublist
      .map((e) => FlSpot(i++, e))
      .toList(growable: false);
}


```

Flutter 3.0.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 676cefaaff (5 weeks ago) • 2022-06-22 11:34:49 -0700
Engine • revision ffe7b86a1e
Tools • Dart 2.17.5 • DevTools 2.12.2

  fl_chart: ^0.55.0



Discussion: I’m pretty sure it’s because of the static cache as I said [here](https://github.com/imaNNeoFighT/fl_chart/pull/995#discussion_r912535648).
The ‘LineChartHelper._cachedResults’ should generate the leak maintaining references to the lists and so the FlSpots.
It might be the case I didn't look too much into this since I managed to find a workaround.
However, I will have a look at the code you mentioned.
Sorry I’m on holidays and I don’t have the time nor the device to check this but could you retry your example having the memory leak but with calling a clear cache on the LineChartHelper each time you change the data values.
Your will need to add this clearCache static method just clearing the _results map.
If it is what I think it is, it should ‘fix’ your leak and we will need to refactor this.
And already thanks for your help and early investigation !
> I’m pretty sure it’s because of the static cache as I said [here](https://github.com/imaNNeoFighT/fl_chart/pull/995#discussion_r912535648). The ‘LineChartHelper._cachedResults’ should generate the leak maintaining references to the lists and so the FlSpots.

Dear @imaNNeo 
What is the solution?I see same problem in memory, so that while I close my chart screen, but memory filled by chart data is not cleared.


> > I’m pretty sure it’s because of the static cache as I said [here](https://github.com/imaNNeoFighT/fl_chart/pull/995#discussion_r912535648). The ‘LineChartHelper._cachedResults’ should generate the leak maintaining references to the lists and so the FlSpots.
> 
> Dear @imaNNeo What is the solution?I see same problem in memory, so that while I close my chart screen, but memory filled by chart data is not cleared.

Fixed in the `main` branch.
I will notify you here when we released a new version.
Fixed in [0.66.1](https://github.com/imaNNeo/fl_chart/releases/tag/0.66.1), please test and let me know if the issue is fixed.

Thanks for your patience!
Thank you dear @imaNNeo 
I will try it and let you know the result here.
I'm using lineChartData, but I'm getting a Platform_enviroment error after upgrading the version. The platform currently used is web.
> I'm using lineChartData, but I'm getting a Platform_enviroment error after upgrading the version. The platform currently used is web.

This is another issue related to #1565
Please test the memory issue in the next release 
Guys, this memory issue should be resolved on [0.66.1](https://github.com/imaNNeo/fl_chart/releases/tag/0.66.1). Can you please validate it in your apps?
I'm on 0.68.0 and still have FlSpots taking up multiple Gigabytes after a few hours. Can't confirm if the cause is the same as described here.
![image](https://github.com/imaNNeo/fl_chart/assets/31779313/93c3ac69-e747-4edf-952c-d622b49a34a7)

same problem here...I can solve the problem by not using the built-in "min" / "max" autocalculation and doing it myself.
I will be more precise soon with some code.
The root cause of this issue is that `_cachedResults` does not have a reliable cleanup mechanism. If you think providing a `isEnableCache` option is bad [1283](https://github.com/imaNNeo/fl_chart/pull/1283) at least add a time limit or size limit?
It seems that in [0.66.2](https://github.com/imaNNeo/fl_chart/tree/0.66.2), the cache was removed in the deletion of `line_chart_data.dart`, in this [commit](https://github.com/imaNNeo/fl_chart/commit/eb82f1c5373af6c6e65ff0c57b43794b76ae6491). However, there is still code using `_cachedResults` in the current project, and the OOM risk still exists.

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d3afe9c6..aba14c114 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## newVersion
+* **BUGFIX** Fix a memory leak issue in the axis-based charts, there was a logic to calculate and cache the minX, maxX, minY and maxY properties to reduce the computation cost. But it caused some memory issues, as we don't have a quick solution for this, we disabled the caching logic for now, later we can move the calculation logic to the render objects to keep and update them only when the data is changed, #1106, #1693
+
 ## 0.68.0
 * **Improvement** (by @imaNNeo) Update LineChartSample6 to implement a way to show a tooltip on a single spot, #1620
 * **Feature** (by @herna) Add `titleSunbeamLayout` inside the [BarChartData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/bar_chart.md#barchartdata) to allow the user to customize the layout of the title sunbeam
diff --git a/lib/src/chart/bar_chart/bar_chart.dart b/lib/src/chart/bar_chart/bar_chart.dart
index c83023340..bd8558968 100644
--- a/lib/src/chart/bar_chart/bar_chart.dart
+++ b/lib/src/chart/bar_chart/bar_chart.dart
@@ -86,10 +86,11 @@ class _BarChartState extends AnimatedWidgetBaseState<BarChart> {
   BarChartData _getData() {
     var newData = widget.data;
     if (newData.minY.isNaN || newData.maxY.isNaN) {
-      final values = _barChartHelper.calculateMaxAxisValues(newData.barGroups);
+      final (minY, maxY) =
+          _barChartHelper.calculateMaxAxisValues(newData.barGroups);
       newData = newData.copyWith(
-        minY: newData.minY.isNaN ? values.minY : newData.minY,
-        maxY: newData.maxY.isNaN ? values.maxY : newData.maxY,
+        minY: newData.minY.isNaN ? minY : newData.minY,
+        maxY: newData.maxY.isNaN ? maxY : newData.maxY,
       );
     }
 
diff --git a/lib/src/chart/bar_chart/bar_chart_helper.dart b/lib/src/chart/bar_chart/bar_chart_helper.dart
index 22b14da56..1af876483 100644
--- a/lib/src/chart/bar_chart/bar_chart_helper.dart
+++ b/lib/src/chart/bar_chart/bar_chart_helper.dart
@@ -1,30 +1,16 @@
 import 'dart:math';
 
-import 'package:equatable/equatable.dart';
 import 'package:fl_chart/src/chart/bar_chart/bar_chart_data.dart';
-import 'package:fl_chart/src/utils/list_wrapper.dart';
 
 /// Contains anything that helps BarChart works
 class BarChartHelper {
-  /// Contains List of cached results, base on [List<BarChartGroupData>]
-  ///
-  /// We use it to prevent redundant calculations
-  final Map<ListWrapper<BarChartGroupData>, BarChartMinMaxAxisValues>
-      _cachedResults = {};
-
   /// Calculates minY, and maxY based on [barGroups],
   /// returns cached values, to prevent redundant calculations.
-  BarChartMinMaxAxisValues calculateMaxAxisValues(
+  (double minY, double maxY) calculateMaxAxisValues(
     List<BarChartGroupData> barGroups,
   ) {
     if (barGroups.isEmpty) {
-      return BarChartMinMaxAxisValues(0, 0);
-    }
-
-    final listWrapper = barGroups.toWrapperClass();
-
-    if (_cachedResults.containsKey(listWrapper)) {
-      return _cachedResults[listWrapper]!.copyWith(readFromCache: true);
+      return (0, 0);
     }
 
     final BarChartGroupData barGroup;
@@ -32,7 +18,7 @@ class BarChartHelper {
       barGroup = barGroups.firstWhere((element) => element.barRods.isNotEmpty);
     } catch (e) {
       // There is no barChartGroupData with at least one barRod
-      return BarChartMinMaxAxisValues(0, 0);
+      return (0, 0);
     }
 
     var maxY = max(barGroup.barRods[0].fromY, barGroup.barRods[0].toY);
@@ -57,33 +43,6 @@ class BarChartHelper {
         }
       }
     }
-
-    final result = BarChartMinMaxAxisValues(minY, maxY);
-    _cachedResults[listWrapper] = result;
-    return result;
-  }
-}
-
-/// Holds minY, and maxY for use in [BarChartData]
-class BarChartMinMaxAxisValues with EquatableMixin {
-  BarChartMinMaxAxisValues(this.minY, this.maxY, {this.readFromCache = false});
-
-  final double minY;
-  final double maxY;
-  final bool readFromCache;
-
-  @override
-  List<Object?> get props => [minY, maxY, readFromCache];
-
-  BarChartMinMaxAxisValues copyWith({
-    double? minY,
-    double? maxY,
-    bool? readFromCache,
-  }) {
-    return BarChartMinMaxAxisValues(
-      minY ?? this.minY,
-      maxY ?? this.maxY,
-      readFromCache: readFromCache ?? this.readFromCache,
-    );
+    return (minY, maxY);
   }
 }
diff --git a/lib/src/chart/line_chart/line_chart.dart b/lib/src/chart/line_chart/line_chart.dart
index f36321df9..01eb3eb0b 100644
--- a/lib/src/chart/line_chart/line_chart.dart
+++ b/lib/src/chart/line_chart/line_chart.dart
@@ -87,14 +87,14 @@ class _LineChartState extends AnimatedWidgetBaseState<LineChart> {
         newData.maxX.isNaN ||
         newData.minY.isNaN ||
         newData.maxY.isNaN) {
-      final values = _lineChartHelper.calculateMaxAxisValues(
+      final (minX, maxX, minY, maxY) = _lineChartHelper.calculateMaxAxisValues(
         newData.lineBarsData,
       );
       newData = newData.copyWith(
-        minX: newData.minX.isNaN ? values.minX : newData.minX,
-        maxX: newData.maxX.isNaN ? values.maxX : newData.maxX,
-        minY: newData.minY.isNaN ? values.minY : newData.minY,
-        maxY: newData.maxY.isNaN ? values.maxY : newData.maxY,
+        minX: newData.minX.isNaN ? minX : newData.minX,
+        maxX: newData.maxX.isNaN ? maxX : newData.maxX,
+        minY: newData.minY.isNaN ? minY : newData.minY,
+        maxY: newData.maxY.isNaN ? maxY : newData.maxY,
       );
     }
 
diff --git a/lib/src/chart/line_chart/line_chart_helper.dart b/lib/src/chart/line_chart/line_chart_helper.dart
index 90e388f03..2a25dfe64 100644
--- a/lib/src/chart/line_chart/line_chart_helper.dart
+++ b/lib/src/chart/line_chart/line_chart_helper.dart
@@ -1,26 +1,14 @@
-import 'package:equatable/equatable.dart';
 import 'package:fl_chart/fl_chart.dart';
-import 'package:fl_chart/src/utils/list_wrapper.dart';
 
 /// Contains anything that helps LineChart works
 class LineChartHelper {
-  /// Contains List of cached results, base on [List<LineChartBarData>]
-  ///
-  /// We use it to prevent redundant calculations
-  final Map<ListWrapper<LineChartBarData>, LineChartMinMaxAxisValues>
-      _cachedResults = {};
-
-  LineChartMinMaxAxisValues calculateMaxAxisValues(
+  /// Calculates the [minX], [maxX], [minY], and [maxY] values of
+  /// the provided [lineBarsData].
+  (double minX, double maxX, double minY, double maxY) calculateMaxAxisValues(
     List<LineChartBarData> lineBarsData,
   ) {
     if (lineBarsData.isEmpty) {
-      return const LineChartMinMaxAxisValues(0, 0, 0, 0);
-    }
-
-    final listWrapper = lineBarsData.toWrapperClass();
-
-    if (_cachedResults.containsKey(listWrapper)) {
-      return _cachedResults[listWrapper]!.copyWith(readFromCache: true);
+      return (0, 0, 0, 0);
     }
 
     final LineChartBarData lineBarData;
@@ -29,7 +17,7 @@ class LineChartHelper {
           lineBarsData.firstWhere((element) => element.spots.isNotEmpty);
     } catch (e) {
       // There is no lineBarData with at least one spot
-      return const LineChartMinMaxAxisValues(0, 0, 0, 0);
+      return (0, 0, 0, 0);
     }
 
     final FlSpot firstValidSpot;
@@ -38,7 +26,7 @@ class LineChartHelper {
           lineBarData.spots.firstWhere((element) => element != FlSpot.nullSpot);
     } catch (e) {
       // There is no valid spot
-      return const LineChartMinMaxAxisValues(0, 0, 0, 0);
+      return (0, 0, 0, 0);
     }
 
     var minX = firstValidSpot.x;
@@ -68,43 +56,6 @@ class LineChartHelper {
       }
     }
 
-    final result = LineChartMinMaxAxisValues(minX, maxX, minY, maxY);
-    _cachedResults[listWrapper] = result;
-    return result;
-  }
-}
-
-/// Holds minX, maxX, minY, and maxY for use in [LineChartData]
-class LineChartMinMaxAxisValues with EquatableMixin {
-  const LineChartMinMaxAxisValues(
-    this.minX,
-    this.maxX,
-    this.minY,
-    this.maxY, {
-    this.readFromCache = false,
-  });
-  final double minX;
-  final double maxX;
-  final double minY;
-  final double maxY;
-  final bool readFromCache;
-
-  @override
-  List<Object?> get props => [minX, maxX, minY, maxY, readFromCache];
-
-  LineChartMinMaxAxisValues copyWith({
-    double? minX,
-    double? maxX,
-    double? minY,
-    double? maxY,
-    bool? readFromCache,
-  }) {
-    return LineChartMinMaxAxisValues(
-      minX ?? this.minX,
-      maxX ?? this.maxX,
-      minY ?? this.minY,
-      maxY ?? this.maxY,
-      readFromCache: readFromCache ?? this.readFromCache,
-    );
+    return (minX, maxX, minY, maxY);
   }
 }
diff --git a/lib/src/chart/scatter_chart/scatter_chart_data.dart b/lib/src/chart/scatter_chart/scatter_chart_data.dart
index a0dbe4572..cd27e50ed 100644
--- a/lib/src/chart/scatter_chart/scatter_chart_data.dart
+++ b/lib/src/chart/scatter_chart/scatter_chart_data.dart
@@ -61,19 +61,19 @@ class ScatterChartData extends AxisChartData with EquatableMixin {
           minX: minX ??
               ScatterChartHelper.calculateMaxAxisValues(
                 scatterSpots ?? const [],
-              ).minX,
+              ).$1,
           maxX: maxX ??
               ScatterChartHelper.calculateMaxAxisValues(
                 scatterSpots ?? const [],
-              ).maxX,
+              ).$2,
           minY: minY ??
               ScatterChartHelper.calculateMaxAxisValues(
                 scatterSpots ?? const [],
-              ).minY,
+              ).$3,
           maxY: maxY ??
               ScatterChartHelper.calculateMaxAxisValues(
                 scatterSpots ?? const [],
-              ).maxY,
+              ).$4,
         );
   final List<ScatterSpot> scatterSpots;
   final ScatterTouchData scatterTouchData;
diff --git a/lib/src/chart/scatter_chart/scatter_chart_helper.dart b/lib/src/chart/scatter_chart/scatter_chart_helper.dart
index abec8a3f6..547df662d 100644
--- a/lib/src/chart/scatter_chart/scatter_chart_helper.dart
+++ b/lib/src/chart/scatter_chart/scatter_chart_helper.dart
@@ -1,28 +1,19 @@
-import 'package:equatable/equatable.dart';
 import 'package:fl_chart/src/chart/scatter_chart/scatter_chart_data.dart';
-import 'package:fl_chart/src/utils/list_wrapper.dart';
 
 /// Contains anything that helps ScatterChart works
 class ScatterChartHelper {
-  /// Contains List of cached results, base on [List<ScatterSpot>]
-  ///
-  /// We use it to prevent redundant calculations
-  static final Map<ListWrapper<ScatterSpot>, ScatterChartMinMaxAxisValues>
-      _cachedResults = {};
-
   /// Calculates minX, maxX, minY, and maxY based on [scatterSpots],
   /// returns cached values, to prevent redundant calculations.
-  static ScatterChartMinMaxAxisValues calculateMaxAxisValues(
+  static (
+    double minX,
+    double maxX,
+    double minY,
+    double maxY,
+  ) calculateMaxAxisValues(
     List<ScatterSpot> scatterSpots,
   ) {
     if (scatterSpots.isEmpty) {
-      return ScatterChartMinMaxAxisValues(0, 0, 0, 0);
-    }
-
-    final listWrapper = scatterSpots.toWrapperClass();
-
-    if (_cachedResults.containsKey(listWrapper)) {
-      return _cachedResults[listWrapper]!.copyWith(readFromCache: true);
+      return (0, 0, 0, 0);
     }
 
     var minX = scatterSpots[0].x;
@@ -47,44 +38,6 @@ class ScatterChartHelper {
         minY = spot.y;
       }
     }
-
-    final result = ScatterChartMinMaxAxisValues(minX, maxX, minY, maxY);
-    _cachedResults[listWrapper] = result;
-    return result;
-  }
-}
-
-/// Holds minX, maxX, minY, and maxY for use in [ScatterChartData]
-class ScatterChartMinMaxAxisValues with EquatableMixin {
-  ScatterChartMinMaxAxisValues(
-    this.minX,
-    this.maxX,
-    this.minY,
-    this.maxY, {
-    this.readFromCache = false,
-  });
-  final double minX;
-  final double maxX;
-  final double minY;
-  final double maxY;
-  final bool readFromCache;
-
-  @override
-  List<Object?> get props => [minX, maxX, minY, maxY, readFromCache];
-
-  ScatterChartMinMaxAxisValues copyWith({
-    double? minX,
-    double? maxX,
-    double? minY,
-    double? maxY,
-    bool? readFromCache,
-  }) {
-    return ScatterChartMinMaxAxisValues(
-      minX ?? this.minX,
-      maxX ?? this.maxX,
-      minY ?? this.minY,
-      maxY ?? this.maxY,
-      readFromCache: readFromCache ?? this.readFromCache,
-    );
+    return (minX, maxX, minY, maxY);
   }
 }
diff --git a/lib/src/utils/list_wrapper.dart b/lib/src/utils/list_wrapper.dart
deleted file mode 100644
index e7e2de0a8..000000000
--- a/lib/src/utils/list_wrapper.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:equatable/equatable.dart';
-
-/// Wraps a list as a property
-///
-/// We needed to use list as key for Maps.
-/// But in dart, List doesn't implement hashCode and equals functions.
-/// That is a workaround to solve the problem.
-/// Issue link: https://github.com/dart-lang/sdk/issues/17963
-class ListWrapper<T> with EquatableMixin {
-  ListWrapper(this.list);
-  final List<T> list;
-
-  @override
-  List<Object?> get props => [list];
-}
-
-/// An Extension to convert a List into ListWrapper class
-extension ListExtension<T> on List<T> {
-  /// Converts List into ListWrapper class
-  ListWrapper<T> toWrapperClass() => ListWrapper<T>(this);
-}
diff --git a/repo_files/documentations/bar_chart.md b/repo_files/documentations/bar_chart.md
index e98208c70..8d1f0f5b0 100644
--- a/repo_files/documentations/bar_chart.md
+++ b/repo_files/documentations/bar_chart.md
@@ -27,8 +27,8 @@ When you change the chart's state, it animates to the new state internally (usin
 |barTouchData| [BarTouchData](#bartouchdata-read-about-touch-handling) holds the touch interactivity details|BarTouchData()|
 |gridData| check the [FlGridData](base_chart.md#FlGridData)|FlGridData()|
 |borderData| check the [FlBorderData](base_chart.md#FlBorderData)|FlBorderData()|
-|maxY| gets maximum y of y axis, if null, value will be read from the input barGroups | null|
-|minY| gets minimum y of y axis, if null, value will be read from the input barGroups | null|
+|maxY| gets maximum y of y axis, if null, value will be read from the input barGroups (But it is more performant if you provide them) | null|
+|minY| gets minimum y of y axis, if null, value will be read from the input barGroups (But it is more performant if you provide them) | null|
 |baselineY| defines the baseline of y-axis | 0|
 |extraLinesData| allows extra horizontal lines to be drawn on the chart. Vertical lines are ignored when used with BarChartData, please see [#1149](https://github.com/imaNNeo/fl_chart/issues/1149), check [ExtraLinesData](base_chart.md#ExtraLinesData)|ExtraLinesData()|
 
diff --git a/repo_files/documentations/line_chart.md b/repo_files/documentations/line_chart.md
index be5ab9dbf..65b4e21a6 100644
--- a/repo_files/documentations/line_chart.md
+++ b/repo_files/documentations/line_chart.md
@@ -26,11 +26,11 @@ When you change the chart's state, it animates to the new state internally (usin
 |showingTooltipIndicators| show the tooltip based on provided list of [LineBarSpot](#LineBarSpot), The point is that you need to disable touches to show these tooltips manually| [] |
 |gridData| check the [FlGridData](base_chart.md#FlGridData)|FlGridData()|
 |borderData| check the [FlBorderData](base_chart.md#FlBorderData)|FlBorderData()|
-|minX| gets minimum x of x axis, if null, value will read from the input lineBars |null|
-|maxX| gets maximum x of x axis, if null, value will read from the input lineBars | null|
+|minX| gets minimum x of x axis, if null, value will read from the input lineBars (But it is more performant if you provide them)|null|
+|maxX| gets maximum x of x axis, if null, value will read from the input lineBars (But it is more performant if you provide them)| null|
 |baselineX| defines the baseline of x-axis | 0|
-|minY| gets minimum y of y axis, if null, value will read from the input lineBars | null|
-|maxY| gets maximum y of y axis, if null, value will read from the input lineBars | null|
+|minY| gets minimum y of y axis, if null, value will read from the input lineBars (But it is more performant if you provide them)| null|
+|maxY| gets maximum y of y axis, if null, value will read from the input lineBars (But it is more performant if you provide them)| null|
 |baselineY| defines the baseline of y-axis | 0|
 |clipData| clip the chart to the border (prevent drawing outside the border) | FlClipData.none()|
 |backgroundColor| a background color which is drawn behind th chart| null |


Test patch:
diff --git a/test/chart/bar_chart/bar_chart_helper_test.dart b/test/chart/bar_chart/bar_chart_helper_test.dart
index 35c5e27f8..9a1631ad3 100644
--- a/test/chart/bar_chart/bar_chart_helper_test.dart
+++ b/test/chart/bar_chart/bar_chart_helper_test.dart
@@ -6,32 +6,12 @@ import '../data_pool.dart';
 
 void main() {
   group('Check caching of BarChartHelper.calculateMaxAxisValues', () {
-    test('Test read from cache1', () {
-      final barChartHelper = BarChartHelper();
-      final barGroups1 = [barChartGroupData1];
-      final result1 = barChartHelper.calculateMaxAxisValues(barGroups1);
-
-      final barGroups2 = [barChartGroupData2];
-      final result2 = barChartHelper.calculateMaxAxisValues(barGroups2);
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, false);
-    });
-
-    test('Test read from cache2', () {
-      final barChartHelper = BarChartHelper();
-      final barGroups = [barChartGroupData1, barChartGroupData2];
-      final result1 = barChartHelper.calculateMaxAxisValues(barGroups);
-      final result2 = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, true);
-    });
-
     test('Test validity 1', () {
       final barChartHelper = BarChartHelper();
       final barGroups = [barChartGroupData1, barChartGroupData2];
-      final result = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result.minY, 0);
-      expect(result.maxY, 1132);
+      final (minY, maxY) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, 0);
+      expect(maxY, 1132);
     });
 
     test('Test validity 2', () {
@@ -47,9 +27,9 @@ void main() {
           ],
         ),
       ];
-      final result = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result.minY, -40);
-      expect(result.maxY, 10);
+      final (minY, maxY) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, -40);
+      expect(maxY, 10);
     });
 
     test('Test validity 3', () {
@@ -57,9 +37,9 @@ void main() {
       final barGroups = [
         barChartGroupData1.copyWith(barRods: []),
       ];
-      final result = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result.minY, 0);
-      expect(result.maxY, 0);
+      final (minY, maxY) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, 0);
+      expect(maxY, 0);
     });
 
     test('Test validity 4', () {
@@ -77,35 +57,16 @@ void main() {
           ],
         ),
       ];
-      final result = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result.minY, -50);
-      expect(result.maxY, 39);
+      final (minY, maxY) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, -50);
+      expect(maxY, 39);
     });
 
     test('Test equality', () {
       final barChartHelper = BarChartHelper();
       final barGroups = [barChartGroupData1, barChartGroupData2];
       final result1 = barChartHelper.calculateMaxAxisValues(barGroups);
-      final result2 = barChartHelper.calculateMaxAxisValues(barGroups).copyWith(
-            readFromCache: false,
-          );
-      expect(result1, result2);
-    });
-
-    test('Test equality2', () {
-      final barChartHelper = BarChartHelper();
-      final barGroups = [barChartGroupData1, barChartGroupData2];
-      final result1 = barChartHelper
-          .calculateMaxAxisValues(barGroups)
-          .copyWith(readFromCache: true);
-      final result2 = result1.copyWith(readFromCache: false);
-      expect(result1 != result2, true);
-    });
-
-    test('Test BarChartMinMaxAxisValues class', () {
-      final result1 = BarChartMinMaxAxisValues(0, 10)
-          .copyWith(minY: 1, maxY: 11, readFromCache: true);
-      final result2 = BarChartMinMaxAxisValues(1, 11, readFromCache: true);
+      final result2 = barChartHelper.calculateMaxAxisValues(barGroups);
       expect(result1, result2);
     });
 
@@ -133,8 +94,8 @@ void main() {
               .toList(),
         ),
       ];
-      final result1 = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result1.minY, 5);
+      final (minY, _) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, 5);
     });
 
     test('Test calculateMaxAxisValues with all negative values', () {
@@ -151,8 +112,8 @@ void main() {
               .toList(),
         ),
       ];
-      final result1 = barChartHelper.calculateMaxAxisValues(barGroups);
-      expect(result1.minY, -8);
+      final (minY, _) = barChartHelper.calculateMaxAxisValues(barGroups);
+      expect(minY, -8);
     });
   });
 }
diff --git a/test/chart/bar_chart/bar_chart_painter_test.dart b/test/chart/bar_chart/bar_chart_painter_test.dart
index ad8fb9af2..8a389f54c 100644
--- a/test/chart/bar_chart/bar_chart_painter_test.dart
+++ b/test/chart/bar_chart/bar_chart_painter_test.dart
@@ -43,12 +43,12 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         barGroups: barGroups,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -347,15 +347,15 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         titlesData: const FlTitlesData(show: false),
         groupsSpace: 10,
         barGroups: barGroups,
         alignment: BarChartAlignment.center,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -612,15 +612,15 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         titlesData: const FlTitlesData(show: false),
         groupsSpace: 10,
         barGroups: barGroups,
         alignment: BarChartAlignment.center,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -848,12 +848,12 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         barGroups: barGroups,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -953,12 +953,12 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         barGroups: barGroups,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -1108,7 +1108,7 @@ void main() {
         },
       );
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         groupsSpace: 10,
@@ -1117,8 +1117,8 @@ void main() {
           touchTooltipData: tooltipData,
         ),
         alignment: BarChartAlignment.center,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -1308,7 +1308,7 @@ void main() {
         },
       );
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         groupsSpace: 10,
@@ -1317,8 +1317,8 @@ void main() {
           touchTooltipData: tooltipData,
         ),
         alignment: BarChartAlignment.center,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -1483,7 +1483,7 @@ void main() {
         },
       );
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         groupsSpace: 10,
@@ -1492,8 +1492,8 @@ void main() {
           touchTooltipData: tooltipData,
         ),
         alignment: BarChartAlignment.center,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -1614,14 +1614,14 @@ void main() {
         BarChartGroupData(x: 0, barRods: [barRod], barsSpace: 5),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         groupsSpace: 10,
         barGroups: barGroups,
         barTouchData: BarTouchData(),
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final barChartPainter = BarChartPainter();
@@ -1792,7 +1792,7 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         barGroups: barGroups,
@@ -1803,8 +1803,8 @@ void main() {
           handleBuiltInTouches: true,
           touchExtraThreshold: const EdgeInsets.all(1),
         ),
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final painter = BarChartPainter();
@@ -1895,7 +1895,7 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
         barGroups: barGroups,
@@ -1906,8 +1906,8 @@ void main() {
           handleBuiltInTouches: true,
           touchExtraThreshold: const EdgeInsets.all(1),
         ),
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
       );
 
       final painter = BarChartPainter();
@@ -2153,11 +2153,11 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
         barGroups: barGroups,
         extraLinesData: ExtraLinesData(
           verticalLines: [verticalLine1],
@@ -2349,11 +2349,11 @@ void main() {
         ),
       ];
 
-      final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+      final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
       final data = BarChartData(
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minY: minY,
+        maxY: maxY,
         barGroups: barGroups,
         extraLinesData: ExtraLinesData(
           horizontalLines: [horizontalLine, horizontalLine1],
diff --git a/test/chart/base/axis_chart/side_titles/side_titles_widget_test.dart b/test/chart/base/axis_chart/side_titles/side_titles_widget_test.dart
index f55d1ef16..b6cbc9e52 100644
--- a/test/chart/base/axis_chart/side_titles/side_titles_widget_test.dart
+++ b/test/chart/base/axis_chart/side_titles/side_titles_widget_test.dart
@@ -169,7 +169,7 @@ void main() {
       ),
     ];
 
-    final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+    final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
     return BarChartData(
       barGroups: barGroups,
@@ -193,14 +193,14 @@ void main() {
         ),
         bottomTitles: const AxisTitles(),
       ),
-      minY: axisValues.minY,
-      maxY: axisValues.maxY,
+      minY: minY,
+      maxY: maxY,
     );
   }
 
   BarChartData createBarChartDataWithEmptyGroups() {
     final barGroups = <BarChartGroupData>[];
-    final axisValues = BarChartHelper().calculateMaxAxisValues(barGroups);
+    final (minY, maxY) = BarChartHelper().calculateMaxAxisValues(barGroups);
 
     return BarChartData(
       barGroups: [],
@@ -224,8 +224,8 @@ void main() {
         ),
         bottomTitles: const AxisTitles(),
       ),
-      minY: axisValues.minY,
-      maxY: axisValues.maxY,
+      minY: minY,
+      maxY: maxY,
     );
   }
 
diff --git a/test/chart/line_chart/line_chart_helper_test.dart b/test/chart/line_chart/line_chart_helper_test.dart
index 341e35f27..155e6cf80 100644
--- a/test/chart/line_chart/line_chart_helper_test.dart
+++ b/test/chart/line_chart/line_chart_helper_test.dart
@@ -6,36 +6,15 @@ import '../data_pool.dart';
 
 void main() {
   group('Check caching of LineChartHelper.calculateMaxAxisValues', () {
-    test('Test read from cache1', () {
-      final lineChartHelper = LineChartHelper();
-      final lineBars1 = [lineChartBarData1];
-      final result1 = lineChartHelper.calculateMaxAxisValues(lineBars1);
-
-      final lineBars2 = [lineChartBarData2];
-      final result2 = lineChartHelper.calculateMaxAxisValues(lineBars2);
-
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, false);
-    });
-
-    test('Test read from cache2', () {
-      final lineChartHelper = LineChartHelper();
-      final lineBars = [lineChartBarData1, lineChartBarData2];
-      final lineBarsClone = [lineChartBarData1Clone, lineChartBarData2];
-      final result1 = lineChartHelper.calculateMaxAxisValues(lineBars);
-      final result2 = lineChartHelper.calculateMaxAxisValues(lineBarsClone);
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, true);
-    });
-
     test('Test validity 1', () {
       final lineChartHelper = LineChartHelper();
       final lineBars = [lineChartBarData1, lineChartBarData2];
-      final result = lineChartHelper.calculateMaxAxisValues(lineBars);
-      expect(result.minX, 1);
-      expect(result.maxX, 4);
-      expect(result.minY, 1);
-      expect(result.maxY, 2);
+      final (minX, maxX, minY, maxY) =
+          lineChartHelper.calculateMaxAxisValues(lineBars);
+      expect(minX, 1);
+      expect(maxX, 4);
+      expect(minY, 1);
+      expect(maxY, 2);
     });
 
     test('Test validity 2', () {
@@ -49,11 +28,12 @@ void main() {
           ],
         ),
       ];
-      final result = lineChartHelper.calculateMaxAxisValues(lineBars);
-      expect(result.minX, -3);
-      expect(result.maxX, 14);
-      expect(result.minY, -10);
-      expect(result.maxY, 50);
+      final (minX, maxX, minY, maxY) =
+          lineChartHelper.calculateMaxAxisValues(lineBars);
+      expect(minX, -3);
+      expect(maxX, 14);
+      expect(minY, -10);
+      expect(maxY, 50);
     });
 
     test('Test equality', () {
@@ -61,10 +41,7 @@ void main() {
       final lineBars = [lineChartBarData1, lineChartBarData2];
       final lineBarsClone = [lineChartBarData1Clone, lineChartBarData2];
       final result1 = lineChartHelper.calculateMaxAxisValues(lineBars);
-      final result2 =
-          lineChartHelper.calculateMaxAxisValues(lineBarsClone).copyWith(
-                readFromCache: false,
-              );
+      final result2 = lineChartHelper.calculateMaxAxisValues(lineBarsClone);
       expect(result1, result2);
     });
 
@@ -80,8 +57,7 @@ void main() {
           ],
         ),
       ];
-      final result1 = lineChartHelper.calculateMaxAxisValues(lineBars);
-      expect(result1, const LineChartMinMaxAxisValues(0, 0, 0, 0));
+      expect(lineChartHelper.calculateMaxAxisValues(lineBars), (0, 0, 0, 0));
     });
 
     test('Test null spot 2', () {
@@ -96,8 +72,7 @@ void main() {
           ],
         ),
       ];
-      final result1 = lineChartHelper.calculateMaxAxisValues(lineBars);
-      expect(result1, const LineChartMinMaxAxisValues(-1, 4, -3, 5));
+      expect(lineChartHelper.calculateMaxAxisValues(lineBars), (-1, 4, -3, 5));
     });
   });
 }
diff --git a/test/chart/line_chart/line_chart_painter_test.dart b/test/chart/line_chart/line_chart_painter_test.dart
index 7cad6c080..19925557f 100644
--- a/test/chart/line_chart/line_chart_painter_test.dart
+++ b/test/chart/line_chart/line_chart_painter_test.dart
@@ -48,15 +48,15 @@ void main() {
       );
 
       final lineChartBarsData = <LineChartBarData>[bar1, bar2];
-      final axisValues = LineChartHelper().calculateMaxAxisValues(
+      final (minX, maxX, minY, maxY) = LineChartHelper().calculateMaxAxisValues(
         lineChartBarsData,
       );
 
       final data = LineChartData(
-        minX: axisValues.minX,
-        maxX: axisValues.maxX,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minX: minX,
+        maxX: maxX,
+        minY: minY,
+        maxY: maxY,
         lineBarsData: lineChartBarsData,
         clipData: const FlClipData.all(),
         extraLinesData: ExtraLinesData(
@@ -147,15 +147,15 @@ void main() {
       );
 
       final lineChartBarsData = <LineChartBarData>[bar1, bar2];
-      final axisValues = LineChartHelper().calculateMaxAxisValues(
+      final (minX, maxX, minY, maxY) = LineChartHelper().calculateMaxAxisValues(
         lineChartBarsData,
       );
 
       final data = LineChartData(
-        minX: axisValues.minX,
-        maxX: axisValues.maxX,
-        minY: axisValues.minY,
-        maxY: axisValues.maxY,
+        minX: minX,
+        maxX: maxX,
+        minY: minY,
+        maxY: maxY,
         lineBarsData: lineChartBarsData,
         clipData: const FlClipData.all(),
         lineTouchData: LineTouchData(
diff --git a/test/chart/scatter_chart/scatter_chart_helper_test.dart b/test/chart/scatter_chart/scatter_chart_helper_test.dart
index d29c88d64..e6893ab73 100644
--- a/test/chart/scatter_chart/scatter_chart_helper_test.dart
+++ b/test/chart/scatter_chart/scatter_chart_helper_test.dart
@@ -6,31 +6,6 @@ import '../data_pool.dart';
 
 void main() {
   group('Check caching of ScatterChartHelper.calculateMaxAxisValues', () {
-    test('Test read from cache', () {
-      final scatterSpots1 = [scatterSpot2];
-      final result1 = ScatterChartHelper.calculateMaxAxisValues(scatterSpots1);
-
-      final scatterSpots2 = [scatterSpot3];
-      final result2 = ScatterChartHelper.calculateMaxAxisValues(scatterSpots2);
-
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, false);
-    });
-
-    test('Test read from cache', () {
-      final scatterSpots = [scatterSpot1, scatterSpot2, scatterSpot3];
-      final scatterSpotsClone = [
-        scatterSpot1Clone,
-        scatterSpot2Clone,
-        scatterSpot3,
-      ];
-      final result1 = ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
-      final result2 =
-          ScatterChartHelper.calculateMaxAxisValues(scatterSpotsClone);
-      expect(result1.readFromCache, false);
-      expect(result2.readFromCache, true);
-    });
-
     test('Test validity 1', () {
       final scatterSpots = [
         scatterSpot1,
@@ -38,11 +13,12 @@ void main() {
         scatterSpot3,
         scatterSpot4,
       ];
-      final result = ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
-      expect(result.minX, -14);
-      expect(result.maxX, 1);
-      expect(result.minY, -8);
-      expect(result.maxY, 40);
+      final (minX, maxX, minY, maxY) =
+          ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
+      expect(minX, -14);
+      expect(maxX, 1);
+      expect(minY, -8);
+      expect(maxY, 40);
     });
 
     test('Test validity 2', () {
@@ -50,20 +26,22 @@ void main() {
         ScatterSpot(3, -1),
         ScatterSpot(-1, 3),
       ];
-      final result = ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
-      expect(result.minX, -1);
-      expect(result.maxX, 3);
-      expect(result.minY, -1);
-      expect(result.maxY, 3);
+      final (minX, maxX, minY, maxY) =
+          ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
+      expect(minX, -1);
+      expect(maxX, 3);
+      expect(minY, -1);
+      expect(maxY, 3);
     });
 
     test('Test validity 3', () {
       final scatterSpots = <ScatterSpot>[];
-      final result = ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
-      expect(result.minX, 0);
-      expect(result.maxX, 0);
-      expect(result.minY, 0);
-      expect(result.maxY, 0);
+      final (minX, maxX, minY, maxY) =
+          ScatterChartHelper.calculateMaxAxisValues(scatterSpots);
+      expect(minX, 0);
+      expect(maxX, 0);
+      expect(minY, 0);
+      expect(maxY, 0);
     });
 
     test('Test equality', () {
@@ -78,13 +56,5 @@ void main() {
           ScatterChartHelper.calculateMaxAxisValues(scatterSpotsClone);
       expect(result1, result2);
     });
-
-    test('Test equality 2', () {
-      final scatterSpots = [scatterSpot1, scatterSpot2, scatterSpot3];
-      final result1 = ScatterChartHelper.calculateMaxAxisValues(scatterSpots)
-          .copyWith(readFromCache: true);
-      final result2 = result1.copyWith(readFromCache: false);
-      expect(result1 != result2, true);
-    });
   });
 }
diff --git a/test/utils/list_wrapper_test.dart b/test/utils/list_wrapper_test.dart
deleted file mode 100644
index 9f61fd6bd..000000000
--- a/test/utils/list_wrapper_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-import 'package:fl_chart/src/utils/list_wrapper.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-void main() {
-  test('test ListWrapper equality check', () {
-    final wrapper1 = ['test1', 'test2'].toWrapperClass();
-    final wrapper2 = ['test1', 'test2'].toWrapperClass();
-    expect(wrapper1, wrapper2);
-  });
-
-  test('test ListWrapper equality check', () {
-    final wrapper1 = ['test1', 'test2'].toWrapperClass();
-    final wrapper2 = ['test1', 'test2'].toWrapperClass();
-    final myMap = <ListWrapper<String>, int>{};
-    myMap[wrapper1] = 11;
-    expect(myMap.containsKey(wrapper2), true);
-  });
-}