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 {
-
+