sophus_viewer/views/
plot_view.rs

1// ported from https://github.com/farm-ng/farm-ng-core/blob/main/rs/plotting/src/plotter_gui/mod.rs
2
3use linked_hash_map::LinkedHashMap;
4use sophus_renderer::HasAspectRatio;
5
6use crate::{
7    interactions::InteractionEnum,
8    packets::{
9        CurveTrait,
10        CurveVec,
11        CurveVecWithConf,
12        PlotViewPacket,
13        ScalarCurve,
14    },
15    prelude::*,
16    views::View,
17};
18
19pub(crate) struct PlotView {
20    pub(crate) enabled: bool,
21    pub(crate) interaction: InteractionEnum,
22    pub curves: BTreeMap<String, CurveStruct>,
23    pub(crate) aspect_ratio: f32,
24}
25
26/// a single curve is a collection of data points
27#[derive(Clone, Debug)]
28pub struct CurveStruct {
29    /// curve
30    pub curve: GraphType,
31    /// show graph
32    pub show_graph: bool,
33}
34
35/// Graph type
36#[derive(Clone, Debug)]
37pub enum GraphType {
38    /// Scalar curve
39    Scalar(ScalarCurve),
40    /// 2d vector curve
41    Vec2(CurveVec<2>),
42    /// 3d vector curve
43    Vec3(CurveVec<3>),
44    /// 2d vector curve with confidence intervals
45    Vec2Conf(CurveVecWithConf<2>),
46    /// 3d vector curve with confidence intervals
47    Vec3Conf(CurveVecWithConf<3>),
48}
49
50impl PlotView {
51    fn create_if_new(views: &mut LinkedHashMap<String, View>, packet: &PlotViewPacket) {
52        if !views.contains_key(&packet.name()) {
53            views.insert(
54                packet.name().clone(),
55                View::Plot(PlotView {
56                    enabled: true,
57                    interaction: InteractionEnum::No,
58                    curves: BTreeMap::new(),
59                    aspect_ratio: 1.0,
60                }),
61            );
62        }
63    }
64
65    pub fn update(views: &mut LinkedHashMap<String, View>, packet: PlotViewPacket) {
66        if let PlotViewPacket::Delete(plot_name) = &packet {
67            views.remove(plot_name);
68            return;
69        }
70        Self::create_if_new(views, &packet);
71
72        let view = views.get_mut(&packet.name()).unwrap();
73        let plot = match view {
74            View::Plot(view) => view,
75            _ => panic!("View type mismatch"),
76        };
77
78        match packet {
79            PlotViewPacket::Scalar(new_value) => {
80                let curve_name = new_value.graph_name.clone();
81
82                plot.curves
83                    .entry(curve_name.clone())
84                    .and_modify(|curve_struct| match &mut curve_struct.curve {
85                        GraphType::Scalar(g) => {
86                            g.append_to(
87                                new_value.scalar_curve.data.clone(),
88                                new_value.scalar_curve.style,
89                                new_value.scalar_curve.clear_cond,
90                                new_value.scalar_curve.v_line.clone(),
91                            );
92                        }
93                        GraphType::Vec3(_) => {}
94                        GraphType::Vec3Conf(_) => {}
95                        GraphType::Vec2(_) => {}
96                        GraphType::Vec2Conf(_) => {}
97                    })
98                    .or_insert(CurveStruct {
99                        curve: GraphType::Scalar(new_value.scalar_curve.clone()),
100                        show_graph: true,
101                    });
102            }
103            PlotViewPacket::Vec2(new_value) => {
104                let curve_name = new_value.curve_name.clone();
105
106                plot.curves
107                    .entry(curve_name.clone())
108                    .and_modify(|curve_struct| match &mut curve_struct.curve {
109                        GraphType::Scalar(_s) => {}
110                        GraphType::Vec2(g) => {
111                            g.append_to(
112                                new_value.scalar_curve.data.clone(),
113                                new_value.scalar_curve.style,
114                                new_value.scalar_curve.clear_cond,
115                                new_value.scalar_curve.v_line.clone(),
116                            );
117                        }
118                        GraphType::Vec3Conf(_) => {}
119                        GraphType::Vec3(_) => {}
120                        GraphType::Vec2Conf(_) => {}
121                    })
122                    .or_insert(CurveStruct {
123                        curve: GraphType::Vec2(new_value.scalar_curve.clone()),
124                        show_graph: true,
125                    });
126            }
127            PlotViewPacket::Vec3(new_value) => {
128                let curve_name = new_value.curve_name.clone();
129
130                plot.curves
131                    .entry(curve_name.clone())
132                    .and_modify(|curve_struct| match &mut curve_struct.curve {
133                        GraphType::Scalar(_s) => {}
134                        GraphType::Vec3(g) => {
135                            g.append_to(
136                                new_value.scalar_curve.data.clone(),
137                                new_value.scalar_curve.style,
138                                new_value.scalar_curve.clear_cond,
139                                new_value.scalar_curve.v_line.clone(),
140                            );
141                        }
142                        GraphType::Vec3Conf(_) => {}
143                        GraphType::Vec2(_) => {}
144                        GraphType::Vec2Conf(_) => {}
145                    })
146                    .or_insert(CurveStruct {
147                        curve: GraphType::Vec3(new_value.scalar_curve.clone()),
148                        show_graph: true,
149                    });
150            }
151            PlotViewPacket::Vec2Conf(new_value) => {
152                let curve_name = new_value.curve_name.clone();
153
154                plot.curves
155                    .entry(curve_name.clone())
156                    .and_modify(|curve_struct| match &mut curve_struct.curve {
157                        GraphType::Scalar(_s) => {}
158                        GraphType::Vec3(_) => {}
159                        GraphType::Vec2Conf(g) => {
160                            g.append_to(
161                                new_value.scalar_curve.data.clone(),
162                                new_value.scalar_curve.style,
163                                new_value.scalar_curve.clear_cond,
164                                new_value.scalar_curve.v_line.clone(),
165                            );
166                        }
167                        GraphType::Vec2(_) => {}
168                        GraphType::Vec3Conf(_) => {}
169                    })
170                    .or_insert(CurveStruct {
171                        curve: GraphType::Vec2Conf(new_value.scalar_curve.clone()),
172                        show_graph: true,
173                    });
174            }
175            PlotViewPacket::Vec3Conf(new_value) => {
176                let curve_name = new_value.curve_name.clone();
177
178                plot.curves
179                    .entry(curve_name.clone())
180                    .and_modify(|curve_struct| match &mut curve_struct.curve {
181                        GraphType::Scalar(_s) => {}
182                        GraphType::Vec3(_) => {}
183                        GraphType::Vec3Conf(g) => {
184                            g.append_to(
185                                new_value.scalar_curve.data.clone(),
186                                new_value.scalar_curve.style,
187                                new_value.scalar_curve.clear_cond,
188                                new_value.scalar_curve.v_line.clone(),
189                            );
190                        }
191                        GraphType::Vec2(_) => {}
192                        GraphType::Vec2Conf(_) => {}
193                    })
194                    .or_insert(CurveStruct {
195                        curve: GraphType::Vec3Conf(new_value.scalar_curve.clone()),
196                        show_graph: true,
197                    });
198            }
199            PlotViewPacket::Delete(_) => unreachable!(),
200        }
201    }
202}
203
204impl HasAspectRatio for PlotView {
205    fn aspect_ratio(&self) -> f32 {
206        self.aspect_ratio
207    }
208}