Skip to content

Commit 4252dee

Browse files
committed
Noice
1 parent 45a709c commit 4252dee

1 file changed

Lines changed: 42 additions & 46 deletions

File tree

manager/src/templates/single_session_data.html

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ <h3 style="text-align:center;">Jitter</h3>
279279

280280
/**** ---------- GENERIC LINE-CHART BUILDER ---------- ****/
281281
function makeLineChart(id, datasets, yLabel, yOpts = {}) {
282-
const ctx = document.getElementById(id);
282+
const ctx = document.getElementById(id);
283283
const chart = new Chart(ctx, {
284284
type: 'line',
285285
data: { datasets },
@@ -306,29 +306,40 @@ <h3 style="text-align:center;">Jitter</h3>
306306
}
307307
});
308308

309-
// Apply pan/zoom handlers and then separately inject limits
309+
// first draw
310+
chart.update();
311+
312+
// --- DYNAMIC LIMITS BASED ON DATA MAXIMA ---
313+
// flatten all X and Y values from our datasets
314+
const xVals = datasets.flatMap(ds => ds.data.map(pt => pt.x));
315+
const yVals = datasets.flatMap(ds => ds.data.map(pt => pt.y));
316+
const xMax = Math.max(...xVals, 0);
317+
const yMax = Math.max(...yVals, 0.1);
318+
310319
chart.options.plugins.zoom = {
311320
...fullscreenZoom(chart),
312321
limits: {
313322
x: {
314-
min: 0,
315-
max: 600,
323+
min: 0,
324+
max: xMax * 2,
316325
minRange: 1,
317-
maxRange: 600
326+
maxRange: xMax * 2
318327
},
319328
y: {
320-
min: 0.1,
321-
max: 300,
329+
min: 0.1,
330+
max: yMax * 2,
322331
minRange: 1,
323-
maxRange: 300
332+
maxRange: yMax * 2
324333
}
325334
}
326335
};
327336

337+
// re-draw with new limits
328338
chart.update();
329339
addResetZoomButton(chart, ctx.parentElement);
330340
}
331341

342+
332343
/**** ---------- METRIC CHARTS ---------- ****/
333344
makeLineChart('hrChart', dictToDatasets(heartData), 'BPM');
334345
makeLineChart('hrvChart', dictToDatasets(hrvData), 'ms');
@@ -451,72 +462,56 @@ <h3 style="text-align:center;">Jitter</h3>
451462

452463
if (Object.keys(clickEvents || {}).length) {
453464
titleEl.textContent = 'Clicks & Sync Markers';
454-
const actors = Object.keys(clickEvents).sort();
465+
const actors = Object.keys(clickEvents).sort();
455466
const topData = (clickEvents[actors[0]] || []).map(t => ({ x: +t, y: bandCenter(0) }));
456467
const bottomData = (clickEvents[actors[1]] || []).map(t => ({ x: +t, y: bandCenter(1) }));
457468
const syncData = (syncEvents || []).map(t => ({ x: +t, y: 0.5 }));
458469

459470
const legendSets = [
460-
{
461-
label: `${actors[0] || 'P1'} Click`,
462-
showLine: false,
463-
data: topData.length ? topData : [{ x: 0, y: bandCenter(0) }],
464-
pointRadius: 0,
465-
borderColor: COLORS[0]
466-
},
467-
{
468-
label: `${actors[1] || 'P2'} Click`,
469-
showLine: false,
470-
data: bottomData.length ? bottomData : [{ x: 0, y: bandCenter(1) }],
471-
pointRadius: 0,
472-
borderColor: COLORS[1]
473-
},
474-
{
475-
label: 'Sync',
476-
showLine: false,
477-
data: syncData.length ? syncData : [{ x: 0, y: 0.5 }],
478-
pointRadius: 0,
479-
borderColor: SYNC_COLOR
480-
}
471+
{ label: `${actors[0] || 'P1'} Click`, showLine: false, data: topData, pointRadius: 0, borderColor: COLORS[0] },
472+
{ label: `${actors[1] || 'P2'} Click`, showLine: false, data: bottomData, pointRadius: 0, borderColor: COLORS[1] },
473+
{ label: 'Sync', showLine: false, data: syncData, pointRadius: 0, borderColor: SYNC_COLOR }
481474
];
482475

483-
const gameCtx = document.getElementById('gameChart');
476+
const gameCtx = document.getElementById('gameChart');
484477
const gameChart = new Chart(gameCtx, {
485478
type: 'scatter',
486479
data: { datasets: legendSets },
487480
options: {
488481
parsing: false,
489482
responsive: true,
490483
scales: {
491-
x: {
492-
type: 'linear',
493-
title: { display: true, text: 'Time (s)' }
494-
},
495-
y: {
496-
display: false,
497-
min: 0,
498-
max: 1
499-
}
484+
x: { type: 'linear', title: { display: true, text: 'Time (s)' } },
485+
y: { display: false, min: 0, max: 1 }
500486
},
501487
plugins: {
502488
tooltip: { enabled: false },
503-
legend: { labels: { usePointStyle: true } }
489+
legend: { labels: { usePointStyle: true } }
504490
}
505491
}
506492
});
507493

494+
// compute the true max timestamp across all three series
495+
const xMax = Math.max(
496+
...topData .map(pt => pt.x),
497+
...bottomData.map(pt => pt.x),
498+
...syncData .map(pt => pt.x)
499+
);
500+
508501
gameChart.options.plugins.zoom = {
509502
...fullscreenZoom(gameChart),
510503
limits: {
511504
x: {
512-
min: 0,
513-
max: 600,
505+
min: 0,
506+
max: xMax * 2, // ← now dynamic
514507
minRange: 1,
515-
maxRange: 60
508+
maxRange: xMax * 2
516509
},
517510
y: {
518-
min: 0,
519-
max: 1
511+
min: 0,
512+
max: 1,
513+
minRange: 0.1,
514+
maxRange: 2
520515
}
521516
}
522517
};
@@ -525,6 +520,7 @@ <h3 style="text-align:center;">Jitter</h3>
525520
addResetZoomButton(gameChart, gameCtx.parentElement);
526521
}
527522

523+
528524
else if (frequencyData && Object.keys(frequencyData).length) {
529525
titleEl.textContent = 'Finger Frequency & Sync Intervals';
530526
const freqSets = Object.keys(frequencyData).map(a => ({

0 commit comments

Comments
 (0)