use std::cmp;
use ratatui::{
layout::{self},
widgets::Widget,
};
use crate::{
state::histogram::DurationHistogram,
view::{self, mini_histogram::MiniHistogram, percentiles::Percentiles},
};
const MIN_HISTOGRAM_BLOCK_WIDTH: u16 = 22;
pub(crate) struct Durations<'a> {
styles: &'a view::Styles,
histogram: Option<&'a DurationHistogram>,
percentiles_title: &'a str,
histogram_title: &'a str,
percentiles_width: u16,
}
impl Widget for Durations<'_> {
fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
let (percentiles_area, histogram_area) = if self.styles.utf8 {
let percentiles_width = match self.percentiles_width {
width if width > 0 => width,
_ => cmp::max(self.percentiles_title.len() as u16, 13_u16) + 2,
};
if area.width < percentiles_width + MIN_HISTOGRAM_BLOCK_WIDTH {
(area, None)
} else {
let areas = layout::Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
layout::Constraint::Length(percentiles_width),
layout::Constraint::Min(MIN_HISTOGRAM_BLOCK_WIDTH),
]
.as_ref(),
)
.split(area);
(areas[0], Some(areas[1]))
}
} else {
(area, None)
};
let percentiles_widget = Percentiles::new(self.styles)
.title(self.percentiles_title)
.histogram(self.histogram);
percentiles_widget.render(percentiles_area, buf);
if let Some(histogram_area) = histogram_area {
let histogram_widget = MiniHistogram::default()
.block(self.styles.border_block().title(self.histogram_title))
.histogram(self.histogram)
.duration_precision(2);
histogram_widget.render(histogram_area, buf);
}
}
}
impl<'a> Durations<'a> {
pub(crate) fn new(styles: &'a view::Styles) -> Self {
Self {
styles,
histogram: None,
percentiles_title: "Percentiles",
histogram_title: "Histogram",
percentiles_width: 0,
}
}
pub(crate) fn histogram(mut self, histogram: Option<&'a DurationHistogram>) -> Self {
self.histogram = histogram;
self
}
pub(crate) fn percentiles_title(mut self, title: &'a str) -> Self {
self.percentiles_title = title;
self
}
pub(crate) fn histogram_title(mut self, title: &'a str) -> Self {
self.histogram_title = title;
self
}
pub(crate) fn percentiles_width(mut self, width: u16) -> Self {
self.percentiles_width = width;
self
}
}