From e4b877de4b05fc4e2d9dd0ec58472c7dd65b77af Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 23 Aug 2026 11:48:45 +0200 Subject: [PATCH] Tag-Ansicht: Zeitachse hugt die Aktivitaet (Start am ersten Spiel statt gerundeter halber Stunde) Vorher rundete winStart auf 30-min + 15-min-Polster -> bis zu 45 min leerer Platz vor dem ersten Balken (z.B. Spiel 09:44, Achse begann 09:00). Jetzt winStart = erstes Spiel minus 4 min, Marker adaptiv auf sauberen Uhrzeiten (15/30/60-min je nach Spanne). Co-Authored-By: Claude Opus 4.8 --- App/teacher.html | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/App/teacher.html b/App/teacher.html index d95913d..2001ca4 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -2138,9 +2138,10 @@ async function renderLiveSummary() { return; } - // Auto-Zoom: minStart / maxEnd über ALLE Sessions ermitteln, dann auf volle - // Stundenränder runden und 10 min Polster. Wenn niemand aktiv war, - // zeigen wir 08 – 14 Uhr als Standard-Bereich. + // Auto-Zoom: minStart / maxEnd über ALLE Sessions ermitteln. Die Achse HUGT + // die tatsächliche Aktivität — sie beginnt knapp vor dem ersten Spiel des Tages + // (nur kleines Polster), NICHT auf einer gerundeten halben Stunde davor. Sonst + // stünde vor dem ersten Balken bis zu 45 min leerer Platz. var minMs = Infinity, maxMs = -Infinity; students.forEach(function(s){ (s.sessions||[]).forEach(function(sess){ @@ -2152,10 +2153,10 @@ async function renderLiveSummary() { }); var dayBase = new Date(_liveDate+'T00:00:00').getTime(); if (!isFinite(minMs)) { minMs = dayBase + 8*3600*1000; maxMs = dayBase + 14*3600*1000; } - // Auf volle 30-min-Schritte runden + 15 min Polster - var winStart = Math.floor((minMs - 15*60*1000) / (30*60*1000)) * (30*60*1000); - var winEnd = Math.ceil ((maxMs + 15*60*1000) / (30*60*1000)) * (30*60*1000); - if (winEnd - winStart < 60*60*1000) winEnd = winStart + 60*60*1000; + var PAD_MS = 4*60*1000; // knappes Polster vorne/hinten + var winStart = minMs - PAD_MS; + var winEnd = maxMs + PAD_MS; + if (winEnd - winStart < 30*60*1000) winEnd = winStart + 30*60*1000; // min. 30-min-Fenster var winSpanMs = winEnd - winStart; function _msToPct(ms) { return ((ms - winStart) / winSpanMs) * 100; } function _fmtHM(ms) { @@ -2169,12 +2170,17 @@ async function renderLiveSummary() { + _fmtHM(winStart) + '–' + _fmtHM(winEnd) + ' · Klick auf Balken öffnet Details.

'; - // Stunden-Marker an der Achse + // Marker an sauberen Uhrzeiten INNERHALB des Fensters — Schrittweite passt sich + // der Spanne an (kurze Stunde = 15-min-Takt, langer Tag = Stunden-Takt), damit + // die Achse weder leer noch überladen wirkt. Erster Marker = erste saubere Zeit + // ab winStart (nicht winStart selbst, das liegt ja mitten im 15-min-Raster). + var stepMs = winSpanMs <= 2*3600*1000 ? 15*60*1000 + : winSpanMs <= 5*3600*1000 ? 30*60*1000 + : 60*60*1000; var scaleMarks = []; - for (var t = winStart; t <= winEnd; t += 30*60*1000) { + for (var t = Math.ceil(winStart / stepMs) * stepMs; t <= winEnd; t += stepMs) { var d = new Date(t); - var isHour = d.getMinutes() === 0; - scaleMarks.push({ ms: t, label: _fmtHM(t), isHour: isHour }); + scaleMarks.push({ ms: t, label: _fmtHM(t), isHour: d.getMinutes() === 0 }); } html += '
';