fix: evenly space chart runs at fixed width and trim initial data to match
This commit is contained in:
parent
766d1094ad
commit
f2fcf1a0b9
|
|
@ -179,12 +179,26 @@
|
|||
'us-west': '🇺🇸 US West', 'ap-southeast': '🇸🇬 AP Southeast'
|
||||
};
|
||||
|
||||
const MAX_RUNS = 50;
|
||||
let chartPings = <%~ JSON.stringify(chartPings.map(p => ({
|
||||
latency_ms: p.latency_ms, region: p.region || '__none__',
|
||||
checked_at: p.checked_at, up: p.up, run_id: p.run_id || null,
|
||||
status_code: p.status_code
|
||||
}))) %>;
|
||||
|
||||
// Trim initial data to MAX_RUNS
|
||||
(function() {
|
||||
const seen = []; const s = new Set();
|
||||
for (const p of chartPings) {
|
||||
const rid = p.run_id || p.checked_at;
|
||||
if (!s.has(rid)) { s.add(rid); seen.push(rid); }
|
||||
}
|
||||
if (seen.length > MAX_RUNS) {
|
||||
const stale = new Set(seen.slice(0, seen.length - MAX_RUNS));
|
||||
chartPings = chartPings.filter(p => !stale.has(p.run_id || p.checked_at));
|
||||
}
|
||||
})();
|
||||
|
||||
function renderChart() {
|
||||
const canvas = document.getElementById('chart-canvas');
|
||||
const container = canvas.parentElement;
|
||||
|
|
@ -208,18 +222,23 @@
|
|||
return;
|
||||
}
|
||||
|
||||
// Compute a shared x-position per run_id (avg checked_at of all pings in the run)
|
||||
// so all regions in the same run align vertically on the chart
|
||||
// Build ordered list of unique runs, sorted by avg checked_at
|
||||
const runTimes = {};
|
||||
for (const p of data) {
|
||||
const rid = p.run_id || p.checked_at; // fallback for pings without run_id
|
||||
const rid = p.run_id || p.checked_at;
|
||||
if (!runTimes[rid]) runTimes[rid] = [];
|
||||
runTimes[rid].push(new Date(p.checked_at).getTime());
|
||||
}
|
||||
const runAvgTime = {};
|
||||
for (const [rid, times] of Object.entries(runTimes)) {
|
||||
runAvgTime[rid] = times.reduce((a, b) => a + b, 0) / times.length;
|
||||
}
|
||||
const runs = Object.keys(runTimes).sort((a, b) => {
|
||||
const avgA = runTimes[a].reduce((x, y) => x + y, 0) / runTimes[a].length;
|
||||
const avgB = runTimes[b].reduce((x, y) => x + y, 0) / runTimes[b].length;
|
||||
return avgA - avgB;
|
||||
});
|
||||
|
||||
// Evenly space runs across the chart width (fixed spacing like SSR)
|
||||
const runIndex = {};
|
||||
runs.forEach((rid, i) => { runIndex[rid] = i; });
|
||||
const maxIdx = Math.max(runs.length - 1, 1);
|
||||
|
||||
// Group by region
|
||||
const byRegion = {};
|
||||
|
|
@ -232,13 +251,12 @@
|
|||
const allLat = data.map(p => p.latency_ms);
|
||||
const yMin = Math.min(...allLat), yMax = Math.max(...allLat);
|
||||
const yRange = yMax - yMin || 1;
|
||||
const avgTimes = Object.values(runAvgTime);
|
||||
const tMin = Math.min(...avgTimes), tMax = Math.max(...avgTimes);
|
||||
const tRange = tMax - tMin || 1;
|
||||
|
||||
function toX(t) { return pad.left + ((t - tMin) / tRange) * cW; }
|
||||
function toY(v) { return pad.top + cH - ((v - yMin) / yRange) * cH; }
|
||||
function pingX(p) { return toX(runAvgTime[p.run_id || p.checked_at]); }
|
||||
function pingX(p) {
|
||||
const idx = runIndex[p.run_id || p.checked_at] || 0;
|
||||
return pad.left + (idx / maxIdx) * cW;
|
||||
}
|
||||
|
||||
// Grid lines
|
||||
ctx.strokeStyle = 'rgba(75,85,99,0.3)'; ctx.lineWidth = 0.5;
|
||||
|
|
@ -310,9 +328,6 @@
|
|||
|
||||
// Store for hover
|
||||
canvas._regionPoints = regionPoints;
|
||||
canvas._toX = toX; canvas._toY = toY;
|
||||
canvas._tMin = tMin; canvas._tRange = tRange;
|
||||
canvas._W = W; canvas._H = H; canvas._pad = pad; canvas._cW = cW;
|
||||
}
|
||||
|
||||
// Group pings by run_id for tooltip
|
||||
|
|
@ -472,7 +487,6 @@
|
|||
status_code: ping.status_code
|
||||
});
|
||||
// Count distinct runs and remove oldest runs as a group
|
||||
const MAX_RUNS = 50;
|
||||
const seen = []; const runSet = new Set();
|
||||
for (const p of chartPings) {
|
||||
const rid = p.run_id || p.checked_at;
|
||||
|
|
|
|||
Loading…
Reference in New Issue