charming_fork_zephyr/component/
legend.rs1use serde::Serialize;
2
3use crate::{
4 datatype::CompositeValue,
5 element::{Color, Icon, ItemStyle, LabelAlign, LineStyle, Orient, Padding, TextStyle},
6};
7
8#[derive(Serialize)]
9#[serde(rename_all = "snake_case")]
10pub enum LegendType {
11 Plain,
13
14 Scroll,
16}
17
18#[derive(Serialize)]
19#[serde(rename_all = "snake_case")]
20pub enum LegendSelectedMode {
21 Multiple,
23
24 Single,
26}
27
28#[derive(Serialize)]
29#[serde(rename_all = "camelCase")]
30pub struct LegendItem {
31 pub name: String,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub icon: Option<Icon>,
35}
36
37impl From<&str> for LegendItem {
38 fn from(name: &str) -> Self {
39 Self {
40 name: name.to_string(),
41 icon: None,
42 }
43 }
44}
45
46impl From<String> for LegendItem {
47 fn from(name: String) -> Self {
48 Self { name, icon: None }
49 }
50}
51
52impl From<(&str, &str)> for LegendItem {
53 fn from((name, icon): (&str, &str)) -> Self {
54 Self {
55 name: name.to_string(),
56 icon: Some(icon.into()),
57 }
58 }
59}
60
61impl From<(String, String)> for LegendItem {
62 fn from((name, icon): (String, String)) -> Self {
63 Self {
64 name,
65 icon: Some(icon.into()),
66 }
67 }
68}
69
70#[derive(Serialize)]
71#[serde(rename_all = "camelCase")]
72pub struct Legend {
73 #[serde(skip_serializing_if = "Option::is_none")]
75 #[serde(rename = "type")]
76 type_: Option<LegendType>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 id: Option<String>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 show: Option<bool>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 zlevel: Option<i64>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 z: Option<i64>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 left: Option<CompositeValue>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 top: Option<CompositeValue>,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 right: Option<CompositeValue>,
105
106 #[serde(skip_serializing_if = "Option::is_none")]
108 bottom: Option<CompositeValue>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 width: Option<CompositeValue>,
113
114 #[serde(skip_serializing_if = "Option::is_none")]
116 height: Option<CompositeValue>,
117
118 #[serde(skip_serializing_if = "Option::is_none")]
120 orient: Option<Orient>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
124 align: Option<LabelAlign>,
125
126 #[serde(skip_serializing_if = "Option::is_none")]
128 padding: Option<Padding>,
129
130 #[serde(skip_serializing_if = "Option::is_none")]
132 item_gap: Option<i64>,
133
134 #[serde(skip_serializing_if = "Option::is_none")]
136 item_width: Option<i64>,
137
138 #[serde(skip_serializing_if = "Option::is_none")]
140 item_height: Option<i64>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
144 item_style: Option<ItemStyle>,
145
146 #[serde(skip_serializing_if = "Option::is_none")]
148 line_style: Option<LineStyle>,
149
150 #[serde(skip_serializing_if = "Option::is_none")]
151 text_style: Option<TextStyle>,
152
153 #[serde(skip_serializing_if = "Option::is_none")]
155 symbol_rotate: Option<String>,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
159 formatter: Option<String>,
160
161 #[serde(skip_serializing_if = "Option::is_none")]
162 selected_mode: Option<LegendSelectedMode>,
163
164 #[serde(skip_serializing_if = "Option::is_none")]
165 border_color: Option<Color>,
166
167 #[serde(skip_serializing_if = "Option::is_none")]
168 inactive_color: Option<Color>,
169
170 #[serde(skip_serializing_if = "Vec::is_empty")]
171 data: Vec<LegendItem>,
172}
173
174impl Legend {
175 pub fn new() -> Self {
176 Self {
177 type_: None,
178 id: None,
179 show: None,
180 zlevel: None,
181 z: None,
182 left: None,
183 top: None,
184 right: None,
185 bottom: None,
186 width: None,
187 height: None,
188 orient: None,
189 align: None,
190 padding: None,
191 item_gap: None,
192 item_width: None,
193 item_height: None,
194 item_style: None,
195 line_style: None,
196 text_style: None,
197 symbol_rotate: None,
198 formatter: None,
199 selected_mode: None,
200 border_color: None,
201 inactive_color: None,
202 data: vec![],
203 }
204 }
205
206 pub fn type_<T: Into<LegendType>>(mut self, type_: T) -> Self {
207 self.type_ = Some(type_.into());
208 self
209 }
210
211 pub fn show(mut self, show: bool) -> Self {
212 self.show = Some(show);
213 self
214 }
215
216 pub fn zlevel<F: Into<i64>>(mut self, zlevel: F) -> Self {
217 self.zlevel = Some(zlevel.into());
218 self
219 }
220
221 pub fn z<F: Into<i64>>(mut self, z: F) -> Self {
222 self.z = Some(z.into());
223 self
224 }
225
226 pub fn left<C: Into<CompositeValue>>(mut self, left: C) -> Self {
227 self.left = Some(left.into());
228 self
229 }
230
231 pub fn top<C: Into<CompositeValue>>(mut self, top: C) -> Self {
232 self.top = Some(top.into());
233 self
234 }
235
236 pub fn right<C: Into<CompositeValue>>(mut self, right: C) -> Self {
237 self.right = Some(right.into());
238 self
239 }
240
241 pub fn bottom<C: Into<CompositeValue>>(mut self, bottom: C) -> Self {
242 self.bottom = Some(bottom.into());
243 self
244 }
245
246 pub fn width<C: Into<CompositeValue>>(mut self, width: C) -> Self {
247 self.width = Some(width.into());
248 self
249 }
250
251 pub fn height<C: Into<CompositeValue>>(mut self, height: C) -> Self {
252 self.height = Some(height.into());
253 self
254 }
255
256 pub fn orient<O: Into<Orient>>(mut self, orient: O) -> Self {
257 self.orient = Some(orient.into());
258 self
259 }
260
261 pub fn align<A: Into<LabelAlign>>(mut self, align: A) -> Self {
262 self.align = Some(align.into());
263 self
264 }
265
266 pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
267 self.padding = Some(padding.into());
268 self
269 }
270
271 pub fn item_gap<F: Into<i64>>(mut self, item_gap: F) -> Self {
272 self.item_gap = Some(item_gap.into());
273 self
274 }
275
276 pub fn item_width<F: Into<i64>>(mut self, item_width: F) -> Self {
277 self.item_width = Some(item_width.into());
278 self
279 }
280
281 pub fn item_height<F: Into<i64>>(mut self, item_height: F) -> Self {
282 self.item_height = Some(item_height.into());
283 self
284 }
285
286 pub fn item_style<S: Into<ItemStyle>>(mut self, item_style: S) -> Self {
287 self.item_style = Some(item_style.into());
288 self
289 }
290
291 pub fn line_style<S: Into<LineStyle>>(mut self, line_style: S) -> Self {
292 self.line_style = Some(line_style.into());
293 self
294 }
295
296 pub fn text_style<S: Into<TextStyle>>(mut self, text_style: S) -> Self {
297 self.text_style = Some(text_style.into());
298 self
299 }
300
301 pub fn symbol_rotate<S: Into<String>>(mut self, symbol_rotate: S) -> Self {
302 self.symbol_rotate = Some(symbol_rotate.into());
303 self
304 }
305
306 pub fn formatter<S: Into<String>>(mut self, formatter: S) -> Self {
307 self.formatter = Some(formatter.into());
308 self
309 }
310
311 pub fn selected_mode<S: Into<LegendSelectedMode>>(mut self, selected_mode: S) -> Self {
312 self.selected_mode = Some(selected_mode.into());
313 self
314 }
315
316 pub fn border_color<C: Into<Color>>(mut self, border_color: C) -> Self {
317 self.border_color = Some(border_color.into());
318 self
319 }
320
321 pub fn inactive_color<C: Into<Color>>(mut self, inactive_color: C) -> Self {
322 self.inactive_color = Some(inactive_color.into());
323 self
324 }
325
326 pub fn data<L: Into<LegendItem>>(mut self, data: Vec<L>) -> Self {
327 self.data = data.into_iter().map(|s| s.into()).collect();
328 self
329 }
330}