""" Auto Visualization -- chon loai bieu do (metric / bar / line / table) dua tren hinh dang ket qua truy van. Heuristic don gian, khong can train rieng: - 1 dong x 1 cot, gia tri so -> "metric" (so lon, vd COUNT(*)) - cot dau la nhan (text), co cot so, ten cot goi y thoi gian -> "line" - cot dau la nhan (text), co cot so, it dong (<=30) -> "bar" - con lai (nhieu cot, nhieu dong, hoac toan text) -> "table" """ import pandas as pd _TIME_HINTS = ("year", "date", "time", "month", "day") def make_chart_data(df: pd.DataFrame): """Tra ve (chart_type, chart_df). chart_type in {'metric', 'bar', 'line', 'table'}. chart_df da duoc set_index() phu hop de truyen truc tiep vao st.bar_chart/ st.line_chart (voi 'table'/'metric' thi chart_df = df goc, khong dung den). Model SQL hay sinh aggregate truoc label (vd SELECT COUNT(*), city FROM ... GROUP BY city), nen label_col duoc tim trong ALL columns, khong chi cot dau. api.py se reorder cot truoc khi serialize neu label_col khong o vi tri 0. """ if df.empty: return "table", df n_rows, n_cols = df.shape numeric_cols = df.select_dtypes(include="number").columns.tolist() text_cols = df.select_dtypes(exclude="number").columns.tolist() if n_rows == 1 and n_cols == 1 and numeric_cols: return "metric", df if n_cols < 2 or not numeric_cols: return "table", df # Can it nhat 1 cot text de lam label thanh truc X cua chart if not text_cols: return "table", df label_col = text_cols[0] value_cols = [c for c in df.columns if c in numeric_cols] if not value_cols or n_rows < 2: return "table", df chart_df = df.set_index(label_col)[value_cols] if any(hint in str(label_col).lower() for hint in _TIME_HINTS): return "line", chart_df if n_rows <= 30: return "bar", chart_df return "table", df