Skip to content

Commit

Permalink
Implemented auto calculate interval function, and used for titles, an…
Browse files Browse the repository at this point in the history
…d grid lines, it prevents performance issues, like imaNNeo#101, imaNNeo#322.
  • Loading branch information
imaNNeo authored and ezmegy committed Nov 16, 2020
1 parent 4b836c7 commit d01a8b5
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 32 deletions.
8 changes: 6 additions & 2 deletions lib/src/chart/bar_chart/bar_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ class BarChartPainter extends AxisChartPainter<BarChartData> with TouchHandler<B

// Left Titles
final leftTitles = targetData.titlesData.leftTitles;
final leftInterval =
leftTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (leftTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -309,12 +311,14 @@ class BarChartPainter extends AxisChartPainter<BarChartData> with TouchHandler<B
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += leftTitles.interval;
verticalSeek += leftInterval;
}
}

// Right Titles
final rightTitles = targetData.titlesData.rightTitles;
final rightInterval =
rightTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (rightTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -340,7 +344,7 @@ class BarChartPainter extends AxisChartPainter<BarChartData> with TouchHandler<B
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += rightTitles.interval;
verticalSeek += rightInterval;
}
}

Expand Down
21 changes: 14 additions & 7 deletions lib/src/chart/base/axis_chart/axis_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:fl_chart/src/chart/base/axis_chart/axis_chart_painter.dart';
import 'package:fl_chart/src/chart/base/base_chart/base_chart_data.dart';
import 'package:fl_chart/src/utils/lerp.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/src/utils/utils.dart';

