dear_implot/plots/
stairs.rs1use super::{PlotData, PlotError, safe_cstring, validate_data_lengths};
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 label_cstring = safe_cstring(self.label);
68
69 unsafe {
70 sys::ImPlot_PlotStairs_doublePtrdoublePtr(
71 label_cstring.as_ptr(),
72 self.x_data.as_ptr(),
73 self.y_data.as_ptr(),
74 self.x_data.len() as i32,
75 self.flags.bits() as i32,
76 self.offset,
77 self.stride,
78 );
79 }
80 }
81}
82
83impl<'a> PlotData for StairsPlot<'a> {
84 fn label(&self) -> &str {
85 self.label
86 }
87
88 fn data_len(&self) -> usize {
89 self.x_data.len().min(self.y_data.len())
90 }
91}
92
93pub struct StairsPlotF32<'a> {
95 label: &'a str,
96 x_data: &'a [f32],
97 y_data: &'a [f32],
98 flags: StairsFlags,
99}
100
101impl<'a> StairsPlotF32<'a> {
102 pub fn new(label: &'a str, x_data: &'a [f32], y_data: &'a [f32]) -> Self {
104 Self {
105 label,
106 x_data,
107 y_data,
108 flags: StairsFlags::NONE,
109 }
110 }
111
112 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
114 self.flags = flags;
115 self
116 }
117
118 pub fn pre_step(mut self) -> Self {
120 self.flags |= StairsFlags::PRE_STEP;
121 self
122 }
123
124 pub fn shaded(mut self) -> Self {
126 self.flags |= StairsFlags::SHADED;
127 self
128 }
129
130 pub fn validate(&self) -> Result<(), PlotError> {
132 if self.x_data.len() != self.y_data.len() {
133 return Err(PlotError::DataLengthMismatch {
134 x_len: self.x_data.len(),
135 y_len: self.y_data.len(),
136 });
137 }
138 if self.x_data.is_empty() {
139 return Err(PlotError::EmptyData);
140 }
141 Ok(())
142 }
143
144 pub fn plot(self) {
146 let label_cstring = safe_cstring(self.label);
147
148 unsafe {
149 sys::ImPlot_PlotStairs_FloatPtrFloatPtr(
150 label_cstring.as_ptr(),
151 self.x_data.as_ptr(),
152 self.y_data.as_ptr(),
153 self.x_data.len() as i32,
154 self.flags.bits() as i32,
155 0,
156 std::mem::size_of::<f32>() as i32,
157 );
158 }
159 }
160}
161
162impl<'a> PlotData for StairsPlotF32<'a> {
163 fn label(&self) -> &str {
164 self.label
165 }
166
167 fn data_len(&self) -> usize {
168 self.x_data.len().min(self.y_data.len())
169 }
170}
171
172pub struct SimpleStairsPlot<'a> {
174 label: &'a str,
175 y_data: &'a [f64],
176 flags: StairsFlags,
177 x_scale: f64,
178 x_start: f64,
179}
180
181impl<'a> SimpleStairsPlot<'a> {
182 pub fn new(label: &'a str, y_data: &'a [f64]) -> Self {
184 Self {
185 label,
186 y_data,
187 flags: StairsFlags::NONE,
188 x_scale: 1.0,
189 x_start: 0.0,
190 }
191 }
192
193 pub fn with_x_scale(mut self, x_scale: f64) -> Self {
195 self.x_scale = x_scale;
196 self
197 }
198
199 pub fn with_x_start(mut self, x_start: f64) -> Self {
201 self.x_start = x_start;
202 self
203 }
204
205 pub fn with_flags(mut self, flags: StairsFlags) -> Self {
207 self.flags = flags;
208 self
209 }
210
211 pub fn pre_step(mut self) -> Self {
213 self.flags |= StairsFlags::PRE_STEP;
214 self
215 }
216
217 pub fn shaded(mut self) -> Self {
219 self.flags |= StairsFlags::SHADED;
220 self
221 }
222
223 pub fn validate(&self) -> Result<(), PlotError> {
225 if self.y_data.is_empty() {
226 return Err(PlotError::EmptyData);
227 }
228 Ok(())
229 }
230
231 pub fn plot(self) {
233 let x_data: Vec<f64> = (0..self.y_data.len())
235 .map(|i| self.x_start + i as f64 * self.x_scale)
236 .collect();
237
238 let label_cstring = safe_cstring(self.label);
239
240 unsafe {
241 sys::ImPlot_PlotStairs_doublePtrdoublePtr(
242 label_cstring.as_ptr(),
243 x_data.as_ptr(),
244 self.y_data.as_ptr(),
245 self.y_data.len() as i32,
246 self.flags.bits() as i32,
247 0,
248 std::mem::size_of::<f64>() as i32,
249 );
250 }
251 }
252}
253
254impl<'a> PlotData for SimpleStairsPlot<'a> {
255 fn label(&self) -> &str {
256 self.label
257 }
258
259 fn data_len(&self) -> usize {
260 self.y_data.len()
261 }
262}