Skip to content

Instantly share code, notes, and snippets.

@BorisKest
Last active April 5, 2025 21:49
Show Gist options
  • Save BorisKest/6fa1da431ebb8579e2f6a22610be0d12 to your computer and use it in GitHub Desktop.
Save BorisKest/6fa1da431ebb8579e2f6a22610be0d12 to your computer and use it in GitHub Desktop.
Simple wind rose impl
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