Dashboard: Stadium Night design system, 5-page Streamlit app, warehouse exporter

- 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)
This commit is contained in:
ramseshk
2026-08-11 14:53:51 +08:00
parent 68670889c7
commit 65f5b66b05
19 changed files with 2217 additions and 0 deletions
+137
View File
@@ -0,0 +1,137 @@
# Fantabeto Dashboard
**Project Al-Cihred** — Production-grade Streamlit dashboard for the 2026/27 Fantacalcio season.
```bash
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
```bash
# 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:
```bash
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`