v0.20.0 -- Full s3 event parse and PDF creation. #28

Merged
serversdown merged 46 commits from dev into main 2026-05-28 17:54:34 -04:00
2 changed files with 19 additions and 20 deletions
Showing only changes of commit 6abfadae4f - Show all commits
+9 -10
View File
@@ -522,8 +522,13 @@ function renderWaveform(data) {
charts = {}; charts = {};
const channels = data.channels || {}; const channels = data.channels || {};
const timeAxis = data.time_axis || null; // ms relative to trigger // time_axis is METADATA from sfm.plot.v1 — sample_rate, pretrig_samples,
const triggerMs = data.trigger_ms ?? 0; // t0_ms (first-sample time relative to trigger; negative when pretrig
// exists), dt_ms. Trigger is at t=0 by convention.
const ta = data.time_axis || {};
const sr = ta.sample_rate || 1024;
const dtMs = ta.dt_ms || (1000.0 / sr);
const t0Ms = ta.t0_ms != null ? ta.t0_ms : 0;
const isPrintMode = document.body.classList.contains('print-view'); const isPrintMode = document.body.classList.contains('print-view');
// Which channels actually have data → determines which one renders the // Which channels actually have data → determines which one renders the
@@ -578,14 +583,8 @@ function renderWaveform(data) {
wrap.appendChild(canvasWrap); wrap.appendChild(canvasWrap);
chartsDiv.appendChild(wrap); chartsDiv.appendChild(wrap);
// Build time labels — use server-provided time_axis if present, else derive from sample_rate // Per-sample time in ms relative to trigger. Negative for pre-trigger samples.
let times; const times = values.map((_, i) => t0Ms + i * dtMs);
if (timeAxis && timeAxis.length === values.length) {
times = timeAxis;
} else {
const sr = data.sample_rate || 1024;
times = values.map((_, i) => (i / sr * 1000 - triggerMs));
}
// Downsample for rendering // Downsample for rendering
const MAX_POINTS = 4000; const MAX_POINTS = 4000;
+10 -10
View File
@@ -2572,8 +2572,14 @@ function _renderScWaveform(data) {
_destroyScCharts(); _destroyScCharts();
const channels = data.channels || {}; const channels = data.channels || {};
const timeAxis = data.time_axis || null; // time_axis is METADATA, not an array — it carries sample_rate,
const triggerMs = data.trigger_ms ?? 0; // pretrig_samples, t0_ms (first-sample time relative to trigger,
// negative when pretrig samples exist), and dt_ms. Trigger is at
// t=0 by convention.
const ta = data.time_axis || {};
const sr = ta.sample_rate || 1024;
const dtMs = ta.dt_ms || (1000.0 / sr);
const t0Ms = ta.t0_ms != null ? ta.t0_ms : 0;
// Which channels have data — determines which one renders the shared bottom axis. // Which channels have data — determines which one renders the shared bottom axis.
const withData = _SC_CHANNEL_ORDER.filter(ch => const withData = _SC_CHANNEL_ORDER.filter(ch =>
@@ -2612,14 +2618,8 @@ function _renderScWaveform(data) {
wrap.appendChild(canvasWrap); wrap.appendChild(canvasWrap);
chartsDiv.appendChild(wrap); chartsDiv.appendChild(wrap);
// Build time axis. Prefer server-provided time_axis; else derive from sample_rate. // Per-sample time in ms relative to trigger. Negative for pre-trigger samples.
let times; const times = values.map((_, i) => t0Ms + i * dtMs);
if (timeAxis && timeAxis.length === values.length) {
times = timeAxis;
} else {
const sr = data.sample_rate || 1024;
times = values.map((_, i) => (i / sr * 1000 - triggerMs));
}
// Downsample for rendering when very long. // Downsample for rendering when very long.
const MAX = 3000; const MAX = 3000;