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