1. Define the decision and grain
Write one sentence describing who uses the dashboard and what action it supports. Choose the row grain: match, team-match, player-match, shot or event. Mixing grains without explicit aggregation creates duplicate totals.
2. Select and license the source
StatsBomb Open Data supplies documented JSON for selected matches and is suitable for prototypes under its stated terms. Metrica's sample repository includes synchronized tracking and event examples. Production coverage requires a source whose rights, competitions and refresh process fit the use case.
3. Preserve raw and modelled layers
| Layer | Contents | Rule |
|---|---|---|
| Raw | Unchanged source payload | Immutable and timestamped |
| Clean | Typed IDs, dates, coordinates | Reproducible transformations |
| Metric | xG, rates, rolling windows | Version every definition |
| Presentation | Tables and charts | No hidden business logic |
4. Build quality tests
- Match identifiers and team sides are unique.
- Score events reconcile with final score under documented exclusions.
- Minutes and periods are valid.
- Coordinates remain inside the provider pitch system.
- Rolling features use only earlier matches.
- Source delay and last successful refresh are visible.
scikit-learn's pitfalls guide documents why transformations must be consistent and why information leakage invalidates evaluation.
5. Design low-effort views
Put the decision summary first, then offer filters for competition, date, venue and sample. Show totals with denominators, definitions and comparison context. Tables should scroll on mobile and remain keyboard-readable.
6. Verify a release
Reconcile at least one match manually, test empty and delayed states, compare aggregates with the raw layer, and take desktop and mobile screenshots. Keep a change log when metrics or providers change.
A reader-centred information architecture
The first view should answer one decision, not display every available field. A useful sequence is:
| Layer | Reader question | Example control |
|---|---|---|
| Summary | What changed? | Date and competition filter |
| Comparison | Relative to what? | Baseline or opponent selector |
| Detail | Which events drove it? | Match or shot drill-down |
| Provenance | Can I trust the number? | Definition, source and updated time |
Keep filters visible in exports and shared URLs. Use consistent units and include denominators beside rates. Colour should reinforce labels, not carry meaning alone. Tables need keyboard access, meaningful headers and horizontal handling on small screens.
Data and release tests
Test duplicate keys, impossible values, missing periods, team identity changes and delayed corrections. Reconcile a small fixture sample against the provider's raw payload. Snapshot formulas and expected results so a dependency or schema change cannot silently alter historical charts.
Before release, ask a reader unfamiliar with the implementation to answer three concrete questions from the dashboard. If the reader cannot identify the date range, definition or comparison baseline, the interface has not made the evidence legible. Monitor freshness and failed ingest separately from page availability; a dashboard that loads stale data successfully is still failing.
Related resources
Use football data providers for source selection or limits of statistics for interpretation controls.
Continue learning
- Next guide: How to Use xG in Pre-Match Research
- Related guide: League-Specific Football Statistics
Assumptions and limitations
This guide is architecture-neutral. Open samples are not equivalent to maintained live feeds, and a visually polished dashboard cannot compensate for missing provenance, invalid rights or stale data.

