diff options
| author | tv <tv@krebsco.de> | 2026-11-05 02:05:34 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-05 02:05:34 +0100 |
| commit | eb2da5d09818e86ed99d0dc967c50ab07fbd679b (patch) | |
| tree | 5e547d4ad22ec99b43f5dd3c0af92ac313d36542 | |
| parent | df8dba88c5199e8f6822a6d134de5892ed011e60 (diff) | |
dashboard: don't reset map after resize
| -rw-r--r-- | docs/dashboard.md | 8 | ||||
| -rw-r--r-- | src/api/dashboard/dashboard.html | 26 |
2 files changed, 20 insertions, 14 deletions
diff --git a/docs/dashboard.md b/docs/dashboard.md index 1f5f136..8cc0b6a 100644 --- a/docs/dashboard.md +++ b/docs/dashboard.md @@ -161,8 +161,7 @@ measured. * **Two fingers turning**, on a touch screen: the map turns with them; labels stay upright. * **Drag a node**: move it. On a dynamic map, the others follow at once, and once - let go of, it moves back among them; on a static map it stays where it is put until - the map is laid out again. + let go of, it moves back among them; on a static map it stays where it is put. * **Double-click a node**: open its dashboard, in this page, where the node publishes one (`--dashboard-url`, in the member list; e.g. behind a reverse proxy, [`operations.md`](operations.md)). The other dashboard asks for its own credentials @@ -181,8 +180,9 @@ measured. Middle-clicked again, it's let go, and moves to its place among the others (on a static map, only it moves). -The map is laid out when the page opens, and again when the window or the box is -resized. A member that comes later is placed among the others, which stay where they +The map is laid out when the page opens. Resized (the window, or the boxes), it stays as +it is, scaled about its middle as the box's area is (resized back, it's as before). A +member that comes later is placed among the others, which stay where they are, as they do when links appear or disappear; pinned nodes always stay put. The view and pins last as long as the page is open. diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index b2a5255..8fbbe96 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -996,25 +996,33 @@ function show(root, children) { } let lastShape = ""; -// The whole map laid out again with the next render (the window or the box resized), -// not only nodes new to it. +// The whole map laid out with the next render, not only nodes new to it: at first. let relayout = true; -function layoutAgain() { - relayout = true; - lastShape = ""; -} +// The map's size at the last render. +let lastSize = null; function renderGraph() { if (document.getElementById("map").classList.contains("collapsed")) return; const root = document.getElementById("graph"); const width = root.clientWidth || 800, height = root.clientHeight || 560; root.setAttribute("viewBox", "0 0 " + width + " " + height); + // Resized (the window, a box): the map as it was, about its middle, scaled by as much + // as the box's area (so resized back, it is as before), not laid out anew; within the + // box. + if (lastSize && (lastSize.width !== width || lastSize.height !== height)) { + const k = Math.sqrt(width / lastSize.width * height / lastSize.height); + for (const p of positions.values()) { + p.x = Math.min(width - 40, Math.max(40, width / 2 + (p.x - lastSize.width / 2) * k)); + p.y = Math.min(height - 20, Math.max(20, height / 2 + (p.y - lastSize.height / 2) * k)); + } + } + lastSize = { width, height }; const nodes = Object.keys(state.graph.members).sort(); const { intended, measured } = edges(); renderLegend(measured); const pairs = lengths(intended, measured, nodes.length, width, height); // Laid out when who's there or who links to whom changed: only the nodes new to the // map, the others staying where they are (links that came, after the first reports, - // don't move them); all of them at first, and when the map was resized. + // don't move them); all of them at first. const shape = nodes.join(",") + "|" + [...intended.keys(), ...measured.keys()].sort().join(","); if (shape !== lastShape) { for (const id of [...positions.keys()]) { @@ -2558,7 +2566,7 @@ connection.addEventListener("click", () => { }); // Ages count on between events; nothing else changes without one. setInterval(() => { if (live) render(true); }, 1000); -window.addEventListener("resize", () => { layoutAgain(); render(); }); +window.addEventListener("resize", () => render()); // --- Sizes: the space between boxes dragged to resize them, double-clicked to reset; // kept in this browser --- @@ -2679,7 +2687,6 @@ const resized = () => { if (!resizing) return; resizing = null; main.classList.remove("resize-columns", "resize-rows"); - layoutAgain(); render(); }; main.addEventListener("pointerup", resized); @@ -2723,7 +2730,6 @@ main.addEventListener("dblclick", event => { if (!gap) return; sizes[gap] = null; applySizes(); - layoutAgain(); render(); }); </script> |
