diff --git a/src/specificClass.js b/src/specificClass.js index 6c58a7b..0185c60 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -205,11 +205,36 @@ class DashboardApi { const yFor = (v) => +(TANK_BOT - (v / heightBasin) * TANK_H).toFixed(2); const tyFor = (yLine) => +(yLine - 8).toFixed(2); // centre 16px text on the line - const y_overflow = yFor(overflowLevel); - const y_highSafety = yFor(highSafetyLevel); - const y_inflow = yFor(inflowLevel); - const y_dryRun = yFor(dryRunLevel); - const y_outflow = yFor(outflowLevel); + let y_overflow = yFor(overflowLevel); + let y_highSafety = yFor(highSafetyLevel); + let y_inflow = yFor(inflowLevel); + let y_dryRun = yFor(dryRunLevel); + let y_outflow = yFor(outflowLevel); + + // Enforce a minimum visual gap between adjacent threshold lines so labels + // can always sit cleanly between them — independent of how close the + // underlying physical thresholds are. Slight geometric distortion is + // acceptable: the tank visual conveys ORDERING and ZONE STRUCTURE, not + // exact-scale level measurement. Dashed/value labels carry the true + // numeric values. + const MIN_LINE_GAP = 28; // px (≈3.7% of 760-tall frame, > LABEL_H + 2) + const sorted = [ + { id: 'overflow', get: () => y_overflow, set: (v) => (y_overflow = v) }, + { id: 'highSafety', get: () => y_highSafety, set: (v) => (y_highSafety = v) }, + { id: 'inflow', get: () => y_inflow, set: (v) => (y_inflow = v) }, + { id: 'dryRun', get: () => y_dryRun, set: (v) => (y_dryRun = v) }, + { id: 'outflow', get: () => y_outflow, set: (v) => (y_outflow = v) }, + ].sort((a, b) => a.get() - b.get()); + // Push down to enforce min gap (anchor: topmost line) + for (let i = 1; i < sorted.length; i++) { + const minY = sorted[i - 1].get() + MIN_LINE_GAP; + if (sorted[i].get() < minY) sorted[i].set(minY); + } + // If the last (lowest) line went past the floor, shift the whole stack up. + const overshoot = sorted[sorted.length - 1].get() - TANK_BOT; + if (overshoot > 0) { + for (const item of sorted) item.set(item.get() - overshoot); + } // Label y-positions: labels sit either ABOVE or BELOW their threshold // line, never on it. Each label is offset by ABOVE_OFFSET=22 px above