diff options
| author | MtBntChvn <[email protected]> | 2026-02-21 08:18:55 +0000 |
|---|---|---|
| committer | MtBntChvn <[email protected]> | 2026-02-21 08:18:55 +0000 |
| commit | f838608240e2340ec7db10e86243585b4eb3a889 (patch) | |
| tree | cb40cf760a903c4b6d6441b8dfee956763e2c33e /src/zenserver/frontend/html | |
| parent | replace fireworks expansion with ripple (concentric rings) placement (diff) | |
| download | zen-f838608240e2340ec7db10e86243585b4eb3a889.tar.xz zen-f838608240e2340ec7db10e86243585b4eb3a889.zip | |
use elliptical rings for node expansion placement
Ripple rings are now elliptical (2:1 horizontal-to-vertical ratio)
to match the rectangular shape of nodes. This spreads children wider
horizontally where nodes need more room, and keeps them tighter
vertically where nodes are slim.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Diffstat (limited to 'src/zenserver/frontend/html')
| -rw-r--r-- | src/zenserver/frontend/html/pages/graph-debug-playground.js | 27 | ||||
| -rw-r--r-- | src/zenserver/frontend/html/util/graphengine.js | 12 |
2 files changed, 26 insertions, 13 deletions
diff --git a/src/zenserver/frontend/html/pages/graph-debug-playground.js b/src/zenserver/frontend/html/pages/graph-debug-playground.js index 19c117d1c..7f371aa1c 100644 --- a/src/zenserver/frontend/html/pages/graph-debug-playground.js +++ b/src/zenserver/frontend/html/pages/graph-debug-playground.js @@ -329,6 +329,7 @@ export class Page extends ZenPage const base_radius = 70; const ring_gap = 40; const min_node_gap = 45; + const ellipse_ratio = 2.0; const arc_span = 2 * Math.PI; var added = 0; var ring = 0; @@ -336,7 +337,9 @@ export class Page extends ZenPage while (added < all_deps.length && added < MAX_VISIBLE_DEPS) { const r = base_radius + ring * ring_gap; - const capacity = Math.max(1, Math.floor(arc_span * r / min_node_gap)); + const rx = r * ellipse_ratio; + const ry = r; + const capacity = Math.max(1, Math.floor(arc_span * rx / min_node_gap)); const remaining = Math.min(all_deps.length, MAX_VISIBLE_DEPS) - added; const batch = Math.min(capacity, remaining); @@ -347,7 +350,7 @@ export class Page extends ZenPage const angle = t * arc_span; const jitter = (this._rng() - 0.5) * 10; const label = short_name(dep.opkey); - engine.add_node(dep.opkey, node.x + Math.cos(angle) * (r + jitter), node.y + Math.sin(angle) * (r + jitter), false, label); + engine.add_node(dep.opkey, node.x + Math.cos(angle) * (rx + jitter), node.y + Math.sin(angle) * (ry + jitter), false, label); engine.add_edge(node, engine.node_map[dep.opkey], dep.dep_name); added++; } @@ -378,19 +381,22 @@ export class Page extends ZenPage const existing = new Set(engine.nodes); - // ripple placement: concentric semi-circle rings + // ripple placement: concentric elliptical semi-rings const arc_span = Math.PI; const arc_start = outward_angle - arc_span / 2; const base_radius = 70; const ring_gap = 40; const min_node_gap = 45; + const ellipse_ratio = 2.0; var added = 0; var ring = 0; while (added < all_deps.length && added < MAX_VISIBLE_DEPS) { const r = base_radius + ring * ring_gap; - const capacity = Math.max(1, Math.floor(arc_span * r / min_node_gap)); + const rx = r * ellipse_ratio; + const ry = r; + const capacity = Math.max(1, Math.floor(arc_span * rx / min_node_gap)); const remaining = Math.min(all_deps.length, MAX_VISIBLE_DEPS) - added; const batch = Math.min(capacity, remaining); @@ -401,7 +407,7 @@ export class Page extends ZenPage const angle = arc_start + t * arc_span; const jitter = (this._rng() - 0.5) * 10; const label = short_name(dep.opkey); - engine.add_node(dep.opkey, node.x + Math.cos(angle) * (r + jitter), node.y + Math.sin(angle) * (r + jitter), false, label); + engine.add_node(dep.opkey, node.x + Math.cos(angle) * (rx + jitter), node.y + Math.sin(angle) * (ry + jitter), false, label); engine.add_edge(node, engine.node_map[dep.opkey], dep.dep_name); added++; } @@ -611,10 +617,11 @@ export class Page extends ZenPage const existing = new Set(engine.nodes); - // ripple placement helper for group node children + // ripple placement helper for group node children (elliptical) const base_radius = 70; const ring_gap = 40; const min_node_gap = 45; + const ellipse_ratio = 2.0; const arc_span = 2 * Math.PI; const place_ripple = (items, create_fn) => { @@ -627,7 +634,9 @@ export class Page extends ZenPage while (added < items.length && added < MAX_VISIBLE_DEPS) { const r = base_radius + ring * ring_gap; - const capacity = Math.max(1, Math.floor(arc_span * r / min_node_gap)); + const rx = r * ellipse_ratio; + const ry = r; + const capacity = Math.max(1, Math.floor(arc_span * rx / min_node_gap)); const remaining = Math.min(items.length, MAX_VISIBLE_DEPS) - added; const batch = Math.min(capacity, remaining); @@ -636,8 +645,8 @@ export class Page extends ZenPage const t = batch > 1 ? j / (batch - 1) : 0.5; const angle = t * arc_span; const jitter = (Math.random() - 0.5) * 10; - const x = node.x + Math.cos(angle) * (r + jitter); - const y = node.y + Math.sin(angle) * (r + jitter); + const x = node.x + Math.cos(angle) * (rx + jitter); + const y = node.y + Math.sin(angle) * (ry + jitter); create_fn(items[added], x, y); added++; } diff --git a/src/zenserver/frontend/html/util/graphengine.js b/src/zenserver/frontend/html/util/graphengine.js index 4248e29f6..95830be2a 100644 --- a/src/zenserver/frontend/html/util/graphengine.js +++ b/src/zenserver/frontend/html/util/graphengine.js @@ -567,17 +567,21 @@ export class GraphEngine arc_span = Math.PI; } - // place children in concentric rings (ripples) + // place children in concentric elliptical rings (ripples) + // ellipse: wider horizontally to match rectangular node shape const base_radius = 70; const ring_gap = 40; const min_node_gap = 45; + const ellipse_ratio = 2.0; // horizontal / vertical var added = 0; var ring = 0; while (added < deps.length && added < MAX_VISIBLE_DEPS) { const r = base_radius + ring * ring_gap; - const arc_len = arc_span * r; + const rx = r * ellipse_ratio; + const ry = r; + const arc_len = arc_span * rx; const capacity = Math.max(1, Math.floor(arc_len / min_node_gap)); const remaining = Math.min(deps.length, MAX_VISIBLE_DEPS) - added; const batch = Math.min(capacity, remaining); @@ -590,8 +594,8 @@ export class GraphEngine const jitter = (Math.random() - 0.5) * 10; const dep_node = this.add_node( dep.opkey, - node.x + Math.cos(angle) * (r + jitter), - node.y + Math.sin(angle) * (r + jitter), + node.x + Math.cos(angle) * (rx + jitter), + node.y + Math.sin(angle) * (ry + jitter), false ); dep_node.unresolved = dep.unresolved || false; |