Skip to main content

dear_imgui_rs/widget/
plot.rs

1//! Basic plots
2//!
3//! Simple line/histogram plot helpers built on top of Dear ImGui. For more
4//! advanced charts, consider using the optional implot bindings.
5//!
6#![allow(
7    clippy::cast_possible_truncation,
8    clippy::cast_sign_loss,
9    clippy::as_conversions
10)]
11use crate::internal::plot_value_count_i32;
12use crate::sys;
13use crate::ui::Ui;
14use std::borrow::Cow;
15
16/// # Plot Widgets
17impl Ui {
18    /// Creates a plot lines widget
19    #[doc(alias = "PlotLines")]
20    pub fn plot_lines(&self, label: impl AsRef<str>, values: &[f32]) {
21        self.plot_lines_config(label.as_ref(), values).build()
22    }
23
24    /// Creates a plot histogram widget
25    #[doc(alias = "PlotHistogram")]
26    pub fn plot_histogram(&self, label: impl AsRef<str>, values: &[f32]) {
27        self.plot_histogram_config(label.as_ref(), values).build()
28    }
29
30    /// Creates a plot lines builder
31    pub fn plot_lines_config<'ui, 'p>(
32        &'ui self,
33        label: impl Into<Cow<'ui, str>>,
34        values: &'p [f32],
35    ) -> PlotLines<'ui, 'p> {
36        PlotLines::new(self, label, values)
37    }
38
39    /// Creates a plot histogram builder
40    pub fn plot_histogram_config<'ui, 'p>(
41        &'ui self,
42        label: impl Into<Cow<'ui, str>>,
43        values: &'p [f32],
44    ) -> PlotHistogram<'ui, 'p> {
45        PlotHistogram::new(self, label, values)
46    }
47}
48
49/// Builder for a plot lines widget
50#[derive(Debug)]
51#[must_use]
52pub struct PlotLines<'ui, 'p> {
53    ui: &'ui Ui,
54    label: Cow<'ui, str>,
55    values: &'p [f32],
56    values_offset: i32,
57    overlay_text: Option<Cow<'ui, str>>,
58    scale_min: f32,
59    scale_max: f32,
60    graph_size: [f32; 2],
61}
62
63impl<'ui, 'p> PlotLines<'ui, 'p> {
64    /// Creates a new plot lines builder
65    pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, values: &'p [f32]) -> Self {
66        Self {
67            ui,
68            label: label.into(),
69            values,
70            values_offset: 0,
71            overlay_text: None,
72            scale_min: f32::MAX,
73            scale_max: f32::MAX,
74            graph_size: [0.0, 0.0],
75        }
76    }
77
78    /// Sets the offset for the values array
79    pub fn values_offset(mut self, offset: i32) -> Self {
80        self.values_offset = offset;
81        self
82    }
83
84    /// Sets the overlay text
85    pub fn overlay_text(mut self, text: impl Into<Cow<'ui, str>>) -> Self {
86        self.overlay_text = Some(text.into());
87        self
88    }
89
90    /// Sets the scale minimum value
91    pub fn scale_min(mut self, scale_min: f32) -> Self {
92        self.scale_min = scale_min;
93        self
94    }
95
96    /// Sets the scale maximum value
97    pub fn scale_max(mut self, scale_max: f32) -> Self {
98        self.scale_max = scale_max;
99        self
100    }
101
102    /// Sets the graph size
103    pub fn graph_size(mut self, size: [f32; 2]) -> Self {
104        self.graph_size = size;
105        self
106    }
107
108    /// Builds the plot lines widget
109    pub fn build(self) {
110        let count = plot_value_count_i32("PlotLines::build()", self.values.len());
111        assert!(
112            self.values_offset >= 0,
113            "PlotLines::build() values_offset must be non-negative"
114        );
115        assert!(
116            count == 0 || self.values_offset < count,
117            "PlotLines::build() values_offset must be less than values.len()"
118        );
119        let (label_ptr, overlay_ptr) = self
120            .ui
121            .scratch_txt_with_opt(self.label.as_ref(), self.overlay_text.as_deref());
122        let graph_size_vec: sys::ImVec2 = self.graph_size.into();
123
124        unsafe {
125            sys::igPlotLines_FloatPtr(
126                label_ptr,
127                self.values.as_ptr(),
128                count,
129                self.values_offset,
130                overlay_ptr,
131                self.scale_min,
132                self.scale_max,
133                graph_size_vec,
134                std::mem::size_of::<f32>() as i32,
135            );
136        }
137    }
138}
139
140/// Builder for a plot histogram widget
141#[derive(Debug)]
142#[must_use]
143pub struct PlotHistogram<'ui, 'p> {
144    ui: &'ui Ui,
145    label: Cow<'ui, str>,
146    values: &'p [f32],
147    values_offset: i32,
148    overlay_text: Option<Cow<'ui, str>>,
149    scale_min: f32,
150    scale_max: f32,
151    graph_size: [f32; 2],
152}
153
154impl<'ui, 'p> PlotHistogram<'ui, 'p> {
155    /// Creates a new plot histogram builder
156    pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, values: &'p [f32]) -> Self {
157        Self {
158            ui,
159            label: label.into(),
160            values,
161            values_offset: 0,
162            overlay_text: None,
163            scale_min: f32::MAX,
164            scale_max: f32::MAX,
165            graph_size: [0.0, 0.0],
166        }
167    }
168
169    /// Sets the offset for the values array
170    pub fn values_offset(mut self, offset: i32) -> Self {
171        self.values_offset = offset;
172        self
173    }
174
175    /// Sets the overlay text
176    pub fn overlay_text(mut self, text: impl Into<Cow<'ui, str>>) -> Self {
177        self.overlay_text = Some(text.into());
178        self
179    }
180
181    /// Sets the scale minimum value
182    pub fn scale_min(mut self, scale_min: f32) -> Self {
183        self.scale_min = scale_min;
184        self
185    }
186
187    /// Sets the scale maximum value
188    pub fn scale_max(mut self, scale_max: f32) -> Self {
189        self.scale_max = scale_max;
190        self
191    }
192
193    /// Sets the graph size
194    pub fn graph_size(mut self, size: [f32; 2]) -> Self {
195        self.graph_size = size;
196        self
197    }
198
199    /// Builds the plot histogram widget
200    pub fn build(self) {
201        let count = plot_value_count_i32("PlotHistogram::build()", self.values.len());
202        assert!(
203            self.values_offset >= 0,
204            "PlotHistogram::build() values_offset must be non-negative"
205        );
206        assert!(
207            count == 0 || self.values_offset < count,
208            "PlotHistogram::build() values_offset must be less than values.len()"
209        );
210        let (label_ptr, overlay_ptr) = self
211            .ui
212            .scratch_txt_with_opt(self.label.as_ref(), self.overlay_text.as_deref());
213        let graph_size_vec: sys::ImVec2 = self.graph_size.into();
214
215        unsafe {
216            sys::igPlotHistogram_FloatPtr(
217                label_ptr,
218                self.values.as_ptr(),
219                count,
220                self.values_offset,
221                overlay_ptr,
222                self.scale_min,
223                self.scale_max,
224                graph_size_vec,
225                std::mem::size_of::<f32>() as i32,
226            );
227        }
228    }
229}