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 fn with_data_layout(mut self, layout: PlotDataLayout) -> Self {
84 self.layout = layout;
85 self
86 }
87
88 pub fn with_offset(mut self, offset: PlotDataOffset) -> Self {
90 self.layout = self.layout.with_offset(offset);
91 self
92 }
93
94 pub fn with_stride(mut self, stride: PlotDataStride) -> Self {
96 self.layout = self.layout.with_stride(stride);
97 self
98 }
99
100 pub fn validate(&self) -> Result<(), PlotError> {
102 validate_data_lengths(self.x_data, self.y_data)
103 }
104}
105
106impl<'a> Plot for PolygonPlot<'a> {
107 fn plot(&self) {
108 if self.validate().is_err() {
109 return;
110 }
111 let Ok(count) = i32::try_from(self.x_data.len()) else {
112 return;
113 };
114
115 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
116 let spec = plot_spec_with_style(
117 self.style,
118 self.flags.bits() | self.item_flags.bits(),
119 self.layout,
120 );
121 sys::ImPlot_PlotPolygon_doublePtr(
122 label_ptr,
123 self.x_data.as_ptr(),
124 self.y_data.as_ptr(),
125 count,
126 spec,
127 );
128 })
129 }
130
131 fn label(&self) -> &str {
132 self.label
133 }
134}
135
136impl<'ui> crate::PlotUi<'ui> {
138 pub fn polygon_plot(
140 &self,
141 label: &str,
142 x_data: &[f64],
143 y_data: &[f64],
144 ) -> Result<(), PlotError> {
145 let plot = PolygonPlot::new(label, x_data, y_data);
146 plot.validate()?;
147 self.bind();
148 plot.plot();
149 Ok(())
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn polygon_plot_creation() {
159 let x_data = [0.0, 1.0, 1.0, 0.0];
160 let y_data = [0.0, 0.0, 1.0, 1.0];
161
162 let plot = PolygonPlot::new("poly", &x_data, &y_data);
163 assert_eq!(plot.label(), "poly");
164 assert!(plot.validate().is_ok());
165 }
166
167 #[test]
168 fn polygon_plot_validation() {
169 let x_data = [0.0, 1.0, 1.0];
170 let y_data = [0.0, 0.0];
171
172 let plot = PolygonPlot::new("poly", &x_data, &y_data);
173 assert!(plot.validate().is_err());
174 }
175}