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 += '';