twine_plot/
lib.rs

1use eframe::egui;
2use egui_plot::{Legend, Line, Plot, PlotPoint};
3
4/// A runnable egui application for plotting data.
5#[derive(Default)]
6pub struct PlotApp {
7    series: Vec<Series>,
8}
9
10struct Series {
11    name: String,
12    points: Vec<PlotPoint>,
13}
14
15impl PlotApp {
16    #[must_use]
17    pub fn new() -> Self {
18        Self::default()
19    }
20
21    #[must_use]
22    pub fn add_series(mut self, name: &str, points: &[[f64; 2]]) -> Self {
23        self.series.push(Series {
24            name: name.to_string(),
25            points: points.iter().copied().map(Into::into).collect(),
26        });
27
28        self
29    }
30
31    #[allow(clippy::missing_errors_doc)]
32    pub fn run(self, name: &str) -> Result<(), eframe::Error> {
33        eframe::run_native(
34            name,
35            eframe::NativeOptions::default(),
36            Box::new(|_cc| Ok(Box::new(self))),
37        )
38    }
39}
40
41impl eframe::App for PlotApp {
42    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
43        egui::CentralPanel::default().show(ctx, |ui| {
44            Plot::new("plot-id")
45                .legend(Legend::default())
46                .show(ui, |plot_ui| {
47                    for series in &self.series {
48                        let points = series.points.as_slice();
49                        let name = &series.name;
50
51                        plot_ui.line(Line::new(points).name(name));
52                    }
53                });
54        });
55    }
56}