charming_fork_zephyr/component/
visual_map.rs

1use serde::Serialize;
2
3use crate::{
4    datatype::CompositeValue,
5    element::{Color, Orient, TextStyle},
6};
7
8#[derive(Serialize)]
9#[serde(rename_all = "snake_case")]
10pub enum VisualMapType {
11    Continuous,
12    Piecewise,
13}
14
15#[derive(Serialize)]
16#[serde(rename_all = "camelCase")]
17pub struct VisualMapPiece {
18    #[serde(skip_serializing_if = "Option::is_none")]
19    min: Option<i64>,
20
21    #[serde(skip_serializing_if = "Option::is_none")]
22    max: Option<i64>,
23
24    #[serde(skip_serializing_if = "Option::is_none")]
25    lt: Option<i64>,
26
27    #[serde(skip_serializing_if = "Option::is_none")]
28    lte: Option<i64>,
29
30    #[serde(skip_serializing_if = "Option::is_none")]
31    gt: Option<i64>,
32
33    #[serde(skip_serializing_if = "Option::is_none")]
34    gte: Option<i64>,
35
36    #[serde(skip_serializing_if = "Option::is_none")]
37    label: Option<String>,
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    color: Option<Color>,
41}
42
43impl VisualMapPiece {
44    pub fn new() -> Self {
45        Self {
46            min: None,
47            max: None,
48            lt: None,
49            lte: None,
50            gt: None,
51            gte: None,
52            label: None,
53            color: None,
54        }
55    }
56
57    pub fn min<F: Into<i64>>(mut self, min: F) -> Self {
58        self.min = Some(min.into());
59        self
60    }
61
62    pub fn max<F: Into<i64>>(mut self, max: F) -> Self {
63        self.max = Some(max.into());
64        self
65    }
66
67    pub fn lt<F: Into<i64>>(mut self, lt: F) -> Self {
68        self.lt = Some(lt.into());
69        self
70    }
71
72    pub fn lte<F: Into<i64>>(mut self, lte: F) -> Self {
73        self.lte = Some(lte.into());
74        self
75    }
76
77    pub fn gt<F: Into<i64>>(mut self, gt: F) -> Self {
78        self.gt = Some(gt.into());
79        self
80    }
81
82    pub fn gte<F: Into<i64>>(mut self, gte: F) -> Self {
83        self.gte = Some(gte.into());
84        self
85    }
86
87    pub fn label<S: Into<String>>(mut self, label: S) -> Self {
88        self.label = Some(label.into());
89        self
90    }
91
92    pub fn color<C: Into<Color>>(mut self, color: C) -> Self {
93        self.color = Some(color.into());
94        self
95    }
96}
97
98impl From<(i64, i64)> for VisualMapPiece {
99    fn from((min, max): (i64, i64)) -> Self {
100        Self::new().min(min).max(max)
101    }
102}
103
104impl From<(i64, i64, &str)> for VisualMapPiece {
105    fn from((min, max, label): (i64, i64, &str)) -> Self {
106        Self::new().min(min).max(max).label(label)
107    }
108}
109
110
111
112#[derive(Serialize)]
113#[serde(rename_all = "camelCase")]
114pub struct VisualMapChannel {
115    #[serde(skip_serializing_if = "Vec::is_empty")]
116    color: Vec<Color>,
117}
118
119impl VisualMapChannel {
120    pub fn new() -> Self {
121        Self { color: vec![] }
122    }
123
124    pub fn color<C: Into<Color>>(mut self, color: Vec<C>) -> Self {
125        self.color = color.into_iter().map(|c| c.into()).collect();
126        self
127    }
128}
129
130#[derive(Serialize)]
131#[serde(rename_all = "camelCase")]
132pub struct VisualMap {
133    #[serde(skip_serializing_if = "Option::is_none")]
134    #[serde(rename = "type")]
135    type_: Option<VisualMapType>,
136
137    #[serde(skip_serializing_if = "Vec::is_empty")]
138    color: Vec<Color>,
139
140    #[serde(skip_serializing_if = "Option::is_none")]
141    show: Option<bool>,
142
143    #[serde(skip_serializing_if = "Option::is_none")]
144    dimension: Option<CompositeValue>,
145
146    #[serde(skip_serializing_if = "Option::is_none")]
147    series_index: Option<i64>,
148
149    #[serde(skip_serializing_if = "Option::is_none")]
150    min: Option<i64>,
151
152    #[serde(skip_serializing_if = "Option::is_none")]
153    max: Option<i64>,
154
155    #[serde(skip_serializing_if = "Vec::is_empty")]
156    categories: Vec<String>,
157
158    #[serde(skip_serializing_if = "Option::is_none")]
159    calculable: Option<bool>,
160
161    #[serde(skip_serializing_if = "Option::is_none")]
162    orient: Option<Orient>,
163
164    #[serde(skip_serializing_if = "Option::is_none")]
165    left: Option<CompositeValue>,
166
167    #[serde(skip_serializing_if = "Option::is_none")]
168    top: Option<CompositeValue>,
169
170    #[serde(skip_serializing_if = "Option::is_none")]
171    right: Option<CompositeValue>,
172
173    #[serde(skip_serializing_if = "Option::is_none")]
174    bottom: Option<CompositeValue>,
175
176    #[serde(skip_serializing_if = "Option::is_none")]
177    text_style: Option<TextStyle>,
178
179    #[serde(skip_serializing_if = "Option::is_none")]
180    range: Option<(i64, i64)>,
181
182    #[serde(skip_serializing_if = "Option::is_none")]
183    realtime: Option<bool>,
184
185    #[serde(skip_serializing_if = "Option::is_none")]
186    inverse: Option<bool>,
187
188    #[serde(skip_serializing_if = "Option::is_none")]
189    precision: Option<i64>,
190
191    #[serde(skip_serializing_if = "Option::is_none")]
192    item_width: Option<i64>,
193
194    #[serde(skip_serializing_if = "Option::is_none")]
195    item_height: Option<i64>,
196
197    #[serde(skip_serializing_if = "Option::is_none")]
198    in_range: Option<VisualMapChannel>,
199
200    #[serde(skip_serializing_if = "Option::is_none")]
201    out_range: Option<VisualMapChannel>,
202
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pieces: Option<Vec<VisualMapPiece>>,
205}
206
207impl VisualMap {
208    pub fn new() -> Self {
209        Self {
210            type_: None,
211            color: vec![],
212            show: None,
213            dimension: None,
214            series_index: None,
215            min: None,
216            max: None,
217            categories: vec![],
218            calculable: None,
219            orient: None,
220            left: None,
221            top: None,
222            right: None,
223            bottom: None,
224            text_style: None,
225            range: None,
226            realtime: None,
227            inverse: None,
228            precision: None,
229            item_width: None,
230            item_height: None,
231            in_range: None,
232            out_range: None,
233            pieces: None,
234        }
235    }
236
237    pub fn type_<S: Into<VisualMapType>>(mut self, type_: S) -> Self {
238        self.type_ = Some(type_.into());
239        self
240    }
241
242    pub fn color<C: Into<Color>>(mut self, color: Vec<C>) -> Self {
243        self.color = color.into_iter().map(|c| c.into()).collect();
244        self
245    }
246
247    pub fn show(mut self, show: bool) -> Self {
248        self.show = Some(show);
249        self
250    }
251
252    pub fn dimension<C: Into<CompositeValue>>(mut self, dimension: C) -> Self {
253        self.dimension = Some(dimension.into());
254        self
255    }
256
257    pub fn series_index<F: Into<i64>>(mut self, series_index: F) -> Self {
258        self.series_index = Some(series_index.into());
259        self
260    }
261
262    pub fn min<F: Into<i64>>(mut self, min: F) -> Self {
263        self.min = Some(min.into());
264        self
265    }
266
267    pub fn max<F: Into<i64>>(mut self, max: F) -> Self {
268        self.max = Some(max.into());
269        self
270    }
271
272    pub fn categories<S: Into<String>>(mut self, categories: Vec<S>) -> Self {
273        self.categories = categories.into_iter().map(|c| c.into()).collect();
274        self
275    }
276
277    pub fn calculable(mut self, calculable: bool) -> Self {
278        self.calculable = Some(calculable);
279        self
280    }
281
282    pub fn orient(mut self, orient: Orient) -> Self {
283        self.orient = Some(orient);
284        self
285    }
286
287    pub fn left<C: Into<CompositeValue>>(mut self, left: C) -> Self {
288        self.left = Some(left.into());
289        self
290    }
291
292    pub fn top<C: Into<CompositeValue>>(mut self, top: C) -> Self {
293        self.top = Some(top.into());
294        self
295    }
296
297    pub fn right<C: Into<CompositeValue>>(mut self, right: C) -> Self {
298        self.right = Some(right.into());
299        self
300    }
301
302    pub fn bottom<C: Into<CompositeValue>>(mut self, bottom: C) -> Self {
303        self.bottom = Some(bottom.into());
304        self
305    }
306
307    pub fn text_style<T: Into<TextStyle>>(mut self, text_style: T) -> Self {
308        self.text_style = Some(text_style.into());
309        self
310    }
311
312    pub fn range<F: Into<i64>>(mut self, range: (F, F)) -> Self {
313        self.range = Some((range.0.into(), range.1.into()));
314        self
315    }
316
317    pub fn realtime(mut self, realtime: bool) -> Self {
318        self.realtime = Some(realtime);
319        self
320    }
321
322    pub fn inverse(mut self, inverse: bool) -> Self {
323        self.inverse = Some(inverse);
324        self
325    }
326
327    pub fn precision<F: Into<i64>>(mut self, precision: F) -> Self {
328        self.precision = Some(precision.into());
329        self
330    }
331
332    pub fn item_width<F: Into<i64>>(mut self, item_width: F) -> Self {
333        self.item_width = Some(item_width.into());
334        self
335    }
336
337    pub fn item_height<F: Into<i64>>(mut self, item_height: F) -> Self {
338        self.item_height = Some(item_height.into());
339        self
340    }
341
342    pub fn in_range<V: Into<VisualMapChannel>>(mut self, in_range: V) -> Self {
343        self.in_range = Some(in_range.into());
344        self
345    }
346
347    pub fn out_range<V: Into<VisualMapChannel>>(mut self, out_range: V) -> Self {
348        self.out_range = Some(out_range.into());
349        self
350    }
351
352    pub fn pieces(mut self, pieces: Vec<VisualMapPiece>) -> Self {
353        self.pieces = Some(pieces);
354        self
355    }
356}