Pierre Laub endurance × creativity

Dashboard-Upgrade: Ghost-Tracking & Performance-Vergleich auf Profi-Niveau

Die Vision: Daten nicht nur sehen, sondern vergleichen

Nachdem die ETL-Pipeline steht und alle Daten sauber in BigQuery landen, stellt sich die nächste Frage:
Wie lerne ich aus diesen Daten?

Eine einzelne Lauf-Einheit zu sehen ist nett. Aber zu verstehen, warum ich heute bei Kilometer 5 eingebrochen bin, während ich letzte Woche an der gleichen Stelle noch fliegen konnte – das ist echtes Data-Driven Training.

Die Lösung: Ein mächtiges Session-Comparison-Feature, das auf dem Konzept von „Ghosts“ (bekannt aus Rennispielen) basiert.


1. Das Ghost-Konzept: Layering statt Suchen

Statt zwischen zwei Tabs hin und her zu springen, habe ich mich für ein Layering-Modell entschieden:

  • Primary Session: Die aktuelle Einheit (fett, volle Farbe, mit Area-Gradient).
  • Ghost Sessions: Vergleichs-Einheiten (dünner, gestrichelt, reduzierte Opazität).

Man kann nun beliebig viele Ghosts über die Primär-Session legen. Jede Ghost-Session erhält eine eigene Farbe, die sich konsistent durch das gesamte UI zieht.


2. Der Gamechanger: Fortschritts-Normalisierung (%)

Hier lag die größte technische Herausforderung. Sessions sind selten exakt gleich lang – weder zeitlich noch von der Distanz her. Ein Chart basierend auf „Samples“ oder „Sekunden“ ist wertlos, wenn eine Einheit 45 Minuten und die andere 60 Minuten dauerte.

Die Lösung: Eine Normalisierung der X-Achse auf den Fortschritt in Prozent (0-100%).

Egal ob 5 km oder 15 km: Beide Einheiten starten bei 0% und enden bei 100%. Dank D3.js Scales berechne ich die Indizes für jeden Datenpunkt dynamisch:

// Beispiel der Normalisierung in D3.js
const xScale = d3.scaleLinear().domain([0, 100]).range([0, width]);

// Line Generator nutzt den relativen Index
const getLineGenerator = (dataLength: number) => d3
  .line()
  .x((_, i) => xScale((i / (dataLength - 1)) * 100))
  // ...

Jetzt kann ich auf einen Blick sehen: „Ah, bei 70% der Strecke war mein Puls beim Ghost deutlich niedriger bei gleicher Pace.“


3. Die Vergleichstabelle: Zahlen lügen nicht

Parallel zum Chart habe ich eine Comparison Table implementiert. Sobald der Vergleichsmodus aktiv ist, wechselt das Dashboard von der Kachel-Ansicht in eine tabellarische Gegenüberstellung.

  • Side-by-Side: Alle Metriken (Puls, Speed, Power, Cadence) direkt nebeneinander.
  • Header-Sync: Die Spaltenköpfe nutzen die Ghost-Farben aus dem Chart für direkte visuelle Zuordnung.
  • Sticky Labels: Die Metrik-Namen bleiben beim Scrollen fixiert – Usability first.

4. UI/UX: Suche mit Präzision

Um Ghosts schnell zu finden, braucht es mehr als eine Liste. Das neue Search-Modal erlaubt Filter nach:

  • Sportart (Running, Cycling, Swimming)
  • Zeitraum (Start-/End-Datum)
  • Distanz-Range (z.B. „alles zwischen 8.000m und 12.000m“)

Fazit: Aus Daten wird Wissen

Mit dem Session-Comparison-Update ist das Dashboard von einem reinen Logbuch zu einem Analyse-Werkzeug gewachsen. Die Kombination aus visuellen Ghost-Pfaden und harten Fakten in der Vergleichstabelle macht Fortschritt (oder Rückschritt) sofort greifbar.

Das Projekt zeigt einmal mehr: Wenn das Backend (BigQuery + Python ETL) solide ist, sind im Frontend keine Grenzen gesetzt.