Training sichtbar machen: Eine GitHub-ähnliche Activity-Heatmap für meine Sportdaten
Motivation: Warum eine Heatmap für Training?
Jede Sport-App zeigt Trainings als Einzelsessions: Dauer, Pace, Watt, Herzfrequenz.
Was dabei fast immer fehlt, ist der Langzeit-Überblick:
- Wie konstant trainiere ich wirklich?
- Wo entstehen Pausen, Überlastungen oder Muster?
- Trainiere ich eher häufig kurz oder selten lang?
In der Software-Welt gibt es dafür seit Jahren ein etabliertes UI-Pattern:
die GitHub Activity Heatmap.
Genau dieses Prinzip wollte ich auf meine Trainingsdaten übertragen –
nicht als Gimmick, sondern als ehrliches Konsistenz-Instrument.
Datenbasis: Von FIT-Files zur Tagesaggregation
Die Heatmap basiert nicht auf Rohdaten, sondern auf einer bewusst stark aggregierten Sicht.
Ausgangspunkt sind meine bereits normalisierten Sessions in BigQuery (FIT-Parsing, ETL, Idempotenz etc. habe ich in den vorherigen Posts beschrieben).
Darauf aufbauend nutze ich eine Materialized View, die pro Tag und Sportart aggregiert:
- Anzahl der Sessions
- Gesamtdistanz
- Gesamtdauer
Warum eine Materialized View?
- Tagesaggregation ändert sich nicht rückwirkend
- Extrem schnelle Abfragen
- Minimale Kosten
- Perfekt für API-Zugriffe
Die View ist damit die Single Source of Truth für alle Kalender- und Heatmap-Visualisierungen.
API-Layer: bewusst langweilig, bewusst schnell
Zwischen BigQuery und Frontend sitzt ein sehr schmaler API-Layer:
- Filter nach Datumsspanne
- Optionaler Sport-Filter
- Read-only
- Redis-Cache davor
Wichtig war mir hier vor allem eines:
keine Logik im Backend, die Visualisierung beeinflusst.
Die API liefert nur rohe Tageswerte –
alle Interpretation passiert im Frontend.
So bleibt das System:
- testbar
- erweiterbar
- unabhängig von UI-Entscheidungen
Das UI-Pattern: GitHub, aber für Training
Die Heatmap folgt sehr bewusst dem GitHub-Mentalmodell:
- Spalten = Kalenderwochen
- Zeilen = Wochentage
- Farbe = Aktivitätsintensität
- Tooltip = exakte Information
Ich habe zwei Darstellungsmodi eingebaut:
1. Session Count
Zeigt, wie oft ich an einem Tag trainiert habe.
Das beantwortet Fragen wie:
- Trainiere ich regelmäßig?
- Wie oft habe ich Doppel-Einheiten?
- Wo sind echte Pausentage?
2. Total Elapsed Time
Zeigt, wie viel Zeit ich investiert habe.
Das offenbart ganz andere Muster:
- lange Grundlagenblöcke
- Wettkampfphasen
- Deload-Wochen
Die Umschaltung zwischen beiden Modi verändert nicht die Daten, sondern nur die Interpretation.
Farblogik: weniger ist mehr
Die Farbskala ist bewusst grob gehalten:
- 0 = keine Aktivität
- 1–4 = steigende Intensität
Warum keine feingranulare Skala?
Weil es hier nicht um Präzision geht, sondern um Pattern Recognition. Die Heatmap soll auf einen Blick beantworten:
„Bin ich gerade im Flow – oder nicht?“
Alles Weitere gehört in Detail-Charts.
Was man plötzlich sieht (und vorher nicht)
Seitdem ich die Heatmap nutze, sind mir Dinge aufgefallen, die kein Pace-Chart zeigt:
- Wochen mit vielen Einheiten, aber zu wenig Gesamtzeit
- „versteckte“ Pausentage rund um stressige Arbeitsphasen
- Phasen hoher Intensität ohne ausreichende Regeneration
Die Heatmap ist kein Analyse-Tool im klassischen Sinn –
sie ist ein Spiegel für Konsistenz.
Und genau das macht sie so wertvoll.
Warum ich das als eigenes Projekt baue (und nicht Strava nutze)
Natürlich gibt es Kalender in Strava, Garmin & Co.
Aber:
- keine volle Datenhoheit
- keine freie Aggregation
- keine eigene Interpretation
- keine Erweiterbarkeit
In meinem Setup kann ich morgen problemlos ergänzen:
- Trainingsstress (TSS)
- Sportarten-Overlays
- Wettkampfmarker
- Vergleich mehrerer Jahre
Die Heatmap ist nur ein Baustein –
aber ein extrem aussagekräftiger.
Fazit
Die GitHub-ähnliche Activity-Heatmap ist für mich eines der besten Beispiele, warum sich ein eigenes Data-Analytics-Setup lohnt:
- wenig Code
- klare Aggregation
- hoher Erkenntnisgewinn
Sie beantwortet keine Detailfragen –
aber sie stellt die richtigen Meta-Fragen zu Training, Konsistenz und Belastung.
Und genau dafür habe ich dieses Projekt gebaut.