diff options
| -rw-r--r-- | docs/dashboard.md | 4 | ||||
| -rw-r--r-- | src/api/dashboard/dashboard.html | 22 |
2 files changed, 12 insertions, 14 deletions
diff --git a/docs/dashboard.md b/docs/dashboard.md index 8cc0b6a..8c3b007 100644 --- a/docs/dashboard.md +++ b/docs/dashboard.md @@ -177,8 +177,8 @@ measured. halo flashes red and "no dashboard" rises from it, fading out. * **Middle-click a node**: pin it where it is (a dot in its middle): the layout leaves it there. Dragged with the middle button, it is pinned where it's dropped. - Middle-clicked again, it's let go, and moves to its place among the others (on a - static map, only it moves). + Middle-clicked again, it's let go: on a dynamic map it moves to its place among the + others; on a static one it stays where it is. 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 diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index 8fbbe96..d07f190 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -791,7 +791,9 @@ function layout(nodes, pairs, width, height, only) { // `most` px. Returns how far the furthest moved. A gain of 1 overshoots where a node // has several links (the pulls add up): it gets close fast, then swings about its // place; well below 1, it comes to rest. `only`, if given: the nodes that move. -function relax(nodes, pairs, width, height, gain, most, only) { +// `placing`: a layout (`layout`), which places the nodes no live link holds too; else +// they stay where they are, sticky, unless none is held. +function relax(nodes, pairs, width, height, gain, most, only, placing) { const ideal = idealLength(nodes.length, width, height); { const force = new Map(nodes.map(id => [id, { x: 0, y: 0 }])); @@ -815,6 +817,7 @@ function relax(nodes, pairs, width, height, gain, most, only) { force.get(b).x -= dx * pull; force.get(b).y -= dy * pull; } let moved = 0; + const sticky = id => held.size > 0 && !held.has(id) && !placing; for (const id of nodes) { if (pinned.has(id) || id === grabbed || (only && !only.has(id))) continue; const p = positions.get(id), f = force.get(id); @@ -876,24 +879,20 @@ function lengths(intended, measured, count, width, height) { } // What `settle` moves the map towards: the latest render's nodes and lengths. let settling = false, settleTo = null, lastLengths = ""; -// Nodes let go (`unpin`) on a static map: the only ones `settle` moves there, to -// their places among the others. -const freed = new Set(); function settle() { if (settling) return; settling = true; let frames = 0; const step = () => { - // Static again: where they are now (but those let go). - if (!byRtt && freed.size === 0) { settling = false; return; } + // Static again: where they are now. + if (!byRtt) { settling = false; return; } const { nodes, pairs, width, height } = settleTo; // Damped: the swings of the layout's rounds die down instead of going on. - const moved = relax(nodes, pairs, width, height, .15, 2, byRtt ? null : freed); + const moved = relax(nodes, pairs, width, height, .15, 2); renderGraph(); if (moved > .1 && ++frames < 600 && !document.hidden) requestAnimationFrame(step); else { settling = false; - freed.clear(); // Hidden: on again with the next render. if (document.hidden) lastLengths = ""; } @@ -2034,13 +2033,12 @@ function pin(id) { pinned.add(id); renderGraph(); } -// A node let go: it moves to its place among the others, smoothly (`settle`); on a -// static map, only it moves. +// A node let go: on a dynamic map, it moves to its place among the others, smoothly +// (`settle`); on a static one, it stays where it is, as every node there does. function unpin(id) { if (!pinned.delete(id)) return; - freed.add(id); renderGraph(); - settle(); + if (byRtt) settle(); } // Beside the nodes, or off the map: nothing hovered (the element left may be gone). graph.addEventListener("mousemove", event => { if (event.target === graph) hover(null); }); |
