aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/frontend/html
diff options
context:
space:
mode:
authorMtBntChvn <[email protected]>2026-02-21 08:18:55 +0000
committerMtBntChvn <[email protected]>2026-02-21 08:18:55 +0000
commitf838608240e2340ec7db10e86243585b4eb3a889 (patch)
treecb40cf760a903c4b6d6441b8dfee956763e2c33e /src/zenserver/frontend/html
parentreplace fireworks expansion with ripple (concentric rings) placement (diff)
downloadzen-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.js27
-rw-r--r--src/zenserver/frontend/html/util/graphengine.js12
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;