From 1aec163edc4d5b7ffc0d4271fab62b8cd06ae804 Mon Sep 17 00:00:00 2001 From: fds2610-bot Date: Wed, 5 Aug 2026 18:30:21 +0200 Subject: [PATCH] KPI-Kacheln direkt untereinander statt ueber die Monitorhoehe verteilt renderKpiMonitor() hat die Hoehe des KPI-Monitors gleichmaessig unter den Kacheln aufgeteilt (rowH = (frame.h - 30) / tiles.length, rund 78px pro Zeile bei vier Kacheln). Der Platz ging dabei in die Sparkline-Kaesten - und genau die Zaehler-Kacheln "Agenten"/"Online" (Issue #39) und "Hooks" (Issue #38) haben history: [] und damit gar keine Linie. Zwischen den Werten standen deshalb grosse leere Kaesten. Die Zeilen stapeln sich jetzt mit fester Hoehe von oben, und einen Sparkline-Kasten bekommt nur noch, wer wirklich einen Verlauf hat: eine Zaehler-Kachel braucht damit 24 statt 77,5 Pixel, vier davon zusammen 96 statt 310. Der Kasten ist ausserdem 32px hoch - die Hoehe, fuer die buildKpiSparklinePoints() die Punkte berechnet; vorher war er rund 51px hoch und die Linie fuellte ihn nie aus. Co-Authored-By: Claude Opus 5 --- html/js/office-render.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/html/js/office-render.js b/html/js/office-render.js index a8d690f..f5016c5 100644 --- a/html/js/office-render.js +++ b/html/js/office-render.js @@ -379,17 +379,34 @@ function renderKpiMonitor(frame, kpis) { return g; } - const rowH = (frame.h - 30) / tiles.length; - tiles.forEach((tile, index) => { - const rowY = frame.y + 20 + index * rowH; + // Die Zeilen stehen direkt untereinander, statt die Monitorhoehe gleichmaessig unter den + // Kacheln aufzuteilen: Zaehler-Kacheln wie "Agenten"/"Online" (Issue #39) und "Hooks" + // (Issue #38) haben history: [] und damit keine Sparkline - verteilt man die Hoehe trotzdem, + // klaffen zwischen den Werten grosse leere Sparkline-Kaesten. Ein Verlauf bekommt seinen + // Platz deshalb nur, wenn es ihn wirklich gibt. + const LABEL_HEIGHT = 20; + // Passt zur Punkteberechnung in buildKpiSparklinePoints() (Default-Hoehe 32) - so fuellt die + // Linie den Kasten genau aus. + const SPARKLINE_HEIGHT = 32; + const ROW_GAP = 4; + + let rowTop = frame.y + 20; + tiles.forEach((tile) => { g.appendChild( text(`${tile.label}: ${tile.currentValue ?? "–"} ${tile.unit}`.trim(), { x: frame.x + 16, - y: rowY + 14, + y: rowTop + 14, class: "kpi-tile-label", }) ); - g.appendChild(renderSparkline(tile.sparklinePoints, frame.w - 32, rowH - 26, frame.x + 16, rowY + 20)); + rowTop += LABEL_HEIGHT; + + if (tile.sparklinePoints) { + g.appendChild(renderSparkline(tile.sparklinePoints, frame.w - 32, SPARKLINE_HEIGHT, frame.x + 16, rowTop)); + rowTop += SPARKLINE_HEIGHT; + } + + rowTop += ROW_GAP; }); return g;