/// This is the base class for axis base charts data
/// that contains a [FlGridData] that holds data for showing grid lines,
Expand All @@ -27,6 +28,12 @@ abstract class AxisChartData extends BaseChartData with EquatableMixin {
/// A background color which is drawn behind th chart.
Color backgroundColor;

/// Difference of [maxY] and [minY]
double get verticalDiff => maxY - minY;

/// Difference of [maxX] and [minX]
double get horizontalDiff => maxX - minX;

AxisChartData({
FlGridData gridData,
FlAxisTitleData axisTitleData,
Expand Down Expand Up @@ -243,8 +250,8 @@ class SideTitles with EquatableMixin {
/// [textStyle] determines the text style of them,
/// [margin] determines margin of texts from the border line,
///
/// by default, texts are showing with 1.0 interval,
/// you can change this value using [interval],
/// texts are showing with provided [interval],
/// or you can let it be null to be calculated using [getEfficientInterval],
///
/// you can change rotation of drawing titles using [rotateAngle].
SideTitles({
Expand All @@ -264,7 +271,7 @@ class SideTitles with EquatableMixin {
fontSize: 11,
),
margin = margin ?? 6,
interval = interval ?? 1.0,
interval = interval,
rotateAngle = rotateAngle ?? 0.0;

/// Lerps a [SideTitles] based on [t] value, check [Tween.lerp].
Expand Down Expand Up @@ -352,7 +359,7 @@ class FlGridData with EquatableMixin {
/// Determines showing or hiding all horizontal lines.
final bool drawHorizontalLine;

/// Determines interval between horizontal lines.
/// Determines interval between horizontal lines, left it null to be auto calculated.
final double horizontalInterval;

/// Gives you a y value, and gets a [FlLine] that represents specified line.
Expand All @@ -364,7 +371,7 @@ class FlGridData with EquatableMixin {
/// Determines showing or hiding all vertical lines.
final bool drawVerticalLine;

/// Determines interval between vertical lines.
/// Determines interval between vertical lines, left it null to be auto calculated.
final double verticalInterval;

/// Gives you a x value, and gets a [FlLine] that represents specified line.
Expand Down Expand Up @@ -407,11 +414,11 @@ class FlGridData with EquatableMixin {
CheckToShowGrid checkToShowVerticalLine,
}) : show = show ?? true,
drawHorizontalLine = drawHorizontalLine ?? true,
horizontalInterval = horizontalInterval ?? 1.0,
horizontalInterval = horizontalInterval,
getDrawingHorizontalLine = getDrawingHorizontalLine ?? defaultGridLine,
checkToShowHorizontalLine = checkToShowHorizontalLine ?? showAllGrids,
drawVerticalLine = drawVerticalLine ?? false,
verticalInterval = verticalInterval ?? 1.0,
verticalInterval = verticalInterval,
getDrawingVerticalLine = getDrawingVerticalLine ?? defaultGridLine,
checkToShowVerticalLine = checkToShowVerticalLine ?? showAllGrids;

Expand Down
23 changes: 13 additions & 10 deletions lib/src/chart/base/axis_chart/axis_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:fl_chart/src/chart/bar_chart/bar_chart_painter.dart';
import 'package:fl_chart/src/chart/base/base_chart/base_chart_painter.dart';
import 'package:fl_chart/src/chart/line_chart/line_chart_painter.dart';
import 'package:fl_chart/src/extensions/canvas_extension.dart';
import 'package:fl_chart/src/utils/utils.dart';
import 'package:flutter/material.dart';

import 'axis_chart_data.dart';
Expand Down Expand Up @@ -201,14 +202,15 @@ abstract class AxisChartPainter<D extends AxisChartData> extends BaseChartPainte
final Size usableViewSize = getChartUsableDrawSize(viewSize);
// Show Vertical Grid
if (data.gridData.drawVerticalLine) {
double verticalSeek = data.minX + data.gridData.verticalInterval;
final int verticalInterval = data.gridData.verticalInterval ??
getEfficientInterval(viewSize.width, data.horizontalDiff);
double verticalSeek = data.minX + verticalInterval;

final double delta = data.maxX - data.minX;
final int count = delta ~/ data.gridData.verticalInterval;
final int count = delta ~/ verticalInterval;
final double lastPosition = count * verticalSeek;
final bool lastPositionOverlapsWithBorder = lastPosition == data.maxX;
final end =
lastPositionOverlapsWithBorder ? data.maxX - data.gridData.verticalInterval : data.maxX;
final end = lastPositionOverlapsWithBorder ? data.maxX - verticalInterval : data.maxX;

while (verticalSeek <= end) {
if (data.gridData.checkToShowVerticalLine(verticalSeek)) {
Expand All @@ -223,21 +225,22 @@ abstract class AxisChartPainter<D extends AxisChartData> extends BaseChartPainte
final double y2 = usableViewSize.height + getTopOffsetDrawSize();
canvas.drawDashedLine(Offset(x1, y1), Offset(x2, y2), _gridPaint, flLineStyle.dashArray);
}
verticalSeek += data.gridData.verticalInterval;
verticalSeek += verticalInterval;
}
}

// Show Horizontal Grid
if (data.gridData.drawHorizontalLine) {
double horizontalSeek = data.minY + data.gridData.horizontalInterval;
final int horizontalInterval = data.gridData.horizontalInterval ??
getEfficientInterval(viewSize.height, data.verticalDiff);
double horizontalSeek = data.minY + horizontalInterval;

final double delta = data.maxY - data.minY;
final int count = delta ~/ data.gridData.horizontalInterval;
final int count = delta ~/ horizontalInterval;
final double lastPosition = count * horizontalSeek;
final bool lastPositionOverlapsWithBorder = lastPosition == data.maxY;

final end =
lastPositionOverlapsWithBorder ? data.maxY - data.gridData.horizontalInterval : data.maxY;
final end = lastPositionOverlapsWithBorder ? data.maxY - horizontalInterval : data.maxY;

while (horizontalSeek <= end) {
if (data.gridData.checkToShowHorizontalLine(horizontalSeek)) {
Expand All @@ -253,7 +256,7 @@ abstract class AxisChartPainter<D extends AxisChartData> extends BaseChartPainte
canvas.drawDashedLine(Offset(x1, y1), Offset(x2, y2), _gridPaint, flLine.dashArray);
}

horizontalSeek += data.gridData.horizontalInterval;
horizontalSeek += horizontalInterval;
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/src/chart/base/base_chart/base_chart_data.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:fl_chart/src/utils/utils.dart';
import 'package:flutter/material.dart';

import 'base_chart_painter.dart';
Expand Down Expand Up @@ -127,9 +128,9 @@ typedef GetTitleFunction = String Function(double value);

/// The default [SideTitles.getTitles] function.
///
/// It maps the axis number to a string and returns it.
/// formats the axis number to a shorter string using [formatNumber].
String defaultGetTitle(double value) {
return '$value';
return formatNumber(value);
}

/// This class holds the touch response details.
Expand Down
16 changes: 12 additions & 4 deletions lib/src/chart/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,8 @@ class LineChartPainter extends AxisChartPainter<LineChartData>

// Left Titles
final leftTitles = targetData.titlesData.leftTitles;
final leftInterval =
leftTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (leftTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -897,12 +899,14 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += leftTitles.interval;
verticalSeek += leftInterval;
}
}

// Top titles
final topTitles = targetData.titlesData.topTitles;
final topInterval =
topTitles.interval ?? getEfficientInterval(viewSize.width, data.horizontalDiff);
if (topTitles.showTitles) {
double horizontalSeek = data.minX;
while (horizontalSeek <= data.maxX) {
Expand All @@ -929,12 +933,14 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

horizontalSeek += topTitles.interval;
horizontalSeek += topInterval;
}
}

// Right Titles
final rightTitles = targetData.titlesData.rightTitles;
final rightInterval =
rightTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (rightTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -961,12 +967,14 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += rightTitles.interval;
verticalSeek += rightInterval;
}
}

// Bottom titles
final bottomTitles = targetData.titlesData.bottomTitles;
final bottomInterval =
bottomTitles.interval ?? getEfficientInterval(viewSize.width, data.horizontalDiff);
if (bottomTitles.showTitles) {
double horizontalSeek = data.minX;
while (horizontalSeek <= data.maxX) {
Expand All @@ -991,7 +999,7 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

horizontalSeek += bottomTitles.interval;
horizontalSeek += bottomInterval;
}
}
}
Expand Down
16 changes: 12 additions & 4 deletions lib/src/chart/scatter_chart/scatter_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData>

// Left Titles
final leftTitles = targetData.titlesData.leftTitles;
final leftInterval =
leftTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (leftTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -90,12 +92,14 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += leftTitles.interval;
verticalSeek += leftInterval;
}
}

// Top titles
final topTitles = targetData.titlesData.topTitles;
final topInterval =
topTitles.interval ?? getEfficientInterval(viewSize.width, data.horizontalDiff);
if (topTitles.showTitles) {
double horizontalSeek = data.minX;
while (horizontalSeek <= data.maxX) {
Expand All @@ -122,12 +126,14 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

horizontalSeek += topTitles.interval;
horizontalSeek += topInterval;
}
}

// Right Titles
final rightTitles = targetData.titlesData.rightTitles;
final rightInterval =
rightTitles.interval ?? getEfficientInterval(viewSize.height, data.verticalDiff);
if (rightTitles.showTitles) {
double verticalSeek = data.minY;
while (verticalSeek <= data.maxY) {
Expand All @@ -154,12 +160,14 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

verticalSeek += rightTitles.interval;
verticalSeek += rightInterval;
}
}

// Bottom titles
final bottomTitles = targetData.titlesData.bottomTitles;
final bottomInterval =
bottomTitles.interval ?? getEfficientInterval(viewSize.width, data.horizontalDiff);
if (bottomTitles.showTitles) {
double horizontalSeek = data.minX;
while (horizontalSeek <= data.maxX) {
Expand All @@ -186,7 +194,7 @@ class ScatterChartPainter extends AxisChartPainter<ScatterChartData>
tp.paint(canvas, Offset(x, y));
canvas.restore();

horizontalSeek += bottomTitles.interval;
horizontalSeek += bottomInterval;
}
}
}
Expand Down
Loading

0 comments on commit d01a8b5

Please sign in to comment.