mdbook_plotly/code_handler/plot_obj_parser/
histogram_parser.rs1use super::until::{Color, Map, must_translate};
2use crate::{translate, translate_enum};
3use anyhow::{Result, anyhow};
4use plotly::Histogram;
5
6pub fn parse_histogram_data(
7 hist_obj: &mut serde_json::Value,
8 map: &Map,
9) -> Result<Box<Histogram<f64>>> {
10 let has_x = hist_obj.get("x").is_some();
11 let has_y = hist_obj.get("y").is_some();
12 let hist = match (has_x, has_y) {
13 (true, true) => {
14 let x: Vec<f64> = must_translate(hist_obj, map, "x")?;
15 let y: Vec<f64> = must_translate(hist_obj, map, "y")?;
16 Histogram::new_xy(x, y)
17 }
18 (true, false) => {
19 let x: Vec<f64> = must_translate(hist_obj, map, "x")?;
20 Histogram::new(x)
21 }
22 (false, true) => {
23 let y: Vec<f64> = must_translate(hist_obj, map, "y")?;
24 Histogram::new_vertical(y)
25 }
26 (false, false) => {
27 return Err(anyhow!("histogram requires at least 'x' or 'y' data"));
28 }
29 };
30 let hist = translate! {
31 hist,
32 hist_obj,
33 map,
34 (name, String),
35 (show_legend, bool),
36 (legend_group, String),
37 (opacity, f64),
38 (text, String),
39 (text_array, Vec<String>),
40 (hover_text, String),
41 (hover_text_array, Vec<String>),
42 (hover_template, String),
43 (hover_template_array, Vec<String>),
44 (auto_bin_x, bool),
45 (n_bins_x, usize),
46 (auto_bin_y, bool),
47 (n_bins_y, usize),
48 (alignment_group, String),
49 (offset_group, String),
50 (bin_group, String),
51 (x_axis, String),
52 (y_axis, String),
53 }?;
54
55 use plotly::common::Orientation;
56 use plotly::histogram::{HistFunc, HistNorm};
57
58 let hist = translate_enum! {
59 hist,
60 hist_obj,
61 map,
62 (orientation, {
63 "v" => Orientation::Vertical,
64 "h" => Orientation::Horizontal,
65 }),
66 (hist_func, {
67 "count" => HistFunc::Count,
68 "sum" => HistFunc::Sum,
69 "avg" => HistFunc::Average,
70 "min" => HistFunc::Minimum,
71 "max" => HistFunc::Maximum,
72 }),
73 (hist_norm, {
74 "percent" => HistNorm::Percent,
75 "probability" => HistNorm::Probability,
76 "density" => HistNorm::Density,
77 "probability density" => HistNorm::ProbabilityDensity,
78 "" => HistNorm::Default,
79 }),
80 }?;
81
82 let hist = if let Some(marker_obj) = hist_obj.get_mut("marker")
83 && marker_obj.is_object()
84 {
85 let marker = plotly::common::Marker::new();
86 let marker = translate! {
87 marker,
88 marker_obj,
89 map,
90 (color, Color),
91 (opacity, f64),
92 (size, usize),
93 (size_array, Vec<usize>),
94 (max_displayed, usize),
95 (size_ref, usize),
96 (size_min, usize),
97 (cauto, bool),
98 (cmax, f64),
99 (cmin, f64),
100 (cmid, f64),
101 (auto_color_scale, bool),
102 (reverse_scale, bool),
103 (show_scale, bool),
104 (outlier_color, Color)
105 }?;
106
107 use plotly::common::{MarkerSymbol, SizeMode};
108 let marker = translate_enum! {
109 marker,
110 marker_obj,
111 map,
112 (symbol, {
113 "circle" => MarkerSymbol::Circle,
114 "square" => MarkerSymbol::Square,
115 "diamond" => MarkerSymbol::Diamond,
116 "cross" => MarkerSymbol::Cross,
117 "x" => MarkerSymbol::X,
118 "triangle-up" => MarkerSymbol::TriangleUp,
119 "triangle-down" => MarkerSymbol::TriangleDown,
120 "triangle-left" => MarkerSymbol::TriangleLeft,
121 "triangle-right" => MarkerSymbol::TriangleRight,
122 "pentagon" => MarkerSymbol::Pentagon,
123 "hexagon" => MarkerSymbol::Hexagon,
124 }),
125 (size_mode, {
126 "area" => SizeMode::Area,
127 "diameter" => SizeMode::Diameter,
128 }),
129 }?;
130 hist.marker(marker)
131 } else {
132 hist
133 };
134
135 Ok(hist)
136}