1 Commits

Author SHA1 Message Date
znetsixe
8a26e17780 chore(dashboardAPI): Tank Layout fills card vertically too
Canvas frame height 600 → 760 px and tank rectangle height 520 → 680 px
so the visual fills the card aspect (taller than wide). Floor footer
moves to y=702 (was 542) to stay just below the new tank floor.

In-canvas bottom readouts (level / volume / fill mini-stats) removed —
they were redundant with the Status row Level stat, the bar gauge, and
the Level/Volume timeseries, and were getting clipped below the card's
visible area anyway. The basin canvas now shows only basin-structure
information (geometry, zones, thresholds).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:12:01 +02:00
2 changed files with 8 additions and 54 deletions

View File

@@ -227,7 +227,7 @@
"root": { "root": {
"name": "Basin", "name": "Basin",
"type": "frame", "type": "frame",
"placement": { "left": 0, "top": 0, "width": 400, "height": 600 }, "placement": { "left": 0, "top": 0, "width": 400, "height": 760 },
"background": { "color": { "fixed": "transparent" } }, "background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "dark-green" } }, "border": { "color": { "fixed": "dark-green" } },
"elements": [ "elements": [
@@ -266,7 +266,7 @@
{ {
"name": "Tank Outline", "name": "Tank Outline",
"type": "rectangle", "type": "rectangle",
"placement": { "top": 20, "left": 10, "width": 380, "height": 520 }, "placement": { "top": 20, "left": 10, "width": 380, "height": 680 },
"background": { "color": { "fixed": "transparent" } }, "background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "#8a8a8a" }, "width": 2 }, "border": { "color": { "fixed": "#8a8a8a" }, "width": 2 },
"config": { "text": { "mode": "fixed", "fixed": "" } } "config": { "text": { "mode": "fixed", "fixed": "" } }
@@ -397,58 +397,10 @@
{ {
"name": "Footer Floor", "name": "Footer Floor",
"type": "text", "type": "text",
"placement": { "top": 542, "left": 10, "width": 380, "height": 16 }, "placement": { "top": 702, "left": 10, "width": 380, "height": 16 },
"background": { "color": { "fixed": "transparent" } }, "background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 }, "border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "fixed", "fixed": "floor (0.00 m)" }, "color": { "fixed": "#8a8a8a" }, "size": 10, "align": "center", "valign": "middle" } "config": { "text": { "mode": "fixed", "fixed": "floor (0.00 m)" }, "color": { "fixed": "#8a8a8a" }, "size": 10, "align": "center", "valign": "middle" }
},
{
"name": "Readout Level Label",
"type": "text",
"placement": { "top": 562, "left": 4, "width": 50, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "fixed", "fixed": "level" }, "color": { "fixed": "#888888" }, "size": 10, "align": "right", "valign": "middle" }
},
{
"name": "Readout Level",
"type": "metric-value",
"placement": { "top": 562, "left": 56, "width": 80, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "field", "fixed": "", "field": "level" }, "color": { "fixed": "#1a1a1a" }, "size": 12, "align": "left", "valign": "middle" }
},
{
"name": "Readout Volume Label",
"type": "text",
"placement": { "top": 562, "left": 140, "width": 50, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "fixed", "fixed": "volume" }, "color": { "fixed": "#888888" }, "size": 10, "align": "right", "valign": "middle" }
},
{
"name": "Readout Volume",
"type": "metric-value",
"placement": { "top": 562, "left": 192, "width": 80, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "field", "fixed": "", "field": "volume" }, "color": { "fixed": "#1a1a1a" }, "size": 12, "align": "left", "valign": "middle" }
},
{
"name": "Readout Fill Label",
"type": "text",
"placement": { "top": 562, "left": 276, "width": 40, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "fixed", "fixed": "fill" }, "color": { "fixed": "#888888" }, "size": 10, "align": "right", "valign": "middle" }
},
{
"name": "Readout Fill",
"type": "metric-value",
"placement": { "top": 562, "left": 318, "width": 70, "height": 16 },
"background": { "color": { "fixed": "transparent" } },
"border": { "color": { "fixed": "transparent" }, "width": 0 },
"config": { "text": { "mode": "field", "fixed": "", "field": "volumePercent" }, "color": { "fixed": "#1a1a1a" }, "size": 12, "align": "left", "valign": "middle" }
} }
] ]
} }

View File

@@ -189,10 +189,12 @@ class DashboardApi {
const dryRunLevel = outflowLevel * (1 + dryRunPct / 100); const dryRunLevel = outflowLevel * (1 + dryRunPct / 100);
const highSafetyLevel = overflowLevel * (highPct / 100); const highSafetyLevel = overflowLevel * (highPct / 100);
// Canvas tank: rim at y=20px, floor at y=540px (520px tall). Must match // Canvas tank: rim at y=20px, floor at y=700px (680px tall). Must match
// hard-coded tank rectangle placement in config/pumpingStation.json // hard-coded tank rectangle placement in config/pumpingStation.json
// (basin row is h:20 grid rows; canvas root frame is 480x600 px). // (basin row is h:20 grid rows; canvas root frame is 400x760 px — taller
const TANK_TOP = 20, TANK_BOT = 540, TANK_H = TANK_BOT - TANK_TOP; // than wide to match the card's aspect ratio so the tank fills the card
// vertically with no letterboxing).
const TANK_TOP = 20, TANK_BOT = 700, TANK_H = TANK_BOT - TANK_TOP;
const yFor = (v) => +(TANK_BOT - (v / heightBasin) * TANK_H).toFixed(2); 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 tyFor = (yLine) => +(yLine - 8).toFixed(2); // centre 16px text on the line