dear_implot/plots/
stairs.rs1use super::{PlotData, PlotError, validate_data_lengths, with_plot_str_or_empty};
4use crate::StairsFlags;
5use crate::sys;
6
7pub struct StairsPlot<'a> {
9 label: &'a str,
10 x_data: &'a [f64],
11 y_data: &'a [f64],
12 flags: StairsFlags,
13 offset: i32,
14 stride: i32,
15}
16
17impl<'a> StairsPlot<'a> {
18 pub fn new(label: &'a str, x_data: &'a [f64], y_data: &'a [f64]) -> Self {
20 Self {
21 label,
22 x_data,
23 y_data,
24 flags: StairsFlags::NONE,
25 offset: 0,
26 stride: std::mem::size_of::<f64>() as i32,
27 }
28 }
29
30 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
32 self.flags = flags;
33 self
34 }
35
36 pub fn pre_step(mut self) -> Self {
38 self.flags |= StairsFlags::PRE_STEP;
39 self
40 }
41
42 pub fn shaded(mut self) -> Self {
44 self.flags |= StairsFlags::SHADED;
45 self
46 }
47
48 pub fn with_offset(mut self, offset: i32) -> Self {
50 self.offset = offset;
51 self
52 }
53
54 pub fn with_stride(mut self, stride: i32) -> Self {
56 self.stride = stride;
57 self
58 }
59
60 pub fn validate(&self) -> Result<(), PlotError> {
62 validate_data_lengths(self.x_data, self.y_data)
63 }
64
65 pub fn plot(self) {
67 let Ok(count) = i32::try_from(self.x_data.len()) else {
68 return;
69 };
70 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
71 sys::ImPlot_PlotStairs_doublePtrdoublePtr(
72 label_ptr,
73 self.x_data.as_ptr(),
74 self.y_data.as_ptr(),
75 count,
76 self.flags.bits() as i32,
77 self.offset,
78 self.stride,
79 );
80 })
81 }
82}
83
84impl<'a> PlotData for StairsPlot<'a> {
85 fn label(&self) -> &str {
86 self.label
87 }
88
89 fn data_len(&self) -> usize {
90 self.x_data.len().min(self.y_data.len())
91 }
92}
93
94pub struct StairsPlotF32<'a> {
96 label: &'a str,
97 x_data: &'a [f32],
98 y_data: &'a [f32],
99 flags: StairsFlags,
100}
101
102impl<'a> StairsPlotF32<'a> {
103 pub fn new(label: &'a str, x_data: &'a [f32], y_data: &'a [f32]) -> Self {
105 Self {
106 label,
107 x_data,
108 y_data,
109 flags: StairsFlags::NONE,
110 }
111 }
112
113 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
115 self.flags = flags;
116 self
117 }
118
119 pub fn pre_step(mut self) -> Self {
121 self.flags |= StairsFlags::PRE_STEP;
122 self
123 }
124
125 pub fn shaded(mut self) -> Self {
127 self.flags |= StairsFlags::SHADED;
128 self
129 }
130
131 pub fn validate(&self) -> Result<(), PlotError> {
133 if self.x_data.len() != self.y_data.len() {
134 return Err(PlotError::DataLengthMismatch {
135 x_len: self.x_data.len(),
136 y_len: self.y_data.len(),
137 });
138 }
139 if self.x_data.is_empty() {
140 return Err(PlotError::EmptyData);
141 }
142 Ok(())
143 }
144
145 pub fn plot(self) {
147 let Ok(count) = i32::try_from(self.x_data.len()) else {
148 return;
149 };
150 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
151 sys::ImPlot_PlotStairs_FloatPtrFloatPtr(
152 label_ptr,
153 self.x_data.as_ptr(),
154 self.y_data.as_ptr(),
155 count,
156 self.flags.bits() as i32,
157 0,
158 std::mem::size_of::<f32>() as i32,
159 );
160 })
161 }
162}
163
164impl<'a> PlotData for StairsPlotF32<'a> {
165 fn label(&self) -> &str {
166 self.label
167 }
168
169 fn data_len(&self) -> usize {
170 self.x_data.len().min(self.y_data.len())
171 }
172}
173
174pub struct SimpleStairsPlot<'a> {
176 label: &'a str,
177 y_data: &'a [f64],
178 flags: StairsFlags,
179 x_scale: f64,
180 x_start: f64,
181}
182
183impl<'a> SimpleStairsPlot<'a> {
184 pub fn new(label: &'a str, y_data: &'a [f64]) -> Self {
186 Self {
187 label,
188 y_data,
189 flags: StairsFlags::NONE,
190 x_scale: 1.0,
191 x_start: 0.0,
192 }
193 }
194
195 pub fn with_x_scale(mut self, x_scale: f64) -> Self {
197 self.x_scale = x_scale;
198 self
199 }
200
201 pub fn with_x_start(mut self, x_start: f64) -> Self {
203 self.x_start = x_start;
204 self
205 }
206
207 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
209 self.flags = flags;
210 self
211 }
212
213 pub fn pre_step(mut self) -> Self {
215 self.flags |= StairsFlags::PRE_STEP;
216 self
217 }
218
219 pub fn shaded(mut self) -> Self {
221 self.flags |= StairsFlags::SHADED;
222 self
223 }
224
225 pub fn validate(&self) -> Result<(), PlotError> {
227 if self.y_data.is_empty() {
228 return Err(PlotError::EmptyData);
229 }
230 Ok(())
231 }
232
233 pub fn plot(self) {
235 let Ok(count) = i32::try_from(self.y_data.len()) else {
236 return;
237 };
238 let x_data: Vec<f64> = (0..self.y_data.len())
240 .map(|i| self.x_start + i as f64 * self.x_scale)
241 .collect();
242
243 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
244 sys::ImPlot_PlotStairs_doublePtrdoublePtr(
245 label_ptr,
246 x_data.as_ptr(),
247 self.y_data.as_ptr(),
248 count,
249 self.flags.bits() as i32,
250 0,
251 std::mem::size_of::<f64>() as i32,
252 );
253 })
254 }
255}
256
257impl<'a> PlotData for SimpleStairsPlot<'a> {
258 fn label(&self) -> &str {
259 self.label
260 }
261
262 fn data_len(&self) -> usize {
263 self.y_data.len()
264 }
265}