1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use super::context::ChartContext;
use crate::coord::{AsRangedCoord, RangedCoord, Shift};
use crate::drawing::backend::DrawingBackend;
use crate::drawing::{DrawingArea, DrawingAreaErrorKind};
use crate::style::TextStyle;
pub struct ChartBuilder<'a, 'b, DB: DrawingBackend> {
x_label_size: u32,
y_label_size: u32,
root_area: &'a DrawingArea<DB, Shift>,
title: Option<(String, TextStyle<'b>)>,
margin: u32,
}
impl<'a, 'b, DB: DrawingBackend> ChartBuilder<'a, 'b, DB> {
pub fn on(root: &'a DrawingArea<DB, Shift>) -> Self {
Self {
x_label_size: 0,
y_label_size: 0,
root_area: root,
title: None,
margin: 0,
}
}
pub fn margin(&mut self, size: u32) -> &mut Self {
self.margin = size;
self
}
pub fn x_label_area_size(&mut self, size: u32) -> &mut Self {
self.x_label_size = size;
self
}
pub fn y_label_area_size(&mut self, size: u32) -> &mut Self {
self.y_label_size = size;
self
}
pub fn caption<S: AsRef<str>, Style: Into<TextStyle<'b>>>(
&mut self,
caption: S,
style: Style,
) -> &mut Self {
self.title = Some((caption.as_ref().to_string(), style.into()));
self
}
#[allow(clippy::type_complexity)]
pub fn build_ranged<X: AsRangedCoord, Y: AsRangedCoord>(
&mut self,
x_spec: X,
y_spec: Y,
) -> Result<
ChartContext<'a, DB, RangedCoord<X::CoordDescType, Y::CoordDescType>>,
DrawingAreaErrorKind<DB::ErrorType>,
> {
let mut x_label_area = None;
let mut y_label_area = None;
let mut drawing_area = DrawingArea::clone(self.root_area);
if self.margin > 0 {
let s = self.margin as i32;
drawing_area = drawing_area.margin(s, s, s, s);
}
if let Some((ref title, ref style)) = self.title {
drawing_area = drawing_area.titled(title, style.clone())?;
}
if self.x_label_size > 0 {
let (_, h) = drawing_area.dim_in_pixel();
let (upper, bottom) =
drawing_area.split_vertically(h as i32 - self.x_label_size as i32);
drawing_area = upper;
x_label_area = Some(bottom);
}
if self.y_label_size > 0 {
let (left, right) = drawing_area.split_horizentally(self.y_label_size as i32);
drawing_area = right;
y_label_area = Some(left);
if let Some(xl) = x_label_area {
let (_, right) = xl.split_horizentally(self.y_label_size as i32);
x_label_area = Some(right);
}
}
let mut pixel_range = drawing_area.get_pixel_range();
pixel_range.1 = pixel_range.1.end..pixel_range.1.start;
Ok(ChartContext {
x_label_area,
y_label_area,
drawing_area: drawing_area.apply_coord_spec(RangedCoord::new(
x_spec,
y_spec,
pixel_range,
)),
series_anno: vec![],
})
}
}