1use crate::common::{Calendar, Dim, ErrorData, HoverInfo, Label, Marker, Orientation, PlotType};
4use crate::Trace;
5use serde::Serialize;
6
7use crate::private;
8use crate::private::copy_iterable_to_vec;
9
10#[cfg(feature = "plotly_ndarray")]
11use ndarray::{Array, Ix1, Ix2};
12#[cfg(feature = "plotly_ndarray")]
13use crate::ndarray::ArrayTraces;
14
15
16#[derive(Serialize, Clone, Debug)]
17pub struct Bins {
18 start: f64,
19 end: f64,
20 size: f64,
21}
22
23impl Bins {
24 pub fn new(start: f64, end: f64, size: f64) -> Bins {
25 Bins { start, end, size }
26 }
27}
28
29#[derive(Serialize, Clone, Debug)]
30pub enum HistFunc {
31 #[serde(rename = "count")]
32 Count,
33 #[serde(rename = "sum")]
34 Sum,
35 #[serde(rename = "avg")]
36 Average,
37 #[serde(rename = "min")]
38 Minimum,
39 #[serde(rename = "max")]
40 Maximum,
41}
42
43#[derive(Serialize, Clone, Debug)]
44pub enum HistNorm {
45 #[serde(rename = "")]
46 Default,
47 #[serde(rename = "percent")]
48 Percent,
49 #[serde(rename = "probability")]
50 Probability,
51 #[serde(rename = "density")]
52 Density,
53 #[serde(rename = "probability density")]
54 ProbabilityDensity,
55}
56
57#[derive(Serialize, Clone, Debug)]
58pub enum HistDirection {
59 #[serde(rename = "increasing")]
60 Increasing,
61 #[serde(rename = "decreasing")]
62 Decreasing,
63}
64
65#[derive(Serialize, Clone, Debug)]
66pub enum CurrentBin {
67 #[serde(rename = "include")]
68 Include,
69 #[serde(rename = "exclude")]
70 Exclude,
71 #[serde(rename = "half")]
72 Half,
73}
74
75#[derive(Serialize, Clone, Debug, Default)]
76pub struct Cumulative {
77 #[serde(skip_serializing_if = "Option::is_none")]
78 enabled: Option<bool>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 direction: Option<HistDirection>,
81 #[serde(skip_serializing_if = "Option::is_none", rename = "currentbin")]
82 current_bin: Option<CurrentBin>,
83}
84
85impl Cumulative {
86 pub fn new() -> Cumulative {
87 Cumulative {
88 enabled: None,
89 direction: None,
90 current_bin: None,
91 }
92 }
93
94 pub fn enabled(mut self, enabled: bool) -> Cumulative {
95 self.enabled = Some(enabled);
96 self
97 }
98
99 pub fn direction(mut self, direction: HistDirection) -> Cumulative {
100 self.direction = Some(direction);
101 self
102 }
103
104 pub fn current_bin(mut self, current_bin: CurrentBin) -> Cumulative {
105 self.current_bin = Some(current_bin);
106 self
107 }
108}
109
110#[derive(Serialize, Clone, Debug)]
111pub struct Histogram<H>
112where
113 H: Serialize + Clone + Default + 'static,
114{
115 r#type: PlotType,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 name: Option<String>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 visible: Option<bool>,
120 #[serde(skip_serializing_if = "Option::is_none", rename = "showlegend")]
121 show_legend: Option<bool>,
122 #[serde(skip_serializing_if = "Option::is_none", rename = "legendgroup")]
123 legend_group: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 opacity: Option<f64>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 x: Option<Vec<H>>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 y: Option<Vec<H>>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 text: Option<Dim<String>>,
132 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertext")]
133 hover_text: Option<Dim<String>>,
134 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverinfo")]
135 hover_info: Option<HoverInfo>,
136 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertemplate")]
137 hover_template: Option<Dim<String>>,
138 #[serde(skip_serializing_if = "Option::is_none", rename = "xaxis")]
139 x_axis: Option<String>,
140 #[serde(skip_serializing_if = "Option::is_none", rename = "yaxis")]
141 y_axis: Option<String>,
142 orientation: Option<Orientation>,
143 #[serde(skip_serializing_if = "Option::is_none", rename = "histfunc")]
144 hist_func: Option<HistFunc>,
145 #[serde(skip_serializing_if = "Option::is_none", rename = "histnorm")]
146 hist_norm: Option<HistNorm>,
147 #[serde(skip_serializing_if = "Option::is_none", rename = "alignmentgroup")]
148 alignment_group: Option<String>,
149 #[serde(skip_serializing_if = "Option::is_none", rename = "offsetgroup")]
150 offset_group: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none", rename = "nbinsx")]
152 n_bins_x: Option<usize>,
153 #[serde(skip_serializing_if = "Option::is_none", rename = "nbinsy")]
154 n_bins_y: Option<usize>,
155 #[serde(skip_serializing_if = "Option::is_none", rename = "autobinx")]
156 auto_bin_x: Option<bool>,
157 #[serde(skip_serializing_if = "Option::is_none", rename = "autobiny")]
158 auto_bin_y: Option<bool>,
159 #[serde(skip_serializing_if = "Option::is_none", rename = "bingroup")]
160 bin_group: Option<String>,
161 #[serde(skip_serializing_if = "Option::is_none", rename = "xbins")]
162 x_bins: Option<Bins>,
163 #[serde(skip_serializing_if = "Option::is_none", rename = "ybins")]
164 y_bins: Option<Bins>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 marker: Option<Marker>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 error_x: Option<ErrorData>,
169 #[serde(skip_serializing_if = "Option::is_none")]
170 error_y: Option<ErrorData>,
171 #[serde(skip_serializing_if = "Option::is_none")]
172 cumulative: Option<Cumulative>,
173 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverlabel")]
174 hover_label: Option<Label>,
175 #[serde(skip_serializing_if = "Option::is_none", rename = "xcalendar")]
176 x_calendar: Option<Calendar>,
177 #[serde(skip_serializing_if = "Option::is_none", rename = "ycalendar")]
178 y_calendar: Option<Calendar>,
179}
180
181impl<H> Default for Histogram<H>
182where
183 H: Serialize + Clone + Default + 'static,
184{
185 fn default() -> Self {
186 Histogram {
187 r#type: PlotType::Histogram,
188 name: None,
189 visible: None,
190 show_legend: None,
191 legend_group: None,
192 opacity: None,
193 x: None,
194 y: None,
195 text: None,
196 hover_text: None,
197 hover_info: None,
198 hover_template: None,
199 x_axis: None,
200 y_axis: None,
201 orientation: None,
202 hist_func: None,
203 hist_norm: None,
204 alignment_group: None,
205 offset_group: None,
206 n_bins_x: None,
207 n_bins_y: None,
208 auto_bin_x: None,
209 auto_bin_y: None,
210 bin_group: None,
211 x_bins: None,
212 y_bins: None,
213 marker: None,
214 error_x: None,
215 error_y: None,
216 cumulative: None,
217 hover_label: None,
218 x_calendar: None,
219 y_calendar: None,
220 }
221 }
222}
223
224impl<H> Histogram<H>
225where
226 H: Serialize + Clone + Default + 'static,
227{
228 pub fn new<I>(x: I) -> Box<Self>
229 where
230 I: IntoIterator<Item = H>,
231 {
232 let x = copy_iterable_to_vec(x);
233 Box::new(Histogram {
234 r#type: PlotType::Histogram,
235 x: Some(x),
236 ..Default::default()
237 })
238 }
239
240 pub fn new_xy<I>(x: I, y: I) -> Box<Self>
241 where
242 I: IntoIterator<Item = H>,
243 {
244 let x = copy_iterable_to_vec(x);
245 let y = copy_iterable_to_vec(y);
246 Box::new(Histogram {
247 r#type: PlotType::Histogram,
248 x: Some(x),
249 y: Some(y),
250 ..Default::default()
251 })
252 }
253
254 pub fn new_vertical<I>(y: I) -> Box<Self>
255 where
256 I: IntoIterator<Item = H>,
257 {
258 let y = copy_iterable_to_vec(y);
259 Box::new(Histogram {
260 r#type: PlotType::Histogram,
261 y: Some(y),
262 ..Default::default()
263 })
264 }
265
266 #[cfg(feature = "plotly_ndarray")]
318 pub fn to_traces(
319 &self,
320 traces_matrix: Array<H, Ix2>,
321 array_traces: ArrayTraces,
322 ) -> Vec<Box<dyn Trace>> {
323 let mut traces: Vec<Box<dyn Trace>> = Vec::new();
324 let mut trace_vectors = private::trace_vectors_from(traces_matrix, array_traces);
325 trace_vectors.reverse();
326 while !trace_vectors.is_empty() {
327 let mut sc = Box::new(self.clone());
328 let data = trace_vectors.pop();
329 if let Some(d) = data {
330 sc.x = Some(d);
331 traces.push(sc);
332 }
333 }
334
335 traces
336 }
337
338 #[cfg(feature = "plotly_ndarray")]
339 pub fn from_array(x: Array<H, Ix1>) -> Box<Self> {
340 Box::new(Histogram {
341 r#type: PlotType::Histogram,
342 x: Some(x.to_vec()),
343 ..Default::default()
344 })
345 }
346
347 pub fn name(mut self, name: &str) -> Box<Self> {
348 self.name = Some(name.to_owned());
349 Box::new(self)
350 }
351
352 pub fn visible(mut self, visible: bool) -> Box<Self> {
353 self.visible = Some(visible);
354 Box::new(self)
355 }
356
357 pub fn show_legend(mut self, show_legend: bool) -> Box<Self> {
358 self.show_legend = Some(show_legend);
359 Box::new(self)
360 }
361
362 pub fn legend_group(mut self, legend_group: &str) -> Box<Self> {
363 self.legend_group = Some(legend_group.to_owned());
364 Box::new(self)
365 }
366
367 pub fn opacity(mut self, opacity: f64) -> Box<Self> {
368 self.opacity = Some(opacity);
369 Box::new(self)
370 }
371
372 pub fn text(mut self, text: &str) -> Box<Self> {
373 self.text = Some(Dim::Scalar(text.to_owned()));
374 Box::new(self)
375 }
376
377 pub fn text_array<S: AsRef<str>>(mut self, text: Vec<S>) -> Box<Self> {
378 let text = private::owned_string_vector(text);
379 self.text = Some(Dim::Vector(text));
380 Box::new(self)
381 }
382
383 pub fn hover_text(mut self, hover_text: &str) -> Box<Self> {
384 self.hover_text = Some(Dim::Scalar(hover_text.to_owned()));
385 Box::new(self)
386 }
387
388 pub fn hover_text_array<S: AsRef<str>>(mut self, hover_text: Vec<S>) -> Box<Self> {
389 let hover_text = private::owned_string_vector(hover_text);
390 self.hover_text = Some(Dim::Vector(hover_text));
391 Box::new(self)
392 }
393
394 pub fn hover_info(mut self, hover_info: HoverInfo) -> Box<Self> {
395 self.hover_info = Some(hover_info);
396 Box::new(self)
397 }
398
399 pub fn hover_template(mut self, hover_template: &str) -> Box<Self> {
400 self.hover_template = Some(Dim::Scalar(hover_template.to_owned()));
401 Box::new(self)
402 }
403
404 pub fn x_axis(mut self, axis: &str) -> Box<Self> {
405 self.x_axis = Some(axis.to_owned());
406 Box::new(self)
407 }
408
409 pub fn y_axis(mut self, axis: &str) -> Box<Self> {
410 self.y_axis = Some(axis.to_owned());
411 Box::new(self)
412 }
413
414 pub fn hover_template_array<S: AsRef<str>>(mut self, hover_template: Vec<S>) -> Box<Self> {
415 let hover_template = private::owned_string_vector(hover_template);
416 self.hover_template = Some(Dim::Vector(hover_template));
417 Box::new(self)
418 }
419
420 pub fn orientation(mut self, orientation: Orientation) -> Box<Self> {
421 self.orientation = Some(orientation);
422 Box::new(self)
423 }
424
425 pub fn hist_func(mut self, hist_func: HistFunc) -> Box<Self> {
426 self.hist_func = Some(hist_func);
427 Box::new(self)
428 }
429
430 pub fn hist_norm(mut self, hist_norm: HistNorm) -> Box<Self> {
431 self.hist_norm = Some(hist_norm);
432 Box::new(self)
433 }
434
435 pub fn alignment_group(mut self, alignment_group: &str) -> Box<Self> {
436 self.alignment_group = Some(alignment_group.to_owned());
437 Box::new(self)
438 }
439
440 pub fn offset_group(mut self, offset_group: &str) -> Box<Self> {
441 self.offset_group = Some(offset_group.to_owned());
442 Box::new(self)
443 }
444
445 pub fn n_bins_x(mut self, n_bins_x: usize) -> Box<Self> {
446 self.n_bins_x = Some(n_bins_x);
447 Box::new(self)
448 }
449
450 pub fn n_bins_y(mut self, n_bins_y: usize) -> Box<Self> {
451 self.n_bins_y = Some(n_bins_y);
452 Box::new(self)
453 }
454
455 pub fn auto_bin_x(mut self, auto_bin_x: bool) -> Box<Self> {
456 self.auto_bin_x = Some(auto_bin_x);
457 Box::new(self)
458 }
459
460 pub fn auto_bin_y(mut self, auto_bin_y: bool) -> Box<Self> {
461 self.auto_bin_y = Some(auto_bin_y);
462 Box::new(self)
463 }
464
465 pub fn bin_group(mut self, bin_group: &str) -> Box<Self> {
466 self.bin_group = Some(bin_group.to_owned());
467 Box::new(self)
468 }
469
470 pub fn x_bins(mut self, x_bins: Bins) -> Box<Self> {
471 self.x_bins = Some(x_bins);
472 Box::new(self)
473 }
474
475 pub fn y_bins(mut self, y_bins: Bins) -> Box<Self> {
476 self.y_bins = Some(y_bins);
477 Box::new(self)
478 }
479
480 pub fn marker(mut self, marker: Marker) -> Box<Self> {
481 self.marker = Some(marker);
482 Box::new(self)
483 }
484
485 pub fn error_x(mut self, error_x: ErrorData) -> Box<Self> {
486 self.error_x = Some(error_x);
487 Box::new(self)
488 }
489
490 pub fn error_y(mut self, error_y: ErrorData) -> Box<Self> {
491 self.error_y = Some(error_y);
492 Box::new(self)
493 }
494
495 pub fn cumulative(mut self, cumulative: Cumulative) -> Box<Self> {
496 self.cumulative = Some(cumulative);
497 Box::new(self)
498 }
499
500 pub fn hover_label(mut self, hover_label: Label) -> Box<Self> {
501 self.hover_label = Some(hover_label);
502 Box::new(self)
503 }
504
505 pub fn x_calendar(mut self, x_calendar: Calendar) -> Box<Self> {
506 self.x_calendar = Some(x_calendar);
507 Box::new(self)
508 }
509
510 pub fn y_calendar(mut self, y_calendar: Calendar) -> Box<Self> {
511 self.y_calendar = Some(y_calendar);
512 Box::new(self)
513 }
514}
515
516impl<H> Trace for Histogram<H>
517where
518 H: Serialize + Clone + Default + 'static,
519{
520 fn serialize(&self) -> String {
521 serde_json::to_string(&self).unwrap()
522 }
523}