fix: align chart points by run_id avg time so regions stack vertically

This commit is contained in:
nate 2026-03-18 19:55:48 +04:00
parent 1706e83a3f
commit e9ca90324b
1 changed files with 18 additions and 4 deletions

View File

@ -208,6 +208,19 @@
return; 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
const runTimes = {};
for (const p of data) {
const rid = p.run_id || p.checked_at; // fallback for pings without run_id
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;
}
// Group by region // Group by region
const byRegion = {}; const byRegion = {};
for (const p of data) { for (const p of data) {
@ -219,12 +232,13 @@
const allLat = data.map(p => p.latency_ms); const allLat = data.map(p => p.latency_ms);
const yMin = Math.min(...allLat), yMax = Math.max(...allLat); const yMin = Math.min(...allLat), yMax = Math.max(...allLat);
const yRange = yMax - yMin || 1; const yRange = yMax - yMin || 1;
const allT = data.map(p => new Date(p.checked_at).getTime()); const avgTimes = Object.values(runAvgTime);
const tMin = Math.min(...allT), tMax = Math.max(...allT); const tMin = Math.min(...avgTimes), tMax = Math.max(...avgTimes);
const tRange = tMax - tMin || 1; const tRange = tMax - tMin || 1;
function toX(t) { return pad.left + ((t - tMin) / tRange) * cW; } function toX(t) { return pad.left + ((t - tMin) / tRange) * cW; }
function toY(v) { return pad.top + cH - ((v - yMin) / yRange) * cH; } function toY(v) { return pad.top + cH - ((v - yMin) / yRange) * cH; }
function pingX(p) { return toX(runAvgTime[p.run_id || p.checked_at]); }
// Grid lines // Grid lines
ctx.strokeStyle = 'rgba(75,85,99,0.3)'; ctx.lineWidth = 0.5; ctx.strokeStyle = 'rgba(75,85,99,0.3)'; ctx.lineWidth = 0.5;
@ -239,10 +253,10 @@
for (const region of regions) { for (const region of regions) {
const color = REGION_COLORS[region] || '#6b7280'; const color = REGION_COLORS[region] || '#6b7280';
const rPings = byRegion[region].slice().sort((a, b) => const rPings = byRegion[region].slice().sort((a, b) =>
new Date(a.checked_at).getTime() - new Date(b.checked_at).getTime() pingX(a) - pingX(b)
); );
const pts = rPings.map(p => ({ const pts = rPings.map(p => ({
x: toX(new Date(p.checked_at).getTime()), x: pingX(p),
y: toY(p.latency_ms), y: toY(p.latency_ms),
ping: p ping: p
})); }));