1use crate::common::color::{Color, ColorWrapper};
4use crate::common::{Calendar, ColorBar, ColorScale, Dim, Font, HoverInfo, Label, Line, PlotType};
5use crate::private;
6use crate::Trace;
7use serde::Serialize;
8
9#[derive(Serialize, Debug)]
10pub enum ContoursType {
11 #[serde(rename = "levels")]
12 Levels,
13 #[serde(rename = "constraint")]
14 Constraint,
15}
16
17#[derive(Serialize, Debug)]
18pub enum ContoursColoring {
19 #[serde(rename = "fill")]
20 Fill,
21 #[serde(rename = "heatmap")]
22 HeatMap,
23 #[serde(rename = "lines")]
24 Lines,
25 #[serde(rename = "none")]
26 None,
27}
28
29#[derive(Serialize, Debug, Default)]
30pub struct Contours {
31 #[serde(skip_serializing_if = "Option::is_none")]
32 r#type: Option<ContoursType>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 start: Option<f64>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 end: Option<f64>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 size: Option<usize>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 coloring: Option<ContoursColoring>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 show_lines: Option<bool>,
43 #[serde(skip_serializing_if = "Option::is_none", rename = "showlabels")]
44 show_labels: Option<bool>,
45 #[serde(skip_serializing_if = "Option::is_none", rename = "labelfont")]
46 label_font: Option<Font>,
47 #[serde(skip_serializing_if = "Option::is_none", rename = "labelformat")]
48 label_format: Option<String>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 operation: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 value: Option<f64>,
53}
54
55impl Contours {
56 pub fn new() -> Contours {
57 Default::default()
58 }
59
60 pub fn type_(mut self, t: ContoursType) -> Contours {
61 self.r#type = Some(t);
62 self
63 }
64
65 pub fn start(mut self, start: f64) -> Contours {
66 self.start = Some(start);
67 self
68 }
69
70 pub fn end(mut self, end: f64) -> Contours {
71 self.end = Some(end);
72 self
73 }
74
75 pub fn size(mut self, size: usize) -> Contours {
76 self.size = Some(size);
77 self
78 }
79
80 pub fn coloring(mut self, coloring: ContoursColoring) -> Contours {
81 self.coloring = Some(coloring);
82 self
83 }
84
85 pub fn show_lines(mut self, show_lines: bool) -> Contours {
86 self.show_lines = Some(show_lines);
87 self
88 }
89
90 pub fn show_labels(mut self, show_labels: bool) -> Contours {
91 self.show_labels = Some(show_labels);
92 self
93 }
94
95 pub fn label_font(mut self, label_font: Font) -> Contours {
96 self.label_font = Some(label_font);
97 self
98 }
99
100 pub fn label_format(mut self, label_format: &str) -> Contours {
101 self.label_format = Some(label_format.to_owned());
102 self
103 }
104
105 pub fn operation(mut self, operation: &str) -> Contours {
106 self.operation = Some(operation.to_owned());
107 self
108 }
109
110 pub fn value(mut self, value: f64) -> Contours {
111 self.value = Some(value);
112 self
113 }
114}
115
116#[derive(Serialize, Debug, Default)]
117pub struct Contour<Z, X = f64, Y = f64>
118where
119 X: Serialize + Default,
120 Y: Serialize + Default,
121 Z: Serialize + Default,
122{
123 r#type: PlotType,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 name: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 visible: Option<bool>,
128 #[serde(skip_serializing_if = "Option::is_none", rename = "showlegend")]
129 show_legend: Option<bool>,
130 #[serde(skip_serializing_if = "Option::is_none", rename = "legendgroup")]
131 legend_group: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 opacity: Option<f64>,
134 #[serde(skip_serializing_if = "Option::is_none")]
135 x: Option<Vec<X>>,
136
137 #[serde(skip_serializing_if = "Option::is_none")]
138 x0: Option<X>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 dx: Option<X>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
143 y: Option<Vec<Y>>,
144
145 #[serde(skip_serializing_if = "Option::is_none")]
146 y0: Option<Y>,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 dy: Option<Y>,
149
150 z: Vec<Z>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 text: Option<Vec<String>>,
153 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertext")]
154 hover_text: Option<Vec<String>>,
155 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverinfo")]
156 hover_info: Option<HoverInfo>,
157 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertemplate")]
158 hover_template: Option<Dim<String>>,
159
160 #[serde(skip_serializing_if = "Option::is_none", rename = "xaxis")]
161 x_axis: Option<String>,
162 #[serde(skip_serializing_if = "Option::is_none", rename = "yaxis")]
163 y_axis: Option<String>,
164
165 #[serde(skip_serializing_if = "Option::is_none")]
166 line: Option<Line>,
167 #[serde(skip_serializing_if = "Option::is_none", rename = "colorbar")]
168 color_bar: Option<ColorBar>,
169 #[serde(skip_serializing_if = "Option::is_none", rename = "autocolorscale")]
170 auto_color_scale: Option<bool>,
171 #[serde(skip_serializing_if = "Option::is_none", rename = "colorscale")]
172 color_scale: Option<ColorScale>,
173 #[serde(skip_serializing_if = "Option::is_none", rename = "showscale")]
174 show_scale: Option<bool>,
175 #[serde(skip_serializing_if = "Option::is_none", rename = "reversescale")]
176 reverse_scale: Option<bool>,
177 #[serde(skip_serializing_if = "Option::is_none")]
178 zauto: Option<bool>,
179 #[serde(skip_serializing_if = "Option::is_none", rename = "zhoverformat")]
180 zhover_format: Option<String>,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 zmax: Option<Z>,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 zmid: Option<Z>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 zmin: Option<Z>,
187 #[serde(skip_serializing_if = "Option::is_none", rename = "autocontour")]
188 auto_contour: Option<bool>,
189 #[serde(skip_serializing_if = "Option::is_none", rename = "connectgaps")]
190 connect_gaps: Option<bool>,
191 #[serde(skip_serializing_if = "Option::is_none")]
192 contours: Option<Contours>,
193 #[serde(skip_serializing_if = "Option::is_none")]
194 fill_color: Option<ColorWrapper>,
195 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverlabel")]
196 hover_label: Option<Label>,
197 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverongaps")]
198 hover_on_gaps: Option<bool>,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 n_contours: Option<usize>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 transpose: Option<bool>,
203 #[serde(skip_serializing_if = "Option::is_none", rename = "xcalendar")]
204 x_calendar: Option<Calendar>,
205 #[serde(skip_serializing_if = "Option::is_none", rename = "ycalendar")]
206 y_calendar: Option<Calendar>,
207}
208
209impl<Z> Contour<Z, f64, f64>
210where
211 Z: Serialize + Default,
212{
213 pub fn new_z(z: Vec<Z>) -> Box<Contour<Z, f64, f64>> {
214 Box::new(Contour {
215 r#type: PlotType::Contour,
216 z,
217 ..Default::default()
218 })
219 }
220}
221
222impl<Z, X, Y> Contour<Z, X, Y>
223where
224 X: Serialize + Default,
225 Y: Serialize + Default,
226 Z: Serialize + Default,
227{
228 pub fn new(x: Vec<X>, y: Vec<Y>, z: Vec<Z>) -> Box<Contour<Z, X, Y>> {
229 Box::new(Contour {
230 r#type: PlotType::Contour,
231 x: Some(x),
232 y: Some(y),
233 z,
234 ..Default::default()
235 })
236 }
237
238 pub fn x(mut self, x: Vec<X>) -> Box<Contour<Z, X, Y>> {
239 self.x = Some(x);
240 Box::new(self)
241 }
242
243 pub fn x0(mut self, x0: X) -> Box<Contour<Z, X, Y>> {
244 self.x0 = Some(x0);
245 Box::new(self)
246 }
247
248 pub fn dx(mut self, dx: X) -> Box<Contour<Z, X, Y>> {
249 self.dx = Some(dx);
250 Box::new(self)
251 }
252
253 pub fn y0(mut self, y0: Y) -> Box<Contour<Z, X, Y>> {
254 self.y0 = Some(y0);
255 Box::new(self)
256 }
257
258 pub fn dy(mut self, dy: Y) -> Box<Contour<Z, X, Y>> {
259 self.dy = Some(dy);
260 Box::new(self)
261 }
262
263 pub fn y(mut self, y: Vec<Y>) -> Box<Contour<Z, X, Y>> {
264 self.y = Some(y);
265 Box::new(self)
266 }
267
268 pub fn name(mut self, name: &str) -> Box<Contour<Z, X, Y>> {
269 self.name = Some(name.to_owned());
270 Box::new(self)
271 }
272
273 pub fn visible(mut self, visible: bool) -> Box<Contour<Z, X, Y>> {
274 self.visible = Some(visible);
275 Box::new(self)
276 }
277
278 pub fn show_legend(mut self, show_legend: bool) -> Box<Contour<Z, X, Y>> {
279 self.show_legend = Some(show_legend);
280 Box::new(self)
281 }
282
283 pub fn legend_group(mut self, legend_group: &str) -> Box<Contour<Z, X, Y>> {
284 self.legend_group = Some(legend_group.to_owned());
285 Box::new(self)
286 }
287
288 pub fn opacity(mut self, opacity: f64) -> Box<Contour<Z, X, Y>> {
289 self.opacity = Some(opacity);
290 Box::new(self)
291 }
292
293 pub fn text<S: AsRef<str>>(mut self, text: Vec<S>) -> Box<Contour<Z, X, Y>> {
294 let text = private::owned_string_vector(text);
295 self.text = Some(text);
296 Box::new(self)
297 }
298
299 pub fn hover_text(mut self, hover_text: Vec<String>) -> Box<Contour<Z, X, Y>> {
300 let hover_text = private::owned_string_vector(hover_text);
301 self.hover_text = Some(hover_text);
302 Box::new(self)
303 }
304
305 pub fn hover_info(mut self, hover_info: HoverInfo) -> Box<Contour<Z, X, Y>> {
306 self.hover_info = Some(hover_info);
307 Box::new(self)
308 }
309
310 pub fn hover_template(mut self, hover_template: &str) -> Box<Contour<Z, X, Y>> {
311 self.hover_template = Some(Dim::Scalar(hover_template.to_owned()));
312 Box::new(self)
313 }
314
315 pub fn x_axis(mut self, axis: &str) -> Box<Contour<Z, X, Y>> {
316 self.x_axis = Some(axis.to_owned());
317 Box::new(self)
318 }
319
320 pub fn y_axis(mut self, axis: &str) -> Box<Contour<Z, X, Y>> {
321 self.y_axis = Some(axis.to_owned());
322 Box::new(self)
323 }
324
325 pub fn hover_template_array<S: AsRef<str>>(
326 mut self,
327 hover_template: Vec<S>,
328 ) -> Box<Contour<Z, X, Y>> {
329 let hover_template = private::owned_string_vector(hover_template);
330 self.hover_template = Some(Dim::Vector(hover_template));
331 Box::new(self)
332 }
333
334 pub fn line(mut self, line: Line) -> Box<Contour<Z, X, Y>> {
335 self.line = Some(line);
336 Box::new(self)
337 }
338
339 pub fn color_bar(mut self, color_bar: ColorBar) -> Box<Contour<Z, X, Y>> {
340 self.color_bar = Some(color_bar);
341 Box::new(self)
342 }
343
344 pub fn auto_color_scale(mut self, auto_color_scale: bool) -> Box<Contour<Z, X, Y>> {
345 self.auto_color_scale = Some(auto_color_scale);
346 Box::new(self)
347 }
348
349 pub fn color_scale(mut self, color_scale: ColorScale) -> Box<Contour<Z, X, Y>> {
350 self.color_scale = Some(color_scale);
351 Box::new(self)
352 }
353
354 pub fn show_scale(mut self, show_scale: bool) -> Box<Contour<Z, X, Y>> {
355 self.show_scale = Some(show_scale);
356 Box::new(self)
357 }
358
359 pub fn reverse_scale(mut self, reverse_scale: bool) -> Box<Contour<Z, X, Y>> {
360 self.reverse_scale = Some(reverse_scale);
361 Box::new(self)
362 }
363
364 pub fn zauto(mut self, zauto: bool) -> Box<Contour<Z, X, Y>> {
365 self.zauto = Some(zauto);
366 Box::new(self)
367 }
368
369 pub fn zhover_format(mut self, zhover_format: &str) -> Box<Contour<Z, X, Y>> {
370 self.zhover_format = Some(zhover_format.to_owned());
371 Box::new(self)
372 }
373
374 pub fn zmax(mut self, zmax: Z) -> Box<Contour<Z, X, Y>> {
375 self.zmax = Some(zmax);
376 Box::new(self)
377 }
378
379 pub fn zmid(mut self, zmid: Z) -> Box<Contour<Z, X, Y>> {
380 self.zmid = Some(zmid);
381 Box::new(self)
382 }
383
384 pub fn zmin(mut self, zmin: Z) -> Box<Contour<Z, X, Y>> {
385 self.zmin = Some(zmin);
386 Box::new(self)
387 }
388
389 pub fn auto_contour(mut self, auto_contour: bool) -> Box<Contour<Z, X, Y>> {
390 self.auto_contour = Some(auto_contour);
391 Box::new(self)
392 }
393
394 pub fn connect_gaps(mut self, connect_gaps: bool) -> Box<Contour<Z, X, Y>> {
395 self.connect_gaps = Some(connect_gaps);
396 Box::new(self)
397 }
398
399 pub fn contours(mut self, contours: Contours) -> Box<Contour<Z, X, Y>> {
400 self.contours = Some(contours);
401 Box::new(self)
402 }
403
404 pub fn fill_color<C: Color>(mut self, fill_color: C) -> Box<Contour<Z, X, Y>> {
405 self.fill_color = Some(fill_color.to_color());
406 Box::new(self)
407 }
408
409 pub fn hover_label(mut self, hover_label: Label) -> Box<Contour<Z, X, Y>> {
410 self.hover_label = Some(hover_label);
411 Box::new(self)
412 }
413
414 pub fn hover_on_gaps(mut self, hover_on_gaps: bool) -> Box<Contour<Z, X, Y>> {
415 self.hover_on_gaps = Some(hover_on_gaps);
416 Box::new(self)
417 }
418
419 pub fn n_contours(mut self, n_contours: usize) -> Box<Contour<Z, X, Y>> {
420 self.n_contours = Some(n_contours);
421 Box::new(self)
422 }
423
424 pub fn transpose(mut self, transpose: bool) -> Box<Contour<Z, X, Y>> {
425 self.transpose = Some(transpose);
426 Box::new(self)
427 }
428
429 pub fn x_calendar(mut self, x_calendar: Calendar) -> Box<Contour<Z, X, Y>> {
430 self.x_calendar = Some(x_calendar);
431 Box::new(self)
432 }
433
434 pub fn y_calendar(mut self, y_calendar: Calendar) -> Box<Contour<Z, X, Y>> {
435 self.y_calendar = Some(y_calendar);
436 Box::new(self)
437 }
438}
439
440impl<X, Y, Z> Trace for Contour<X, Y, Z>
441where
442 X: Serialize + Default,
443 Y: Serialize + Default,
444 Z: Serialize + Default,
445{
446 fn serialize(&self) -> String {
447 serde_json::to_string(&self).unwrap()
448 }
449}