Minor fixes and plot stub

This commit is contained in:
Andrew Golovashevich 2026-03-11 00:12:12 +03:00
parent 9084fc895a
commit 78de49cbc2
5 changed files with 75 additions and 22 deletions

View File

@ -15,7 +15,6 @@ pub struct SynchronizedServersStorage<A: Address + Hash + Eq> {
data: UnsafeCell<ServersStorage<A>>,
}
unsafe impl<A: Address + Hash + Eq> Sync for SynchronizedServersStorage<A> {}
impl<A: Address + Hash + Eq> SynchronizedServersStorage<A> {
@ -86,4 +85,8 @@ impl<A: Address + Hash + Eq> ServersGuiCtx for _Impl<'_, A> {
r_lock_scope,
);
}
fn graph_sections_count(&self) -> usize {
return unsafe { self.get_unprotected() }.graph_sections_count();
}
}

View File

@ -68,4 +68,8 @@ impl<A: Address + Hash + Eq> ServersGuiCtx for ServersStorage<A> {
.iter()
.map(|(k, v)| (k, v.0.as_str(), v.1.iter().map(|x| *x)));
}
fn graph_sections_count(&self) -> usize {
return self.history_capacity;
}
}

View File

@ -7,5 +7,9 @@ pub trait ServersStorage {
fn remove_server(&mut self, addr: &Self::Address);
// type TimeIterator: Iterator<Item = Option<u128>>;
fn iter_servers(&self) -> impl Iterator<Item = (&Self::Address, &str, impl Iterator<Item = Option<u128>>)>;
fn iter_servers(
&self,
) -> impl Iterator<Item = (&Self::Address, &str, impl Iterator<Item = Option<u128>>)>;
fn graph_sections_count(&self) -> usize;
}

View File

@ -55,21 +55,27 @@ impl<Ctx: ServersStorage> App for EguiApp<'_, Ctx> {
.striped(true) // Alternating row colors
.resizable(true)
.vscroll(true)
.columns(Column::remainder(), 3)
.column(Column::exact(self.ctx.graph_sections_count() as f32 * 20.0))
.column(Column::remainder())
.column(Column::remainder())
.header(20.0, |mut r| {
r.col(|ui| {
ui.label("Graph");
});
r.col(|ui| {
ui.label("Address");
});
r.col(|ui| {
ui.label("Memo");
});
r.col(|ui| {
ui.label("Graph");
});
})
.body(|mut t| {
for (addr, memo, pings) in self.ctx.iter_servers() {
t.row(20.0, |mut r| {
r.col(|ui| {
draw_plot(ui, self.ctx.graph_sections_count(), pings);
});
r.col(|ui| {
ui.horizontal(|ui| {
ui.add_enabled_ui(
@ -97,10 +103,6 @@ impl<Ctx: ServersStorage> App for EguiApp<'_, Ctx> {
);
});
});
r.col(|ui| {
draw_plot(ui, pings);
});
})
}
});
@ -158,5 +160,6 @@ impl<Ctx: ServersStorage> App for EguiApp<'_, Ctx> {
ModalWindows::Edit => {}
};
});
ctx.request_repaint()
}
}

View File

@ -1,14 +1,53 @@
use eframe::egui::{Color32, Rect, StrokeKind, Ui};
use eframe::epaint::{Pos2, Stroke};
use eframe::egui::{Color32, Frame, Rect, StrokeKind, Ui};
use eframe::epaint::{Pos2, Stroke, Vec2};
use std::cmp::{max, min};
pub(crate) fn draw_plot(ui: &mut Ui, time: impl Iterator<Item = Option<u128>>) {
let rect = ui.available_size();
let canvas = ui.painter();
canvas.rect(
Rect::from_min_size(Pos2::new(0.0, 0.0), rect),
0,
Color32::from_rgb(255, 255, 255),
Stroke::new(1.0, Color32::from_rgb(127, 127, 127)),
StrokeKind::Inside
);
pub(crate) fn draw_plot(
ui: &mut Ui,
sections_count: usize,
times: impl Iterator<Item = Option<u128>>,
) {
Frame::canvas(ui.style()).show(ui, |ui| {
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().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) => {
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,
),
],
Stroke::new(3.0, Color32::from_rgb(0, 0, 255)),
);
}
}
}
});
}