From 2c32bc1115f8ad0bf0579fa511d6139fc4391dd5 Mon Sep 17 00:00:00 2001 From: M1 Date: Tue, 17 Mar 2026 07:42:36 +0400 Subject: [PATCH] Revert "fix: client-side sparkline with local buffer, no server fetch on update" This reverts commit 72bc11813d40b9e3fa4b88eb2e53d688dd2be175. --- apps/web/src/views/home.ejs | 65 +++++++++++-------------------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/apps/web/src/views/home.ejs b/apps/web/src/views/home.ejs index 57190cb..32303cc 100644 --- a/apps/web/src/views/home.ejs +++ b/apps/web/src/views/home.ejs @@ -75,44 +75,9 @@ } catch {} }, 30000); - // Client-side sparkline — seed with SSR data, update locally on SSE - const _sparkData = { - <% it.monitors.forEach(function(m, i) { - const lats = (m.pings || []).filter(p => p.latency_ms != null).map(p => p.latency_ms); - %>'<%= m.id %>': [<%- lats.join(',') %>]<% if (i < it.monitors.length - 1) { %>,<% } %> - <% }) %> - }; - - function drawSparkline(values, el) { - const W = 120, H = 32; - if (!values.length) { el.innerHTML = ''; return; } - const max = Math.max(...values, 1); - const min = Math.min(...values, 0); - const range = max - min || 1; - const step = W / Math.max(values.length - 1, 1); - const pts = values.map((v, i) => { - const x = i * step; - const y = H - ((v - min) / range) * (H - 4) - 2; - return `${x},${y}`; - }).join(' '); - const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - svg.setAttribute('viewBox', `0 0 ${W} ${H}`); - svg.setAttribute('width', W); - svg.setAttribute('height', H); - const pl = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); - pl.setAttribute('points', pts); - pl.setAttribute('fill', 'none'); - pl.setAttribute('stroke', '#60a5fa'); - pl.setAttribute('stroke-width', '1.5'); - pl.setAttribute('stroke-linecap', 'round'); - pl.setAttribute('stroke-linejoin', 'round'); - svg.appendChild(pl); - const old = el.querySelector('svg'); - if (old) old.replaceWith(svg); else el.appendChild(svg); - } - - // SSE: update cards in realtime - watchAccount((ping) => { + // SSE: on each ping, update text fields and fetch fresh sparkline + const _fetchingSparkline = new Set(); + watchAccount(async (ping) => { const card = document.querySelector(`[data-monitor-id="${ping.monitor_id}"]`); if (!card) return; @@ -124,14 +89,22 @@ if (ping.latency_ms != null) card.querySelector('.stat-latency').textContent = ping.latency_ms + 'ms'; card.querySelector('.stat-last').innerHTML = timeAgo(ping.checked_at); - // Sparkline — update buffer and redraw locally - if (ping.latency_ms != null) { - const buf = _sparkData[ping.monitor_id] = _sparkData[ping.monitor_id] || []; - buf.push(ping.latency_ms); - if (buf.length > 20) buf.shift(); - const sparkEl = card.querySelector('.stat-sparkline'); - if (sparkEl) drawSparkline(buf, sparkEl); - } + // Sparkline + const sparkEl = card.querySelector('.stat-sparkline'); + if (!sparkEl || _fetchingSparkline.has(ping.monitor_id)) return; + _fetchingSparkline.add(ping.monitor_id); + try { + const res = await fetch(`/dashboard/monitors/${ping.monitor_id}/sparkline`, { credentials: 'same-origin' }); + if (res.ok) { + const tmp = document.createElement('div'); + tmp.innerHTML = await res.text(); + const newSvg = tmp.firstElementChild; + const oldSvg = sparkEl.querySelector('svg'); + if (newSvg && oldSvg) oldSvg.replaceWith(newSvg); + else if (newSvg) sparkEl.appendChild(newSvg); + } + } catch {} + _fetchingSparkline.delete(ping.monitor_id); });