Skip to content

Commit

Permalink
Merge branch 'imaNNeo:main' into scaleable
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsocrat committed Sep 12, 2024
2 parents a42706e + 15c66cf commit 2db829e
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 32 deletions.
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
## 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
* **BUGFIX** Fix showing grid lines even when there is no line to show in the LineChart, #1691
## 0.69.0
* **BUGFIX** (by @imaNNeo) 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
* **BUGFIX** (by @imaNNeo) Fix showing grid lines even when there is no line to show in the LineChart, #1691
* **IMPROVEMENT** (by @sczesla) Allow users to control minIncluded and maxIncluded using SideTitles, #906
* **IMPROVEMENT** (by @elizabethzhenliu) Reverse the touch order in ScatterChart, so now the top spots are touched first, #1675
* **IMPROVEMENT** (by @ksw2000) Remove redundant math import, #1683
* **IMPROVEMENT** (by @Neer-Pathak) Fix linux example build issue, #1668
* **IMPROVEMENT** (by @TobiasRump) Update the bar chart documentation, #1662

## 0.68.0
* **Improvement** (by @imaNNeo) Update LineChartSample6 to implement a way to show a tooltip on a single spot, #1620
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Your financial support acts as fuel for fl_chart's development. [Support here](h
<td>
<a href="https://github.com/sponsors/imaNNeo">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/imaNNeo/fl_chart/raw/main/repo_files/sponsors/become_a_hero_dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/imaNNeo/fl_chart/raw/main/repo_files/sponsors/become_a_hero_light.png">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/imaNNeo/fl_chart/raw/main/repo_files/sponsors/become_a_sponsor_dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/imaNNeo/fl_chart/raw/main/repo_files/sponsors/become_a_sponsor_light.png">
<img alt="Become a sponsor" >
</picture>
</a>
Expand Down
2 changes: 1 addition & 1 deletion example/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(runner LANGUAGES CXX)

# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "FL Chart App")
set(BINARY_NAME "fLChartApp")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "dev.flchart.app")
Expand Down
6 changes: 3 additions & 3 deletions example/macos/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399

PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7

Expand Down
2 changes: 1 addition & 1 deletion example/macos/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Cocoa
import FlutterMacOS

@NSApplicationMain
@main
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
Expand Down
18 changes: 9 additions & 9 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
cupertino_icons: ^1.0.6
google_fonts: ^6.1.0
flutter_svg: ^2.0.7
universal_platform: ^1.0.0+1
cupertino_icons: ^1.0.8
google_fonts: ^6.2.1
flutter_svg: ^2.0.10+1
universal_platform: ^1.1.0
flutter_staggered_grid_view: ^0.7.0
url_launcher: ^6.1.14
go_router: ^11.1.2
url_launcher: ^6.3.0
go_router: ^14.2.7
dartx: ^1.2.0
fl_chart:
path: ../
flutter_bloc: ^8.1.3
package_info_plus: ^4.2.0
flutter_bloc: ^8.1.6
package_info_plus: ^8.0.2
equatable: ^2.0.5

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.3
flutter_lints: ^4.0.0

flutter:
uses-material-design: true
Expand Down
18 changes: 18 additions & 0 deletions lib/src/chart/base/axis_chart/axis_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ class SideTitles with EquatableMixin {
this.getTitlesWidget = defaultGetTitle,
this.reservedSize = 22,
this.interval,
this.minIncluded = true,
this.maxIncluded = true,
}) : assert(interval != 0, "SideTitles.interval couldn't be zero");

/// Determines showing or hiding this side titles
Expand All @@ -178,13 +180,23 @@ class SideTitles with EquatableMixin {
/// we try to find a suitable value to set as [interval] under the hood.
final double? interval;

/// If true (default), a title for the minimum data value is included
/// independent of the sampling interval
final bool minIncluded;

/// If true (default), a title for the maximum data value is included
/// independent of the sampling interval
final bool maxIncluded;

/// Lerps a [SideTitles] based on [t] value, check [Tween.lerp].
static SideTitles lerp(SideTitles a, SideTitles b, double t) {
return SideTitles(
showTitles: b.showTitles,
getTitlesWidget: b.getTitlesWidget,
reservedSize: lerpDouble(a.reservedSize, b.reservedSize, t)!,
interval: lerpDouble(a.interval, b.interval, t),
minIncluded: b.minIncluded,
maxIncluded: b.maxIncluded,
);
}

Expand All @@ -195,12 +207,16 @@ class SideTitles with EquatableMixin {
GetTitleWidgetFunction? getTitlesWidget,
double? reservedSize,
double? interval,
bool? minIncluded,
bool? maxIncluded,
}) {
return SideTitles(
showTitles: showTitles ?? this.showTitles,
getTitlesWidget: getTitlesWidget ?? this.getTitlesWidget,
reservedSize: reservedSize ?? this.reservedSize,
interval: interval ?? this.interval,
minIncluded: minIncluded ?? this.minIncluded,
maxIncluded: maxIncluded ?? this.maxIncluded,
);
}

