Improved cursors functionality

This commit is contained in:
Martino Ferrari
2026-05-27 16:46:06 +02:00
parent 915c6fc126
commit d5b1986761
2 changed files with 76 additions and 1 deletions
+62 -1
View File
@@ -225,6 +225,7 @@ function setActiveSig(plotId, key) {
b.classList.toggle('sig-badge-active', key != null && b.dataset.key === key));
const p = plots.find(q => q.id === plotId);
if (p && p.uplot) p.uplot.redraw(false);
updatePlotCursorReadouts();
}
// Mark plots containing key dirty and refresh badge vscale text.
@@ -1287,8 +1288,10 @@ function drawCursorLines(u, p) {
ctx.fillText(label, px + 14, bbox.top + 2);
// Per-trace: diamond at crossing point + value label
if (p) {
const DSZ = 5; // diamond half-size in px
const activeKey = plotActiveSignal[p.id];
p.traces.forEach((key, idx) => {
const isActive = key === activeKey || (!activeKey && p.traces.length === 1);
const DSZ = isActive ? 9 : 5; // diamond half-size in px
const vNorm = interpAtTime(u, idx + 1, val);
if (vNorm === null) return;
const cy = u.valToPos(vNorm, 'y', true);
@@ -2019,10 +2022,56 @@ document.getElementById('btn-cursor').addEventListener('click', () => {
cursorsDirty = true;
});
// Format a signal value for the per-plot cursor readout.
function fmtVal(v) {
if (v === null || v === undefined) return '—';
return Math.abs(v) >= 10000 ? v.toExponential(2) : parseFloat(v.toPrecision(4)).toString();
}
// Interpolate the real-unit value of the active/sole signal in plot p at time t.
function getValueAtCursor(p, t) {
if (!p.uplot || t === null) return null;
const key = plotActiveSignal[p.id] || (p.traces.length === 1 ? p.traces[0] : null);
if (!key) return null;
const idx = p.traces.indexOf(key);
if (idx < 0) return null;
const vNorm = interpAtTime(p.uplot, idx + 1, t);
if (vNorm === null) return null;
// Un-normalize: y_norm = (y_raw - offset) / divValue + screenPos
const vs = sigVScale[p.id + ':' + key];
if (!vs) return vNorm;
const dv = vs._resolvedDiv != null ? vs._resolvedDiv : (vs.divValue || 1);
const ofs = vs._resolvedOffset != null ? vs._resolvedOffset : (vs.offset || 0);
const sp = vs.screenPos || 0;
return (vNorm - sp) * dv + ofs;
}
// Update per-plot cursor value readouts (A, B, ΔV) for all plots.
function updatePlotCursorReadouts() {
plots.forEach(p => {
const el = document.getElementById('pcur-' + p.id);
if (!el) return;
// Show only when cursors are on and the plot has an active or sole signal.
const key = plotActiveSignal[p.id] || (p.traces.length === 1 ? p.traces[0] : null);
if (cursors.mode !== 'on' || !key || !p.uplot) {
el.style.display = 'none';
return;
}
const vA = getValueAtCursor(p, cursors.tA);
const vB = getValueAtCursor(p, cursors.tB);
const dv = (vA !== null && vB !== null) ? vB - vA : null;
document.getElementById('pcur-a-' + p.id).textContent = 'A: ' + fmtVal(vA);
document.getElementById('pcur-b-' + p.id).textContent = 'B: ' + fmtVal(vB);
document.getElementById('pcur-dv-' + p.id).textContent = 'ΔV: ' + fmtVal(dv);
el.style.display = 'flex';
});
}
function updateCursorReadout() {
const ro = document.getElementById('cursor-readout');
const active = cursors.mode === 'on';
ro.classList.toggle('visible', active);
updatePlotCursorReadouts();
if (!active) return;
// Use the current visible x-range to pick the display unit.
@@ -2605,6 +2654,13 @@ function addPlot() {
<div class="plot-card-header">
<span class="plot-title" id="ptitle-${id}" title="Click to configure">Plot ${id}</span>
<div class="sig-badges" id="badges-${id}"></div>
<div class="plot-cursor-ro" id="pcur-${id}" style="display:none">
<span class="pcur-a" id="pcur-a-${id}">A: —</span>
<span class="pcur-sep">│</span>
<span class="pcur-b" id="pcur-b-${id}">B: —</span>
<span class="pcur-sep">│</span>
<span class="pcur-dv" id="pcur-dv-${id}">ΔV: —</span>
</div>
</div>
<div class="plot-cfg-bar" id="pcfg-${id}" style="display:none">
<div class="vstb-header">
@@ -2657,6 +2713,7 @@ function addTraceTo(plotId, signalKey) {
// Recreate uPlot with new series list
createUPlot(p);
p.needsRedraw = true;
updatePlotCursorReadouts();
}
function removeTraceFrom(plotId, signalKey) {
@@ -2672,6 +2729,7 @@ function removeTraceFrom(plotId, signalKey) {
createUPlot(p);
p.needsRedraw = true;
if (!p.traces.length) document.querySelector('#hint-' + plotId).style.display = '';
updatePlotCursorReadouts();
}
function addBadge(plotId, key) {
@@ -2843,6 +2901,9 @@ function renderDirtyPlots() {
zoomGuard = false;
});
// Keep per-plot cursor value readouts in sync with live data.
if (cursors.mode === 'on') updatePlotCursorReadouts();
requestAnimationFrame(renderDirtyPlots);
}