From fa473d2b61f761e5a3017cc86ab101e5fe6152ad Mon Sep 17 00:00:00 2001 From: Carsten Rehfeld Date: Sun, 17 May 2026 01:26:08 +0200 Subject: [PATCH] =?UTF-8?q?feat(admin):=20chart=20redraws=20every=201=20s?= =?UTF-8?q?=20=E2=80=94=20live=20bucket=20at=20right=20edge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Separate chart refresh from bucket flush: - 5 s flush commits completed bucket into buf, resets accumulator - Every poll (1 s): redraw path as buf[1..] + current live bucket so the rightmost bar visually builds up in real time - Label and chart now both update at 1 s cadence Co-Authored-By: Mira Rehfeld --- .../resources/META-INF/resources/admin.js | 36 +++++++++++-------- .../templates/DashboardResource/global.html | 2 +- .../templates/DashboardResource/sandbox.html | 2 +- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/apix-admin/src/main/resources/META-INF/resources/admin.js b/apix-admin/src/main/resources/META-INF/resources/admin.js index 4f98f0c..e64366b 100644 --- a/apix-admin/src/main/resources/META-INF/resources/admin.js +++ b/apix-admin/src/main/resources/META-INF/resources/admin.js @@ -206,20 +206,28 @@ if (elLive) elLive.textContent = fmt(rpm) + ' req/min (' + pct + '%)'; } - // Chart bucket: flush accumulated delta every 5 s regardless of poll rate - // Cap at rateLimit so the area never visually exceeds 100% (live label shows true value) + // Compute the current in-progress bucket value (capped at rateLimit) + function liveRpm() { + var windowMs = Math.max(Date.now() - lastFlushTime, 1); + return Math.min(Math.round(accDelta * (60000 / windowMs)), rateLimit); + } + + // Redraw: historical buf + current live bucket at the right edge ("now") + function redraw() { + var view = buf.slice(1).concat([liveRpm()]); + path.attr('d', areaFn(view)); + } + + // Every 5 s: commit the current bucket into buf, reset accumulator setInterval(function () { - var now = Date.now(); - var elapsed = now - lastFlushTime; - var rpm = Math.min(Math.round(accDelta * (60000 / (elapsed || CHART_TICK))), rateLimit); + var rpm = liveRpm(); lastWindowRpm = rpm; - lastFlushTime = now; + lastFlushTime = Date.now(); buf.push(rpm); buf.shift(); - path.attr('d', areaFn(buf)); accDelta = 0; }, CHART_TICK); - async function poll(elapsed) { + async function poll() { try { var r = await fetch('/sandbox/' + sid + '/poll'); if (!r.ok) return; @@ -229,12 +237,10 @@ var delta = Math.max(0, total - lastTotal); accDelta += delta; if (delta > 0) lastActivity = Date.now(); - // Use accumulated rate over current window — smooth, not instantaneous per-poll delta var windowMs = Date.now() - lastFlushTime; - var liveRpm = windowMs > 200 - ? Math.round(accDelta * (60000 / windowMs)) - : lastWindowRpm; // too early in window — carry previous - updateLabel(liveRpm); + var rpm = windowMs > 200 ? liveRpm() : lastWindowRpm; + updateLabel(rpm); + redraw(); // update chart on every poll, not just every 5 s } lastTotal = total; currentInterval = (Date.now() - lastActivity > IDLE_AFTER_MS) ? IDLE_INTERVAL : FAST_INTERVAL; @@ -243,9 +249,9 @@ function scheduleNext() { var interval = currentInterval; - setTimeout(function () { poll(interval).then(scheduleNext); }, interval); + setTimeout(function () { poll().then(scheduleNext); }, interval); } - poll(0); // set lastTotal immediately, no rpm yet + poll(); // set lastTotal immediately scheduleNext(); })(); diff --git a/apix-admin/src/main/resources/templates/DashboardResource/global.html b/apix-admin/src/main/resources/templates/DashboardResource/global.html index a475bfe..41fcd20 100644 --- a/apix-admin/src/main/resources/templates/DashboardResource/global.html +++ b/apix-admin/src/main/resources/templates/DashboardResource/global.html @@ -106,6 +106,6 @@ nav { - + diff --git a/apix-admin/src/main/resources/templates/DashboardResource/sandbox.html b/apix-admin/src/main/resources/templates/DashboardResource/sandbox.html index 312db76..302c8f6 100644 --- a/apix-admin/src/main/resources/templates/DashboardResource/sandbox.html +++ b/apix-admin/src/main/resources/templates/DashboardResource/sandbox.html @@ -151,6 +151,6 @@ button.promote:hover { background: #2ea043; } - +