You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
3.2 KiB
95 lines
3.2 KiB
"""Browser tab for the parliamentary explorer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
import analysis.explorer_data as explorer_data
|
|
from analysis.tabs._rendering import _render_voting_results, st
|
|
|
|
|
|
def build_browser_tab(db_path: str, show_rejected: bool) -> None:
|
|
"""Build the Motie Browser tab."""
|
|
st.subheader("Motie Browser")
|
|
|
|
df = explorer_data.load_motions_df(db_path)
|
|
if df.empty:
|
|
st.warning("Geen moties beschikbaar.")
|
|
return
|
|
|
|
if not show_rejected:
|
|
df = df[df["title"].fillna("").str.strip() != "Verworpen."]
|
|
|
|
col1, col2, col3 = st.columns(3)
|
|
with col1:
|
|
years = sorted(df["year"].dropna().astype(int).unique().tolist())
|
|
year_filter = st.selectbox("Jaar", ["(Alle)"] + [str(y) for y in years])
|
|
with col2:
|
|
min_controversy_b = st.slider(
|
|
"Min. controverse",
|
|
min_value=0.0,
|
|
max_value=1.0,
|
|
value=0.0,
|
|
step=0.05,
|
|
key="browser_controversy",
|
|
)
|
|
with col3:
|
|
sort_by = st.selectbox("Sorteren op", ["Datum (nieuw)", "Controverse", "Marge"])
|
|
|
|
working = df.copy()
|
|
if year_filter != "(Alle)":
|
|
working = working[working["year"] == int(year_filter)]
|
|
if min_controversy_b > 0:
|
|
working = working[working["controversy_score"] >= min_controversy_b]
|
|
|
|
sort_map = {
|
|
"Datum (nieuw)": ("date", False),
|
|
"Controverse": ("controversy_score", False),
|
|
"Marge": ("winning_margin", True),
|
|
}
|
|
sort_col, sort_asc = sort_map[sort_by]
|
|
working = working.sort_values(by=sort_col, ascending=sort_asc)
|
|
|
|
display_cols = ["id", "title", "date", "controversy_score", "winning_margin"]
|
|
available_display = [c for c in display_cols if c in working.columns]
|
|
st.dataframe(
|
|
working[available_display].reset_index(drop=True),
|
|
use_container_width=True,
|
|
height=350,
|
|
)
|
|
|
|
st.divider()
|
|
|
|
st.markdown("**Detail weergave** — vul een motie-ID in:")
|
|
sel_id = st.number_input(
|
|
"Motie ID",
|
|
min_value=int(working["id"].min()) if not working.empty else 1,
|
|
max_value=int(working["id"].max()) if not working.empty else 99999,
|
|
value=int(working["id"].iloc[0]) if not working.empty else 1,
|
|
step=1,
|
|
)
|
|
motion_row = df[df["id"] == sel_id]
|
|
if not motion_row.empty:
|
|
row = motion_row.iloc[0]
|
|
st.markdown(f"### {row.get('title') or 'Onbekend'}")
|
|
date_str = row["date"].strftime("%d %b %Y") if pd.notna(row["date"]) else "?"
|
|
st.caption(
|
|
f"{date_str} | Controverse: {row.get('controversy_score', 0):.2f}"
|
|
)
|
|
|
|
url = row.get("url")
|
|
if url and str(url).startswith("http"):
|
|
st.markdown(f"[Bekijk op Tweede Kamer]({url})")
|
|
|
|
st.markdown("**Stemuitslag:**")
|
|
_render_voting_results(row.get("voting_results"))
|
|
|
|
sim = explorer_data.query_similar(db_path, int(sel_id), top_k=10)
|
|
if not sim.empty:
|
|
st.markdown("**Vergelijkbare moties:**")
|
|
st.dataframe(
|
|
sim[["title", "score", "date", "policy_area"]],
|
|
use_container_width=True,
|
|
)
|
|
else:
|
|
st.caption("_Nog geen vergelijkbare moties beschikbaar voor deze motie_")
|
|
|