Last active
April 5, 2025 21:49
-
-
Save BorisKest/6fa1da431ebb8579e2f6a22610be0d12 to your computer and use it in GitHub Desktop.
Simple wind rose impl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'dart:math'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: Scaffold( | |
appBar: AppBar(title: Text("Роза ветров")), | |
body: Center(child: WindRose()), | |
), | |
); | |
} | |
} | |
class WindRose extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return CustomPaint( | |
size: Size(300, 300), | |
painter: WindRosePainter(), | |
); | |
} | |
} | |
class WindRosePainter extends CustomPainter { | |
@override | |
void paint(Canvas canvas, Size size) { | |
final center = Offset(size.width / 2, size.height / 2); | |
final radius = min(size.width / 2, size.height / 2); | |
final paint = Paint() | |
..color = Colors.red | |
..strokeWidth = 2 | |
..style = PaintingStyle.stroke; | |
final textStyle = TextStyle(color: Colors.black, fontSize: 14); | |
// Число направлений (С, СВ, В и т.д.) | |
final numDirections = 8; | |
final angleStep = 2 * pi / numDirections; | |
final directions = ["С", "СВ", "В", "ЮВ", "Ю", "ЮЗ", "З", "СЗ"]; | |
// Пример случайных данных (вы можете вставить сюда свои данные) | |
final random = Random(); | |
final List<double> data = | |
List.generate(numDirections, (_) => random.nextDouble() * radius); | |
// Рисуем оси | |
for (int i = 0; i < numDirections; i++) { | |
final angle = i * angleStep; | |
final x = center.dx + radius * cos(angle); | |
final y = center.dy + radius * sin(angle); | |
// Ось | |
canvas.drawLine(center, Offset(x, y), paint..color = Colors.grey); | |
// Подписи направлений | |
final textOffset = Offset(x - 10, y - 10); | |
drawText(canvas, directions[i], textOffset, textStyle); | |
} | |
// Рисуем многоугольник розы ветров | |
final polygonPath = Path(); | |
for (int i = 0; i < numDirections; i++) { | |
final angle = i * angleStep; | |
final x = center.dx + data[i] * cos(angle); | |
final y = center.dy + data[i] * sin(angle); | |
if (i == 0) { | |
polygonPath.moveTo(x, y); | |
} else { | |
polygonPath.lineTo(x, y); | |
} | |
} | |
polygonPath.close(); | |
canvas.drawPath(polygonPath, paint..color = Colors.red); | |
// Рисуем круговые метки | |
drawCircles(canvas, center, radius, paint); | |
} | |
void drawText(Canvas canvas, String text, Offset position, TextStyle style) { | |
final textSpan = TextSpan(text: text, style: style); | |
final textPainter = TextPainter( | |
text: textSpan, | |
textDirection: TextDirection.ltr, | |
); | |
textPainter.layout(minWidth: 0, maxWidth: double.maxFinite); | |
textPainter.paint(canvas, position); | |
} | |
// Отрисовка круговых линий для меток | |
void drawCircles(Canvas canvas, Offset center, double radius, Paint paint) { | |
final numCircles = 4; | |
final step = radius / numCircles; | |
paint.color = Colors.grey; | |
paint.style = PaintingStyle.stroke; | |
for (int i = 1; i <= numCircles; i++) { | |
canvas.drawCircle(center, step * i, paint); | |
} | |
} | |
@override | |
bool shouldRepaint(CustomPainter oldDelegate) { | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment