From 1ae3e520c1ee970e258727c76aae389a3a9f8dee Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Wed, 11 Mar 2026 01:09:54 +0300 Subject: [PATCH] Graph with strait lines --- gui/egui/src/plot.rs | 132 +++++++++++++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 30 deletions(-) diff --git a/gui/egui/src/plot.rs b/gui/egui/src/plot.rs index 94bbcae..af17b73 100644 --- a/gui/egui/src/plot.rs +++ b/gui/egui/src/plot.rs @@ -1,5 +1,6 @@ +use eframe::egui::Key::Copy; 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}; 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 = ui.painter(); - 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, ); - for (i, time) in times.take(sections_count).enumerate() { - match time { - None => { - canvas.rect_filled( - Rect::from_min_size( - Pos2::new( - canvas_rect.max.x - section_size.x * (i as f32 + 1.0), - canvas_rect.min.y, - ), - section_size, - ), - 0, - Color32::from_rgb(0, 0, 0), - ); - } - Some(time) => { + let gradient_precision = 25; + + times + .take(sections_count) + .enumerate() + .reduce(|prev, current| { + let vertical_zoom = (canvas_rect.size().y / 1000.0); + + let start = ( + Pos2::new( + canvas_rect.max.x - section_size.x * (prev.0 as f32), + canvas_rect.max.y + - (min(1000, prev.1.unwrap_or(1000)) as f32) * vertical_zoom, + ), + time2color(prev.1), + ); + 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( [ - Pos2::new( - canvas_rect.max.x - section_size.x * (i as f32 + 1.0), - 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, - ), + gradient_pos(start.0, end.0, ratio1), + gradient_pos(start.0, end.0, ratio2), ], - 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) -> 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), + ); +}