Files
tuiche/lib/pages/sleep_report/chart/RadarChart.dart
2025-05-22 08:56:27 +08:00

110 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:math';
class RadarChart extends StatelessWidget {
final List<List<double>> data; // 存储多个数据集
final List<String> 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<List<double>> data;
final List<String> 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<Offset> 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;
}