import 'package:flutter/material.dart'; import 'dart:ui' as ui; import 'dart:math'; class RadarChart extends StatelessWidget { final List> data; // 存储多个数据集 final List labels; // 每个角的标签 final double maxValue; // 数据的最大值,用来统一尺度 const RadarChart({ Key? key, required this.data, required this.labels, this.maxValue = 100, }) : super(key: key); @override Widget build(BuildContext context) { return CustomPaint( size: Size(300, 300), // 图表的大小 painter: RadarChartPainter( data: data, labels: labels, maxValue: maxValue, ), ); } } class RadarChartPainter extends CustomPainter { final List> data; final List labels; final double maxValue; RadarChartPainter({ required this.data, required this.labels, required this.maxValue, }); @override void paint(Canvas canvas, Size size) { Paint paintLine = Paint() ..color = Colors.blue ..style = PaintingStyle.stroke ..strokeWidth = 2; Paint axisPaint = Paint() ..color = Colors.grey.withOpacity(0.5) ..strokeWidth = 1; double centerX = size.width / 2; double centerY = size.height / 2; double radius = size.width / 2; int numOfPoints = labels.length; // 绘制雷达图的轴线 for (int i = 0; i < numOfPoints; i++) { double angle = (2 * pi / numOfPoints) * i; double x = centerX + radius * cos(angle); double y = centerY + radius * sin(angle); // 画轴线 canvas.drawLine(Offset(centerX, centerY), Offset(x, y), axisPaint); // 绘制标签 TextPainter tp = TextPainter( text: TextSpan( text: labels[i], style: TextStyle(color: Colors.black, fontSize: 12), ), textDirection: ui.TextDirection.ltr, ); tp.layout(); tp.paint(canvas, Offset(x + 8, y - 8)); // 设置标签位置 } // 绘制多个数据集 for (int i = 0; i < data.length; i++) { Paint fillPaint = Paint() ..color = Colors.primaries[i % Colors.primaries.length].withOpacity(0.3) ..style = PaintingStyle.fill; Paint linePaint = Paint() ..color = Colors.primaries[i % Colors.primaries.length] ..style = PaintingStyle.stroke ..strokeWidth = 2; List points = []; for (int j = 0; j < numOfPoints; j++) { double angle = (2 * pi / numOfPoints) * j; double pointRadius = (data[i][j] / maxValue) * radius; double x = centerX + pointRadius * cos(angle); double y = centerY + pointRadius * sin(angle); points.add(Offset(x, y)); } // 画出数据连接线 Path path = Path()..addPolygon(points, true); canvas.drawPath(path, linePaint); canvas.drawPath(path, fillPaint); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; }