fix(admin): single update path per poll — no competing D3 transitions
Deploy to Production / deploy (push) Successful in 3m15s

Removed separate setInterval for buf flush. Flush + redraw now happen
together inside poll() — one atomic step, one D3 transition(950ms).
Two independent 1 s timers were firing out of phase and interrupting
each other's transitions, causing flicker and apparent 2 s cadence.

Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
This commit is contained in:
Carsten Rehfeld
2026-05-17 01:49:37 +02:00
parent f895bcf0cf
commit 4d980d7fc3
3 changed files with 5 additions and 15 deletions
@@ -214,18 +214,6 @@
return Math.min(Math.round(sum * (60000 / CHART_TICK)), rateLimit); return Math.min(Math.round(sum * (60000 / CHART_TICK)), rateLimit);
} }
// Redraw: historical buf + live bucket at right edge, with smooth transition
function redraw() {
var view = buf.slice(1).concat([liveRpm()]);
path.transition().duration(900).ease(d3.easeLinear).attr('d', areaFn(view));
}
// Every 1 s: snapshot the sliding-window rate into the history buffer
// Smaller buckets (1 s each, 72 s total) so the chart scrolls visibly every second
setInterval(function () {
buf.push(liveRpm()); buf.shift();
}, 1000);
async function poll() { async function poll() {
try { try {
var r = await fetch('/sandbox/' + sid + '/poll'); var r = await fetch('/sandbox/' + sid + '/poll');
@@ -240,7 +228,9 @@
} }
var rpm = liveRpm(); var rpm = liveRpm();
updateLabel(rpm); updateLabel(rpm);
redraw(); // Flush + redraw in one step — no separate timer, no competing transitions
buf.push(rpm); buf.shift();
path.transition().duration(950).ease(d3.easeLinear).attr('d', areaFn(buf));
} }
lastTotal = total; lastTotal = total;
currentInterval = (Date.now() - lastActivity > IDLE_AFTER_MS) ? IDLE_INTERVAL : FAST_INTERVAL; currentInterval = (Date.now() - lastActivity > IDLE_AFTER_MS) ? IDLE_INTERVAL : FAST_INTERVAL;
@@ -106,6 +106,6 @@ nav {
<script>var __D = {statsJson.raw};</script> <script>var __D = {statsJson.raw};</script>
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
<script src="/admin.js?v=11"></script> <script src="/admin.js?v=12"></script>
</body> </body>
</html> </html>
@@ -151,6 +151,6 @@ button.promote:hover { background: #2ea043; }
<script>var __D = {dataJson.raw};</script> <script>var __D = {dataJson.raw};</script>
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
<script src="/admin.js?v=11"></script> <script src="/admin.js?v=12"></script>
</body> </body>
</html> </html>