charming_fork_zephyr/series/
gauge.rs1use 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}