65f5b66b05
- src/export/warehouse.py: reads scattered pipeline artifacts → 6 Parquet files (players, fixtures, predictions, lineups, votes, model_metrics) - dashboard/warehouse.py: read-only cached Parquet loader - .streamlit/config.toml: dark theme base, server config - dashboard/viz/template.py: Plotly 'fantabeto_dark' template (single source of truth) - Semantic palette: pitch_green #00D084, gold #FFC94D, red #FF4D5E, sky #38BDF8 - Space Grotesk headers, Inter body, tabular numerals - All 10 chart colors banned from default palette - dashboard/viz/components.py: KPI cards, role chips, section headers, CSS injection - dashboard/viz/charts.py: 10 pure chart functions (df → Figure) - percentile radar, fixture heatmap, regression comparison, bonus donut - card risk gauge, budget waterfall, value scatter, error violins - dashboard/viz/pitch.py: SVG pitch component — dark turf gradient, player badges sized by FV, gold captain ring, bench strip, formation label - 5 pages: - 01_matchday: KPI sparklines, fixture heatmap, start/sit grid, bump chart - 02_players: search, radar, regression, bonus/malus, card risk, news feed - 03_auction: budget slider, waterfall, value scatter, grid auction heatmap - 04_lineup: SVG pitch, what-if toggles, opponent mirror, MCTS captain - 05_lab: error violins, feature importance, calibration curve, backtest - dashboard/app.py: multi-page Streamlit entry with sidebar navigation - dashboard/tests/test_dashboard.py: 18 unit tests (warehouse, template, charts, pitch) - DASHBOARD.md: full architecture docs, design system reference - 49 total tests passing (31 existing + 18 dashboard)
5.4 KiB
5.4 KiB
Fantabeto Dashboard
Project Al-Cihred — Production-grade Streamlit dashboard for the 2026/27 Fantacalcio season.
streamlit run dashboard/app.py
Architecture
data/warehouse/ ← Versioned Parquet (read by dashboard)
players.parquet 505 rows — roster + 25/26 stats + per-90 metrics
fixtures.parquet 10 rows — matchday 1 home/away + formations
predictions.parquet 505 rows — FV projections with std + starter prob
lineups.parquet 466 rows — probable lineups with starter %
votes.parquet 12,049 rows — historical per-matchday votes (25/26)
model_metrics.parquet 1 row — RMSE, R², sample count
dashboard/
app.py ← Entry point: multi-page routing via sidebar
warehouse.py ← Read-only Parquet loader (@st.cache_data)
viz/
template.py ← Plotly template "fantabeto_dark" + color palette
charts.py ← Pure functions: df → Figure (heatmap, radar, etc.)
pitch.py ← SVG pitch component with player badges
components.py ← KPI cards, role chips, section headers, CSS
pages/
01_matchday.py ← Control Room: KPIs, fixture heatmap, start/sit
02_players.py ← Intelligence: radar, regression, card risk, news
03_auction.py ← War Room: waterfall, value scatter, grid heatmap
04_lineup.py ← Optimizer: SVG pitch, what-if toggles, opponent
05_lab.py ← Model Lab: error violins, calibration, backtest
tests/
test_dashboard.py 18 unit tests (warehouse, template, charts, pitch)
src/export/warehouse.py ← Exporter: reads pipeline artifacts → Parquet
.streamlit/config.toml ← Dark theme base, server config
Design System — Stadium Night
| Property | Value |
|---|---|
| Background | #0B0F17 |
| Card bg | #111827 at 70% opacity, 14px radius, blur 8px |
| Border | #1F2937 |
| Pitch Green | #00D084 — positive, bonus |
| Gold | #FFC94D — captain, highlight |
| Red | #FF4D5E — malus, risk |
| Sky | #38BDF8 — neutral data |
| Violet | #A78BFA — uncertainty |
| Type | Space Grotesk (headers), Inter (body), tabular numerals |
| Charts | All use fantabeto_dark template. No default Plotly palette anywhere. |
Pages
1. Matchday Control Room
- KPI row: projected points, players at risk (P(start) < 70%), matchday count, FV trend sparkline
- Fixture difficulty heatmap: teams × gameweeks, colored by opponent xGA/FV strength
- Start/Sit grid: top 20 players with role chips, H/A indicator, projected FV ± std, risk status (🟢 START / 🟡 DOUBT / 🔴 RISK)
- Bump chart: projected rank trajectory across first 10 GWs
2. Player Intelligence
- Search: autocomplete on all 505 players, filtered by role/team
- Player header: FV avg, games played, GW1 start %, role chip, FVM, QI
- Percentile radar: 7 metrics normalized vs role average (goals, assists, xG, prog passes, tackles, interceptions, SoT%)
- Goals vs Expected: bar chart with divergence annotation
- Bonus/malus donut: goal bonus + assist bonus − card malus breakdown
- Card risk gauge: yellow/red card per-game risk indicators
- News feed: placeholder for RAG pipeline output (injuries, suspensions, tactical shifts)
- Historical votes: last 10 matchday votes table
3. Auction War Room
- Budget controls: sliders for budget (300–700 cr) and role quotas
- KPI row: players drafted, total spent, projected FV, avg price per player
- Budget waterfall: Sankey-style allocation per role (GK/DEF/MID/FWD)
- Value scatter: FV avg vs QI, bubble size = games played, top steals labeled, cost-per-FV isolines
- Grid auction heatmap: top players × bid multipliers, colored by value surplus
- Recommended squad: per-role player list with max bid, FV, and games played
4. Lineup Optimizer
- What-if controls: force IN/OUT a player, select formation (4-4-2, 4-3-3, 3-5-2, etc.)
- KPI row: expected points (with captain), captain name, avg start %, win probability
- SVG pitch: dark turf gradient, player badges sized by FV, gold captain ring, risk markers, bench strip, formation label
- Player list: role-chipped players with FV and risk flags
- Opponent mirror: per-duel edge arrows (🟢 advantage / 🔴 disadvantage / ⚪ neutral)
5. Model Lab
- KPI row: RMSE, R², training samples, feature count
- Error violins: prediction error distribution by role
- Feature importance: Pearson correlation with FV avg
- Calibration curve: predicted vs observed uncertainty
- Backtest: league average FV across 38 matchdays
- Architecture notes: model overview, key insights, limitations
Running
# First time: export warehouse
python -m src.export.warehouse
# Install (if not already)
pip install streamlit
# Launch dashboard
streamlit run dashboard/app.py
# Run tests
python -m pytest dashboard/tests/ -v
Data Refresh
The warehouse reads pre-computed Parquet files. To refresh after running the pipeline:
python -m src.export.warehouse
Then reload the dashboard — @st.cache_data(ttl=3600) will pick up new files after 1 hour or on manual cache clear.
Dependencies
Added to requirements.txt:
streamlit>=1.35
Already present:
plotly>=5.18,pandas>=2.1,numpy>=1.26,openpyxl>=3.1