feat(explorer): restructure SVD tab — pole-split motions, party axis chart, inline expanders with voting

main
Sven Geboers 1 month ago
parent 1515661929
commit 6b8ec93fe0
  1. 118
      explorer.py

@ -929,62 +929,90 @@ def build_svd_components_tab(db_path: str) -> None:
) )
comp_sel = comp_options[comp_sel_idx] comp_sel = comp_options[comp_sel_idx]
# Show theme explanation + poles # Show theme explanation
theme = SVD_THEMES.get(comp_sel, {}) theme = SVD_THEMES.get(comp_sel, {})
if theme: if theme:
st.info(f"**{theme['label']}** — {theme['explanation']}") st.info(f"**{theme['label']}** — {theme['explanation']}")
pos = theme.get("positive_pole", "")
neg = theme.get("negative_pole", "")
if pos or neg:
pcol, ncol = st.columns(2)
with pcol:
st.success(f"▲ **Positieve pool:** {pos}")
with ncol:
st.error(f"▼ **Negatieve pool:** {neg}")
motions = comp_map.get(comp_sel, []) motions = comp_map.get(comp_sel, [])
col1, col2 = st.columns([1, 2]) # Party axis chart
with col1: party_scores = load_party_axis_scores(db_path)
st.markdown("**Top-moties (titels)**") _render_party_axis_chart(party_scores, comp_sel)
for m in motions:
mid = m.get("motion_id")
score = m.get("score", 0.0)
title = m.get("title") or f"Motie #{mid}"
sign = "" if score >= 0 else ""
if st.button(f"{sign} {mid}: {title[:72]}", key=f"btn_{comp_sel}_{mid}"):
st.session_state["svd_selected_mid"] = mid
with col2: # Batch-fetch motion details (title, date, policy_area, url, body_text, voting_results)
sel_mid = st.session_state.get("svd_selected_mid") motion_ids = [m.get("motion_id") for m in motions if m.get("motion_id") is not None]
if not sel_mid and motions: motion_details: Dict[int, tuple] = {}
sel_mid = motions[0].get("motion_id") if motion_ids:
if sel_mid:
# fetch motion metadata from DB for completeness
try: try:
placeholders = ", ".join("?" for _ in motion_ids)
con = duckdb.connect(database=db_path, read_only=True) con = duckdb.connect(database=db_path, read_only=True)
row = con.execute( db_rows = con.execute(
"SELECT id, title, date, policy_area, url, body_text FROM motions WHERE id=?", f"SELECT id, title, date, policy_area, url, body_text, voting_results "
[int(sel_mid)], f"FROM motions WHERE id IN ({placeholders})",
).fetchone() [int(mid) for mid in motion_ids],
).fetchall()
con.close() con.close()
motion_details = {r[0]: r for r in db_rows}
except Exception: except Exception:
row = None logger.exception("Failed to batch-fetch motion details")
if row: # Split motions by pole sign
st.markdown(f"### {row[1] or f'Motie #{row[0]}'}") pos_motions = [m for m in motions if float(m.get("score", 0.0)) >= 0]
try: neg_motions = [m for m in motions if float(m.get("score", 0.0)) < 0]
date_str = str(row[2])[:10]
except Exception: pos_pole = (
date_str = "?" theme.get("positive_pole", "Positieve pool") if theme else "Positieve pool"
st.caption(f"📅 {date_str} | {row[3]}") )
if row[4] and str(row[4]).startswith("http"): neg_pole = (
st.markdown(f"[🔗 Bekijk op Tweede Kamer]({row[4]})") theme.get("negative_pole", "Negatieve pool") if theme else "Negatieve pool"
if row[5]: )
with st.expander("Toon volledige tekst"):
st.write(row[5]) pcol, ncol = st.columns(2)
else:
st.info(f"Metadata not found in DB for motion {sel_mid}") with pcol:
st.success(f"▲ **Positieve pool:** {pos_pole}")
for m in pos_motions:
mid = m.get("motion_id")
raw_title = m.get("title") or f"Motie #{mid}"
with st.expander(f"{raw_title[:80]}"):
row = motion_details.get(int(mid)) if mid is not None else None
if row:
try:
date_str = str(row[2])[:10]
except Exception:
date_str = "?"
st.caption(f"📅 {date_str} | {row[3] or ''}")
if row[4] and str(row[4]).startswith("http"):
st.markdown(f"[🔗 Bekijk op Tweede Kamer]({row[4]})")
if row[5]:
with st.expander("Toon volledige tekst"):
st.write(row[5])
_render_voting_results(row[6])
else:
st.caption("_Geen metadata beschikbaar_")
with ncol:
st.error(f"▼ **Negatieve pool:** {neg_pole}")
for m in neg_motions:
mid = m.get("motion_id")
raw_title = m.get("title") or f"Motie #{mid}"
with st.expander(f"{raw_title[:80]}"):
row = motion_details.get(int(mid)) if mid is not None else None
if row:
try:
date_str = str(row[2])[:10]
except Exception:
date_str = "?"
st.caption(f"📅 {date_str} | {row[3] or ''}")
if row[4] and str(row[4]).startswith("http"):
st.markdown(f"[🔗 Bekijk op Tweede Kamer]({row[4]})")
if row[5]:
with st.expander("Toon volledige tekst"):
st.write(row[5])
_render_voting_results(row[6])
else:
st.caption("_Geen metadata beschikbaar_")
def build_mp_quiz_tab(db_path: str) -> None: def build_mp_quiz_tab(db_path: str) -> None:

Loading…
Cancel
Save