use ratatui::{
prelude::*,
widgets::{Block, Borders, Row, Table, Cell, Paragraph}, };
use polars::prelude::DataFrame;
use crate::ui::theme;
pub struct StatsPanel<'a> {
stats_df: &'a DataFrame,
}
impl<'a> StatsPanel<'a> {
pub fn new(stats_df: &'a DataFrame) -> Self {
Self { stats_df }
}
pub fn render(&self, f: &mut Frame, area: Rect) {
let block = Block::default()
.title("Descriptive Statistics")
.borders(Borders::ALL)
.border_style(theme::BORDER_STYLE); f.render_widget(block, area);
let inner_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(0)].as_ref())
.margin(1) .split(area);
let title = Paragraph::new("Summary").alignment(Alignment::Center);
f.render_widget(title, inner_chunks[0]);
let headers = self.stats_df.get_column_names();
let header_cells = headers.iter()
.map(|s| Cell::from(s.to_string()).style(theme::ACCENT_BOLD_STYLE)) .collect::<Vec<Cell>>();
let mut rows: Vec<Row> = Vec::new();
for i in 0..self.stats_df.height() {
if let Ok(row) = self.stats_df.get_row(i) {
let cells = row.0.iter().map(|item| Cell::from(item.to_string())).collect::<Vec<Cell>>();
rows.push(Row::new(cells));
}
}
let mut widths: Vec<u16> = headers.iter()
.map(|name| name.len() as u16)
.collect();
for i in 0..self.stats_df.height() {
if let Ok(row) = self.stats_df.get_row(i) {
for (j, cell_data) in row.0.iter().enumerate() {
let cell_width = cell_data.to_string().len() as u16;
if j < widths.len() && cell_width > widths[j] {
widths[j] = cell_width;
}
}
}
}
let constraints: Vec<Constraint> = widths.iter()
.map(|&w| Constraint::Length(w + 2)) .collect();
let table = Table::new(rows, &constraints)
.header(Row::new(header_cells))
.block(Block::default())
.row_highlight_style(Style::new().add_modifier(Modifier::BOLD).bg(theme::TEXT_COLOR));
f.render_widget(table, inner_chunks[1]);
}
}