1use 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}