Pierre Laub endurance × creativity

Weekly & Monthly Activity Charts – Langzeit-Überblick aus BigQuery

Weekly & Monthly Activity Charts – Langzeit-Überblick aus BigQuery

Motivation: Mehr als nur Trainingstage zählen

Nach der GitHub-ähnlichen Activity-Heatmap war klar:
Ich sehe damit Konsistenz, aber noch kein echtes Volumen-Gefühl.

Die Fragen, die offen blieben:

  • Wo liegen meine Belastungsspitzen?
  • Wie verteilt sich Run / Bike / Swim über Wochen und Monate?
  • Wie sieht eine komplette Saison „in einem Bild“ aus?

Die Antwort darauf sind Weekly und Monthly Activity Charts – als gestapelte Balkendiagramme.


Architektur-Prinzip

Das Grundprinzip bleibt bewusst simpel:

  • BigQuery: Aggregation & Fakten
  • Backend API: reines Durchreichen
  • Frontend: Filter, Darstellung, Interpretation

Keine Chart-Logik im Backend, keine unnötigen ETL-Stufen.

Single Source of Truth bleibt eine Daily Materialized View.


Datenbasis: Daily → Weekly / Monthly

Alle Auswertungen basieren auf einer Tagesaggregation pro Sportart:

  • session_count
  • total_distance_m
  • total_elapsed_time

Darauf aufbauend existieren zwei reine Views.


BigQuery: Monthly Activity View

CREATE OR REPLACE VIEW
  `fit-analyze-480219.fitness_data.monthly_activity_summary_v`
AS
SELECT
  DATE_TRUNC(activity_date, MONTH)  AS month_start_date,
  EXTRACT(YEAR FROM activity_date)  AS year,
  EXTRACT(MONTH FROM activity_date) AS month,
  sport,
  SUM(session_count)        AS session_count,
  SUM(total_distance_m)     AS total_distance_m,
  SUM(total_elapsed_time)   AS total_elapsed_time
FROM
  `fit-analyze-480219.fitness_data.daily_activity_summary_mv`
GROUP BY
  month_start_date,
  year,
  month,
  sport;

BigQuery: Weekly Activity View (ISO-Woche!)

CREATE OR REPLACE VIEW
  `fit-analyze-480219.fitness_data.weekly_activity_summary_v`
AS
SELECT
  DATE_TRUNC(activity_date, WEEK(MONDAY)) AS week_start_date,
  EXTRACT(ISOYEAR FROM activity_date)     AS iso_year,
  EXTRACT(ISOWEEK FROM activity_date)     AS iso_week,
  sport,
  SUM(session_count)        AS session_count,
  SUM(total_distance_m)     AS total_distance_m,
  SUM(total_elapsed_time)   AS total_elapsed_time
FROM
  `fit-analyze-480219.fitness_data.daily_activity_summary_mv`
GROUP BY
  week_start_date,
  iso_year,
  iso_week,
  sport;

Backend: absichtlich langweilig

Das Backend macht:

  • Query auf die View
  • optional Caching
  • JSON zurückgeben

Frontend: Stacked Bars ohne Chart-Library

Die Charts bestehen aus:

  • Flexbox
  • gestapelten divs
  • fixer Höhe
  • Farbcode pro Sport

Features:

  • Year-Tabs
  • Sport-Filter
  • Data Modes (Sessions / km / h)
  • Hover-Tooltips

Fazit

Mit zwei simplen BigQuery-Views und einem dünnen API-Layer entsteht ein Dashboard, das performant, günstig und extrem aussagekräftig ist.

Hier gehts zum Dashboard: Monthly Activity Chart