1 | use plotters::{ |
2 | coord::ranged1d::{KeyPointHint, NoDefaultFormatting, ValueFormatter}, |
3 | prelude::*, |
4 | }; |
5 | const OUT_FILE_NAME: &'static str = "plotters-doc-data/customized_coord.svg" ; |
6 | |
7 | struct CustomizedX(u32); |
8 | |
9 | impl Ranged for CustomizedX { |
10 | type ValueType = u32; |
11 | type FormatOption = NoDefaultFormatting; |
12 | fn map(&self, value: &Self::ValueType, limit: (i32, i32)) -> i32 { |
13 | let size = limit.1 - limit.0; |
14 | ((*value as f64 / self.0 as f64) * size as f64) as i32 + limit.0 |
15 | } |
16 | |
17 | fn range(&self) -> std::ops::Range<Self::ValueType> { |
18 | 0..self.0 |
19 | } |
20 | |
21 | fn key_points<Hint: KeyPointHint>(&self, hint: Hint) -> Vec<Self::ValueType> { |
22 | if hint.max_num_points() < (self.0 as usize) { |
23 | return vec![]; |
24 | } |
25 | |
26 | (0..self.0).collect() |
27 | } |
28 | } |
29 | |
30 | impl ValueFormatter<u32> for CustomizedX { |
31 | fn format_ext(&self, value: &u32) -> String { |
32 | format!("{} of {}" , value, self.0) |
33 | } |
34 | } |
35 | |
36 | fn main() -> Result<(), Box<dyn std::error::Error>> { |
37 | let area = SVGBackend::new(OUT_FILE_NAME, (1024, 760)).into_drawing_area(); |
38 | area.fill(&WHITE)?; |
39 | |
40 | let mut chart = ChartBuilder::on(&area) |
41 | .set_all_label_area_size(50) |
42 | .build_cartesian_2d(CustomizedX(7), 0.0..10.0)?; |
43 | |
44 | chart.configure_mesh().draw()?; |
45 | |
46 | area.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir" ); |
47 | println!("Result has been saved to {}" , OUT_FILE_NAME); |
48 | Ok(()) |
49 | } |
50 | |
51 | #[test] |
52 | fn entry_point() { |
53 | main().unwrap() |
54 | } |
55 | |