plotlars_core/plots/
array2dplot.rs1use bon::bon;
2
3use crate::{
4 components::{Axis, Text},
5 ir::layout::LayoutIR,
6 ir::trace::{Array2dPlotIR, TraceIR},
7};
8
9#[allow(dead_code)]
57#[derive(Clone)]
58pub struct Array2dPlot {
59 traces: Vec<TraceIR>,
60 layout: LayoutIR,
61}
62
63#[bon]
64impl Array2dPlot {
65 #[builder(on(String, into), on(Text, into))]
66 pub fn new(
67 data: &[Vec<[u8; 3]>],
68 plot_title: Option<Text>,
69 x_title: Option<Text>,
70 y_title: Option<Text>,
71 x_axis: Option<&Axis>,
72 y_axis: Option<&Axis>,
73 ) -> Self {
74 let ir_trace = TraceIR::Array2dPlot(Array2dPlotIR {
75 data: data.to_vec(),
76 });
77 let traces = vec![ir_trace];
78
79 let layout = LayoutIR {
80 title: plot_title,
81 x_title,
82 y_title,
83 y2_title: None,
84 z_title: None,
85 legend_title: None,
86 legend: None,
87 dimensions: None,
88 bar_mode: None,
89 box_mode: None,
90 box_gap: None,
91 margin_bottom: None,
92 axes_2d: Some(crate::ir::layout::Axes2dIR {
93 x_axis: x_axis.cloned(),
94 y_axis: y_axis.cloned(),
95 y2_axis: None,
96 }),
97 scene_3d: None,
98 polar: None,
99 mapbox: None,
100 grid: None,
101 annotations: vec![],
102 };
103
104 Self { traces, layout }
105 }
106}
107
108#[bon]
109impl Array2dPlot {
110 #[builder(
111 start_fn = try_builder,
112 finish_fn = try_build,
113 builder_type = Array2dPlotTryBuilder,
114 on(String, into),
115 on(Text, into),
116 )]
117 pub fn try_new(
118 data: &[Vec<[u8; 3]>],
119 plot_title: Option<Text>,
120 x_title: Option<Text>,
121 y_title: Option<Text>,
122 x_axis: Option<&Axis>,
123 y_axis: Option<&Axis>,
124 ) -> Result<Self, crate::io::PlotlarsError> {
125 std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
126 Self::__orig_new(data, plot_title, x_title, y_title, x_axis, y_axis)
127 }))
128 .map_err(|panic| {
129 let msg = panic
130 .downcast_ref::<String>()
131 .cloned()
132 .or_else(|| panic.downcast_ref::<&str>().map(|s| s.to_string()))
133 .unwrap_or_else(|| "unknown error".to_string());
134 crate::io::PlotlarsError::PlotBuild { message: msg }
135 })
136 }
137}
138
139impl crate::Plot for Array2dPlot {
140 fn ir_traces(&self) -> &[TraceIR] {
141 &self.traces
142 }
143
144 fn ir_layout(&self) -> &LayoutIR {
145 &self.layout
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use crate::Plot;
153
154 fn pixel_data() -> Vec<Vec<[u8; 3]>> {
155 vec![
156 vec![[255, 0, 0], [0, 255, 0]],
157 vec![[0, 0, 255], [255, 255, 0]],
158 ]
159 }
160
161 #[test]
162 fn test_basic_one_trace() {
163 let data = pixel_data();
164 let plot = Array2dPlot::builder().data(&data).build();
165 assert_eq!(plot.ir_traces().len(), 1);
166 }
167
168 #[test]
169 fn test_trace_variant() {
170 let data = pixel_data();
171 let plot = Array2dPlot::builder().data(&data).build();
172 assert!(matches!(plot.ir_traces()[0], TraceIR::Array2dPlot(_)));
173 }
174
175 #[test]
176 fn test_layout_no_axes_by_default() {
177 let data = pixel_data();
178 let plot = Array2dPlot::builder().data(&data).build();
179 let axes = plot.ir_layout().axes_2d.as_ref().unwrap();
180 assert!(axes.x_axis.is_none());
181 assert!(axes.y_axis.is_none());
182 }
183}