in resctl-demo/src/graph.rs [125:219]
fn plot_graph(
data: &str,
size: (usize, usize),
span_len: u64,
g1: &PlotSpec,
g2: Option<&PlotSpec>,
g3: Option<&PlotSpec>,
) -> Result<StyledString> {
let bin = match find_bin("gnuplot", Option::<&str>::None) {
Some(v) => v,
None => bail!("Failed to find \"gnuplot\""),
};
let mut cmd = format!(
"set term dumb size {xsize}, {ysize};\n\
set xrange [{xmin}:0];\n\
set xtics out nomirror;\n\
set ytics out nomirror;\n\
set key left top;\n",
xsize = size.0,
ysize = size.1,
xmin = -(span_len as i64),
);
let (ymin, ymax) = ((g1.min)(), (g1.max)());
if ymax > ymin {
cmd += &format!("set yrange [{ymin}:{ymax}];\n", ymin = ymin, ymax = ymax,);
} else if ymin >= 0.0 {
cmd += "set yrange [0:];\n";
} else {
cmd += "set yrange [:];\n";
}
if let Some(g2) = &g2 {
cmd += "set y2tics out;\n";
let (ymin, ymax) = ((g2.min)(), (g2.max)());
if ymax > ymin {
cmd += &format!("set y2range [{ymin}:{ymax}];\n", ymin = ymin, ymax = ymax);
} else if ymin >= 0.0 {
cmd += "set y2range [0:];\n";
} else {
cmd += "set y2range [:];\n";
}
}
cmd += &format!(
"plot \"{data}\" using 1:{idx} with lines axis x1y1 title \"{title}\"",
data = data,
idx = 2,
title = (g1.title)()
);
let y2 = if let Some(_) = &g3 { "y1" } else { "y2" };
if let Some(g2) = &g2 {
cmd += &format!(
", \"{data}\" using 1:{idx} with lines axis x1{y2} title \"{title}\"\n",
data = data,
idx = 3,
y2 = y2,
title = (g2.title)()
);
}
if let Some(g3) = &g3 {
let title = (g3.title)();
if title.len() > 0 {
cmd += &format!(
", \"{data}\" using 1:{idx} with lines axis x1{y2} title \"{title}\"\n",
data = data,
idx = 4,
y2 = y2,
title = title,
);
}
}
let output = Command::new(&bin).arg("-e").arg(cmd).output()?;
if !output.status.success() {
bail!("gnuplot failed with {:?}", &output);
}
let mut graph = StyledString::new();
for line in String::from_utf8(output.stdout).unwrap().lines() {
if line.trim().len() == 0 {
continue;
}
for c in line.chars() {
match c {
'*' => graph.append_styled("*", *COLOR_GRAPH_1),
'#' => graph.append_styled("+", *COLOR_GRAPH_2),
'$' => graph.append_styled(".", *COLOR_GRAPH_3),
v => graph.append_plain(&format!("{}", v)),
}
}
graph.append_plain("\n");
}
Ok(graph)
}