mdbook_plotly/code_handler/plot_obj_parser/
surface_parser.rs1use super::until::{Color, Map, must_translate};
2use crate::{translate, translate_enum};
3use anyhow::Result;
4use plotly::Surface;
5
6pub fn parse_surface_data(
7 sf_obj: &mut serde_json::Value,
8 map: &Map,
9) -> Result<Box<Surface<f64, f64, f64>>> {
10 let z: Vec<Vec<f64>> = must_translate(sf_obj, map, "z")?;
11 let surface = Surface::new(z);
12
13 let surface = translate! {
14 surface,
15 sf_obj,
16 map,
17 (x, Vec<f64>),
18 (y, Vec<f64>),
19 (name, String),
20 (opacity, f64),
21 (text, String),
22 (text_array, Vec<String>),
23 (hover_text, String),
24 (hover_text_array, Vec<String>),
25 (hover_template, String),
26 (hover_template_array, Vec<String>),
27 (show_legend, bool),
28 (legend_group, String),
29 (connect_gaps, bool),
30 (hide_surface, bool),
31 (surface_color, Vec<Color>),
32 (auto_color_scale, bool),
33 (reverse_scale, bool),
34 (show_scale, bool),
35 (cauto, bool),
36 (cmax, f64),
37 (cmin, f64),
38 (cmid, f64),
39 }?;
40
41 use plotly::common::HoverInfo;
42 let surface = translate_enum! {
43 surface,
44 sf_obj,
45 map,
46 (hover_info, {
47 "all" => HoverInfo::All,
48 "x" => HoverInfo::X,
49 "y" => HoverInfo::Y,
50 "z" => HoverInfo::Z,
51 "x+y" => HoverInfo::XAndY,
52 "x+z" => HoverInfo::XAndZ,
53 "y+z" => HoverInfo::YAndZ,
54 "x+y+z" => HoverInfo::XAndYAndZ,
55 "text" => HoverInfo::Text,
56 "name" => HoverInfo::Name,
57 "none" => HoverInfo::None,
58 "skip" => HoverInfo::Skip,
59 }),
60 }?;
61
62 let surface = if let Some(color_bar_obj) = sf_obj.get_mut("color_bar")
63 && color_bar_obj.is_object()
64 {
65 use plotly::common::ColorBar;
66 let color_bar = translate! {
67 ColorBar::new(),
68 color_bar_obj,
69 map,
70 (thickness, usize),
71 (len, usize),
72 (x, f64),
73 (y, f64),
74 (title, String),
75 }?;
76 surface.color_bar(color_bar)
77 } else {
78 surface
79 };
80
81 let surface = if sf_obj.get("color_scale").is_some() {
82 use plotly::common::{ColorScale, ColorScalePalette};
83 let color_scale_str: String = must_translate(sf_obj, map, "color_scale")?;
84 let palette = match color_scale_str.to_lowercase().as_str() {
85 "greys" => ColorScalePalette::Greys,
86 "ylgnbu" => ColorScalePalette::YlGnBu,
87 "greens" => ColorScalePalette::Greens,
88 "ylorrd" => ColorScalePalette::YlOrRd,
89 "bluered" => ColorScalePalette::Bluered,
90 "rdbu" => ColorScalePalette::RdBu,
91 "reds" => ColorScalePalette::Reds,
92 "blues" => ColorScalePalette::Blues,
93 "picnic" => ColorScalePalette::Picnic,
94 "rainbow" => ColorScalePalette::Rainbow,
95 "portland" => ColorScalePalette::Portland,
96 "jet" => ColorScalePalette::Jet,
97 "hot" => ColorScalePalette::Hot,
98 "blackbody" => ColorScalePalette::Blackbody,
99 "earth" => ColorScalePalette::Earth,
100 "electric" => ColorScalePalette::Electric,
101 "viridis" => ColorScalePalette::Viridis,
102 "cividis" => ColorScalePalette::Cividis,
103 _ => return Err(anyhow::anyhow!("unknown color_scale: {}", color_scale_str)),
104 };
105 surface.color_scale(ColorScale::Palette(palette))
106 } else {
107 surface
108 };
109
110 let surface = if let Some(lighting_obj) = sf_obj.get_mut("lighting")
111 && lighting_obj.is_object()
112 {
113 use plotly::traces::surface::Lighting;
114 let lighting = translate! {
115 Lighting::new(),
116 lighting_obj,
117 map,
118 (ambient, f64),
119 (diffuse, f64),
120 (specular, f64),
121 (roughness, f64),
122 (fresnel, f64),
123 }?;
124 surface.lighting(lighting)
125 } else {
126 surface
127 };
128
129 let surface = if let Some(light_pos_obj) = sf_obj.get_mut("light_position")
130 && light_pos_obj.is_object()
131 {
132 use plotly::traces::surface::Position;
133 let x: i32 = must_translate(light_pos_obj, map, "x")?;
134 let y: i32 = must_translate(light_pos_obj, map, "y")?;
135 let z: i32 = must_translate(light_pos_obj, map, "z")?;
136 surface.light_position(Position::new(x, y, z))
137 } else {
138 surface
139 };
140
141 Ok(surface)
142}