from html import escape import pandas as pd import streamlit as st TABLE_CSS = """ """ TEXT_COLUMN_HINTS = ( "tweet", "teks", "isi", "keterangan", "bersih", "clean", "hasil akhir", ) NOWRAP_COLUMN_HINTS = ( "id", "no", "tanggal", "waktu", "status", "sentimen", "keyakinan", "database", ) def _plain_value(value): if value is None: return "-" try: if pd.isna(value): return "-" except (TypeError, ValueError): pass return str(value) def _badge_class(value): text = value.lower() if "negatif" in text or "gagal" in text: return "sd-badge-red" if "positif" in text or "berhasil" in text: return "sd-badge-green" if "netral" in text: return "sd-badge-slate" return "sd-badge-blue" def _is_text_column(column): name = column.lower() return any(hint in name for hint in TEXT_COLUMN_HINTS) def _is_nowrap_column(column): name = column.lower() return any(hint in name for hint in NOWRAP_COLUMN_HINTS) def render_standard_table( df, *, height=380, min_width=760, right_align=None, nowrap=None, badge_columns=None, wide_columns=None, column_widths=None, ): if df.empty: st.info("Tidak ada data untuk ditampilkan.") return right_align = set(right_align or []) nowrap = set(nowrap or []) badge_columns = set(badge_columns or []) wide_columns = set(wide_columns or []) column_widths = column_widths or {} columns = list(df.columns) colgroup = "" if column_widths: col_tags = [] for column in columns: width = column_widths.get(column) style = f' style="width:{escape(str(width))};"' if width else "" col_tags.append(f"") colgroup = f"{''.join(col_tags)}" header_cells = [] for column in columns: classes = [] if column in right_align: classes.append("sd-table-right") header_cells.append( f'{escape(str(column))}' ) body_rows = [] for _, row in df.iterrows(): cells = [] for column in columns: value = _plain_value(row[column]) classes = [] if column in right_align: classes.append("sd-table-right") if column in nowrap or _is_nowrap_column(str(column)): classes.append("sd-table-nowrap") if column in wide_columns or _is_text_column(str(column)): classes.append("sd-table-wide") class_attr = f' class="{" ".join(classes)}"' if classes else "" if column in badge_columns: badge_class = _badge_class(value) cell_html = ( f'' f"{escape(value)}" ) else: cell_html = escape(value) cells.append(f"{cell_html}") body_rows.append(f"{''.join(cells)}") table_html = f""" {TABLE_CSS}
{colgroup} {''.join(header_cells)} {''.join(body_rows)}
""" st.markdown(table_html, unsafe_allow_html=True)