dear_implot/plots/
polygon.rs1use super::{
4 Plot, PlotDataLayout, PlotDataOffset, PlotDataStride, PlotError, PlotItemStyle,
5 plot_spec_with_style, validate_data_lengths, with_plot_str_or_empty,
6};
7use crate::{ItemFlags, PolygonFlags, sys};
8
9pub struct PolygonPlot<'a> {
11 label: &'a str,
12 x_data: &'a [f64],
13 y_data: &'a [f64],
14 style: PlotItemStyle,
15 flags: PolygonFlags,
16 item_flags: ItemFlags,
17 layout: PlotDataLayout,
18}
19
20impl<'a> super::PlotItemStyled for PolygonPlot<'a> {
21 fn style_mut(&mut self) -> &mut PlotItemStyle {
22 &mut self.style
23 }
24}
25
26impl<'a> PolygonPlot<'a> {
27 pub fn new(label: &'a str, x_data: &'a [f64], y_data: &'a [f64]) -> Self {
29 Self {
30 label,
31 x_data,
32 y_data,
33 style: PlotItemStyle::default(),
34 flags: PolygonFlags::NONE,
35 item_flags: ItemFlags::NONE,
36 layout: PlotDataLayout::DEFAULT,
37 }
38 }
39
40 pub fn with_style(mut self, style: PlotItemStyle) -> Self {
42 self.style = style;
43 self
44 }
45
46 pub fn with_line_color(mut self, color: [f32; 4]) -> Self {
48 self.style = self.style.with_line_color(color);
49 self
50 }
51
52 pub fn with_line_weight(mut self, weight: f32) -> Self {
54 self.style = self.style.with_line_weight(weight);
55 self
56 }
57
58 pub fn with_fill_color(mut self, color: [f32; 4]) -> Self {
60 self.style = self.style.with_fill_color(color);
61 self
62 }
63
64 pub fn with_fill_alpha(mut self, alpha: f32) -> Self {
66 self.style = self.style.with_fill_alpha(alpha);
67 self
68 }
69
70 pub fn with_flags(mut self, flags: PolygonFlags) -> Self {
72 self.flags = flags;
73 self
74 }
75
76 pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
78 self.item_flags = flags;
79 self
80 }
81
82 pub unsafe fn with_data_layout(mut self, layout: PlotDataLayout) -> Self {
89 self.layout = layout;
90 self
91 }
92
93 pub fn with_offset(mut self, offset: PlotDataOffset) -> Self {
95 self.layout = self.layout.with_offset(offset);
96 self
97 }
98
99 pub unsafe fn with_stride(mut self, stride: PlotDataStride) -> Self {
106 self.layout = self.layout.with_stride(stride);
107 self
108 }
109
110 pub fn validate(&self) -> Result<(), PlotError> {
112 validate_data_lengths(self.x_data, self.y_data)
113 }
114}
115
116impl<'a> Plot for PolygonPlot<'a> {
117 fn plot(&self, plot_ui: &crate::PlotUi<'_>) {
118 if self.validate().is_err() {
119 return;
120 }
121 let Ok(count) = i32::try_from(self.x_data.len()) else {
122 return;
123 };
124
125 plot_ui.with_bound_context(|| {
126 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
127 let spec = plot_spec_with_style(
128 self.style,
129 self.flags.bits() | self.item_flags.bits(),
130 self.layout,
131 );
132 sys::ImPlot_PlotPolygon_doublePtr(
133 label_ptr,
134 self.x_data.as_ptr(),
135 self.y_data.as_ptr(),
136 count,
137 spec,
138 );
139 })
140 })
141 }
142
143 fn label(&self) -> &str {
144 self.label
145 }
146}
147
148impl<'ui> crate::PlotUi<'ui> {
150 pub fn polygon_plot(
152 &self,
153 label: &str,
154 x_data: &[f64],
155 y_data: &[f64],
156 ) -> Result<(), PlotError> {
157 let plot = PolygonPlot::new(label, x_data, y_data);
158 plot.validate()?;
159 plot.plot(self);
160 Ok(())
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn polygon_plot_creation() {
170 let x_data = [0.0, 1.0, 1.0, 0.0];
171 let y_data = [0.0, 0.0, 1.0, 1.0];
172
173 let plot = PolygonPlot::new("poly", &x_data, &y_data);
174 assert_eq!(plot.label(), "poly");
175 assert!(plot.validate().is_ok());
176 }
177
178 #[test]
179 fn polygon_plot_validation() {
180 let x_data = [0.0, 1.0, 1.0];
181 let y_data = [0.0, 0.0];
182
183 let plot = PolygonPlot::new("poly", &x_data, &y_data);
184 assert!(plot.validate().is_err());
185 }
186}