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:
+137
@@ -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`
|
||||
Reference in New Issue
Block a user