Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save machinescream/15d8f6166c665d19c754b4adb626e95c to your computer and use it in GitHub Desktop.
Save machinescream/15d8f6166c665d19c754b4adb626e95c to your computer and use it in GitHub Desktop.
Graphica
import 'package:flutter/material.dart';
class GraphData {
final Color color;
final List<int> values;
GraphData({
required this.color,
required this.values,
});
}
class Graphica extends CustomPainter {
final List<GraphData> graphs;
final int indicatorsPadding;
final List<String>? dxIndicators;
final List<String>? dyIndicators;
final Color? dxIndicatorsColor;
final Color? dyIndicatorsColor;
final Color backgroundColor;
final Color dxLineColor;
final Color dyLineColor;
final double lineWidth;
final double graphsWidth;
final int xCap;
final int yCap;
final List<TextPainter> _dxTextPainters = [];
final List<TextPainter> _dyTextPainters = [];
Graphica({
this.backgroundColor = Colors.white,
this.dxLineColor = Colors.black,
this.dyLineColor = Colors.black,
this.lineWidth = 1.0,
required this.graphs,
this.indicatorsPadding = 8,
this.dxIndicators,
List<String>? dyIndicators,
this.dyIndicatorsColor,
this.dxIndicatorsColor,
this.graphsWidth = 2,
}) : xCap =
graphs.map((g) => g.values.length).reduce((a, b) => a > b ? a : b),
yCap = graphs
.map((g) => g.values.reduce((a, b) => a > b ? a : b))
.reduce((a, b) => a > b ? a : b),
dyIndicators = dyIndicators?.reversed.toList() {
_initTextPainters();
}
@override
void paint(Canvas canvas, Size size) {
final h = size.height;
final w = size.width;
_paintBackground(canvas, h, w);
final xCap =
graphs.map((g) => g.values.length).reduce((a, b) => a > b ? a : b);
final yCap = graphs
.map((g) => g.values.reduce((a, b) => a > b ? a : b))
.reduce((a, b) => a > b ? a : b);
final dxStep = w / (xCap - 1);
final dyStep = h / yCap;
if (dxIndicators != null) {
_paintXIndicators(canvas, dxStep, h);
}
if (dyIndicators != null) {
_paintYIndicators(canvas, dyStep);
}
_paintXLines(canvas, dxStep, h);
_paintYLines(canvas, dyStep, w, h);
for (final g in graphs) {
final values = g.values;
for (int index = 0; index < values.length - 1; index++) {
canvas.drawLine(
Offset(dxStep * index, h - (h / yCap * values[index])),
Offset(dxStep * (index + 1), h - (h / yCap * values[index + 1])),
Paint()
..color = g.color
..strokeWidth = graphsWidth,
);
}
}
}
void _initTextPainters() {
if (dxIndicators != null) {
for (final indicator in dxIndicators!) {
_dxTextPainters.add(
TextPainter(
text: TextSpan(
text: indicator, style: TextStyle(color: dxIndicatorsColor)),
textDirection: TextDirection.ltr,
)..layout(),
);
}
}
if (dyIndicators != null) {
for (final indicator in dyIndicators!) {
_dyTextPainters.add(
TextPainter(
text: TextSpan(
text: indicator, style: TextStyle(color: dyIndicatorsColor)),
textDirection: TextDirection.ltr,
)..layout(),
);
}
}
}
void _paintBackground(Canvas canvas, double h, double w) {
canvas.drawRect(
Rect.fromPoints(Offset.zero, Offset(w, h)),
Paint()
..style = PaintingStyle.fill
..color = backgroundColor,
);
}
void _paintXLines(Canvas canvas, double dxStep, double h) {
for (var x = 0; x < xCap; x++) {
canvas.drawLine(
Offset(dxStep * x, 0),
Offset(dxStep * x, h),
Paint()
..color = dxLineColor
..strokeWidth = lineWidth,
);
}
}
void _paintYLines(Canvas canvas, double dyStep, double w, double h) {
for (var y = 0; y < yCap; y++) {
canvas.drawLine(
Offset(0, h - dyStep * y),
Offset(w, h - dyStep * y),
Paint()
..color = dyLineColor
..strokeWidth = lineWidth,
);
}
}
void _paintXIndicators(Canvas canvas, double dxStep, double h) {
for (var x = 0; x < xCap; x++) {
_dxTextPainters[x].paint(
canvas,
Offset(x * dxStep, h + indicatorsPadding),
);
}
}
void _paintYIndicators(Canvas canvas, double dyStep) {
for (var y = 0; y < yCap + 1; y++) {
_dyTextPainters[y].paint(
canvas,
Offset(-_dyTextPainters[y].width - indicatorsPadding, y * dyStep),
);
}
}
@override
bool shouldRepaint(covariant Graphica oldDelegate) {
return oldDelegate.graphs != graphs ||
oldDelegate.dxIndicators != dxIndicators ||
oldDelegate.dyIndicators != dyIndicators ||
oldDelegate.dxIndicatorsColor != dxIndicatorsColor ||
oldDelegate.dyIndicatorsColor != dyIndicatorsColor ||
oldDelegate.backgroundColor != backgroundColor ||
oldDelegate.dxLineColor != dxLineColor ||
oldDelegate.dyLineColor != dyLineColor ||
oldDelegate.lineWidth != lineWidth ||
oldDelegate.graphsWidth != graphsWidth;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment