From c9a5223eb68d44cc5be181cb7ea5acc2bda425c2 Mon Sep 17 00:00:00 2001 From: xRangerDE Date: Mon, 11 May 2026 04:59:33 +0200 Subject: [PATCH] =?UTF-8?q?cleanup:=20stats=20activity=20chart=20=E2=80=94?= =?UTF-8?q?=20extract=2030-day=20bar=20inline=20styles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing the renderer-stats.ts inline-style extraction. The "Aktivitaet (letzte 30 Tage)" bar chart built each day-column as a 5-inline-style template:
30 columns rendered per refresh meant ~7.5KB of duplicated inline style attribute strings in the DOM after every refresh. Extracted to .stats-day-col + .stats-day-bar-track + .stats-day-bar- fill + .stats-day-label, plus .stats-activity-row + .stats-activity- summary for the outer wrappers. Only the per-day height percent stays inline (it's truly dynamic, per-day data). Polish riders: - Bar fill picks up height: 0.3s ease-out transition so the bars animate up on data refresh instead of snapping - Hover state shifts the bar from accent to accent-hover so the hovered day reads as the focus - Day-label spans get tabular-nums so the "05-12" type strings align column-to-column Co-Authored-By: Claude Opus 4.7 (1M context) --- src/renderer-stats.ts | 14 ++++++------ src/styles.css | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/renderer-stats.ts b/src/renderer-stats.ts index 97ab578..b418d27 100644 --- a/src/renderer-stats.ts +++ b/src/renderer-stats.ts @@ -108,7 +108,7 @@ function renderStatsActivity(days: ArchiveStatsDay[]): void { const maxCount = days.reduce((m, d) => Math.max(m, d.count), 0); if (maxCount === 0) { - applyHtml(container, `
${escapeStatsHtml(UI_TEXT.static.statsActivityEmpty)}
`); + applyHtml(container, `
${escapeStatsHtml(UI_TEXT.static.statsActivityEmpty)}
`); return; } @@ -118,11 +118,11 @@ function renderStatsActivity(days: ArchiveStatsDay[]): void { const showLabel = idx === 0 || idx === days.length - 1 || idx % 7 === 0; const dayLabel = showLabel ? d.date.slice(5) : ''; return ` -
-
-
+
+
+
-
${escapeStatsHtml(dayLabel)}
+
${escapeStatsHtml(dayLabel)}
`; }).join(''); @@ -130,8 +130,8 @@ function renderStatsActivity(days: ArchiveStatsDay[]): void { const totalCount = days.reduce((s, d) => s + d.count, 0); const totalBytes = days.reduce((s, d) => s + d.bytes, 0); applyHtml(container, ` -
${bars}
-
${escapeStatsHtml(UI_TEXT.static.statsActivitySummary +
${bars}
+
${escapeStatsHtml(UI_TEXT.static.statsActivitySummary .replace('{count}', String(totalCount)) .replace('{size}', formatBytesForStats(totalBytes)))}
`); diff --git a/src/styles.css b/src/styles.css index b185b40..f9086b5 100644 --- a/src/styles.css +++ b/src/styles.css @@ -2311,6 +2311,56 @@ select option { pointer-events: none; } +/* 30-day activity chart — vertical bar per day with optional date + label below every 7th column. */ +.stats-activity-row { + display: flex; + gap: 2px; + align-items: flex-end; + padding: 6px 0; +} + +.stats-day-col { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + min-width: 0; +} + +.stats-day-bar-track { + width: 100%; + height: 90px; + display: flex; + align-items: flex-end; +} + +.stats-day-bar-fill { + width: 100%; + background: var(--accent, #9146ff); + border-radius: 2px 2px 0 0; + transition: height 0.3s ease-out, background 0.2s; +} + +.stats-day-bar-fill:hover { + background: var(--accent-hover, #b97aff); +} + +.stats-day-label { + font-size: 9px; + color: var(--text-secondary); + white-space: nowrap; + font-variant-numeric: tabular-nums; +} + +.stats-activity-summary { + font-size: 12px; + color: var(--text-secondary); + margin-top: 6px; + font-variant-numeric: tabular-nums; +} + /* Old generic scrollbar rules were dead — superseded by the purple-themed *::-webkit-scrollbar block further down the file. Removed to avoid confusion when someone greps for scrollbar styles. */