plotly_patched/
surface.rs

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