charming_fork_zephyr/series/
funnel.rs

1use serde::Serialize;
2
3use crate::{
4    datatype::{CompositeValue, DataFrame, DataPoint},
5    element::{ColorBy, Emphasis, ItemStyle, Label, LabelLine, Orient, Sort},
6};
7
8#[derive(Serialize)]
9#[serde(rename_all = "snake_case")]
10pub enum Align {
11    Left,
12    Right,
13    Center,
14}
15
16#[derive(Serialize)]
17#[serde(rename_all = "camelCase")]
18pub struct Funnel {
19    #[serde(rename = "type")]
20    type_: String,
21
22    #[serde(skip_serializing_if = "Option::is_none")]
23    id: Option<String>,
24
25    #[serde(skip_serializing_if = "Option::is_none")]
26    name: Option<String>,
27
28    #[serde(skip_serializing_if = "Option::is_none")]
29    color_by: Option<ColorBy>,
30
31    #[serde(skip_serializing_if = "Option::is_none")]
32    min: Option<i64>,
33
34    #[serde(skip_serializing_if = "Option::is_none")]
35    max: Option<i64>,
36
37    #[serde(skip_serializing_if = "Option::is_none")]
38    min_size: Option<String>,
39
40    #[serde(skip_serializing_if = "Option::is_none")]
41    max_size: Option<String>,
42
43    #[serde(skip_serializing_if = "Option::is_none")]
44    width: Option<CompositeValue>,
45
46    #[serde(skip_serializing_if = "Option::is_none")]
47    height: Option<CompositeValue>,
48
49    #[serde(skip_serializing_if = "Option::is_none")]
50    left: Option<CompositeValue>,
51
52    #[serde(skip_serializing_if = "Option::is_none")]
53    top: Option<CompositeValue>,
54
55    #[serde(skip_serializing_if = "Option::is_none")]
56    right: Option<CompositeValue>,
57
58    #[serde(skip_serializing_if = "Option::is_none")]
59    bottom: Option<CompositeValue>,
60
61    #[serde(skip_serializing_if = "Option::is_none")]
62    orient: Option<Orient>,
63
64    #[serde(skip_serializing_if = "Option::is_none")]
65    sort: Option<Sort>,
66
67    #[serde(skip_serializing_if = "Option::is_none")]
68    gap: Option<i64>,
69
70    #[serde(skip_serializing_if = "Option::is_none")]
71    legend_hover_link: Option<bool>,
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    funnel_align: Option<Align>,
75
76    #[serde(skip_serializing_if = "Option::is_none")]
77    label: Option<Label>,
78
79    #[serde(skip_serializing_if = "Option::is_none")]
80    label_line: Option<LabelLine>,
81
82    #[serde(skip_serializing_if = "Option::is_none")]
83    item_style: Option<ItemStyle>,
84
85    #[serde(skip_serializing_if = "Option::is_none")]
86    emphasis: Option<Emphasis>,
87
88    #[serde(skip_serializing_if = "Vec::is_empty")]
89    data: DataFrame,
90}
91
92impl Funnel {
93    pub fn new() -> Self {
94        Self {
95            type_: "funnel".to_string(),
96            id: None,
97            name: None,
98            color_by: None,
99            min: None,
100            max: None,
101            min_size: None,
102            max_size: None,
103            width: None,
104            height: None,
105            left: None,
106            top: None,
107            right: None,
108            bottom: None,
109            orient: None,
110            sort: None,
111            gap: None,
112            legend_hover_link: None,
113            funnel_align: None,
114            label: None,
115            label_line: None,
116            item_style: None,
117            emphasis: None,
118            data: vec![],
119        }
120    }
121
122    pub fn id<S: Into<String>>(mut self, id: S) -> Self {
123        self.id = Some(id.into());
124        self
125    }
126
127    pub fn name<S: Into<String>>(mut self, name: S) -> Self {
128        self.name = Some(name.into());
129        self
130    }
131
132    pub fn color_by(mut self, color_by: ColorBy) -> Self {
133        self.color_by = Some(color_by);
134        self
135    }
136
137    pub fn min<F: Into<i64>>(mut self, min: F) -> Self {
138        self.min = Some(min.into());
139        self
140    }
141
142    pub fn max<F: Into<i64>>(mut self, max: F) -> Self {
143        self.max = Some(max.into());
144        self
145    }
146
147    pub fn min_size<S: Into<String>>(mut self, min_size: S) -> Self {
148        self.min_size = Some(min_size.into());
149        self
150    }
151
152    pub fn max_size<S: Into<String>>(mut self, max_size: S) -> Self {
153        self.max_size = Some(max_size.into());
154        self
155    }
156
157    pub fn width<C: Into<CompositeValue>>(mut self, width: C) -> Self {
158        self.width = Some(width.into());
159        self
160    }
161
162    pub fn height<C: Into<CompositeValue>>(mut self, height: C) -> Self {
163        self.height = Some(height.into());
164        self
165    }
166
167    pub fn left<C: Into<CompositeValue>>(mut self, left: C) -> Self {
168        self.left = Some(left.into());
169        self
170    }
171
172    pub fn top<C: Into<CompositeValue>>(mut self, top: C) -> Self {
173        self.top = Some(top.into());
174        self
175    }
176
177    pub fn right<C: Into<CompositeValue>>(mut self, right: C) -> Self {
178        self.right = Some(right.into());
179        self
180    }
181
182    pub fn bottom<C: Into<CompositeValue>>(mut self, bottom: C) -> Self {
183        self.bottom = Some(bottom.into());
184        self
185    }
186
187    pub fn orient<O: Into<Orient>>(mut self, orient: O) -> Self {
188        self.orient = Some(orient.into());
189        self
190    }
191
192    pub fn sort<S: Into<Sort>>(mut self, sort: S) -> Self {
193        self.sort = Some(sort.into());
194        self
195    }
196
197    pub fn gap<F: Into<i64>>(mut self, gap: F) -> Self {
198        self.gap = Some(gap.into());
199        self
200    }
201
202    pub fn legend_hover_link(mut self, legend_hover_link: bool) -> Self {
203        self.legend_hover_link = Some(legend_hover_link);
204        self
205    }
206
207    pub fn funnel_align<A: Into<Align>>(mut self, funnel_align: A) -> Self {
208        self.funnel_align = Some(funnel_align.into());
209        self
210    }
211
212    pub fn label<L: Into<Label>>(mut self, label: L) -> Self {
213        self.label = Some(label.into());
214        self
215    }
216
217    pub fn label_line<L: Into<LabelLine>>(mut self, label_line: L) -> Self {
218        self.label_line = Some(label_line.into());
219        self
220    }
221
222    pub fn item_style<I: Into<ItemStyle>>(mut self, item_style: I) -> Self {
223        self.item_style = Some(item_style.into());
224        self
225    }
226
227    pub fn emphasis<E: Into<Emphasis>>(mut self, emphasis: E) -> Self {
228        self.emphasis = Some(emphasis.into());
229        self
230    }
231
232    pub fn data<D: Into<DataPoint>>(mut self, data: Vec<D>) -> Self {
233        self.data = data.into_iter().map(|d| d.into()).collect();
234        self
235    }
236}