Skip to content

Instantly share code, notes, and snippets.

@juskek
Last active August 18, 2021 11:10
Show Gist options
  • Save juskek/54536d3bd1234141b6978c3f4e8ac52f to your computer and use it in GitHub Desktop.
Save juskek/54536d3bd1234141b6978c3f4e8ac52f to your computer and use it in GitHub Desktop.
How the radar chart is drawn in CustomPainter.
void paint(ui.Canvas canvas, ui.Size size) {
final Offset centerPoint = Offset(0, 0);
// math for each branch
final angle = 360 / nodes;
// list of branch end points (x,y)
List<List<double>> points = [];
// for each branch
for (int i = 0; i < nodes; i++) {
final double lineLength = 200;
// paint styles
// branch
final lineStyle = Paint()
..strokeWidth = 3
..color = Colors.black;
// node
final nodeRadius = 5;
final nodeStyle = Paint()..color = Colors.black;
if (i == 0) {
// start at 12 o clock
points.add([0, -lineLength]);
} else {
// everything else
final currentAngle = i * angle * pi / 180;
final x = lineLength * sin(currentAngle); // x
final y = -lineLength * cos(currentAngle); // y
points.add([x, y]);
}
// draw branch
Offset endPoint = Offset(points[i][0], points[i][1]);
canvas.drawLine(centerPoint, endPoint, lineStyle);
// draw node
canvas.drawCircle(endPoint, nodeRadius, nodeStyle);
}
// draw segments
int totalSegments = segments * nodes;
int i = 0;
for (var j = 0; j < totalSegments; j++) {
if (j >= 0 && j < nodes) {
i++;
if (i >= nodes) {
i = 0;
}
continue; // skip nodes at center
}
// segment
final segRadius = 2.5;
final segStyle = Paint()..color = Colors.black;
var segNo = (j / nodes).floor() / segments;
Offset segPoint = Offset(points[i][0], points[i][1]) * segNo.toDouble();
canvas.drawCircle(segPoint, segRadius, segStyle);
i++;
if (i >= nodes) {
i = 0;
}
}
// draw poly
final polyStyle = Paint()
..strokeWidth = 2
..color = Colors.grey.withAlpha(100);
List<Offset> dataOffsets = [];
for (var i = 0; i < nodes; i++) {
var temp = Offset(points[i][0], points[i][1]) * data[i];
dataOffsets.add(temp);
}
Path polyPath = Path();
polyPath.addPolygon(dataOffsets, true);
canvas.drawPath(polyPath, polyStyle);
// draw labels
double fontHeight = 12.0;
TextStyle style = TextStyle(
color: Colors.grey.withAlpha((255).toInt()),
fontSize: fontHeight,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
fontFamily: 'Open Sans',
);
for (var i = 0; i < nodes; i++) {
final paraBuilder = ui.ParagraphBuilder(ui.ParagraphStyle(
fontSize: style.fontSize,
fontFamily: style.fontFamily,
fontStyle: style.fontStyle,
fontWeight: style.fontWeight,
textAlign: TextAlign.center,
))
..pushStyle(style.getTextStyle());
paraBuilder.addText(labels[i]);
final ui.Paragraph labelPara = paraBuilder.build()
..layout(ui.ParagraphConstraints(width: size.width));
var temp =
Offset(points[i][0] - fontHeight / 4, points[i][1] - fontHeight / 2) *
1.1;
canvas.drawParagraph(labelPara, temp);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment