debug: figuring out whats wrong with waveform viewer

This commit is contained in:
2026-04-14 16:00:14 -04:00
parent 0da88ec6aa
commit 4f4c1a8f64
3 changed files with 118 additions and 88 deletions
+95 -87
View File
@@ -573,95 +573,103 @@
renderData = plotSamples.filter((_, i) => i % step === 0);
}
const chart = new Chart(canvas, {
type: 'line',
data: {
labels: renderTimes,
datasets: [{
data: renderData,
borderColor: color,
borderWidth: 1,
pointRadius: 0,
tension: 0,
let chart;
try {
chart = new Chart(canvas, {
type: 'line',
data: {
labels: renderTimes,
datasets: [{
data: renderData,
borderColor: color,
borderWidth: 1,
pointRadius: 0,
tension: 0,
}],
},
options: {
animation: false,
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
title: items => `t = ${items[0].label} ms`,
label: item => tooltipFmt(item.raw),
},
},
},
scales: {
x: {
type: 'category',
ticks: {
color: '#484f58',
maxTicksLimit: 10,
maxRotation: 0,
callback: (val, i) => renderTimes[i] + ' ms',
},
grid: { color: '#21262d' },
},
y: {
// Clamp geo-channel y-axis to ±(0C peak × 1.4) so near-saturation
// decode artifacts (which inflate autoscale to full range) don't
// squash the actual blast signal into an invisible flat line.
// The 0C peak value is authoritative for the true signal amplitude.
// Guard: only apply if peak0C is a valid finite positive number.
...(isGeo && peak0C !== null && peak0C !== undefined
&& isFinite(peak0C) && peak0C > 0 ? {
min: -(peak0C * 1.4),
max: (peak0C * 1.4),
} : {}),
ticks: {
color: '#484f58',
maxTicksLimit: 5,
callback: v => tickFmt(v),
},
grid: { color: '#21262d' },
title: {
display: true,
text: yUnit,
color: '#484f58',
font: { size: 10 },
},
},
},
},
plugins: [{
// Draw trigger line at t=0
id: 'triggerLine',
afterDraw(chart) {
const ctx = chart.ctx;
const xAxis = chart.scales.x;
const yAxis = chart.scales.y;
// Find index of t=0
const zeroIdx = renderTimes.findIndex(t => parseFloat(t) >= 0);
if (zeroIdx < 0) return;
const x = xAxis.getPixelForValue(zeroIdx);
ctx.save();
ctx.beginPath();
ctx.moveTo(x, yAxis.top);
ctx.lineTo(x, yAxis.bottom);
ctx.strokeStyle = 'rgba(248, 81, 73, 0.7)';
ctx.lineWidth = 1.5;
ctx.setLineDash([4, 3]);
ctx.stroke();
ctx.restore();
},
}],
},
options: {
animation: false,
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
title: items => `t = ${items[0].label} ms`,
label: item => tooltipFmt(item.raw),
},
},
},
scales: {
x: {
type: 'category',
ticks: {
color: '#484f58',
maxTicksLimit: 10,
maxRotation: 0,
callback: (val, i) => renderTimes[i] + ' ms',
},
grid: { color: '#21262d' },
},
y: {
// Clamp geo-channel y-axis to ±(0C peak × 1.4) so near-saturation
// decode artifacts (which inflate autoscale to full range) don't
// squash the actual blast signal into an invisible flat line.
// The 0C peak value is authoritative for the true signal amplitude.
...(isGeo && peak0C !== null && peak0C > 0 ? {
min: -(peak0C * 1.4),
max: (peak0C * 1.4),
} : {}),
ticks: {
color: '#484f58',
maxTicksLimit: 5,
callback: v => tickFmt(v),
},
grid: { color: '#21262d' },
title: {
display: true,
text: yUnit,
color: '#484f58',
font: { size: 10 },
},
},
},
},
plugins: [{
// Draw trigger line at t=0
id: 'triggerLine',
afterDraw(chart) {
const ctx = chart.ctx;
const xAxis = chart.scales.x;
const yAxis = chart.scales.y;
});
} catch (err) {
console.error(`Chart.js error for channel ${ch}:`, err);
canvasWrap.innerHTML = `<p style="color:#f85149;padding:8px;font-size:11px;">Chart error: ${err.message}</p>`;
}
// Find index of t=0
const zeroIdx = renderTimes.findIndex(t => parseFloat(t) >= 0);
if (zeroIdx < 0) return;
const x = xAxis.getPixelForValue(zeroIdx);
ctx.save();
ctx.beginPath();
ctx.moveTo(x, yAxis.top);
ctx.lineTo(x, yAxis.bottom);
ctx.strokeStyle = 'rgba(248, 81, 73, 0.7)';
ctx.lineWidth = 1.5;
ctx.setLineDash([4, 3]);
ctx.stroke();
ctx.restore();
},
}],
});
charts[ch] = chart;
if (chart) charts[ch] = chart;
}
}