Skip to main content

dear_implot/plots/
inf_lines.rs

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