Expand All @@ -211,6 +227,8 @@ class SideTitles with EquatableMixin {
getTitlesWidget,
reservedSize,
interval,
minIncluded,
maxIncluded,
];
}

Expand Down
3 changes: 3 additions & 0 deletions lib/src/chart/base/axis_chart/axis_chart_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class AxisChartHelper {
var axisSeek = initialValue;
final firstPositionOverlapsWithMin = axisSeek == min;
if (!minIncluded && firstPositionOverlapsWithMin) {
// If inital value is equal to data minimum,
// move first label one interval further
axisSeek += interval;
}
final diff = max - min;
Expand All @@ -43,6 +45,7 @@ class AxisChartHelper {

final epsilon = interval / 100000;
if (minIncluded && !firstPositionOverlapsWithMin) {
// Data minimum shall be included and is not yet covered
yield min;
}
while (axisSeek <= end + epsilon) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class SideTitlesWidget extends StatelessWidget {
final axisValues = AxisChartHelper().iterateThroughAxis(
min: axisMin,
max: axisMax,
minIncluded: sideTitles.minIncluded,
maxIncluded: sideTitles.maxIncluded,
baseLine: axisBaseLine,
interval: interval,
);
Expand Down
3 changes: 2 additions & 1 deletion lib/src/chart/scatter_chart/scatter_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData> {
) {
final data = holder.data;

for (var i = 0; i < data.scatterSpots.length; i++) {
for (var i = data.scatterSpots.length - 1; i >= 0; i--) {
// Reverse the loop to check the topmost spot first
final spot = data.scatterSpots[i];

final spotPixelX = getPixelX(spot.x, viewSize, holder);
Expand Down
19 changes: 9 additions & 10 deletions lib/src/utils/utils.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:math' as math;
import 'dart:math';

import 'package:flutter/material.dart';

Expand Down Expand Up @@ -45,9 +44,9 @@ class Utils {

Offset calculateRotationOffset(Size size, double degree) {
final rotatedHeight = (size.width * math.sin(radians(degree))).abs() +
(size.height * cos(radians(degree))).abs();
final rotatedWidth = (size.width * cos(radians(degree))).abs() +
(size.height * sin(radians(degree))).abs();
(size.height * math.cos(radians(degree))).abs();
final rotatedWidth = (size.width * math.cos(radians(degree))).abs() +
(size.height * math.sin(radians(degree))).abs();
return Offset(
(size.width - rotatedWidth) / 2,
(size.height - rotatedHeight) / 2,
Expand Down Expand Up @@ -178,26 +177,26 @@ class Utils {
precisionCount -= numbersToRemove;
}

final pow10onPrecision = pow(10, precisionCount);
final pow10onPrecision = math.pow(10, precisionCount);
input *= pow10onPrecision;
return _roundIntervalAboveOne(input) / pow10onPrecision;
}

double _roundIntervalAboveOne(double input) {
assert(input >= 1.0);
final decimalCount = input.toInt().toString().length - 1;
input /= pow(10, decimalCount);
input /= math.pow(10, decimalCount);

final scaled = input >= 10 ? input.round() / 10 : input;

if (scaled >= 7.6) {
return 10 * pow(10, decimalCount).toInt().toDouble();
return 10 * math.pow(10, decimalCount).toInt().toDouble();
} else if (scaled >= 2.6) {
return 5 * pow(10, decimalCount).toInt().toDouble();
return 5 * math.pow(10, decimalCount).toInt().toDouble();
} else if (scaled >= 1.6) {
return 2 * pow(10, decimalCount).toInt().toDouble();
return 2 * math.pow(10, decimalCount).toInt().toDouble();
} else {
return 1 * pow(10, decimalCount).toInt().toDouble();
return 1 * math.pow(10, decimalCount).toInt().toDouble();
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: fl_chart
description: A highly customizable Flutter chart library that supports Line Chart, Bar Chart, Pie Chart, Scatter Chart, and Radar Chart.
version: 0.68.0
version: 0.69.0
homepage: https://flchart.dev/
repository: https://github.com/imaNNeo/fl_chart
issue_tracker: https://github.com/imaNNeo/fl_chart/issues
Expand Down
2 changes: 1 addition & 1 deletion repo_files/documentations/bar_chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ When you change the chart's state, it animates to the new state internally (usin
|:---------------|:---------------|:-------|
|barGroups| list of [BarChartGroupData ](#BarChartGroupData) to show the bar lines together, you can provide one item per group to show normal bar chart|[]|
|groupsSpace| space between groups, it applies only when the [alignment](#BarChartAlignment) is `BarChartAlignment.start`, `BarChartAlignment.center` or `BarChartAlignment.end`|16|
|alignment| a [BarChartAlignment](#BarChartAlignment) that determines the alignment of the barGroups, inspired by [Flutter MainAxisAlignment](https://docs.flutter.io/flutter/rendering/MainAxisAlignment-class.html)| BarChartAlignment.spaceBetween|
|alignment| a [BarChartAlignment](#BarChartAlignment) that determines the alignment of the barGroups, inspired by [Flutter MainAxisAlignment](https://docs.flutter.io/flutter/rendering/MainAxisAlignment-class.html)| BarChartAlignment.spaceEvenly|
|titlesData| check the [FlTitlesData](base_chart.md#FlTitlesData)|FlTitlesData()|
|axisTitleData| check the [FlAxisTitleData](base_chart.md#FlAxisTitleData)| FlAxisTitleData()|
|rangeAnnotations| show range annotations behind the chart, check [RangeAnnotations](base_chart.md#RangeAnnotations) | RangeAnnotations()|
Expand Down
3 changes: 3 additions & 0 deletions repo_files/documentations/base_chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
|getTitlesWidget| A function to retrieve the title widget with given value on the related axis.|defaultGetTitle|
|reservedSize| It determines the maximum space that your titles need, |22|
|interval| Texts are showing with provided `interval`. If you don't provide anything, we try to find a suitable value to set as `interval` under the hood. | null |
|minIncluded| Determines whether to include title for minimum data value | true |
|maxIncluded| Determines whether to include title for maximum data value | true |


### SideTitleFitInsideData
|PropName |Description |default value|
Expand Down
Binary file added repo_files/sponsors/become_a_sponsor_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added repo_files/sponsors/become_a_sponsor_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions test/chart/base/axis_chart/side_titles/side_titles_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
final data = [
const FlSpot(0, 0.5),
const FlSpot(1, 1.3),
const FlSpot(2, 1.9),
];

const viewSize = Size(400, 400);

testWidgets(
'Test the effect of minIncluded and maxIncluded in sideTitles',
(WidgetTester tester) async {
// Minimum/maximum included
final mima = [
[true, true],
[true, false],
[false, true],
[false, false],
];

for (final e in mima) {
final titlesData = FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
minIncluded: e[0],
maxIncluded: e[1],
reservedSize: 50,
interval: 1,
),
),
rightTitles: const AxisTitles(),
topTitles: const AxisTitles(),
bottomTitles: const AxisTitles(),
);

await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: viewSize.width,
height: viewSize.height,
child: LineChart(
LineChartData(
titlesData: titlesData,
lineBarsData: [
LineChartBarData(
spots: data,
),
],
),
),
),
),
),
),
);
// Number of expected text widgets (titles) on the y-axis
expect(
find.byType(Text),
findsNWidgets((e[0] ? 1 : 0) + (e[1] ? 1 : 0) + 1),
);
// Always there
expect(find.text('1'), findsOneWidget);
if (e[0]) {
// Minimum included
expect(find.text('0.5'), findsOneWidget);
}
if (e[1]) {
// Maximum included
expect(find.text('1.9'), findsOneWidget);
}
}
},
);
}

0 comments on commit 2db829e

Please sign in to comment.