更新
This commit is contained in:
109
lib/pages/sleep_report/chart/RadarChart.dart
Normal file
109
lib/pages/sleep_report/chart/RadarChart.dart
Normal file
@@ -0,0 +1,109 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user