dear_implot/plots/
polygon.rs1use super::{
4 Plot, PlotError, PlotItemStyle, plot_spec_with_style, validate_data_lengths,
5 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 offset: i32,
18 stride: i32,
19}
20
21impl<'a> super::PlotItemStyled for PolygonPlot<'a> {
22 fn style_mut(&mut self) -> &mut PlotItemStyle {
23 &mut self.style
24 }
25}
26
27impl<'a> PolygonPlot<'a> {
28 pub fn new(label: &'a str, x_data: &'a [f64], y_data: &'a [f64]) -> Self {
30 Self {
31 label,
32 x_data,
33 y_data,
34 style: PlotItemStyle::default(),
35 flags: PolygonFlags::NONE,
36 item_flags: ItemFlags::NONE,
37 offset: 0,
38 stride: std::mem::size_of::<f64>() as i32,
39 }
40 }
41
42 pub fn with_style(mut self, style: PlotItemStyle) -> Self {
44 self.style = style;
45 self
46 }
47
48 pub fn with_line_color(mut self, color: [f32; 4]) -> Self {
50 self.style = self.style.with_line_color(color);
51 self
52 }
53
54 pub fn with_line_weight(mut self, weight: f32) -> Self {
56 self.style = self.style.with_line_weight(weight);
57 self
58 }
59
60 pub fn with_fill_color(mut self, color: [f32; 4]) -> Self {
62 self.style = self.style.with_fill_color(color);
63 self
64 }
65
66 pub fn with_fill_alpha(mut self, alpha: f32) -> Self {
68 self.style = self.style.with_fill_alpha(alpha);
69 self
70 }
71
72 pub fn with_flags(mut self, flags: PolygonFlags) -> Self {
74 self.flags = flags;
75 self
76 }
77
78 pub fn with_item_flags(mut self, flags: ItemFlags) -> Self {
80 self.item_flags = flags;
81 self
82 }
83
84 pub fn with_offset(mut self, offset: i32) -> Self {
86 self.offset = offset;
87 self
88 }
89
90 pub fn with_stride(mut self, stride: i32) -> Self {
92 self.stride = stride;
93 self
94 }
95
96 pub fn validate(&self) -> Result<(), PlotError> {
98 validate_data_lengths(self.x_data, self.y_data)
99 }
100}
101
102impl<'a> Plot for PolygonPlot<'a> {
103 fn plot(&self) {
104 if self.validate().is_err() {
105 return;
106 }
107 let Ok(count) = i32::try_from(self.x_data.len()) else {
108 return;
109 };
110
111 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
112 let spec = plot_spec_with_style(
113 self.style,
114 self.flags.bits() | self.item_flags.bits(),
115 self.offset,
116 self.stride,
117 );
118 sys::ImPlot_PlotPolygon_doublePtr(
119 label_ptr,
120 self.x_data.as_ptr(),
121 self.y_data.as_ptr(),
122 count,
123 spec,
124 );
125 })
126 }
127
128 fn label(&self) -> &str {
129 self.label
130 }
131}
132
133impl<'ui> crate::PlotUi<'ui> {
135 pub fn polygon_plot(
137 &self,
138 label: &str,
139 x_data: &[f64],
140 y_data: &[f64],
141 ) -> Result<(), PlotError> {
142 let plot = PolygonPlot::new(label, x_data, y_data);
143 plot.validate()?;
144 plot.plot();
145 Ok(())
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn polygon_plot_creation() {
155 let x_data = [0.0, 1.0, 1.0, 0.0];
156 let y_data = [0.0, 0.0, 1.0, 1.0];
157
158 let plot = PolygonPlot::new("poly", &x_data, &y_data);
159 assert_eq!(plot.label(), "poly");
160 assert!(plot.validate().is_ok());
161 }
162
163 #[test]
164 fn polygon_plot_validation() {
165 let x_data = [0.0, 1.0, 1.0];
166 let y_data = [0.0, 0.0];
167
168 let plot = PolygonPlot::new("poly", &x_data, &y_data);
169 assert!(plot.validate().is_err());
170 }
171}