use super::{
PlotData, PlotError, PlotItemStyle, plot_spec_with_style, validate_data_lengths,
with_plot_str_or_empty,
};
use crate::{ItemFlags, StairsFlags, sys};
pub struct StairsPlot<'a> {
label: &'a str,
x_data: &'a [f64],
y_data: &'a [f64],
style: PlotItemStyle,
flags: StairsFlags,
item_flags: ItemFlags,
offset: i32,
stride: i32,
}
impl<'a> super::PlotItemStyled for StairsPlot<'a> {
fn style_mut(&mut self) -> &mut PlotItemStyle {
&mut self.style
}
}
impl<'a> StairsPlot<'a> {
pub fn new(label: &'a str, x_data: &'a [f64], y_data: &'a [f64]) -> Self {
Self {
label,
x_data,
y_data,
style: PlotItemStyle::default(),
flags: StairsFlags::NONE,
item_flags: ItemFlags::NONE,
offset: 0,
stride: std::mem::size_of::<f64>() as i32,
}
}
pub fn with_flags(mut self, flags: StairsFlags) -> Self {
self.flags = flags;
self
}
pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
self.item_flags = flags;
self
}
pub fn pre_step(mut self) -> Self {
self.flags |= StairsFlags::PRE_STEP;
self
}
pub fn shaded(mut self) -> Self {
self.flags |= StairsFlags::SHADED;
self
}
pub fn with_offset(mut self, offset: i32) -> Self {
self.offset = offset;
self
}
pub fn with_stride(mut self, stride: i32) -> Self {
self.stride = stride;
self
}
pub fn validate(&self) -> Result<(), PlotError> {
validate_data_lengths(self.x_data, self.y_data)
}
pub fn plot(self) {
let Ok(count) = i32::try_from(self.x_data.len()) else {
return;
};
with_plot_str_or_empty(self.label, |label_ptr| unsafe {
let spec = plot_spec_with_style(
self.style,
self.flags.bits() | self.item_flags.bits(),
self.offset,
self.stride,
);
sys::ImPlot_PlotStairs_doublePtrdoublePtr(
label_ptr,
self.x_data.as_ptr(),
self.y_data.as_ptr(),
count,
spec,
);
})
}
}
impl<'a> PlotData for StairsPlot<'a> {
fn label(&self) -> &str {
self.label
}
fn data_len(&self) -> usize {
self.x_data.len().min(self.y_data.len())
}
}
pub struct StairsPlotF32<'a> {
label: &'a str,
x_data: &'a [f32],
y_data: &'a [f32],
style: PlotItemStyle,
flags: StairsFlags,
item_flags: ItemFlags,
}
impl<'a> super::PlotItemStyled for StairsPlotF32<'a> {
fn style_mut(&mut self) -> &mut PlotItemStyle {
&mut self.style
}
}
impl<'a> StairsPlotF32<'a> {
pub fn new(label: &'a str, x_data: &'a [f32], y_data: &'a [f32]) -> Self {
Self {
label,
x_data,
y_data,
style: PlotItemStyle::default(),
flags: StairsFlags::NONE,
item_flags: ItemFlags::NONE,
}
}
pub fn with_flags(mut self, flags: StairsFlags) -> Self {
self.flags = flags;
self
}
pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
self.item_flags = flags;
self
}
pub fn pre_step(mut self) -> Self {
self.flags |= StairsFlags::PRE_STEP;
self
}
pub fn shaded(mut self) -> Self {
self.flags |= StairsFlags::SHADED;
self
}
pub fn validate(&self) -> Result<(), PlotError> {
if self.x_data.len() != self.y_data.len() {
return Err(PlotError::DataLengthMismatch {
x_len: self.x_data.len(),
y_len: self.y_data.len(),
});
}
if self.x_data.is_empty() {
return Err(PlotError::EmptyData);
}
Ok(())
}
pub fn plot(self) {
let Ok(count) = i32::try_from(self.x_data.len()) else {
return;
};
with_plot_str_or_empty(self.label, |label_ptr| unsafe {
let spec = plot_spec_with_style(
self.style,
self.flags.bits() | self.item_flags.bits(),
0,
std::mem::size_of::<f32>() as i32,
);
sys::ImPlot_PlotStairs_FloatPtrFloatPtr(
label_ptr,
self.x_data.as_ptr(),
self.y_data.as_ptr(),
count,
spec,
);
})
}
}
impl<'a> PlotData for StairsPlotF32<'a> {
fn label(&self) -> &str {
self.label
}
fn data_len(&self) -> usize {
self.x_data.len().min(self.y_data.len())
}
}
pub struct SimpleStairsPlot<'a> {
label: &'a str,
y_data: &'a [f64],
style: PlotItemStyle,
flags: StairsFlags,
item_flags: ItemFlags,
x_scale: f64,
x_start: f64,
}
impl<'a> super::PlotItemStyled for SimpleStairsPlot<'a> {
fn style_mut(&mut self) -> &mut PlotItemStyle {
&mut self.style
}
}
impl<'a> SimpleStairsPlot<'a> {
pub fn new(label: &'a str, y_data: &'a [f64]) -> Self {
Self {
label,
y_data,
style: PlotItemStyle::default(),
flags: StairsFlags::NONE,
item_flags: ItemFlags::NONE,
x_scale: 1.0,
x_start: 0.0,
}
}
pub fn with_x_scale(mut self, x_scale: f64) -> Self {
self.x_scale = x_scale;
self
}
pub fn with_x_start(mut self, x_start: f64) -> Self {
self.x_start = x_start;
self
}
pub fn with_flags(mut self, flags: StairsFlags) -> Self {
self.flags = flags;
self
}
pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
self.item_flags = flags;
self
}
pub fn pre_step(mut self) -> Self {
self.flags |= StairsFlags::PRE_STEP;
self
}
pub fn shaded(mut self) -> Self {
self.flags |= StairsFlags::SHADED;
self
}
pub fn validate(&self) -> Result<(), PlotError> {
if self.y_data.is_empty() {
return Err(PlotError::EmptyData);
}
Ok(())
}
pub fn plot(self) {
let Ok(count) = i32::try_from(self.y_data.len()) else {
return;
};
with_plot_str_or_empty(self.label, |label_ptr| unsafe {
let spec = plot_spec_with_style(
self.style,
self.flags.bits() | self.item_flags.bits(),
0,
std::mem::size_of::<f64>() as i32,
);
sys::ImPlot_PlotStairs_doublePtrInt(
label_ptr,
self.y_data.as_ptr(),
count,
self.x_scale,
self.x_start,
spec,
);
})
}
}
impl<'a> PlotData for SimpleStairsPlot<'a> {
fn label(&self) -> &str {
self.label
}
fn data_len(&self) -> usize {
self.y_data.len()
}
}