146 lines
4.7 KiB
Dart
146 lines
4.7 KiB
Dart
|
import 'dart:math';
|
||
|
import 'dart:ui';
|
||
|
|
||
|
import 'package:flutter/material.dart';
|
||
|
|
||
|
class DrawSkyPlot {
|
||
|
double width = 500;
|
||
|
double height = 500;
|
||
|
late Canvas ctx;
|
||
|
Map legend = {};
|
||
|
final Paint _paint = Paint();
|
||
|
Path path = Path();
|
||
|
bool isPortrait = false;
|
||
|
final bool isDarkMode;
|
||
|
Color color = Colors.black;
|
||
|
DrawSkyPlot(op, this.isDarkMode) {
|
||
|
ctx = op['ctx']; // canvas dom 对象
|
||
|
height = op['height']; // 画布高
|
||
|
width = op['width']; // 画布宽
|
||
|
if (isDarkMode) {
|
||
|
color = Colors.white;
|
||
|
} else {
|
||
|
color = Colors.black;
|
||
|
}
|
||
|
_paint
|
||
|
..color = color
|
||
|
..strokeWidth = 3
|
||
|
..style = PaintingStyle.stroke;
|
||
|
MediaQueryData mediaQueryData =
|
||
|
MediaQueryData.fromView(WidgetsBinding.instance.window);
|
||
|
final orientation = mediaQueryData.orientation;
|
||
|
// 横屏竖屏宽高重新设置
|
||
|
if (orientation == Orientation.portrait) {
|
||
|
height = op['width'];
|
||
|
isPortrait = true;
|
||
|
} else {
|
||
|
width = op['height'];
|
||
|
isPortrait = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//外圈
|
||
|
drawSkyPlotCircle() {
|
||
|
double x = (width / 2) + 50;
|
||
|
double y = (height / 2) - 15;
|
||
|
double r = height / 2.5;
|
||
|
ctx.drawCircle(Offset(x, y), r, _paint);
|
||
|
ctx.drawCircle(Offset(x, y), r * 2 / 3, _paint);
|
||
|
ctx.drawCircle(Offset(x, y), r / 3, _paint);
|
||
|
path.moveTo(x - r, y);
|
||
|
path.lineTo(x + r, y);
|
||
|
path.moveTo(x, y - r);
|
||
|
path.lineTo(x, y + r);
|
||
|
path.moveTo(x + cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r);
|
||
|
path.lineTo(x - cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r);
|
||
|
path.moveTo(x + cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r);
|
||
|
path.lineTo(x - cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r);
|
||
|
path.moveTo(x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r);
|
||
|
path.lineTo(x - cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r);
|
||
|
path.moveTo(x - cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r);
|
||
|
path.lineTo(x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r);
|
||
|
path.moveTo(x + cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r);
|
||
|
path.lineTo(x - cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r);
|
||
|
path.moveTo(x - cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r);
|
||
|
path.lineTo(x + cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r);
|
||
|
ctx.drawPath(path, _paint);
|
||
|
|
||
|
Map textList = {
|
||
|
'0': Offset(x, y - r - 25),
|
||
|
'30': Offset(
|
||
|
x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r - 25),
|
||
|
'60': Offset(
|
||
|
x + cos(30 * (pi / 180)) * r + 10, y - sin(30 * (pi / 180)) * r - 10),
|
||
|
'90': Offset(x + r + 10, y - 5),
|
||
|
'120': Offset(
|
||
|
x + cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r + 5),
|
||
|
'150': Offset(
|
||
|
x + cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r + 5),
|
||
|
'180': Offset(x - 10, y + r),
|
||
|
'210': Offset(
|
||
|
x - cos(60 * (pi / 180)) * r - 20, y + sin(60 * (pi / 180)) * r + 10),
|
||
|
'240': Offset(
|
||
|
x - cos(30 * (pi / 180)) * r - 30, y + sin(30 * (pi / 180)) * r + 5),
|
||
|
'270': Offset(x - r - 35, y - 5),
|
||
|
'300': Offset(
|
||
|
x - cos(30 * (pi / 180)) * r - 37, y - sin(30 * (pi / 180)) * r - 20),
|
||
|
'330': Offset(
|
||
|
x - cos(60 * (pi / 180)) * r - 30, y - sin(60 * (pi / 180)) * r - 25)
|
||
|
};
|
||
|
textList.forEach((key, offset) {
|
||
|
TextPainter(
|
||
|
text: TextSpan(text: key, style: TextStyle(color: color, fontSize: 20)),
|
||
|
textDirection: TextDirection.ltr,
|
||
|
)
|
||
|
..layout()
|
||
|
..paint(ctx, offset);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
getCircles() {
|
||
|
// legend = {};
|
||
|
double radius = height / 2.5;
|
||
|
// double radius = height / 4;
|
||
|
double r = 15;
|
||
|
}
|
||
|
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
class DrawSky extends CustomPainter {
|
||
|
final BuildContext context;
|
||
|
final bool isDarkMode;
|
||
|
final List svData;
|
||
|
DrawSky(this.context, this.isDarkMode, this.svData);
|
||
|
@override
|
||
|
void paint(Canvas canvas, Size size) {
|
||
|
canvas.translate(0, -15);
|
||
|
final bool isPortrait =
|
||
|
MediaQuery.of(context).orientation == Orientation.portrait;
|
||
|
DrawSkyPlot skyPlot = DrawSkyPlot(
|
||
|
{'ctx': canvas, 'width': size.width, 'height': size.height},
|
||
|
isDarkMode);
|
||
|
if (!isPortrait) {
|
||
|
canvas.translate(-30, 0);
|
||
|
}
|
||
|
skyPlot.drawSkyPlotCircle();
|
||
|
// if (controller.chartData.value.time != 0) {
|
||
|
if (isPortrait) {
|
||
|
canvas.translate(size.width / 2, size.height / 2);
|
||
|
} else {
|
||
|
canvas.translate(size.width / 2, size.height / 2);
|
||
|
}
|
||
|
|
||
|
skyPlot.getCircles();
|
||
|
if (isPortrait) {
|
||
|
canvas.translate(-size.width / 2, -size.height / 2);
|
||
|
} else {
|
||
|
canvas.translate(-size.width / 2, -size.height / 2);
|
||
|
}
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
|
||
|
}
|