Ereignis-Timeline: Überlappungen oben auflösen
Im Top-Bereich der Achse kollidierten Tagesmarker, Themen-Labels und Lagebericht-Stempel auf der gleichen Höhe. Jetzt klare Schichten: - Tagesmarker (Heute/Gestern/Datum): top 0 - Themen-Labels: eigene Schiene direkt darunter (top 22 / 42 hourly), nicht mehr Kind der Bar — verhindert Wandern bei verschieden hohen Bars - Bars: nach unten verschoben (top 44 / 64 hourly) - Lagebericht-Linien: gehen jetzt nur durch den Bar-Bereich, Pin-Symbol (Cap) hängt UNTEN an der Achsenlinie statt oben in den Tagesmarkern - Heute-Linie: bei stündlicher Granularität ausgeblendet (Tagesmarker zeigt eh "Heute, ..."), bei Tag/Woche/Monat weiterhin aktiv Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -1182,15 +1182,35 @@ const App = {
|
||||
});
|
||||
html += '</div>';
|
||||
|
||||
// "Heute"-Linie wenn heute im sichtbaren Bereich liegt
|
||||
// "Heute"-Linie nur bei taeglicher/woechentlicher/monatlicher Granularitaet sinnvoll —
|
||||
// bei "hour" zeigt der Tagesmarker eh schon "Heute, ..."
|
||||
const now = Date.now();
|
||||
if (rangeEnd > rangeStart && now >= rangeStart && now <= rangeEnd) {
|
||||
if (!isHourly && rangeEnd > rangeStart && now >= rangeStart && now <= rangeEnd) {
|
||||
const todayPos = ((now - rangeStart) / (rangeEnd - rangeStart)) * 100;
|
||||
html += `<div class="ht-today-line" style="left:${todayPos}%;" aria-hidden="true">
|
||||
<div class="ht-today-label">Heute</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Themen-Labels als eigene Schiene (nicht mehr Kind der Bar) — verhindert Ueberlappung mit Datums-Markern
|
||||
const labelEntries = [];
|
||||
buckets.forEach((bucket, idx) => {
|
||||
if (!topActiveIdx.has(idx)) return;
|
||||
const articleCount = bucket.entries.filter(e => e.kind === 'article').length;
|
||||
if (articleCount < 2) return;
|
||||
const kw = this._extractBucketKeyword(bucket);
|
||||
if (!kw) return;
|
||||
const pos = this._bucketPositionPercent(bucket, rangeStart, rangeEnd, buckets.length);
|
||||
labelEntries.push({ pos, text: kw });
|
||||
});
|
||||
if (labelEntries.length > 0) {
|
||||
html += '<div class="ht-bucket-labels">';
|
||||
labelEntries.forEach(le => {
|
||||
html += `<div class="ht-bucket-label" style="left:${le.pos}%;">${UI.escape(le.text)}</div>`;
|
||||
});
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// Saeulen pro Bucket
|
||||
html += '<div class="ht-bars">';
|
||||
buckets.forEach((bucket, idx) => {
|
||||
@@ -1200,8 +1220,6 @@ const App = {
|
||||
// Bar-Hoehe: Anteil articleCount/articleMax, mindestens 6%, maximal 100%
|
||||
const heightPct = articleCount === 0 ? 0 : Math.max(6, Math.round((articleCount / articleMax) * 100));
|
||||
const isActive = this._activePointIndex === idx;
|
||||
const showLabel = topActiveIdx.has(idx) && articleCount >= 2;
|
||||
const keyword = showLabel ? this._extractBucketKeyword(bucket) : null;
|
||||
const top3 = this._topRelevantHeadlines(bucket, 3);
|
||||
const remaining = bucket.entries.filter(e => e.kind === 'article').length - top3.length;
|
||||
|
||||
@@ -1220,10 +1238,6 @@ const App = {
|
||||
if (snapshotCount > 0) {
|
||||
html += `<div class="ht-bar-snap-cap" aria-hidden="true"></div>`;
|
||||
}
|
||||
// Themen-Label fuer aktivste Buckets
|
||||
if (keyword) {
|
||||
html += `<div class="ht-bucket-label">${UI.escape(keyword)}</div>`;
|
||||
}
|
||||
// Hover-Vorschaukarte
|
||||
html += `<div class="ht-hover-card">
|
||||
<div class="ht-hover-card-head">${UI.escape(bucket.label)} · ${articleCount + snapshotCount} Eintr${(articleCount + snapshotCount) === 1 ? 'ag' : 'äge'}</div>`;
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren