1use serde::Serialize;
2
3use crate::{
4 datatype::CompositeValue,
5 element::{
6 AxisLabel, AxisLine, AxisTick, Color, Formatter, Padding, Shape, SplitArea, SplitLine,
7 },
8};
9
10#[derive(Serialize)]
12#[serde(rename_all = "camelCase")]
13pub struct RadarAxisName {
14 #[serde(skip_serializing_if = "Option::is_none")]
16 show: Option<bool>,
17
18 #[serde(skip_serializing_if = "Option::is_none")]
20 formatter: Option<Formatter>,
21
22 #[serde(skip_serializing_if = "Option::is_none")]
23 color: Option<Color>,
24
25 #[serde(skip_serializing_if = "Option::is_none")]
26 font_style: Option<String>,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
29 font_weight: Option<String>,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
32 font_family: Option<String>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
35 font_size: Option<i64>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
38 line_height: Option<i64>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
41 background_color: Option<Color>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
44 border_color: Option<Color>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
47 border_width: Option<i64>,
48
49 #[serde(skip_serializing_if = "Option::is_none")]
50 border_type: Option<String>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
53 border_dash_offset: Option<i64>,
54
55 #[serde(skip_serializing_if = "Option::is_none")]
56 border_radius: Option<CompositeValue>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
59 padding: Option<Padding>,
60
61 #[serde(skip_serializing_if = "Option::is_none")]
62 shadow_color: Option<Color>,
63
64 #[serde(skip_serializing_if = "Option::is_none")]
65 shadow_blur: Option<i64>,
66
67 #[serde(skip_serializing_if = "Option::is_none")]
68 shadow_offset_x: Option<i64>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
71 shadow_offset_y: Option<i64>,
72
73 #[serde(skip_serializing_if = "Option::is_none")]
74 width: Option<CompositeValue>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
77 height: Option<CompositeValue>,
78
79 #[serde(skip_serializing_if = "Option::is_none")]
80 text_border_color: Option<Color>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
83 text_border_width: Option<i64>,
84
85 #[serde(skip_serializing_if = "Option::is_none")]
86 text_border_type: Option<String>,
87
88 #[serde(skip_serializing_if = "Option::is_none")]
89 text_border_dash_offset: Option<i64>,
90
91 #[serde(skip_serializing_if = "Option::is_none")]
92 text_shadow_color: Option<Color>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
95 text_shadow_blur: Option<i64>,
96
97 #[serde(skip_serializing_if = "Option::is_none")]
98 text_shadow_offset_x: Option<i64>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
101 text_shadow_offset_y: Option<i64>,
102
103 #[serde(skip_serializing_if = "Option::is_none")]
104 overflow: Option<String>,
105}
106
107impl RadarAxisName {
108 pub fn new() -> Self {
109 Self {
110 show: None,
111 formatter: None,
112 color: None,
113 font_style: None,
114 font_weight: None,
115 font_family: None,
116 font_size: None,
117 line_height: None,
118 background_color: None,
119 border_color: None,
120 border_width: None,
121 border_type: None,
122 border_dash_offset: None,
123 border_radius: None,
124 padding: None,
125 shadow_color: None,
126 shadow_blur: None,
127 shadow_offset_x: None,
128 shadow_offset_y: None,
129 width: None,
130 height: None,
131 text_border_color: None,
132 text_border_width: None,
133 text_border_type: None,
134 text_border_dash_offset: None,
135 text_shadow_color: None,
136 text_shadow_blur: None,
137 text_shadow_offset_x: None,
138 text_shadow_offset_y: None,
139 overflow: None,
140 }
141 }
142
143 pub fn show(mut self, show: bool) -> Self {
144 self.show = Some(show);
145 self
146 }
147
148 pub fn formatter<C: Into<Formatter>>(mut self, formatter: C) -> Self {
149 self.formatter = Some(formatter.into());
150 self
151 }
152
153 pub fn color<C: Into<Color>>(mut self, color: C) -> Self {
154 self.color = Some(color.into());
155 self
156 }
157
158 pub fn font_style<S: Into<String>>(mut self, font_style: S) -> Self {
159 self.font_style = Some(font_style.into());
160 self
161 }
162
163 pub fn font_weight<S: Into<String>>(mut self, font_weight: S) -> Self {
164 self.font_weight = Some(font_weight.into());
165 self
166 }
167
168 pub fn font_family<S: Into<String>>(mut self, font_family: S) -> Self {
169 self.font_family = Some(font_family.into());
170 self
171 }
172
173 pub fn font_size<F: Into<i64>>(mut self, font_size: F) -> Self {
174 self.font_size = Some(font_size.into());
175 self
176 }
177
178 pub fn line_height<F: Into<i64>>(mut self, line_height: F) -> Self {
179 self.line_height = Some(line_height.into());
180 self
181 }
182
183 pub fn background_color<C: Into<Color>>(mut self, background_color: C) -> Self {
184 self.background_color = Some(background_color.into());
185 self
186 }
187
188 pub fn border_color<C: Into<Color>>(mut self, border_color: C) -> Self {
189 self.border_color = Some(border_color.into());
190 self
191 }
192
193 pub fn border_width<F: Into<i64>>(mut self, border_width: F) -> Self {
194 self.border_width = Some(border_width.into());
195 self
196 }
197
198 pub fn border_type<S: Into<String>>(mut self, border_type: S) -> Self {
199 self.border_type = Some(border_type.into());
200 self
201 }
202
203 pub fn border_dash_offset<F: Into<i64>>(mut self, border_dash_offset: F) -> Self {
204 self.border_dash_offset = Some(border_dash_offset.into());
205 self
206 }
207
208 pub fn border_radius<C: Into<CompositeValue>>(mut self, border_radius: C) -> Self {
209 self.border_radius = Some(border_radius.into());
210 self
211 }
212
213 pub fn padding<C: Into<Padding>>(mut self, padding: C) -> Self {
214 self.padding = Some(padding.into());
215 self
216 }
217
218 pub fn shadow_color<C: Into<Color>>(mut self, shadow_color: C) -> Self {
219 self.shadow_color = Some(shadow_color.into());
220 self
221 }
222
223 pub fn shadow_blur<F: Into<i64>>(mut self, shadow_blur: F) -> Self {
224 self.shadow_blur = Some(shadow_blur.into());
225 self
226 }
227
228 pub fn shadow_offset_x<F: Into<i64>>(mut self, shadow_offset_x: F) -> Self {
229 self.shadow_offset_x = Some(shadow_offset_x.into());
230 self
231 }
232
233 pub fn shadow_offset_y<F: Into<i64>>(mut self, shadow_offset_y: F) -> Self {
234 self.shadow_offset_y = Some(shadow_offset_y.into());
235 self
236 }
237
238 pub fn width<C: Into<CompositeValue>>(mut self, width: C) -> Self {
239 self.width = Some(width.into());
240 self
241 }
242
243 pub fn height<C: Into<CompositeValue>>(mut self, height: C) -> Self {
244 self.height = Some(height.into());
245 self
246 }
247
248 pub fn text_border_color<C: Into<Color>>(mut self, text_border_color: C) -> Self {
249 self.text_border_color = Some(text_border_color.into());
250 self
251 }
252
253 pub fn text_border_width<F: Into<i64>>(mut self, text_border_width: F) -> Self {
254 self.text_border_width = Some(text_border_width.into());
255 self
256 }
257
258 pub fn text_border_type<S: Into<String>>(mut self, text_border_type: S) -> Self {
259 self.text_border_type = Some(text_border_type.into());
260 self
261 }
262
263 pub fn text_border_dash_offset<F: Into<i64>>(mut self, text_border_dash_offset: F) -> Self {
264 self.text_border_dash_offset = Some(text_border_dash_offset.into());
265 self
266 }
267
268 pub fn text_shadow_color<C: Into<Color>>(mut self, text_shadow_color: C) -> Self {
269 self.text_shadow_color = Some(text_shadow_color.into());
270 self
271 }
272
273 pub fn text_shadow_blur<F: Into<i64>>(mut self, text_shadow_blur: F) -> Self {
274 self.text_shadow_blur = Some(text_shadow_blur.into());
275 self
276 }
277
278 pub fn text_shadow_offset_x<F: Into<i64>>(mut self, text_shadow_offset_x: F) -> Self {
279 self.text_shadow_offset_x = Some(text_shadow_offset_x.into());
280 self
281 }
282
283 pub fn text_shadow_offset_y<F: Into<i64>>(mut self, text_shadow_offset_y: F) -> Self {
284 self.text_shadow_offset_y = Some(text_shadow_offset_y.into());
285 self
286 }
287
288 pub fn overflow<S: Into<String>>(mut self, overflow: S) -> Self {
289 self.overflow = Some(overflow.into());
290 self
291 }
292}
293
294#[derive(Serialize)]
295#[serde(rename_all = "camelCase")]
296pub struct RadarIndicator {
297 #[serde(skip_serializing_if = "Option::is_none")]
298 name: Option<String>,
299
300 #[serde(skip_serializing_if = "Option::is_none")]
301 max: Option<i64>,
302
303 #[serde(skip_serializing_if = "Option::is_none")]
304 min: Option<i64>,
305
306 #[serde(skip_serializing_if = "Option::is_none")]
307 color: Option<Color>,
308}
309
310impl RadarIndicator {
311 pub fn new() -> Self {
312 Self {
313 name: None,
314 max: None,
315 min: None,
316 color: None,
317 }
318 }
319
320 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
321 self.name = Some(name.into());
322 self
323 }
324
325 pub fn max(mut self, max: impl Into<i64>) -> Self {
326 self.max = Some(max.into());
327 self
328 }
329
330 pub fn min(mut self, min: impl Into<i64>) -> Self {
331 self.min = Some(min.into());
332 self
333 }
334
335 pub fn color(mut self, color: Color) -> Self {
336 self.color = Some(color);
337 self
338 }
339}
340
341impl From<(&str, i64, i64)> for RadarIndicator {
342 fn from((name, min, max): (&str, i64, i64)) -> Self {
343 Self {
344 name: Some(name.into()),
345 min: Some(min),
346 max: Some(max),
347 color: None,
348 }
349 }
350}
351
352
353
354#[derive(Serialize)]
355#[serde(rename_all = "camelCase")]
356pub struct RadarCoordinate {
357 #[serde(skip_serializing_if = "Option::is_none")]
358 id: Option<String>,
359
360 #[serde(skip_serializing_if = "Option::is_none")]
362 zlevel: Option<i64>,
363
364 #[serde(skip_serializing_if = "Option::is_none")]
366 z: Option<i64>,
367
368 #[serde(skip_serializing_if = "Option::is_none")]
369 center: Option<CompositeValue>,
370
371 #[serde(skip_serializing_if = "Option::is_none")]
372 radius: Option<CompositeValue>,
373
374 #[serde(skip_serializing_if = "Option::is_none")]
375 start_angle: Option<i64>,
376
377 #[serde(skip_serializing_if = "Option::is_none")]
378 axis_name: Option<RadarAxisName>,
379
380 #[serde(skip_serializing_if = "Option::is_none")]
381 name_gap: Option<i64>,
382
383 #[serde(skip_serializing_if = "Option::is_none")]
384 split_number: Option<i64>,
385
386 #[serde(skip_serializing_if = "Option::is_none")]
387 shape: Option<Shape>,
388
389 #[serde(skip_serializing_if = "Option::is_none")]
390 scale: Option<bool>,
391
392 #[serde(skip_serializing_if = "Option::is_none")]
393 axis_line: Option<AxisLine>,
394
395 #[serde(skip_serializing_if = "Option::is_none")]
396 axis_tick: Option<AxisTick>,
397
398 #[serde(skip_serializing_if = "Option::is_none")]
399 axis_label: Option<AxisLabel>,
400
401 #[serde(skip_serializing_if = "Option::is_none")]
402 split_line: Option<SplitLine>,
403
404 #[serde(skip_serializing_if = "Option::is_none")]
405 split_area: Option<SplitArea>,
406
407 #[serde(skip_serializing_if = "Vec::is_empty")]
408 indicator: Vec<RadarIndicator>,
409}
410
411impl RadarCoordinate {
412 pub fn new() -> Self {
413 Self {
414 id: None,
415 zlevel: None,
416 z: None,
417 center: None,
418 radius: None,
419 start_angle: None,
420 axis_name: None,
421 name_gap: None,
422 split_number: None,
423 shape: None,
424 scale: None,
425 axis_line: None,
426 axis_tick: None,
427 axis_label: None,
428 split_line: None,
429 split_area: None,
430 indicator: vec![],
431 }
432 }
433
434 pub fn center<C: Into<CompositeValue>>(mut self, center: C) -> Self {
435 self.center = Some(center.into());
436 self
437 }
438
439 pub fn radius<C: Into<CompositeValue>>(mut self, radius: C) -> Self {
440 self.radius = Some(radius.into());
441 self
442 }
443
444 pub fn start_angle<F: Into<i64>>(mut self, start_angle: F) -> Self {
445 self.start_angle = Some(start_angle.into());
446 self
447 }
448
449 pub fn axis_name<R: Into<RadarAxisName>>(mut self, axis_name: R) -> Self {
450 self.axis_name = Some(axis_name.into());
451 self
452 }
453
454 pub fn name_gap<F: Into<i64>>(mut self, name_gap: F) -> Self {
455 self.name_gap = Some(name_gap.into());
456 self
457 }
458
459 pub fn split_number<F: Into<i64>>(mut self, split_number: F) -> Self {
460 self.split_number = Some(split_number.into());
461 self
462 }
463
464 pub fn shape<S: Into<Shape>>(mut self, shape: S) -> Self {
465 self.shape = Some(shape.into());
466 self
467 }
468
469 pub fn scale(mut self, scale: bool) -> Self {
470 self.scale = Some(scale);
471 self
472 }
473
474 pub fn axis_line<L: Into<AxisLine>>(mut self, axis_line: L) -> Self {
475 self.axis_line = Some(axis_line.into());
476 self
477 }
478
479 pub fn axis_tick<T: Into<AxisTick>>(mut self, axis_tick: T) -> Self {
480 self.axis_tick = Some(axis_tick.into());
481 self
482 }
483
484 pub fn axis_label<L: Into<AxisLabel>>(mut self, axis_label: L) -> Self {
485 self.axis_label = Some(axis_label.into());
486 self
487 }
488
489 pub fn split_line<L: Into<SplitLine>>(mut self, split_line: L) -> Self {
490 self.split_line = Some(split_line.into());
491 self
492 }
493
494 pub fn split_area<A: Into<SplitArea>>(mut self, split_area: A) -> Self {
495 self.split_area = Some(split_area.into());
496 self
497 }
498
499 pub fn indicator<I: Into<RadarIndicator>>(mut self, indicator: Vec<I>) -> Self {
500 self.indicator = indicator.into_iter().map(|i| i.into()).collect();
501 self
502 }
503}