Tag-Zeitachse: gestauchte Skala - Nacht 00-06 und Abend 21-24 je 1 Block, Tag 06-21 stuendlich
Regler UND Zeitachse/Balken nutzen dieselbe Stunde-Einheit-Abbildung (_hourToUnit/_unitToHour, 17 gleich breite Bloecke). Nacht-/Abend-Bloecke dunkel ohne interne Linien; Tag stuendlich beschriftet + Trennlinien. Auto-Default rundet auf Block-Grenzen. Marker an den Block-Grenzen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+55
-33
@@ -2105,6 +2105,21 @@ function _vHM(ms){
|
||||
var s = new Date(ms).toLocaleString('en-GB', {timeZone:'Europe/Vienna', hour:'2-digit', minute:'2-digit', hour12:false});
|
||||
var p = s.split(':'); return { h: parseInt(p[0],10)||0, m: parseInt(p[1],10)||0 };
|
||||
}
|
||||
// Gestauchte Tages-Skala: Nacht 00–06 und Abend 21–24 je NUR EIN Block, dazwischen
|
||||
// (06–21) stündlich. 17 Blöcke → „Einheiten" 0..17. Stunde ⇄ Einheit.
|
||||
function _hourToUnit(h){
|
||||
h = Math.max(0, Math.min(24, h));
|
||||
if (h <= 6) return h/6; // 00–06 → Einheit 0..1
|
||||
if (h <= 21) return 1 + (h-6); // 06–21 → Einheit 1..16 (1 pro Stunde)
|
||||
return 16 + (h-21)/3; // 21–24 → Einheit 16..17
|
||||
}
|
||||
function _unitToHour(u){
|
||||
u = Math.max(0, Math.min(17, u));
|
||||
if (u <= 1) return u*6; // 0→00, 1→06
|
||||
if (u <= 16) return 6 + (u-1); // 1→06 … 16→21
|
||||
return 21 + (u-16)*3; // 16→21, 17→24
|
||||
}
|
||||
var TS_STOPS = [0,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,24]; // Einheit-Index → Stunde
|
||||
function _tsInjectCss(){
|
||||
if (document.getElementById('ts-css')) return;
|
||||
var s = document.createElement('style'); s.id = 'ts-css';
|
||||
@@ -2128,21 +2143,22 @@ function _tsInjectCss(){
|
||||
document.head.appendChild(s);
|
||||
}
|
||||
// Schieberegler-Interaktion (global, für inline-Handler).
|
||||
// Regler arbeitet in EINHEITEN 0..17 (gestauchte Skala). from/to = Einheit-Index.
|
||||
function _tsClamp(){
|
||||
var fe=document.getElementById('tsFrom'), te=document.getElementById('tsTo');
|
||||
if(!fe||!te) return null;
|
||||
var f=+fe.value, t=+te.value;
|
||||
if(f>=t){ if(f>=24){f=23;} t=Math.min(24,f+1); if(+te.value<t) te.value=t; if(+fe.value>f) fe.value=f; }
|
||||
if(f>=t){ if(f>=17){f=16;} t=Math.min(17,f+1); if(+te.value<t) te.value=t; if(+fe.value>f) fe.value=f; }
|
||||
return {f:f,t:t};
|
||||
}
|
||||
function _tsVisual(){
|
||||
var v=_tsClamp(); if(!v) return;
|
||||
var r=document.getElementById('tsRange'); if(r){ r.style.left=(v.f/24*100)+'%'; r.style.width=((v.t-v.f)/24*100)+'%'; }
|
||||
var l=document.getElementById('tsLbl'); if(l) l.textContent=_pad2(v.f)+':00 – '+_pad2(v.t)+':00';
|
||||
var r=document.getElementById('tsRange'); if(r){ r.style.left=(v.f/17*100)+'%'; r.style.width=((v.t-v.f)/17*100)+'%'; }
|
||||
var l=document.getElementById('tsLbl'); if(l) l.textContent=_pad2(_unitToHour(v.f))+':00 – '+_pad2(_unitToHour(v.t))+':00';
|
||||
}
|
||||
function _tsCommit(){
|
||||
var v=_tsClamp(); if(!v) return;
|
||||
_liveWin.from=v.f; _liveWin.to=v.t;
|
||||
_liveWin.from=v.f; _liveWin.to=v.t; // Einheiten
|
||||
renderLiveSummary();
|
||||
}
|
||||
function _tsReset(){ _liveWin.from=null; _liveWin.to=null; renderLiveSummary(); }
|
||||
@@ -2239,15 +2255,25 @@ async function renderLiveSummary() {
|
||||
var _lo=_vHM(minMs), _hi=_vHM(maxMs);
|
||||
var autoFromH = Math.max(0, _lo.h);
|
||||
var autoToH = Math.min(24, _hi.h + ((_hi.m>0)?1:0));
|
||||
if (autoToH <= autoFromH) autoToH = Math.min(24, autoFromH+1);
|
||||
// Effektives Fenster: Schieberegler-Auswahl (falls gesetzt) ODER Auto.
|
||||
var fromH = (_liveWin.from!=null) ? _liveWin.from : autoFromH;
|
||||
var toH = (_liveWin.to !=null) ? _liveWin.to : autoToH;
|
||||
if (toH <= fromH) toH = Math.min(24, fromH+1);
|
||||
// Auto-Grenzen als EINHEITEN der gestauchten Skala (auf Block-Grenzen gerundet).
|
||||
var autoFromU = Math.floor(_hourToUnit(autoFromH));
|
||||
var autoToU = Math.ceil(_hourToUnit(autoToH));
|
||||
if (autoToU <= autoFromU) autoToU = Math.min(17, autoFromU+1);
|
||||
// Effektives Fenster in Einheiten: Regler-Auswahl ODER Auto.
|
||||
var fromU = (_liveWin.from!=null) ? _liveWin.from : autoFromU;
|
||||
var toU = (_liveWin.to !=null) ? _liveWin.to : autoToU;
|
||||
if (toU <= fromU) toU = Math.min(17, fromU+1);
|
||||
var fromH = _unitToHour(fromU), toH = _unitToHour(toU);
|
||||
var winStart = dayBase + fromH*3600*1000;
|
||||
var winEnd = dayBase + toH*3600*1000;
|
||||
var winSpanMs = winEnd - winStart;
|
||||
function _msToPct(ms) { return ((ms - winStart) / winSpanMs) * 100; }
|
||||
// Position auf der GESTAUCHTEN Skala (Nacht/Abend gestaucht, Tag stündlich) —
|
||||
// nicht linear in der Zeit.
|
||||
function _msToPct(ms){
|
||||
var h = (ms - dayBase)/3600000;
|
||||
if (toU === fromU) return 0;
|
||||
return ((_hourToUnit(h) - fromU) / (toU - fromU)) * 100;
|
||||
}
|
||||
function _fmtHM(ms) {
|
||||
return new Date(ms).toLocaleTimeString('de-AT', {timeZone:'Europe/Vienna', hour:'2-digit', minute:'2-digit'});
|
||||
}
|
||||
@@ -2262,15 +2288,15 @@ async function renderLiveSummary() {
|
||||
// (erste bis letzte Aktivität). onchange committet + rendert neu, oninput nur Visual.
|
||||
_tsInjectCss();
|
||||
var _isAuto = (_liveWin.from==null && _liveWin.to==null);
|
||||
// Hintergrund: dunklere Nachtzeiten (00–01 und 20–24, um Mitternacht = ein Bereich)
|
||||
// + 23 stündliche Trennlinien.
|
||||
var _bg = '<span class="ts-night" style="left:0;width:'+(1/24*100)+'%"></span>'
|
||||
+ '<span class="ts-night" style="left:'+(20/24*100)+'%;width:'+(4/24*100)+'%"></span>';
|
||||
// Stunden-Trennlinien NUR im Tag-Bereich (2–19); die Nacht-Bänder (00–01, 20–24)
|
||||
// bleiben glatt dunkel (zusammengefasst, keine Linien).
|
||||
for (var _d=2; _d<20; _d++){ _bg += '<span class="ts-div" style="left:'+(_d/24*100)+'%"></span>'; }
|
||||
// Stündliche Beschriftung 0–24.
|
||||
var _ticks=''; for (var _h=0;_h<=24;_h++){ _ticks += '<span style="left:'+(_h/24*100)+'%">'+_pad2(_h)+'</span>'; }
|
||||
// Gestauchte Skala (17 gleich breite Blöcke): Nacht 00–06 = Block 0, Tag 06–21
|
||||
// stündlich = Blöcke 1–15, Abend 21–24 = Block 16. Dunklere Nacht-/Abend-Blöcke
|
||||
// OHNE interne Linien; Stunden-Trennlinien nur im Tag.
|
||||
var _u2p = function(u){ return (u/17*100); };
|
||||
var _bg = '<span class="ts-night" style="left:0;width:'+_u2p(1)+'%"></span>' // 00–06
|
||||
+ '<span class="ts-night" style="left:'+_u2p(16)+'%;width:'+(_u2p(17)-_u2p(16))+'%"></span>'; // 21–24
|
||||
for (var _d=2; _d<16; _d++){ _bg += '<span class="ts-div" style="left:'+_u2p(_d)+'%"></span>'; } // Tag-Stundenlinien
|
||||
// Beschriftung an jeder Block-Grenze: 00,06,07,…,21,24.
|
||||
var _ticks=''; for (var _u=0;_u<=17;_u++){ _ticks += '<span style="left:'+_u2p(_u)+'%">'+_pad2(_unitToHour(_u))+'</span>'; }
|
||||
html += '<div class="ts-wrap">'
|
||||
+ '<div class="ts-head">🕒 Zeitraum <b id="tsLbl">'+_pad2(fromH)+':00 – '+_pad2(toH)+':00</b>'
|
||||
+ (_isAuto ? '<span style="color:#8a8a8a;font-size:.66rem">Auto: erste – letzte Aktivität</span>'
|
||||
@@ -2278,25 +2304,21 @@ async function renderLiveSummary() {
|
||||
+ '</div>'
|
||||
+ '<div class="ts-slider">'
|
||||
+ '<div class="ts-bg">'+_bg+'</div>'
|
||||
+ '<div class="ts-range" id="tsRange" style="left:'+(fromH/24*100)+'%;width:'+((toH-fromH)/24*100)+'%"></div>'
|
||||
+ '<input type="range" id="tsFrom" min="0" max="24" step="1" value="'+fromH+'" aria-label="Von" oninput="_tsVisual()" onchange="_tsCommit()">'
|
||||
+ '<input type="range" id="tsTo" min="0" max="24" step="1" value="'+toH+'" aria-label="Bis" oninput="_tsVisual()" onchange="_tsCommit()">'
|
||||
+ '<div class="ts-range" id="tsRange" style="left:'+_u2p(fromU)+'%;width:'+(_u2p(toU)-_u2p(fromU))+'%"></div>'
|
||||
+ '<input type="range" id="tsFrom" min="0" max="17" step="1" value="'+fromU+'" aria-label="Von" oninput="_tsVisual()" onchange="_tsCommit()">'
|
||||
+ '<input type="range" id="tsTo" min="0" max="17" step="1" value="'+toU+'" aria-label="Bis" oninput="_tsVisual()" onchange="_tsCommit()">'
|
||||
+ '</div>'
|
||||
+ '<div class="ts-ticks">'+_ticks+'</div>'
|
||||
+ '</div>';
|
||||
|
||||
// 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;
|
||||
// Marker an den Block-Grenzen der gestauchten Skala (Stopp-Stunden 0,6,7,…,21,24),
|
||||
// soweit sie im gewählten Fenster liegen. So verdichtet sich nichts in den
|
||||
// gestauchten Nacht-/Abend-Blöcken.
|
||||
var scaleMarks = [];
|
||||
for (var t = Math.ceil(winStart / stepMs) * stepMs; t <= winEnd; t += stepMs) {
|
||||
var d = new Date(t);
|
||||
scaleMarks.push({ ms: t, label: _fmtHM(t), isHour: d.getMinutes() === 0 });
|
||||
}
|
||||
TS_STOPS.forEach(function(hh){
|
||||
if (hh < fromH - 0.001 || hh > toH + 0.001) return;
|
||||
scaleMarks.push({ ms: dayBase + hh*3600*1000, label: _pad2(hh)+':00', isHour: true });
|
||||
});
|
||||
|
||||
html += '<div style="display:grid;grid-template-columns:140px 1fr;gap:.5rem;font-size:.72rem;align-items:start">';
|
||||
html += '<div></div><div style="position:relative;height:20px;border-bottom:1.5px solid rgba(0,0,0,.1);margin-bottom:.3rem">';
|
||||
|
||||
Reference in New Issue
Block a user