@@ -3,16 +3,12 @@ use plotters::prelude::*;
3
3
use std:: fs:: File ;
4
4
use std:: io:: BufReader ;
5
5
6
- use chrono:: NaiveDate ;
7
- use std:: str:: FromStr ;
8
-
9
6
#[ derive( serde_derive:: Deserialize ) ]
10
7
struct DailyData {
11
- date : String ,
12
8
#[ serde( default ) ]
13
- new_cases_smoothed_per_million : f64 ,
9
+ new_cases : f64 ,
14
10
#[ serde( default ) ]
15
- total_cases_per_million : f64 ,
11
+ total_cases : f64 ,
16
12
}
17
13
18
14
#[ derive( serde_derive:: Deserialize ) ]
@@ -22,68 +18,68 @@ struct CountryData {
22
18
23
19
fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
24
20
let root =
25
- BitMapBackend :: gif ( "/tmp/tick_control.gif" , ( 800 , 600 ) , 100 ) ?. into_drawing_area ( ) ;
26
-
27
- for a in 0 ..200 {
28
-
29
- root. fill ( & WHITE ) ?;
30
-
31
-
32
- let mut chart = ChartBuilder :: on ( & root)
33
- . set_label_area_size ( LabelAreaPosition :: Left , ( 8 ) . percent ( ) )
34
- . set_label_area_size ( LabelAreaPosition :: Bottom , ( 6 ) . percent ( ) )
35
- . margin ( ( 1 ) . percent ( ) )
36
- . build_cartesian_3d (
37
- ( 20u32 ..10_0000u32 )
38
- . log_scale ( )
39
- . with_key_points ( vec ! [ 50 , 100 , 200 , 500 , 1000 , 10000 ] ) ,
40
- ( 0u32 ..1000u32 )
41
- . log_scale ( )
42
- . with_key_points ( vec ! [ 2 , 5 , 10 , 20 , 50 , 100 , 200 ] ) ,
43
- NaiveDate :: from_ymd ( 2020 , 1 , 1 ) ..NaiveDate :: from_ymd ( 2020 , 9 , 5 ) ,
44
- ) ?;
21
+ SVGBackend :: new ( "plotters-doc-data/tick_control.svg" , ( 1024 , 768 ) ) . into_drawing_area ( ) ;
22
+ root. fill ( & WHITE ) ?;
45
23
46
- chart. with_projection ( |mut pb| {
47
- pb. yaw = ( 1.57 - a as f64 / 100.0 * 1.57 ) . abs ( ) ;
48
- pb. into_matrix ( )
49
- } ) ;
24
+ let ( upper, lower) = root. split_vertically ( 750 ) ;
50
25
51
- chart
52
- . configure_axes ( )
53
- . draw ( ) ?;
26
+ lower. titled (
27
+ "Data Source: https://covid.ourworldindata.org/data/owid-covid-data.json" ,
28
+ ( "sans-serif" , 10 ) . into_font ( ) . color ( & BLACK . mix ( 0.5 ) ) ,
29
+ ) ?;
54
30
55
- let data: std:: collections:: HashMap < String , CountryData > = serde_json:: from_reader (
56
- BufReader :: new ( File :: open ( "plotters-doc-data/covid-data.json" ) ?) ,
31
+ let mut chart = ChartBuilder :: on ( & upper)
32
+ . caption ( "World COVID-19 Cases" , ( "sans-serif" , ( 5 ) . percent_height ( ) ) )
33
+ . set_label_area_size ( LabelAreaPosition :: Left , ( 8 ) . percent ( ) )
34
+ . set_label_area_size ( LabelAreaPosition :: Bottom , ( 4 ) . percent ( ) )
35
+ . margin ( ( 1 ) . percent ( ) )
36
+ . build_cartesian_2d (
37
+ ( 20u32 ..5000_0000u32 )
38
+ . log_scale ( )
39
+ . with_key_points ( vec ! [ 50 , 100 , 1000 , 10000 , 100000 , 1000000 , 10000000 ] ) ,
40
+ ( 0u32 ..50_0000u32 )
41
+ . log_scale ( )
42
+ . with_key_points ( vec ! [ 10 , 50 , 100 , 1000 , 10000 , 100000 , 200000 ] ) ,
57
43
) ?;
58
44
59
- for ( idx, & series) in [ "USA" , "CHN" ]
60
- . iter ( )
61
- . enumerate ( )
62
- {
63
- let color = Palette99 :: pick ( idx) . mix ( 1.0 ) ;
64
- chart
65
- . draw_series ( LineSeries :: new (
66
- data[ series] . data . iter ( ) . map (
67
- |DailyData {
68
- date,
69
- new_cases_smoothed_per_million,
70
- total_cases_per_million,
71
- ..
72
- } | ( * total_cases_per_million as u32 , * new_cases_smoothed_per_million as u32 , chrono:: NaiveDate :: from_str ( date) . unwrap ( ) , ) ,
73
- ) ,
74
- color. stroke_width ( 1 ) ,
75
- ) ) ?
76
- . label ( series)
77
- . legend ( move |( x, y) | Rectangle :: new ( [ ( x, y - 5 ) , ( x + 10 , y + 5 ) ] , color. filled ( ) ) ) ;
78
- }
45
+ chart
46
+ . configure_mesh ( )
47
+ . x_desc ( "Total Cases" )
48
+ . y_desc ( "New Cases" )
49
+ . draw ( ) ?;
79
50
80
- chart
81
- . configure_series_labels ( )
82
- . border_style ( & BLACK )
83
- . draw ( ) ?;
51
+ let data: std:: collections:: HashMap < String , CountryData > = serde_json:: from_reader (
52
+ BufReader :: new ( File :: open ( "plotters-doc-data/covid-data.json" ) ?) ,
53
+ ) ?;
84
54
85
- root. present ( ) ?;
55
+ for ( idx, & series) in [ "CHN" , "USA" , "RUS" , "JPN" , "DEU" , "IND" , "OWID_WRL" ]
56
+ . iter ( )
57
+ . enumerate ( )
58
+ {
59
+ let color = Palette99 :: pick ( idx) . mix ( 0.9 ) ;
60
+ chart
61
+ . draw_series ( LineSeries :: new (
62
+ data[ series] . data . iter ( ) . map (
63
+ |& DailyData {
64
+ new_cases,
65
+ total_cases,
66
+ ..
67
+ } | ( total_cases as u32 , new_cases as u32 ) ,
68
+ ) ,
69
+ color. stroke_width ( 3 ) ,
70
+ ) ) ?
71
+ . label ( series)
72
+ . legend ( move |( x, y) | Rectangle :: new ( [ ( x, y - 5 ) , ( x + 10 , y + 5 ) ] , color. filled ( ) ) ) ;
86
73
}
87
74
75
+ chart
76
+ . configure_series_labels ( )
77
+ . border_style ( & BLACK )
78
+ . draw ( ) ?;
79
+
88
80
Ok ( ( ) )
89
81
}
82
+ #[ test]
83
+ fn entry_point ( ) {
84
+ main ( ) . unwrap ( )
85
+ }
0 commit comments