use super::{Plot, PlotError, PlotItemStyle, plot_spec_with_style, with_plot_str_or_empty};
use crate::{InfLinesFlags, ItemFlags, sys};
pub struct InfLinesPlot<'a> {
label: &'a str,
positions: &'a [f64],
style: PlotItemStyle,
flags: InfLinesFlags,
item_flags: ItemFlags,
offset: i32,
stride: i32,
}
impl<'a> super::PlotItemStyled for InfLinesPlot<'a> {
fn style_mut(&mut self) -> &mut PlotItemStyle {
&mut self.style
}
}
impl<'a> InfLinesPlot<'a> {
pub fn new(label: &'a str, positions: &'a [f64]) -> Self {
Self {
label,
positions,
style: PlotItemStyle::default(),
flags: InfLinesFlags::NONE,
item_flags: ItemFlags::NONE,
offset: 0,
stride: std::mem::size_of::<f64>() as i32,
}
}
pub fn horizontal(mut self) -> Self {
self.flags |= InfLinesFlags::HORIZONTAL;
self
}
pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
self.item_flags = flags;
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> {
if self.positions.is_empty() {
return Err(PlotError::EmptyData);
}
Ok(())
}
}
impl<'a> Plot for InfLinesPlot<'a> {
fn plot(&self) {
if self.validate().is_err() {
return;
}
let Ok(count) = i32::try_from(self.positions.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_PlotInfLines_doublePtr(label_ptr, self.positions.as_ptr(), count, spec);
})
}
fn label(&self) -> &str {
self.label
}
}
impl<'ui> crate::PlotUi<'ui> {
pub fn inf_lines_vertical(&self, label: &str, xs: &[f64]) -> Result<(), PlotError> {
let plot = InfLinesPlot::new(label, xs);
plot.validate()?;
plot.plot();
Ok(())
}
pub fn inf_lines_horizontal(&self, label: &str, ys: &[f64]) -> Result<(), PlotError> {
let plot = InfLinesPlot::new(label, ys).horizontal();
plot.validate()?;
plot.plot();
Ok(())
}
}