Skip to main content

mdbook_plotly/code_handler/plot_obj_parser/
contour_parser.rs

1use super::common::parse_color_bar;
2use super::until::{Color, must_translate_from_context};
3use crate::code_handler::parse_context::ParseContext;
4use crate::{translate_enum_with_config, translate_with_config};
5use anyhow::Result;
6use plotly::{Contour, Trace};
7
8pub fn parse_contour_data(
9    ct_obj: &mut serde_json::Value,
10    context: &ParseContext<'_>,
11) -> Result<Box<Contour<Vec<f64>, f64, f64>>> {
12    let z: Vec<Vec<f64>> = must_translate_from_context(ct_obj, context, "z")?;
13    let contour = if ct_obj.get("x").is_some() {
14        let x: Vec<f64> = must_translate_from_context(ct_obj, context, "x")?;
15        let y: Vec<f64> = must_translate_from_context(ct_obj, context, "y")?;
16        Contour::new(x, y, z)
17    } else {
18        Contour::new_z(z)
19    };
20
21    let contour = translate_with_config! {
22        contour,
23        ct_obj,
24        context.map(),
25        context.map_eval(),
26        (x0, f64),
27        (dx, f64),
28        (y0, f64),
29        (dy, f64),
30        (opacity, f64),
31        (n_contours, usize),
32        (connect_gaps, bool),
33        (hover_on_gaps, bool),
34        (show_legend, bool),
35        (transpose, bool),
36        (auto_contour, bool),
37        (auto_color_scale, bool),
38        (reverse_scale, bool),
39        (show_scale, bool),
40        (zauto, bool),
41        (fill_color, Color),
42    }?;
43
44    use plotly::common::HoverInfo;
45    let contour = translate_enum_with_config! {
46        contour,
47        ct_obj,
48        context.map(),
49        context.map_eval(),
50        (hover_info, {
51            "all" => HoverInfo::All,
52            "x" => HoverInfo::X,
53            "y" => HoverInfo::Y,
54            "z" => HoverInfo::Z,
55            "x+y" => HoverInfo::XAndY,
56            "x+z" => HoverInfo::XAndZ,
57            "y+z" => HoverInfo::YAndZ,
58            "x+y+z" => HoverInfo::XAndYAndZ,
59            "text" => HoverInfo::Text,
60            "name" => HoverInfo::Name,
61            "none" => HoverInfo::None,
62            "skip" => HoverInfo::Skip,
63        }),
64    }?;
65
66    let contour = if let Some(contours_obj) = ct_obj.get_mut("contours")
67        && contours_obj.is_object()
68    {
69        use plotly::traces::contour::Contours;
70        let contours = translate_with_config! {
71            Contours::new(),
72            contours_obj,
73            context.map(),
74            context.map_eval(),
75            (start, f64),
76            (end, f64),
77            (size, f64),
78        }?;
79
80        use plotly::traces::contour::Coloring;
81        let contours = translate_enum_with_config! {
82            contours,
83            contours_obj,
84            context.map(),
85            context.map_eval(),
86            (coloring, {
87                "fill"        => Coloring::Fill,
88                "heatmap"     => Coloring::HeatMap,
89                "lines"       => Coloring::Lines,
90                "none"        => Coloring::None,
91            }),
92        }?;
93        contour.contours(contours)
94    } else {
95        contour
96    };
97
98    let contour = if let Some(line_obj) = ct_obj.get_mut("line")
99        && line_obj.is_object()
100    {
101        use plotly::common::Line;
102        let line = translate_with_config! {
103            Line::new(),
104            line_obj,
105            context.map(),
106            context.map_eval(),
107            (color, Color),
108            (width, f64),
109        }?;
110        use plotly::common::DashType;
111        let line = translate_enum_with_config! {
112            line,
113            line_obj,
114            context.map(),
115            context.map_eval(),
116            (dash, {
117                "solid" => DashType::Solid,
118                "dot" => DashType::Dot,
119                "dash" => DashType::Dash,
120                "longdash" => DashType::LongDash,
121                "dashdot" => DashType::DashDot,
122                "longdashdot" => DashType::LongDashDot,
123            }),
124        }?;
125        contour.line(line)
126    } else {
127        contour
128    };
129
130    let contour = if let Some(color_bar_obj) = ct_obj.get_mut("color_bar")
131        && color_bar_obj.is_object()
132    {
133        let color_bar = parse_color_bar(color_bar_obj, context)?;
134        contour.color_bar(color_bar)
135    } else {
136        contour
137    };
138
139    let contour = if ct_obj.get("color_scale").is_some() {
140        use plotly::common::{ColorScale, ColorScalePalette};
141        let color_scale_str: String = must_translate_from_context(ct_obj, context, "color_scale")?;
142        let palette = match color_scale_str.to_lowercase().as_str() {
143            "greys" => ColorScalePalette::Greys,
144            "ylgnbu" => ColorScalePalette::YlGnBu,
145            "greens" => ColorScalePalette::Greens,
146            "ylorrd" => ColorScalePalette::YlOrRd,
147            "bluered" => ColorScalePalette::Bluered,
148            "rdbu" => ColorScalePalette::RdBu,
149            "reds" => ColorScalePalette::Reds,
150            "blues" => ColorScalePalette::Blues,
151            "picnic" => ColorScalePalette::Picnic,
152            "rainbow" => ColorScalePalette::Rainbow,
153            "portland" => ColorScalePalette::Portland,
154            "jet" => ColorScalePalette::Jet,
155            "hot" => ColorScalePalette::Hot,
156            "blackbody" => ColorScalePalette::Blackbody,
157            "earth" => ColorScalePalette::Earth,
158            "electric" => ColorScalePalette::Electric,
159            "viridis" => ColorScalePalette::Viridis,
160            "cividis" => ColorScalePalette::Cividis,
161            _ => return Err(anyhow::anyhow!("unknown color_scale: {}", color_scale_str)),
162        };
163        contour.color_scale(ColorScale::Palette(palette))
164    } else {
165        contour
166    };
167
168    Ok(contour)
169}
170
171pub fn parse_contour_trace(
172    ct_obj: &mut serde_json::Value,
173    context: &ParseContext<'_>,
174) -> Result<Box<dyn Trace>> {
175    Ok(parse_contour_data(ct_obj, context)?)
176}