Working on better plotting

This commit is contained in:
Martino Ferrari
2026-04-12 16:20:44 +02:00
parent 1a39b3a54e
commit 41410e4e3d
10 changed files with 2088 additions and 1064 deletions
+83 -39
View File
@@ -1,6 +1,7 @@
use rmon_common::signal::{SignalId, SignalInfo, Sample};
use std::collections::{HashMap, VecDeque};
use std::sync::{Arc, Mutex};
use eframe::egui::ecolor::Color32;
pub struct SignalHistory {
pub info: SignalInfo,
@@ -13,7 +14,7 @@ impl SignalHistory {
Self {
info,
samples: VecDeque::new(),
max_samples: 1000, // Default for display
max_samples: 10000,
}
}
@@ -25,52 +26,95 @@ impl SignalHistory {
}
}
pub struct SessionState {
pub connected: bool,
pub signals: HashMap<SignalId, Arc<Mutex<SignalHistory>>>,
#[derive(Clone)]
pub struct SignalStyle {
pub color: Color32,
pub line_width: f32,
}
impl SessionState {
pub fn new() -> Self {
impl Default for SignalStyle {
fn default() -> Self {
Self {
connected: false,
signals: HashMap::new(),
color: Color32::WHITE,
line_width: 1.5,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use rmon_common::signal::SourceType;
#[derive(Clone, Default)]
pub struct PlotCursor {
pub x: f64,
pub active: bool,
}
#[test]
fn test_signal_history_push() {
let info = SignalInfo {
id: "test://1".to_string(),
label: "L".to_string(),
unit: "U".to_string(),
scale: 1.0,
offset: 0.0,
sampling_period: None,
source_type: SourceType::Csv,
path: vec![],
};
let mut history = SignalHistory::new(info);
history.max_samples = 2;
history.push(Sample { timestamp: 1, value: 1.0 });
history.push(Sample { timestamp: 2, value: 2.0 });
history.push(Sample { timestamp: 3, value: 3.0 });
assert_eq!(history.samples.len(), 2);
assert_eq!(history.samples[0].timestamp, 2);
}
#[derive(Clone)]
pub struct PlotDefinition {
pub id: String,
pub title: String,
pub signal_ids: Vec<SignalId>,
pub cursors: [PlotCursor; 2],
pub show_legend: bool,
pub follow_mode: bool,
pub time_window: f64, // seconds
}
#[test]
fn test_session_state_init() {
let state = SessionState::new();
assert!(!state.connected);
assert!(state.signals.is_empty());
impl PlotDefinition {
pub fn new(title: String) -> Self {
Self {
id: uuid::Uuid::new_v4().to_string(),
title,
signal_ids: Vec::new(),
cursors: [PlotCursor::default(), PlotCursor::default()],
show_legend: true,
follow_mode: true,
time_window: 600.0, // Default to 10 minutes
}
}
}
pub struct SessionState {
pub connected: bool,
pub signals: HashMap<SignalId, Arc<Mutex<SignalHistory>>>,
pub tree: egui_tiles::Tree<PlotDefinition>,
pub signal_styles: HashMap<SignalId, SignalStyle>,
}
impl SessionState {
pub fn new() -> Self {
let mut tiles = egui_tiles::Tiles::default();
let root = tiles.insert_pane(PlotDefinition::new("Main Plot".to_string()));
let tree = egui_tiles::Tree::new("main_tree", root, tiles);
Self {
connected: false,
signals: HashMap::new(),
tree,
signal_styles: HashMap::new(),
}
}
pub fn get_style(&mut self, id: &SignalId) -> SignalStyle {
if let Some(style) = self.signal_styles.get(id) {
return style.clone();
}
let colors = [
Color32::from_rgb(255, 80, 80),
Color32::from_rgb(80, 255, 80),
Color32::from_rgb(80, 80, 255),
Color32::from_rgb(255, 255, 80),
Color32::from_rgb(255, 80, 255),
Color32::from_rgb(80, 255, 255),
Color32::from_rgb(255, 150, 50),
Color32::from_rgb(150, 80, 255),
];
let mut hash = 0u64;
for b in id.as_bytes() { hash = hash.wrapping_add(*b as u64); }
let color = colors[(hash % colors.len() as u64) as usize];
let style = SignalStyle { color, line_width: 1.5 };
self.signal_styles.insert(id.clone(), style.clone());
style
}
}