dear_implot/plots/
inf_lines.rs

1//! Infinite lines plot implementation
2
3use super::{Plot, PlotError, with_plot_str_or_empty};
4use crate::{InfLinesFlags, sys};
5
6/// Builder for infinite lines plots
7pub struct InfLinesPlot<'a> {
8    label: &'a str,
9    positions: &'a [f64],
10    flags: InfLinesFlags,
11    offset: i32,
12    stride: i32,
13}
14
15impl<'a> InfLinesPlot<'a> {
16    /// Create a new infinite lines plot with the given label and positions (vertical by default)
17    pub fn new(label: &'a str, positions: &'a [f64]) -> Self {
18        Self {
19            label,
20            positions,
21            flags: InfLinesFlags::NONE,
22            offset: 0,
23            stride: std::mem::size_of::<f64>() as i32,
24        }
25    }
26
27    /// Make lines horizontal instead of vertical
28    pub fn horizontal(mut self) -> Self {
29        self.flags |= InfLinesFlags::HORIZONTAL;
30        self
31    }
32
33    /// Set data offset for partial plotting
34    pub fn with_offset(mut self, offset: i32) -> Self {
35        self.offset = offset;
36        self
37    }
38
39    /// Set data stride for non-contiguous data
40    pub fn with_stride(mut self, stride: i32) -> Self {
41        self.stride = stride;
42        self
43    }
44
45    /// Validate the plot data
46    pub fn validate(&self) -> Result<(), PlotError> {
47        if self.positions.is_empty() {
48            return Err(PlotError::EmptyData);
49        }
50        Ok(())
51    }
52}
53
54impl<'a> Plot for InfLinesPlot<'a> {
55    fn plot(&self) {
56        if self.validate().is_err() {
57            return;
58        }
59        let Ok(count) = i32::try_from(self.positions.len()) else {
60            return;
61        };
62        with_plot_str_or_empty(self.label, |label_ptr| unsafe {
63            sys::ImPlot_PlotInfLines_doublePtr(
64                label_ptr,
65                self.positions.as_ptr(),
66                count,
67                self.flags.bits() as i32,
68                self.offset,
69                self.stride,
70            );
71        })
72    }
73
74    fn label(&self) -> &str {
75        self.label
76    }
77}
78
79/// Convenience functions for quick inf-lines plotting
80impl<'ui> crate::PlotUi<'ui> {
81    /// Plot vertical infinite lines at given x positions
82    pub fn inf_lines_vertical(&self, label: &str, xs: &[f64]) -> Result<(), PlotError> {
83        let plot = InfLinesPlot::new(label, xs);
84        plot.validate()?;
85        plot.plot();
86        Ok(())
87    }
88
89    /// Plot horizontal infinite lines at given y positions
90    pub fn inf_lines_horizontal(&self, label: &str, ys: &[f64]) -> Result<(), PlotError> {
91        let plot = InfLinesPlot::new(label, ys).horizontal();
92        plot.validate()?;
93        plot.plot();
94        Ok(())
95    }
96}