charming_fork_zephyr/series/
gauge.rs

1use serde::Serialize;
2
3use crate::{
4    datatype::{DataFrame, DataPoint},
5    element::{
6        Anchor, AxisLabel, AxisLine, AxisTick, Color, ColorBy, Formatter, ItemStyle, Pointer,
7        SplitLine,
8    },
9};
10
11#[derive(Serialize)]
12#[serde(rename_all = "camelCase")]
13pub struct GaugeDetail {
14    #[serde(skip_serializing_if = "Option::is_none")]
15    show: Option<bool>,
16
17    #[serde(skip_serializing_if = "Option::is_none")]
18    color: Option<Color>,
19
20    #[serde(skip_serializing_if = "Option::is_none")]
21    font_style: Option<String>,
22
23    #[serde(skip_serializing_if = "Option::is_none")]
24    font_weight: Option<String>,
25
26    #[serde(skip_serializing_if = "Option::is_none")]
27    font_family: Option<String>,
28
29    #[serde(skip_serializing_if = "Option::is_none")]
30    font_size: Option<i64>,
31
32    #[serde(skip_serializing_if = "Option::is_none")]
33    precision: Option<i64>,
34
35    #[serde(skip_serializing_if = "Option::is_none")]
36    value_animation: Option<bool>,
37
38    #[serde(skip_serializing_if = "Option::is_none")]
39    formatter: Option<Formatter>,
40}
41
42impl GaugeDetail {
43    pub fn new() -> Self {
44        Self {
45            show: None,
46            color: None,
47            font_style: None,
48            font_weight: None,
49            font_family: None,
50            font_size: None,
51            precision: None,
52            value_animation: None,
53            formatter: None,
54        }
55    }
56
57    pub fn show(mut self, show: bool) -> Self {
58        self.show = Some(show);
59        self
60    }
61
62    pub fn color<C: Into<Color>>(mut self, color: C) -> Self {
63        self.color = Some(color.into());
64        self
65    }
66
67    pub fn font_style<S: Into<String>>(mut self, font_style: S) -> Self {
68        self.font_style = Some(font_style.into());
69        self
70    }
71
72    pub fn font_weight<S: Into<String>>(mut self, font_weight: S) -> Self {
73        self.font_weight = Some(font_weight.into());
74        self
75    }
76
77    pub fn font_family<S: Into<String>>(mut self, font_family: S) -> Self {
78        self.font_family = Some(font_family.into());
79        self
80    }
81
82    pub fn font_size<F: Into<i64>>(mut self, font_size: F) -> Self {
83        self.font_size = Some(font_size.into());
84        self
85    }
86
87    pub fn precision<F: Into<i64>>(mut self, precision: F) -> Self {
88        self.precision = Some(precision.into());
89        self
90    }
91
92    pub fn value_animation(mut self, value_animation: bool) -> Self {
93        self.value_animation = Some(value_animation);
94        self
95    }
96
97    pub fn formatter<F: Into<Formatter>>(mut self, formatter: F) -> Self {
98        self.formatter = Some(formatter.into());
99        self
100    }
101}
102
103#[derive(Serialize)]
104#[serde(rename_all = "camelCase")]
105pub struct GaugeTitle {
106    #[serde(skip_serializing_if = "Option::is_none")]
107    show: Option<bool>,
108
109    #[serde(skip_serializing_if = "Option::is_none")]
110    offset_center: Option<(String, String)>,
111}
112
113impl GaugeTitle {
114    pub fn new() -> Self {
115        Self {
116            show: None,
117            offset_center: None,
118        }
119    }
120
121    pub fn show(mut self, show: bool) -> Self {
122        self.show = Some(show);
123        self
124    }
125
126    pub fn offset_center<S: Into<String>>(mut self, offset_center: (S, S)) -> Self {
127        self.offset_center = Some((offset_center.0.into(), offset_center.1.into()));
128        self
129    }
130}
131
132#[derive(Serialize)]
133#[serde(rename_all = "camelCase")]
134pub struct GaugeProgress {
135    #[serde(skip_serializing_if = "Option::is_none")]
136    show: Option<bool>,
137
138    #[serde(skip_serializing_if = "Option::is_none")]
139    overlap: Option<bool>,
140
141    #[serde(skip_serializing_if = "Option::is_none")]
142    width: Option<i64>,
143
144    #[serde(skip_serializing_if = "Option::is_none")]
145    round_cap: Option<bool>,
146
147    #[serde(skip_serializing_if = "Option::is_none")]
148    clip: Option<bool>,
149
150    #[serde(skip_serializing_if = "Option::is_none")]
151    item_style: Option<ItemStyle>,
152}
153
154impl GaugeProgress {
155    pub fn new() -> Self {
156        Self {
157            show: None,
158            overlap: None,
159            width: None,
160            round_cap: None,
161            clip: None,
162            item_style: None,
163        }
164    }
165
166    pub fn show(mut self, show: bool) -> Self {
167        self.show = Some(show);
168        self
169    }
170
171    pub fn overlap(mut self, overlap: bool) -> Self {
172        self.overlap = Some(overlap);
173        self
174    }
175
176    pub fn width<F: Into<i64>>(mut self, width: F) -> Self {
177        self.width = Some(width.into());
178        self
179    }
180
181    pub fn round_cap(mut self, round_cap: bool) -> Self {
182        self.round_cap = Some(round_cap);
183        self
184    }
185
186    pub fn clip(mut self, clip: bool) -> Self {
187        self.clip = Some(clip);
188        self
189    }
190
191    pub fn item_style(mut self, item_style: ItemStyle) -> Self {
192        self.item_style = Some(item_style);
193        self
194    }
195}
196
197#[derive(Serialize)]
198#[serde(rename_all = "camelCase")]
199pub struct Gauge {
200    #[serde(rename = "type")]
201    type_: String,
202
203    #[serde(skip_serializing_if = "Option::is_none")]
204    id: Option<String>,
205
206    #[serde(skip_serializing_if = "Option::is_none")]
207    name: Option<String>,
208
209    #[serde(skip_serializing_if = "Option::is_none")]
210    color_by: Option<ColorBy>,
211
212    #[serde(skip_serializing_if = "Option::is_none")]
213    zlevel: Option<i64>,
214
215    #[serde(skip_serializing_if = "Option::is_none")]
216    z: Option<i64>,
217
218    #[serde(skip_serializing_if = "Option::is_none")]
219    center: Option<(String, String)>,
220
221    #[serde(skip_serializing_if = "Option::is_none")]
222    legend_hover_link: Option<bool>,
223
224    #[serde(skip_serializing_if = "Option::is_none")]
225    start_angle: Option<i64>,
226
227    #[serde(skip_serializing_if = "Option::is_none")]
228    end_angle: Option<i64>,
229
230    #[serde(skip_serializing_if = "Option::is_none")]
231    clockwise: Option<bool>,
232
233    #[serde(skip_serializing_if = "Option::is_none")]
234    min: Option<i64>,
235
236    #[serde(skip_serializing_if = "Option::is_none")]
237    max: Option<i64>,
238
239    #[serde(skip_serializing_if = "Option::is_none")]
240    split_number: Option<i64>,
241
242    #[serde(skip_serializing_if = "Option::is_none")]
243    radius: Option<String>,
244
245    #[serde(skip_serializing_if = "Option::is_none")]
246    progress: Option<GaugeProgress>,
247
248    #[serde(skip_serializing_if = "Option::is_none")]
249    axis_line: Option<AxisLine>,
250
251    #[serde(skip_serializing_if = "Option::is_none")]
252    axis_tick: Option<AxisTick>,
253
254    #[serde(skip_serializing_if = "Option::is_none")]
255    axis_label: Option<AxisLabel>,
256
257    #[serde(skip_serializing_if = "Option::is_none")]
258    split_line: Option<SplitLine>,
259
260    #[serde(skip_serializing_if = "Option::is_none")]
261    pointer: Option<Pointer>,
262
263    #[serde(skip_serializing_if = "Option::is_none")]
264    anchor: Option<Anchor>,
265
266    #[serde(skip_serializing_if = "Option::is_none")]
267    detail: Option<GaugeDetail>,
268
269    #[serde(skip_serializing_if = "Option::is_none")]
270    title: Option<GaugeTitle>,
271
272    #[serde(skip_serializing_if = "Vec::is_empty")]
273    data: DataFrame,
274}
275
276impl Gauge {
277    pub fn new() -> Self {
278        Self {
279            type_: "gauge".to_string(),
280            id: None,
281            name: None,
282            color_by: None,
283            zlevel: None,
284            z: None,
285            center: None,
286            legend_hover_link: None,
287            start_angle: None,
288            end_angle: None,
289            clockwise: None,
290            min: None,
291            max: None,
292            split_number: None,
293            radius: None,
294            progress: None,
295            axis_line: None,
296            axis_tick: None,
297            axis_label: None,
298            split_line: None,
299            pointer: None,
300            anchor: None,
301            detail: None,
302            title: None,
303            data: vec![],
304        }
305    }
306
307    pub fn id<S: Into<String>>(mut self, id: S) -> Self {
308        self.id = Some(id.into());
309        self
310    }
311
312    pub fn name<S: Into<String>>(mut self, name: S) -> Self {
313        self.name = Some(name.into());
314        self
315    }
316
317    pub fn color_by<C: Into<ColorBy>>(mut self, color_by: C) -> Self {
318        self.color_by = Some(color_by.into());
319        self
320    }
321
322    pub fn zlevel<F: Into<i64>>(mut self, zlevel: F) -> Self {
323        self.zlevel = Some(zlevel.into());
324        self
325    }
326
327    pub fn z<F: Into<i64>>(mut self, z: F) -> Self {
328        self.z = Some(z.into());
329        self
330    }
331
332    pub fn center<S: Into<String>>(mut self, center: (S, S)) -> Self {
333        self.center = Some((center.0.into(), center.1.into()));
334        self
335    }
336
337    pub fn legend_hover_link(mut self, legend_hover_link: bool) -> Self {
338        self.legend_hover_link = Some(legend_hover_link);
339        self
340    }
341
342    pub fn start_angle<F: Into<i64>>(mut self, start_angle: F) -> Self {
343        self.start_angle = Some(start_angle.into());
344        self
345    }
346
347    pub fn end_angle<F: Into<i64>>(mut self, end_angle: F) -> Self {
348        self.end_angle = Some(end_angle.into());
349        self
350    }
351
352    pub fn clockwise(mut self, clockwise: bool) -> Self {
353        self.clockwise = Some(clockwise);
354        self
355    }
356
357    pub fn min<F: Into<i64>>(mut self, min: F) -> Self {
358        self.min = Some(min.into());
359        self
360    }
361
362    pub fn max<F: Into<i64>>(mut self, max: F) -> Self {
363        self.max = Some(max.into());
364        self
365    }
366
367    pub fn split_number<F: Into<i64>>(mut self, split_number: F) -> Self {
368        self.split_number = Some(split_number.into());
369        self
370    }
371
372    pub fn radius<S: Into<String>>(mut self, radius: S) -> Self {
373        self.radius = Some(radius.into());
374        self
375    }
376
377    pub fn progress<P: Into<GaugeProgress>>(mut self, progress: P) -> Self {
378        self.progress = Some(progress.into());
379        self
380    }
381
382    pub fn axis_line<L: Into<AxisLine>>(mut self, axis_line: L) -> Self {
383        self.axis_line = Some(axis_line.into());
384        self
385    }
386
387    pub fn axis_tick<T: Into<AxisTick>>(mut self, axis_tick: T) -> Self {
388        self.axis_tick = Some(axis_tick.into());
389        self
390    }
391
392    pub fn axis_label<L: Into<AxisLabel>>(mut self, axis_label: L) -> Self {
393        self.axis_label = Some(axis_label.into());
394        self
395    }
396
397    pub fn split_line<L: Into<SplitLine>>(mut self, split_line: L) -> Self {
398        self.split_line = Some(split_line.into());
399        self
400    }
401
402    pub fn pointer<P: Into<Pointer>>(mut self, pointer: P) -> Self {
403        self.pointer = Some(pointer.into());
404        self
405    }
406
407    pub fn anchor<A: Into<Anchor>>(mut self, anchor: A) -> Self {
408        self.anchor = Some(anchor.into());
409        self
410    }
411
412    pub fn detail<D: Into<GaugeDetail>>(mut self, detail: D) -> Self {
413        self.detail = Some(detail.into());
414        self
415    }
416
417    pub fn title<T: Into<GaugeTitle>>(mut self, title: T) -> Self {
418        self.title = Some(title.into());
419        self
420    }
421
422    pub fn data<D: Into<DataPoint>>(mut self, data: Vec<D>) -> Self {
423        self.data = data.into_iter().map(|d| d.into()).collect();
424        self
425    }
426}