Skip to content

Commit

Permalink
Show command values (current, min, max) as decimals if appropriate
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Vetter authored and svetter committed Feb 18, 2024
1 parent 5972fd3 commit 9d83be0
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 65 deletions.
21 changes: 13 additions & 8 deletions src/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,26 @@ impl DataStore {
}
}

pub fn stats(&self) -> Vec<Histogram> {
pub fn stats(&self) -> Vec<Result<(f64, f64, u64), &str>> {
self.data
.iter()
.map(|data| {
let mut hist = Histogram::new();
let mut min = f64::INFINITY;
let mut max = 0_f64;

for (_, val) in data.iter().filter(|v| v.1 != 0f64) {
hist.increment(*val as u64).unwrap_or(());
min = min.min(*val);
max = max.max(*val);
}

hist
if let Ok(p95) = hist.percentile(95.0) {
if min != f64::INFINITY && max != 0_f64 {
return Ok((min, max, p95));
}
}
Err("No data")
})
.collect()
}
Expand Down Expand Up @@ -121,12 +130,8 @@ impl DataStore {
}

fn format_tick(&self, increment: f64, value: f64) -> String {
if increment >= 1.0 {
format!("{:.0}", value)
} else {
let precision: usize = increment.log10().abs().ceil() as usize;
format!("{:.precision$}", value)
}
let precision: usize = increment.log10().abs().ceil().max(1.0) as usize;
format!("{:.precision$}", value)
}

pub fn y_axis_labels(&self, bounds: [f64; 2], num_ticks: i32) -> Vec<Span> {
Expand Down
122 changes: 65 additions & 57 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,6 @@ pub fn draw_ui<T: tui::backend::Backend>(
) {
terminal
.draw(|f| {
let chunks: Vec<tui::layout::Rect> = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints(
iter::repeat(Constraint::Length(1))
.take(args.cmds.len())
.chain(iter::once(Constraint::Percentage(10)))
.collect::<Vec<Constraint>>(),
)
.split(f.size());
for (((cmd_id, cmd), stats), &style) in args
.cmds
.iter()
.enumerate()
.zip(data_store.stats())
.zip(&data_store.styles)
{
let header_layout = Layout::default()
.direction(Direction::Horizontal)
.constraints(
[
Constraint::Percentage(40),
Constraint::Percentage(15),
Constraint::Percentage(15),
Constraint::Percentage(15),
Constraint::Percentage(15),
]
.as_ref(),
)
.split(chunks[cmd_id]);

f.render_widget(
Paragraph::new(format!("Running cmd: {}", cmd)).style(style),
header_layout[0],
);

f.render_widget(
Paragraph::new(format!("current {:?}", data_store.last(cmd_id) as u64))
.style(style),
header_layout[1],
);

f.render_widget(
Paragraph::new(format!("min {:?}", stats.minimum().unwrap_or(0))).style(style),
header_layout[2],
);
f.render_widget(
Paragraph::new(format!("max {:?}", stats.maximum().unwrap_or(0))).style(style),
header_layout[3],
);
f.render_widget(
Paragraph::new(format!("p95 {:?}", stats.percentile(95.0).unwrap_or(0)))
.style(style),
header_layout[4],
);
}

let datasets: Vec<_> = data_store
.data
.iter()
Expand Down Expand Up @@ -114,6 +57,71 @@ pub fn draw_ui<T: tui::backend::Backend>(
([min, max], num_ticks)
};

let increment = (y_axis_bounds[1] - y_axis_bounds[0]) / (y_axis_num_ticks - 1) as f64;
let precision: usize = increment.log10().abs().ceil().max(1.0) as usize + 1;

// Top level layout
let chunks: Vec<tui::layout::Rect> = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints(
iter::repeat(Constraint::Length(1))
.take(args.cmds.len())
.chain(iter::once(Constraint::Percentage(10)))
.collect::<Vec<Constraint>>(),
)
.split(f.size());

// Header line for each command
for (((cmd_id, cmd), stats), &style) in args
.cmds
.iter()
.enumerate()
.zip(data_store.stats())
.zip(&data_store.styles)
{
let header_layout = Layout::default()
.direction(Direction::Horizontal)
.constraints(
[
Constraint::Percentage(40),
Constraint::Percentage(15),
Constraint::Percentage(15),
Constraint::Percentage(15),
Constraint::Percentage(15),
]
.as_ref(),
)
.split(chunks[cmd_id]);

f.render_widget(
Paragraph::new(format!("Running cmd: {}", cmd)).style(style),
header_layout[0],
);

f.render_widget(
Paragraph::new(format!("current {:.precision$}", data_store.last(cmd_id)))
.style(style),
header_layout[1],
);

if let Ok((min, max, p95)) = stats {
f.render_widget(
Paragraph::new(format!("min {:.precision$}", min)).style(style),
header_layout[2],
);
f.render_widget(
Paragraph::new(format!("max {:.precision$}", max)).style(style),
header_layout[3],
);
f.render_widget(
Paragraph::new(format!("p95 {:.precision$}", p95)).style(style),
header_layout[4],
);
}
}

// Chart
let chart = Chart::new(datasets)
.block(Block::default().borders(Borders::NONE))
.x_axis(
Expand Down

0 comments on commit 9d83be0

Please sign in to comment.