aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-05 02:05:34 +0100
committertv <tv@krebsco.de>2026-11-05 02:05:34 +0100
commiteb2da5d09818e86ed99d0dc967c50ab07fbd679b (patch)
tree5e547d4ad22ec99b43f5dd3c0af92ac313d36542
parentdf8dba88c5199e8f6822a6d134de5892ed011e60 (diff)
dashboard: don't reset map after resize
-rw-r--r--docs/dashboard.md8
-rw-r--r--src/api/dashboard/dashboard.html26
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>