-
Notifications
You must be signed in to change notification settings - Fork 1
/
plot.rs
116 lines (104 loc) · 3.35 KB
/
plot.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
106
107
108
109
110
111
112
113
114
115
116
use plotters::coord::Shift;
use plotters::prelude::*;
use regex::Regex;
use std::io::BufRead;
const BAR_HEIGHT: i32 = 18;
const BAR_WIDTH: i32 = 5;
fn main() {
let bars = parse(std::io::stdin().lock());
let width = bars
.iter()
.map(|bar| bar.begin + bar.length)
.max()
.unwrap_or(0) as u32
* BAR_WIDTH as u32
+ 200;
let height = bars.len() as u32 * BAR_HEIGHT as u32 + 5;
println!("Drawing area: {}, {}", width, height);
let drawing_area = SVGBackend::new("plot.svg", (width, height)).into_drawing_area();
draw(drawing_area, &bars);
}
fn draw<DB: DrawingBackend>(drawing_area: DrawingArea<DB, Shift>, bars: &[Bar]) {
let text_style = TextStyle::from(("monospace", BAR_HEIGHT).into_font()).color(&BLACK);
for (i, bar) in bars.iter().enumerate() {
let i = i as i32;
let rect = [
(BAR_WIDTH * bar.begin, BAR_HEIGHT * i),
(
BAR_WIDTH * (bar.begin + bar.length) + 2,
BAR_HEIGHT * (i + 1),
),
];
drawing_area
.draw(&Rectangle::new(
rect,
ShapeStyle {
color: bar.color.to_rgba(),
filled: true,
stroke_width: 0,
},
))
.unwrap();
drawing_area
.draw_text(
&format!("{}({})", bar.label, bar.id),
&text_style,
(BAR_WIDTH * bar.begin, BAR_HEIGHT * i),
)
.unwrap();
}
}
fn parse(input: impl BufRead) -> Vec<Bar> {
let re_fetch =
Regex::new(r"^\[(\d+)\] \#{1,2} ([a-z_]+)\((\d+)\) will complete in (\d+) ms$").unwrap();
let re_data = Regex::new(r"^\#\# data = d:(\d+) \(([a-z]+)\)$").unwrap();
let mut bars = Vec::new();
for line in input.lines() {
let line = line.unwrap();
if let Some(caps) = re_fetch.captures(&line) {
println!("Line matches fetching: {}", line);
let label = caps[2].to_owned();
let color = if label == "get_page" || label == "get_data" {
RGBColor(0xA0, 0xC0, 0xFF)
} else if label == "fetch_resource" {
RGBColor(0xA0, 0xFF, 0xC0)
} else {
RGBColor(0xC0, 0xC0, 0xC0)
};
bars.push(Bar {
begin: caps[1].parse().unwrap(),
length: caps[4].parse().unwrap(),
label,
id: caps[3].parse().unwrap(),
color,
});
}
if let Some(caps) = re_data.captures(&line) {
println!("Line matches data: {}", line);
let id: usize = caps[1].parse().unwrap();
let status = &caps[2];
for bar in bars.iter_mut() {
if bar.label == "get_data" && bar.id == id {
if status == "valid" {
bar.color = GREEN;
} else {
bar.color = RED;
}
}
}
}
}
// Normalize for the starting time.
let start = bars.iter().map(|bar| bar.begin).min().unwrap_or(0);
for bar in bars.iter_mut() {
bar.begin -= start;
}
bars
}
struct Bar {
begin: i32,
length: i32,
label: String,
id: usize,
color: RGBColor,
}