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