fix: constructor mismatch breaking waveforms, restore clock, hide ECG/Pleth strips until real data arrives
- WaveformTrack was being called with old (baseline, amplitude) args instead of new (mode) string, breaking all normalization - Clock function was accidentally removed in a prior edit - ECG and Pleth strips now hidden by default and only appear when the monitor actually sends waveform data for that channel - Resp strip always visible (synthetic from RR value)
This commit is contained in:
@@ -159,6 +159,14 @@ body{
|
||||
background:rgba(0,0,0,0.7);pointer-events:none;z-index:3;
|
||||
}
|
||||
|
||||
/* ── No data overlay on strip ── */
|
||||
.strip-nodata{
|
||||
position:absolute;inset:0;z-index:4;
|
||||
display:flex;align-items:center;justify-content:center;
|
||||
font-size:12px;color:#2a4a2a;letter-spacing:1px;
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
/* ── Minimal mode ── */
|
||||
body.minimal-mode #statusBar{display:none;}
|
||||
body.minimal-mode #monitorBody{height:100vh;}
|
||||
@@ -192,12 +200,14 @@ body.minimal-mode #monitorBody{height:100vh;}
|
||||
|
||||
<!-- Waveform strips -->
|
||||
<div id="waveformCol">
|
||||
<div class="waveform-strip" id="strip-ecg">
|
||||
<div class="waveform-strip" id="strip-ecg" style="display:none;">
|
||||
<div class="strip-label ecg">I ECG</div>
|
||||
<div class="strip-nodata" id="nodata-ecg">Waiting for ECG lead data…</div>
|
||||
<canvas class="strip-canvas" id="canvas-ecg"></canvas>
|
||||
</div>
|
||||
<div class="waveform-strip" id="strip-pleth">
|
||||
<div class="waveform-strip" id="strip-pleth" style="display:none;">
|
||||
<div class="strip-label pleth">PLETH</div>
|
||||
<div class="strip-nodata" id="nodata-pleth">Waiting for SpO₂ probe…</div>
|
||||
<canvas class="strip-canvas" id="canvas-pleth"></canvas>
|
||||
</div>
|
||||
<div class="waveform-strip" id="strip-resp">
|
||||
@@ -259,6 +269,17 @@ const isDemo = params.get('demo') === 'true' || params.get('synth') === 'true';
|
||||
|
||||
if (isMinimal) document.body.classList.add('minimal-mode');
|
||||
|
||||
// ════════════════════════════════════════════════════
|
||||
// CLOCK
|
||||
// ════════════════════════════════════════════════════
|
||||
function updateClock(){
|
||||
const n = new Date();
|
||||
document.getElementById('clockDisplay').textContent =
|
||||
n.toLocaleTimeString('en-GB',{hour12:false});
|
||||
}
|
||||
setInterval(updateClock, 1000);
|
||||
updateClock();
|
||||
|
||||
// ════════════════════════════════════════════════════
|
||||
// CANVAS WAVEFORM ENGINE
|
||||
// Continuous right-to-left scrolling sweep
|
||||
@@ -434,15 +455,22 @@ class WaveformTrack {
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════════
|
||||
// TRACKS
|
||||
// TRACKS (mode must match constructor: 'ecg' | 'pleth' | 'resp')
|
||||
// ════════════════════════════════════════════════════
|
||||
const ecgTrack = new WaveformTrack('canvas-ecg', '#00ff41', 0.5, 0.42);
|
||||
const plethTrack = new WaveformTrack('canvas-pleth','#00e5ff', 0.5, 0.38);
|
||||
const respTrack = new WaveformTrack('canvas-resp', '#ffb300', 0.5, 0.30);
|
||||
const ecgTrack = new WaveformTrack('canvas-ecg', '#00ff41', 'ecg');
|
||||
const plethTrack = new WaveformTrack('canvas-pleth','#00e5ff', 'pleth');
|
||||
const respTrack = new WaveformTrack('canvas-resp', '#ffb300', 'resp');
|
||||
|
||||
ecgTrack.synthType = 'ecg';
|
||||
plethTrack.synthType = 'pleth';
|
||||
respTrack.synthType = 'resp';
|
||||
// Track whether real data has been received (to show/hide strips)
|
||||
let ecgActive = false;
|
||||
let plethActive = false;
|
||||
|
||||
function showStrip(id, nodataId) {
|
||||
const strip = document.getElementById(id);
|
||||
const nd = document.getElementById(nodataId);
|
||||
if (strip) strip.style.display = '';
|
||||
if (nd) nd.style.display = 'none';
|
||||
}
|
||||
|
||||
// Resize observer
|
||||
const ro = new ResizeObserver(() => {
|
||||
@@ -455,9 +483,13 @@ const TICKS_PER_FRAME = 3; // speed of sweep
|
||||
function loop() {
|
||||
ecgTrack.resize(); plethTrack.resize(); respTrack.resize();
|
||||
for (let i=0;i<TICKS_PER_FRAME;i++){
|
||||
ecgTrack.tick(); plethTrack.tick(); respTrack.tick();
|
||||
if (ecgActive) ecgTrack.tick();
|
||||
if (plethActive) plethTrack.tick();
|
||||
respTrack.tick();
|
||||
}
|
||||
ecgTrack.draw(); plethTrack.draw(); respTrack.draw();
|
||||
if (ecgActive) ecgTrack.draw();
|
||||
if (plethActive) plethTrack.draw();
|
||||
respTrack.draw();
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
@@ -600,9 +632,15 @@ function connectWS() {
|
||||
// Filter by device if known
|
||||
if (deviceId && d.device_id && d.device_id !== deviceId) return;
|
||||
|
||||
// Push waveform samples if present
|
||||
if (d.ecg_wave && d.ecg_wave.length) ecgTrack.pushSamples(d.ecg_wave);
|
||||
if (d.pleth_wave && d.pleth_wave.length) plethTrack.pushSamples(d.pleth_wave);
|
||||
// Push waveform samples if present — show strip on first real data
|
||||
if (d.ecg_wave && d.ecg_wave.length) {
|
||||
if (!ecgActive) { ecgActive = true; showStrip('strip-ecg', 'nodata-ecg'); }
|
||||
ecgTrack.pushSamples(d.ecg_wave);
|
||||
}
|
||||
if (d.pleth_wave && d.pleth_wave.length) {
|
||||
if (!plethActive) { plethActive = true; showStrip('strip-pleth', 'nodata-pleth'); }
|
||||
plethTrack.pushSamples(d.pleth_wave);
|
||||
}
|
||||
|
||||
// Update numeric params
|
||||
updateParams(d);
|
||||
|
||||
Reference in New Issue
Block a user