1use super::{
4 PlotData, PlotDataLayout, PlotDataOffset, PlotDataStride, PlotError, PlotItemStyle,
5 plot_spec_with_style, validate_data_lengths, with_plot_str_or_empty,
6};
7use crate::{ItemFlags, StairsFlags, sys};
8
9pub struct StairsPlot<'a> {
11 label: &'a str,
12 x_data: &'a [f64],
13 y_data: &'a [f64],
14 style: PlotItemStyle,
15 flags: StairsFlags,
16 item_flags: ItemFlags,
17 layout: PlotDataLayout,
18}
19
20impl<'a> super::PlotItemStyled for StairsPlot<'a> {
21 fn style_mut(&mut self) -> &mut PlotItemStyle {
22 &mut self.style
23 }
24}
25
26impl<'a> StairsPlot<'a> {
27 pub fn new(label: &'a str, x_data: &'a [f64], y_data: &'a [f64]) -> Self {
29 Self {
30 label,
31 x_data,
32 y_data,
33 style: PlotItemStyle::default(),
34 flags: StairsFlags::NONE,
35 item_flags: ItemFlags::NONE,
36 layout: PlotDataLayout::DEFAULT,
37 }
38 }
39
40 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
42 self.flags = flags;
43 self
44 }
45
46 pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
48 self.item_flags = flags;
49 self
50 }
51
52 pub fn pre_step(mut self) -> Self {
54 self.flags |= StairsFlags::PRE_STEP;
55 self
56 }
57
58 pub fn shaded(mut self) -> Self {
60 self.flags |= StairsFlags::SHADED;
61 self
62 }
63
64 pub fn with_data_layout(mut self, layout: PlotDataLayout) -> Self {
66 self.layout = layout;
67 self
68 }
69
70 pub fn with_offset(mut self, offset: PlotDataOffset) -> Self {
72 self.layout = self.layout.with_offset(offset);
73 self
74 }
75
76 pub fn with_stride(mut self, stride: PlotDataStride) -> Self {
78 self.layout = self.layout.with_stride(stride);
79 self
80 }
81
82 pub fn validate(&self) -> Result<(), PlotError> {
84 validate_data_lengths(self.x_data, self.y_data)
85 }
86
87 pub fn plot(self) {
89 let Ok(count) = i32::try_from(self.x_data.len()) else {
90 return;
91 };
92 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
93 let spec = plot_spec_with_style(
94 self.style,
95 self.flags.bits() | self.item_flags.bits(),
96 self.layout,
97 );
98 sys::ImPlot_PlotStairs_doublePtrdoublePtr(
99 label_ptr,
100 self.x_data.as_ptr(),
101 self.y_data.as_ptr(),
102 count,
103 spec,
104 );
105 })
106 }
107}
108
109impl<'a> PlotData for StairsPlot<'a> {
110 fn label(&self) -> &str {
111 self.label
112 }
113
114 fn data_len(&self) -> usize {
115 self.x_data.len().min(self.y_data.len())
116 }
117}
118
119pub struct StairsPlotF32<'a> {
121 label: &'a str,
122 x_data: &'a [f32],
123 y_data: &'a [f32],
124 style: PlotItemStyle,
125 flags: StairsFlags,
126 item_flags: ItemFlags,
127}
128
129impl<'a> super::PlotItemStyled for StairsPlotF32<'a> {
130 fn style_mut(&mut self) -> &mut PlotItemStyle {
131 &mut self.style
132 }
133}
134
135impl<'a> StairsPlotF32<'a> {
136 pub fn new(label: &'a str, x_data: &'a [f32], y_data: &'a [f32]) -> Self {
138 Self {
139 label,
140 x_data,
141 y_data,
142 style: PlotItemStyle::default(),
143 flags: StairsFlags::NONE,
144 item_flags: ItemFlags::NONE,
145 }
146 }
147
148 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
150 self.flags = flags;
151 self
152 }
153
154 pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
156 self.item_flags = flags;
157 self
158 }
159
160 pub fn pre_step(mut self) -> Self {
162 self.flags |= StairsFlags::PRE_STEP;
163 self
164 }
165
166 pub fn shaded(mut self) -> Self {
168 self.flags |= StairsFlags::SHADED;
169 self
170 }
171
172 pub fn validate(&self) -> Result<(), PlotError> {
174 if self.x_data.len() != self.y_data.len() {
175 return Err(PlotError::DataLengthMismatch {
176 x_len: self.x_data.len(),
177 y_len: self.y_data.len(),
178 });
179 }
180 if self.x_data.is_empty() {
181 return Err(PlotError::EmptyData);
182 }
183 Ok(())
184 }
185
186 pub fn plot(self) {
188 let Ok(count) = i32::try_from(self.x_data.len()) else {
189 return;
190 };
191 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
192 let spec = plot_spec_with_style(
193 self.style,
194 self.flags.bits() | self.item_flags.bits(),
195 PlotDataLayout::DEFAULT,
196 );
197 sys::ImPlot_PlotStairs_FloatPtrFloatPtr(
198 label_ptr,
199 self.x_data.as_ptr(),
200 self.y_data.as_ptr(),
201 count,
202 spec,
203 );
204 })
205 }
206}
207
208impl<'a> PlotData for StairsPlotF32<'a> {
209 fn label(&self) -> &str {
210 self.label
211 }
212
213 fn data_len(&self) -> usize {
214 self.x_data.len().min(self.y_data.len())
215 }
216}
217
218pub struct SimpleStairsPlot<'a> {
220 label: &'a str,
221 y_data: &'a [f64],
222 style: PlotItemStyle,
223 flags: StairsFlags,
224 item_flags: ItemFlags,
225 x_scale: f64,
226 x_start: f64,
227}
228
229impl<'a> super::PlotItemStyled for SimpleStairsPlot<'a> {
230 fn style_mut(&mut self) -> &mut PlotItemStyle {
231 &mut self.style
232 }
233}
234
235impl<'a> SimpleStairsPlot<'a> {
236 pub fn new(label: &'a str, y_data: &'a [f64]) -> Self {
238 Self {
239 label,
240 y_data,
241 style: PlotItemStyle::default(),
242 flags: StairsFlags::NONE,
243 item_flags: ItemFlags::NONE,
244 x_scale: 1.0,
245 x_start: 0.0,
246 }
247 }
248
249 pub fn with_x_scale(mut self, x_scale: f64) -> Self {
251 self.x_scale = x_scale;
252 self
253 }
254
255 pub fn with_x_start(mut self, x_start: f64) -> Self {
257 self.x_start = x_start;
258 self
259 }
260
261 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
263 self.flags = flags;
264 self
265 }
266
267 pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
269 self.item_flags = flags;
270 self
271 }
272
273 pub fn pre_step(mut self) -> Self {
275 self.flags |= StairsFlags::PRE_STEP;
276 self
277 }
278
279 pub fn shaded(mut self) -> Self {
281 self.flags |= StairsFlags::SHADED;
282 self
283 }
284
285 pub fn validate(&self) -> Result<(), PlotError> {
287 if self.y_data.is_empty() {
288 return Err(PlotError::EmptyData);
289 }
290 Ok(())
291 }
292
293 pub fn plot(self) {
295 let Ok(count) = i32::try_from(self.y_data.len()) else {
296 return;
297 };
298 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
299 let spec = plot_spec_with_style(
300 self.style,
301 self.flags.bits() | self.item_flags.bits(),
302 PlotDataLayout::DEFAULT,
303 );
304 sys::ImPlot_PlotStairs_doublePtrInt(
305 label_ptr,
306 self.y_data.as_ptr(),
307 count,
308 self.x_scale,
309 self.x_start,
310 spec,
311 );
312 })
313 }
314}
315
316impl<'a> PlotData for SimpleStairsPlot<'a> {
317 fn label(&self) -> &str {
318 self.label
319 }
320
321 fn data_len(&self) -> usize {
322 self.y_data.len()
323 }
324}