-
Notifications
You must be signed in to change notification settings - Fork 73
/
confidence_band.rs
105 lines (101 loc) · 3.71 KB
/
confidence_band.rs
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
use charming::{
component::{Axis, Grid, Title},
element::{
AreaStyle, AxisLabel, AxisPointer, AxisPointerType, AxisType, Formatter, ItemStyle, Label,
LineStyle, Symbol, Tooltip, Trigger,
},
series::Line,
Chart,
};
use serde::Deserialize;
pub fn chart() -> Chart {
let data: Vec<DataItem> =
serde_json::from_str(include_str!("../../asset/confidence-band.json"))
.expect("failed to parse data");
let base = -data
.iter()
.fold(f64::INFINITY, |min, val| f64::floor(f64::min(min, val.l)));
Chart::new()
.title(
Title::new()
.text("Confidence Band")
.subtext("Example in MetricsGraphics.js")
.left("center"),
)
.tooltip(
Tooltip::new()
.trigger(Trigger::Axis)
.axis_pointer(
AxisPointer::new().type_(AxisPointerType::Cross).label(
Label::new()
.background_color("#ccc")
.border_color("#aaa")
.border_width(1)
.shadow_blur(0)
.shadow_offset_x(0)
.shadow_offset_y(0)
.color("#222"),
),
)
.formatter(
Formatter::Function(
format!("function (params) {{ return (params[2].name + '<br />' + ((params[2].value - {}) * 100).toFixed(1) + '%'); }}", base
).into())
),
)
.grid(Grid::new().left("3%").right("4%").bottom("3%").contain_label(true))
.x_axis(
Axis::new()
.type_(AxisType::Category)
.data(data.iter().map(|x| x.date.clone()).collect())
.axis_label(
AxisLabel::new().formatter(
Formatter::Function(
"function (value, idx) { var date = new Date(value); return idx === 0 ? value : [date.getMonth() + 1, date.getDate()].join('-'); }".into())
)
)
.boundary_gap(false)
)
.y_axis(
Axis::new()
.axis_label(AxisLabel::new().formatter(
Formatter::Function(format!("function (val) {{ return (val - {}) * 100 + '%'; }}", base).into()))
)
.axis_pointer(
AxisPointer::new().label(
Label::new().formatter(
Formatter::Function(format!("function (params) {{ return ((params.value - {}) * 100).toFixed(1) + '%'; }}", base).into())
)
)
).split_number(3)
)
.series(
Line::new()
.name("L")
.data(data.iter().map(|x| x.l + base).collect())
.line_style(LineStyle::new().opacity(0))
.stack("confidence-band")
.symbol(Symbol::None)
)
.series(
Line::new()
.name("U")
.data(data.iter().map(|x| x.u - x.l).collect())
.line_style(LineStyle::new().opacity(0))
.area_style(AreaStyle::new().color("#ccc"))
.stack("confidence-band")
.symbol(Symbol::None)
)
.series(
Line::new()
.data(data.iter().map(|x| x.value + base).collect())
.item_style(ItemStyle::new().color("#333"))
.show_symbol(false))
}
#[derive(Deserialize)]
struct DataItem {
date: String,
value: f64,
l: f64,
u: f64,
}