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