1 use plotters::prelude::*;
2 
3 use chrono::{TimeZone, Utc};
4 
5 use std::error::Error;
6 
7 const OUT_FILE_NAME: &'static str = "plotters-doc-data/slc-temp.png";
main() -> Result<(), Box<dyn Error>>8 fn main() -> Result<(), Box<dyn Error>> {
9     let root = BitMapBackend::new(OUT_FILE_NAME, (1024, 768)).into_drawing_area();
10 
11     root.fill(&WHITE)?;
12 
13     let mut chart = ChartBuilder::on(&root)
14         .margin(10)
15         .caption(
16             "Monthly Average Temperate in Salt Lake City, UT",
17             ("sans-serif", 40),
18         )
19         .set_label_area_size(LabelAreaPosition::Left, 60)
20         .set_label_area_size(LabelAreaPosition::Right, 60)
21         .set_label_area_size(LabelAreaPosition::Bottom, 40)
22         .build_cartesian_2d(
23             (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(),
24             14.0..104.0,
25         )?
26         .set_secondary_coord(
27             (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(),
28             -10.0..40.0,
29         );
30 
31     chart
32         .configure_mesh()
33         .disable_x_mesh()
34         .disable_y_mesh()
35         .x_labels(30)
36         .max_light_lines(4)
37         .y_desc("Average Temp (F)")
38         .draw()?;
39     chart
40         .configure_secondary_axes()
41         .y_desc("Average Temp (C)")
42         .draw()?;
43 
44     chart.draw_series(LineSeries::new(
45         DATA.iter().map(|(y, m, t)| (Utc.ymd(*y, *m, 1), *t)),
46         &BLUE,
47     ))?;
48 
49     chart.draw_series(
50         DATA.iter()
51             .map(|(y, m, t)| Circle::new((Utc.ymd(*y, *m, 1), *t), 3, BLUE.filled())),
52     )?;
53 
54     // To avoid the IO failure being ignored silently, we manually call the present function
55     root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir");
56     println!("Result has been saved to {}", OUT_FILE_NAME);
57 
58     Ok(())
59 }
60 
61 const DATA: [(i32, u32, f64); 12 * 9] = [
62     (2010, 1, 32.4),
63     (2010, 2, 37.5),
64     (2010, 3, 44.5),
65     (2010, 4, 50.3),
66     (2010, 5, 55.0),
67     (2010, 6, 70.0),
68     (2010, 7, 78.7),
69     (2010, 8, 76.5),
70     (2010, 9, 68.9),
71     (2010, 10, 56.3),
72     (2010, 11, 40.3),
73     (2010, 12, 36.5),
74     (2011, 1, 28.8),
75     (2011, 2, 35.1),
76     (2011, 3, 45.5),
77     (2011, 4, 48.9),
78     (2011, 5, 55.1),
79     (2011, 6, 68.8),
80     (2011, 7, 77.9),
81     (2011, 8, 78.4),
82     (2011, 9, 68.2),
83     (2011, 10, 55.0),
84     (2011, 11, 41.5),
85     (2011, 12, 31.0),
86     (2012, 1, 35.6),
87     (2012, 2, 38.1),
88     (2012, 3, 49.1),
89     (2012, 4, 56.1),
90     (2012, 5, 63.4),
91     (2012, 6, 73.0),
92     (2012, 7, 79.0),
93     (2012, 8, 79.0),
94     (2012, 9, 68.8),
95     (2012, 10, 54.9),
96     (2012, 11, 45.2),
97     (2012, 12, 34.9),
98     (2013, 1, 19.7),
99     (2013, 2, 31.1),
100     (2013, 3, 46.2),
101     (2013, 4, 49.8),
102     (2013, 5, 61.3),
103     (2013, 6, 73.3),
104     (2013, 7, 80.3),
105     (2013, 8, 77.2),
106     (2013, 9, 68.3),
107     (2013, 10, 52.0),
108     (2013, 11, 43.2),
109     (2013, 12, 25.7),
110     (2014, 1, 31.5),
111     (2014, 2, 39.3),
112     (2014, 3, 46.4),
113     (2014, 4, 52.5),
114     (2014, 5, 63.0),
115     (2014, 6, 71.3),
116     (2014, 7, 81.0),
117     (2014, 8, 75.3),
118     (2014, 9, 70.0),
119     (2014, 10, 58.6),
120     (2014, 11, 42.1),
121     (2014, 12, 38.0),
122     (2015, 1, 35.3),
123     (2015, 2, 45.2),
124     (2015, 3, 50.9),
125     (2015, 4, 54.3),
126     (2015, 5, 60.5),
127     (2015, 6, 77.1),
128     (2015, 7, 76.2),
129     (2015, 8, 77.3),
130     (2015, 9, 70.4),
131     (2015, 10, 60.6),
132     (2015, 11, 40.9),
133     (2015, 12, 32.4),
134     (2016, 1, 31.5),
135     (2016, 2, 35.1),
136     (2016, 3, 49.1),
137     (2016, 4, 55.1),
138     (2016, 5, 60.9),
139     (2016, 6, 76.9),
140     (2016, 7, 80.0),
141     (2016, 8, 77.0),
142     (2016, 9, 67.1),
143     (2016, 10, 59.1),
144     (2016, 11, 47.4),
145     (2016, 12, 31.8),
146     (2017, 1, 29.4),
147     (2017, 2, 42.4),
148     (2017, 3, 51.7),
149     (2017, 4, 51.7),
150     (2017, 5, 62.5),
151     (2017, 6, 74.8),
152     (2017, 7, 81.3),
153     (2017, 8, 78.1),
154     (2017, 9, 65.7),
155     (2017, 10, 52.5),
156     (2017, 11, 49.0),
157     (2017, 12, 34.4),
158     (2018, 1, 38.1),
159     (2018, 2, 37.5),
160     (2018, 3, 45.4),
161     (2018, 4, 54.6),
162     (2018, 5, 64.0),
163     (2018, 6, 74.9),
164     (2018, 7, 82.5),
165     (2018, 8, 78.1),
166     (2018, 9, 71.9),
167     (2018, 10, 53.2),
168     (2018, 11, 39.7),
169     (2018, 12, 33.6),
170 ];
171 #[test]
entry_point()172 fn entry_point() {
173     main().unwrap()
174 }
175