You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/packages/edited_pie_chart/lib/src/chart_painter.dart

155 lines
5.2 KiB
Dart

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:pie_chart/pie_chart.dart';
class PieChartPainter extends CustomPainter {
List<Paint> _paintList = [];
List<double> _subParts;
List<String> _subTitles;
double _total = 0;
double _totalAngle = math.pi * 2;
final TextStyle chartValueStyle;
final Color chartValueBackgroundColor;
final double initialAngle;
final bool showValuesInPercentage;
final bool showChartValues;
final bool showChartValuesOutside;
final int decimalPlaces;
final bool showChartValueLabel;
final ChartType chartType;
final Function formatChartValues;
final double strokeWidth;
final bool selected;
final List<Color> colorList;
double _prevAngle = 0;
final TextStyle sideTextStyle;
PieChartPainter(
double angleFactor,
this.showChartValues,
this.showChartValuesOutside,
this.colorList, {
this.chartValueStyle,
this.chartValueBackgroundColor,
List<double> values,
List<String> titles,
this.initialAngle,
this.showValuesInPercentage,
this.decimalPlaces,
this.showChartValueLabel,
this.chartType,
this.formatChartValues,
this.strokeWidth,
this.selected = false,
this.sideTextStyle,
}) {
for (int i = 0; i < values.length; i++) {
final paint = Paint()..color = getColor(colorList, i);
if (chartType == ChartType.ring) {
paint.style = PaintingStyle.stroke;
paint.strokeWidth = strokeWidth;
}
_paintList.add(paint);
}
_totalAngle = angleFactor * math.pi * 2;
_subParts = values;
_subTitles = titles;
_total = values.fold(0, (v1, v2) => v1 + v2);
}
@override
void paint(Canvas canvas, Size size) {
final side = size.width < size.height ? size.width : size.height;
2 years ago
_prevAngle = initialAngle * math.pi / 180;
for (int i = 0; i < _subParts.length; i++) {
canvas.drawArc(
2 years ago
Rect.fromLTWH(0.0, 0.0, side, size.height),
_prevAngle,
(((_totalAngle) / _total) * _subParts[i]),
chartType == ChartType.disc ? true : false,
_paintList[i],
);
final radius = showChartValuesOutside ? (side / 2) + 16 : side / 3;
final x = (radius) * math.cos(_prevAngle + ((((_totalAngle) / _total) * _subParts[i]) / 2));
final y = (radius) * math.sin(_prevAngle + ((((_totalAngle) / _total) * _subParts[i]) / 2));
if (_subParts.elementAt(i).toInt() != 0) {
final value = formatChartValues != null ? formatChartValues(_subParts.elementAt(i)) : _subParts.elementAt(i).toStringAsFixed(this.decimalPlaces);
// final name = showValuesInPercentage
// ? (((_subParts.elementAt(i) / _total) * 100)
// .toStringAsFixed(this.decimalPlaces) +
// '%')
// : value;
// final name = showValuesInPercentage ? (((_subParts.elementAt(i) / _total) * 100).toStringAsFixed(this.decimalPlaces) + '%') : _subTitles.elementAt(i);
if (showChartValues) {
2 years ago
final name = "${_subTitles[i]} " + (showValuesInPercentage ? (((_subParts.elementAt(i) / _total) * 100).toStringAsFixed(this.decimalPlaces) + '%') : value);
var yLabel = y > 0 ? y + 40 : y - 20;
var xLabel = (y > 0 ? x - y : x * 1.6) - 20;
var yPopup = y;
if (_subParts[i] <= (_total / _subParts.length)) {
yLabel = y;
xLabel *= 1.1;
yPopup *= 1.25;
}
if (selected) _drawLabel(canvas, name, x, yPopup, side, true, statusColor: getColor(colorList, i));
_drawLabel(canvas, _subTitles[i], xLabel, yLabel, side + 8, false);
}
}
_prevAngle = _prevAngle + (((_totalAngle) / _total) * _subParts[i]);
}
}
void _drawLabel(Canvas canvas, String name, double x, double y, double side, bool withBackground, {Color statusColor = Colors.white}) {
TextSpan span = TextSpan(
style: withBackground ? chartValueStyle : sideTextStyle,
text: name,
);
TextPainter tp = TextPainter(
text: span,
textAlign: TextAlign.center,
textDirection: TextDirection.ltr,
);
tp.layout();
if (withBackground && showChartValueLabel) {
//Draw text background box
final rect = Rect.fromCenter(
center: Offset((side / 2 + (x + 16)), (side / 2 + y)),
width: tp.width + 45,
height: tp.height + 16,
);
final rect2 = Rect.fromCenter(
2 years ago
center: Offset(
(side / 2 + x) - ((tp.width - 16) / 2),
(side / 2 + y) - ((tp.height - 16) / 2),
),
width: 12,
height: 12,
);
2 years ago
final rRect = RRect.fromRectAndRadius(rect, const Radius.circular(8));
final rRect2 = RRect.fromRectAndRadius(rect2, const Radius.circular(1));
final paint = Paint()
..color = chartValueBackgroundColor ?? Colors.grey[200]
..style = PaintingStyle.fill;
canvas.drawRRect(rRect, paint);
canvas.drawRRect(rRect2, paint..color = statusColor);
}
//Finally paint the text above box
tp.paint(
canvas,
2 years ago
Offset(
(side / 2 + x) - ((tp.width - 50) / 2),
(side / 2 + y) - ((tp.height) / 2),
),
);
}
@override
2 years ago
bool shouldRepaint(PieChartPainter oldDelegate) => selected != oldDelegate.selected;
}