Graph with strait lines

This commit is contained in:
Andrew Golovashevich 2026-03-11 01:09:54 +03:00
parent 78de49cbc2
commit 1ae3e520c1

View File

@ -1,5 +1,6 @@
use eframe::egui::Key::Copy;
use eframe::egui::{Color32, Frame, Rect, StrokeKind, Ui}; use eframe::egui::{Color32, Frame, Rect, StrokeKind, Ui};
use eframe::epaint::{Pos2, Stroke, Vec2}; use eframe::epaint::{Mesh, Pos2, Stroke, Vec2};
use std::cmp::{max, min}; use std::cmp::{max, min};
pub(crate) fn draw_plot( pub(crate) fn draw_plot(
@ -11,43 +12,114 @@ pub(crate) fn draw_plot(
let canvas_rect = ui.allocate_space(ui.available_size()).1; let canvas_rect = ui.allocate_space(ui.available_size()).1;
let canvas = ui.painter(); let canvas = ui.painter();
let section_size = Vec2::new( let section_size = Vec2::new(
canvas_rect.size().x / (sections_count as f32), canvas_rect.size().x / (sections_count as f32 - 1.0),
canvas_rect.size().y, canvas_rect.size().y,
); );
for (i, time) in times.take(sections_count).enumerate() { let gradient_precision = 25;
match time {
None => { times
canvas.rect_filled( .take(sections_count)
Rect::from_min_size( .enumerate()
Pos2::new( .reduce(|prev, current| {
canvas_rect.max.x - section_size.x * (i as f32 + 1.0), let vertical_zoom = (canvas_rect.size().y / 1000.0);
canvas_rect.min.y,
), let start = (
section_size, Pos2::new(
), canvas_rect.max.x - section_size.x * (prev.0 as f32),
0, canvas_rect.max.y
Color32::from_rgb(0, 0, 0), - (min(1000, prev.1.unwrap_or(1000)) as f32) * vertical_zoom,
); ),
} time2color(prev.1),
Some(time) => { );
let end = (
Pos2::new(
canvas_rect.max.x - section_size.x * (current.0 as f32),
canvas_rect.max.y
- (min(1000, current.1.unwrap_or(1000)) as f32) * vertical_zoom,
),
time2color(current.1),
);
for j in 0..(gradient_precision) {
let gradient_precision = gradient_precision as f32;
let ratio1 = (j as f32) / gradient_precision;
let ratio2 = (j as f32 + 1.0) / gradient_precision;
canvas.line_segment( canvas.line_segment(
[ [
Pos2::new( gradient_pos(start.0, end.0, ratio1),
canvas_rect.max.x - section_size.x * (i as f32 + 1.0), gradient_pos(start.0, end.0, ratio2),
canvas_rect.max.y - min(section_size.y as u128, time / 50) as f32,
),
Pos2::new(
canvas_rect.max.x - section_size.x * (i as f32),
canvas_rect.max.y - min(section_size.y as u128, time / 50) as f32,
),
], ],
Stroke::new(3.0, Color32::from_rgb(0, 0, 255)), Stroke::new(1.0, gradient_color(start.1, end.1, ratio1)),
); );
} }
}
} return current;
});
}); });
} }
fn time2color(time: Option<u128>) -> Color32 {
match time {
None => return Color32::from_rgb(0, 0, 0),
Some(time) => match time {
0..20 => return Color32::from_rgb(0, 0, 255),
20..50 => {
return Color32::from_rgb(0, min((255 * (time as u64 - 20) / 30), 255) as u8, 255);
}
50..100 => {
return Color32::from_rgb(
0,
255,
255 - min((255 * (time as u64 - 50) / 50), 255) as u8,
);
}
100..200 => {
return Color32::from_rgb(
min((255 * (time as u64 - 100) / 100), 255) as u8,
255,
0,
);
}
200..1000 => {
return Color32::from_rgb(
255,
255 - min((255 * (time as u64 - 200) / 800), 255) as u8,
0,
);
}
1000..10_000 => {
return Color32::from_rgb(
255 - min((255 * (time as u64 - 1000) / 9000), 255) as u8,
0,
0,
);
}
_ => Color32::from_rgb(0, 0, 0),
},
}
}
fn gradient_f32(start: f32, end: f32, ratio: f32) -> f32 {
return start * (1.0 - ratio) + end * ratio;
}
fn gradient_u8(start: u8, end: u8, ratio: f32) -> u8 {
return (start as f32 * (1.0 - ratio) + end as f32 * ratio) as u8;
}
fn gradient_color(start: Color32, end: Color32, ratio: f32) -> Color32 {
return Color32::from_rgb(
gradient_u8(start.r(), end.r(), ratio),
gradient_u8(start.g(), end.g(), ratio),
gradient_u8(start.b(), end.b(), ratio),
);
}
fn gradient_pos(start: Pos2, end: Pos2, ratio: f32) -> Pos2 {
return Pos2::new(
gradient_f32(start.x, end.x, ratio),
gradient_f32(start.y, end.y, ratio),
);
}