@yuneta/gobj-ui 7.23.152 → 7.23.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -3
- package/dist/gobj-ui.cjs.js +345 -27
- package/dist/gobj-ui.es.js +345 -27
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +68 -5
- package/src/treedb_elbow.js +231 -13
- package/src/treedb_elbow.test.js +192 -1
- package/src/treedb_layout.js +146 -14
- package/src/treedb_layout.test.js +84 -12
package/README.md
CHANGED
|
@@ -1413,7 +1413,13 @@ layouts by three thin adapters in `c_g6_nodes_tree.js`:
|
|
|
1413
1413
|
shaped like a real one; a uniform tree is the same width. The contour
|
|
1414
1414
|
arithmetic is Moen's (1990) as mxGraph wrote it in `mxCompactTreeLayout`
|
|
1415
1415
|
(JGraph Ltd, Apache-2.0), read in maxGraph — a port, not a dependency,
|
|
1416
|
-
because maxGraph's layouts drive its own graph model.
|
|
1416
|
+
because maxGraph's layouts drive its own graph model. Since `7.23.154` a run
|
|
1417
|
+
of three or more **leaf** children is **stacked**: two columns under the
|
|
1418
|
+
parent with a corridor between them, row after row — the contour alone
|
|
1419
|
+
gained nothing on a whole level opened with the stepper, where every parent
|
|
1420
|
+
still needed the row of its children beside it. Against `tree`: regions
|
|
1421
|
+
only 10% of the width, one region open with a 24-device hall 21%, a whole
|
|
1422
|
+
level open 41%. The tree grows taller instead; read it with elbow edges.
|
|
1417
1423
|
- **`radial`** (`treedb-radial`) — the root in the middle, a ring per depth,
|
|
1418
1424
|
every subtree an angular **sector** proportional to its leaves, and the
|
|
1419
1425
|
radius of each ring the largest of three: one `ranksep` out from the ring
|
|
@@ -1460,8 +1466,23 @@ what gets routed is a detour with a third card in its way, an edge dropping
|
|
|
1460
1466
|
several rows, an edge between two cards of one row. Since `7.23.152` a node is
|
|
1461
1467
|
measured **whole** — card, ports and label — so a line keeps clear of the
|
|
1462
1468
|
ports as well; the edge's own ports stick out of its own cards, so its first
|
|
1463
|
-
and last segments are not tested against their own box.
|
|
1464
|
-
|
|
1469
|
+
and last segments are not tested against their own box.
|
|
1470
|
+
|
|
1471
|
+
The edges sharing an **end** do not lie on top of each other either
|
|
1472
|
+
(`7.23.153`): the forward edges leaving one card — all of them, not only one
|
|
1473
|
+
port's, or two hooks side by side would stack their runs — and those reaching
|
|
1474
|
+
one card (all its fkeys enter by one point) are **staggered**, each turning at
|
|
1475
|
+
its own height in the channel, 10px apart at most and closer when the channel
|
|
1476
|
+
is short. Leaving, the farthest turns highest; arriving, the farthest turns
|
|
1477
|
+
lowest: the orders in which the lines of one end nest without crossing. A
|
|
1478
|
+
routed line leaves its port and reaches the other one **sideways**, because
|
|
1479
|
+
the column straight under or over a port is where the staggered edges of that
|
|
1480
|
+
port run. Only the stub at the port is shared. Into a lower row of a stack of
|
|
1481
|
+
the compact tree an edge runs a **comb** (`7.23.154`): along the channel to a
|
|
1482
|
+
lane of its own in the stack's corridor, down it, and into the gap above its
|
|
1483
|
+
card; lanes go outermost first by row, so none crosses another, and a comb is
|
|
1484
|
+
drawn as laid out, never routed. G6's `shortest-path` router is not used: it is
|
|
1485
|
+
not exported, it
|
|
1465
1486
|
falls back in silence to a route that crosses cards, and it rewrites its
|
|
1466
1487
|
module defaults with every config it is given.
|
|
1467
1488
|
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -29331,6 +29331,14 @@ function tidy_tree_lr(nodes, edges, o) {
|
|
|
29331
29331
|
* the packing across the depths differs, so switching between the
|
|
29332
29332
|
* two moves cards sideways and never reorders them.
|
|
29333
29333
|
*
|
|
29334
|
+
* And a run of three or more LEAF children -- a hall's devices, a
|
|
29335
|
+
* region's places when none is open -- is STACKED: two columns
|
|
29336
|
+
* under the parent with a corridor between them, row after row.
|
|
29337
|
+
* That is what makes it compact when a whole level is open, where
|
|
29338
|
+
* the contour alone gains nothing: every parent needed the whole
|
|
29339
|
+
* row of its children beside it. The tree grows taller instead of
|
|
29340
|
+
* wider. Its elbow edges run down the corridor (elbow_combs).
|
|
29341
|
+
*
|
|
29334
29342
|
* The contour arithmetic is Moen's ("Drawing dynamic trees", IEEE
|
|
29335
29343
|
* Software, 1990) in the form mxGraph gave it in mxCompactTreeLayout
|
|
29336
29344
|
* -- Copyright (c) 2006-2015 JGraph Ltd, Apache License 2.0 -- read in
|
|
@@ -29411,10 +29419,81 @@ function contour_merge(p1, p2) {
|
|
|
29411
29419
|
p1.lower_head = p2.lower_head;
|
|
29412
29420
|
return total;
|
|
29413
29421
|
}
|
|
29422
|
+
function stack_trunk_width(k) {
|
|
29423
|
+
let lanes = Math.max(0, k - 2);
|
|
29424
|
+
return Math.max(36, 20 + Math.max(0, lanes - 1) * 6);
|
|
29425
|
+
}
|
|
29426
|
+
function stack_geometry(t, st, col_x, col_w) {
|
|
29427
|
+
let d = st.depth;
|
|
29428
|
+
let k = st.ids.length;
|
|
29429
|
+
let rows = Math.ceil(k / 2);
|
|
29430
|
+
let side = [0, 0];
|
|
29431
|
+
let row_len = [];
|
|
29432
|
+
for (let i = 0; i < k; i++) {
|
|
29433
|
+
let n = t.by_id.get(st.ids[i]);
|
|
29434
|
+
let r = Math.floor(i / 2);
|
|
29435
|
+
side[i % 2] = Math.max(side[i % 2], n.h);
|
|
29436
|
+
row_len[r] = Math.max(row_len[r] || 0, n.w);
|
|
29437
|
+
}
|
|
29438
|
+
row_len[0] = col_w[d];
|
|
29439
|
+
let trunk = stack_trunk_width(k);
|
|
29440
|
+
let starts = [col_x[d]];
|
|
29441
|
+
for (let r = 1; r < rows; r++) starts[r] = starts[r - 1] + row_len[r - 1] + 40;
|
|
29442
|
+
return {
|
|
29443
|
+
side,
|
|
29444
|
+
trunk,
|
|
29445
|
+
starts,
|
|
29446
|
+
row_len,
|
|
29447
|
+
len: starts[rows - 1] + row_len[rows - 1] - col_x[d],
|
|
29448
|
+
ext: side[0] + trunk + side[1]
|
|
29449
|
+
};
|
|
29450
|
+
}
|
|
29451
|
+
function place_stack(t, st, g, top, pos) {
|
|
29452
|
+
for (let i = 0; i < st.ids.length; i++) {
|
|
29453
|
+
let n = t.by_id.get(st.ids[i]);
|
|
29454
|
+
let r = Math.floor(i / 2);
|
|
29455
|
+
let across = i % 2 === 0 ? top + g.side[0] - n.h / 2 : top + g.side[0] + g.trunk + n.h / 2;
|
|
29456
|
+
pos.set(st.ids[i], {
|
|
29457
|
+
x: g.starts[r] + g.row_len[r] / 2,
|
|
29458
|
+
y: across
|
|
29459
|
+
});
|
|
29460
|
+
}
|
|
29461
|
+
}
|
|
29414
29462
|
function compact_tree_lr(nodes, edges, o) {
|
|
29415
29463
|
let t = spanning_tree(nodes, edges);
|
|
29416
|
-
let order = walk_order(t);
|
|
29417
29464
|
let pos = /* @__PURE__ */ new Map();
|
|
29465
|
+
let kids_of = /* @__PURE__ */ new Map();
|
|
29466
|
+
let stacks = /* @__PURE__ */ new Map();
|
|
29467
|
+
for (let [id, kids] of t.children) {
|
|
29468
|
+
let out = [];
|
|
29469
|
+
let run = [];
|
|
29470
|
+
let flush = () => {
|
|
29471
|
+
if (run.length >= 3) {
|
|
29472
|
+
let key = { stack: stacks.size };
|
|
29473
|
+
stacks.set(key, {
|
|
29474
|
+
ids: run,
|
|
29475
|
+
depth: t.depth.get(run[0])
|
|
29476
|
+
});
|
|
29477
|
+
out.push(key);
|
|
29478
|
+
} else out.push(...run);
|
|
29479
|
+
run = [];
|
|
29480
|
+
};
|
|
29481
|
+
for (let kid of kids) if ((t.children.get(kid) || []).length === 0) run.push(kid);
|
|
29482
|
+
else {
|
|
29483
|
+
flush();
|
|
29484
|
+
out.push(kid);
|
|
29485
|
+
}
|
|
29486
|
+
flush();
|
|
29487
|
+
kids_of.set(id, out);
|
|
29488
|
+
}
|
|
29489
|
+
let order = [];
|
|
29490
|
+
let todo = t.roots.slice().reverse();
|
|
29491
|
+
while (todo.length) {
|
|
29492
|
+
let id = todo.pop();
|
|
29493
|
+
order.push(id);
|
|
29494
|
+
let kids = kids_of.get(id) || [];
|
|
29495
|
+
for (let i = kids.length - 1; i >= 0; i--) todo.push(kids[i]);
|
|
29496
|
+
}
|
|
29418
29497
|
let col_w = [];
|
|
29419
29498
|
for (let [id, d] of t.depth) col_w[d] = Math.max(col_w[d] || 0, t.by_id.get(id).w);
|
|
29420
29499
|
let col_x = [];
|
|
@@ -29427,18 +29506,32 @@ function compact_tree_lr(nodes, edges, o) {
|
|
|
29427
29506
|
let dist = o.nodesep;
|
|
29428
29507
|
let level_distance = o.ranksep - pad;
|
|
29429
29508
|
let tn = /* @__PURE__ */ new Map();
|
|
29430
|
-
for (let id of order)
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
|
|
29436
|
-
|
|
29437
|
-
|
|
29509
|
+
for (let id of order) {
|
|
29510
|
+
let st = stacks.get(id);
|
|
29511
|
+
if (st) {
|
|
29512
|
+
let g = stack_geometry(t, st, col_x, col_w);
|
|
29513
|
+
tn.set(id, {
|
|
29514
|
+
len: g.len,
|
|
29515
|
+
ext: g.ext,
|
|
29516
|
+
geom: g,
|
|
29517
|
+
off_x: 0,
|
|
29518
|
+
off_y: 0,
|
|
29519
|
+
y: 0,
|
|
29520
|
+
contour: null
|
|
29521
|
+
});
|
|
29522
|
+
} else tn.set(id, {
|
|
29523
|
+
len: col_w[t.depth.get(id)],
|
|
29524
|
+
ext: t.by_id.get(id).h,
|
|
29525
|
+
off_x: 0,
|
|
29526
|
+
off_y: 0,
|
|
29527
|
+
y: 0,
|
|
29528
|
+
contour: null
|
|
29529
|
+
});
|
|
29530
|
+
}
|
|
29438
29531
|
for (let i = order.length - 1; i >= 0; i--) {
|
|
29439
29532
|
let id = order[i];
|
|
29440
29533
|
let n = tn.get(id);
|
|
29441
|
-
let kids =
|
|
29534
|
+
let kids = kids_of.get(id) || [];
|
|
29442
29535
|
if (!kids.length) {
|
|
29443
29536
|
let upper = contour_line(n.len + dist, 0);
|
|
29444
29537
|
let lower_tail = contour_line(0, -n.ext - dist);
|
|
@@ -29474,7 +29567,7 @@ function compact_tree_lr(nodes, edges, o) {
|
|
|
29474
29567
|
for (let id of order) {
|
|
29475
29568
|
let n = tn.get(id);
|
|
29476
29569
|
if (!root_of.has(id)) root_of.set(id, id);
|
|
29477
|
-
let kids =
|
|
29570
|
+
let kids = kids_of.get(id) || [];
|
|
29478
29571
|
if (!kids.length) continue;
|
|
29479
29572
|
let running = n.y + tn.get(kids[0]).off_y;
|
|
29480
29573
|
tn.get(kids[0]).y = running;
|
|
@@ -29501,9 +29594,14 @@ function compact_tree_lr(nodes, edges, o) {
|
|
|
29501
29594
|
top += hi.get(r) - lo.get(r) + o.nodesep * 2;
|
|
29502
29595
|
}
|
|
29503
29596
|
for (let id of order) {
|
|
29504
|
-
let d = t.depth.get(id);
|
|
29505
29597
|
let n = tn.get(id);
|
|
29506
29598
|
let y = n.y + shift.get(root_of.get(id));
|
|
29599
|
+
let st = stacks.get(id);
|
|
29600
|
+
if (st) {
|
|
29601
|
+
place_stack(t, st, n.geom, y, pos);
|
|
29602
|
+
continue;
|
|
29603
|
+
}
|
|
29604
|
+
let d = t.depth.get(id);
|
|
29507
29605
|
pos.set(id, {
|
|
29508
29606
|
x: col_x[d] + col_w[d] / 2,
|
|
29509
29607
|
y: y + n.ext / 2
|
|
@@ -29640,6 +29738,23 @@ function elbow_lane(ids, id) {
|
|
|
29640
29738
|
if (k <= 0) return 0;
|
|
29641
29739
|
return (k % 2 ? 1 : -1) * Math.ceil(k / 2);
|
|
29642
29740
|
}
|
|
29741
|
+
/************************************************************
|
|
29742
|
+
* The rank of `id` among `items` ([{id, span}]): the forward
|
|
29743
|
+
* edges that share one end with it, each with how far it runs
|
|
29744
|
+
* ACROSS. Farthest first; a tie goes to the edge made first.
|
|
29745
|
+
* Returns {rank, count}.
|
|
29746
|
+
************************************************************/
|
|
29747
|
+
function elbow_rank(items, id) {
|
|
29748
|
+
let sorted = items.slice().sort((a, b) => {
|
|
29749
|
+
if (b.span !== a.span) return b.span - a.span;
|
|
29750
|
+
return String(a.id).localeCompare(String(b.id), void 0, { numeric: true });
|
|
29751
|
+
});
|
|
29752
|
+
let rank = sorted.findIndex((it) => it.id === id);
|
|
29753
|
+
return {
|
|
29754
|
+
rank: rank < 0 ? 0 : rank,
|
|
29755
|
+
count: sorted.length
|
|
29756
|
+
};
|
|
29757
|
+
}
|
|
29643
29758
|
function swap(p) {
|
|
29644
29759
|
return [p[1], p[0]];
|
|
29645
29760
|
}
|
|
@@ -29651,6 +29766,136 @@ function swap_box(b) {
|
|
|
29651
29766
|
y2: b.x2
|
|
29652
29767
|
};
|
|
29653
29768
|
}
|
|
29769
|
+
function staggered_turn(lo, hi, st) {
|
|
29770
|
+
let mid = (lo + hi) / 2;
|
|
29771
|
+
let group = null;
|
|
29772
|
+
let k = 0;
|
|
29773
|
+
if (st.dep && st.dep.count > 1) {
|
|
29774
|
+
group = st.dep;
|
|
29775
|
+
k = st.dep.rank;
|
|
29776
|
+
} else if (st.arr && st.arr.count > 1) {
|
|
29777
|
+
group = st.arr;
|
|
29778
|
+
k = st.arr.count - 1 - st.arr.rank;
|
|
29779
|
+
}
|
|
29780
|
+
if (group) {
|
|
29781
|
+
let room = Math.max(0, hi - lo - 12);
|
|
29782
|
+
let step = Math.min(10, room / (group.count - 1));
|
|
29783
|
+
mid = mid - (group.count - 1) * step / 2 + k * step;
|
|
29784
|
+
}
|
|
29785
|
+
return mid;
|
|
29786
|
+
}
|
|
29787
|
+
/************************************************************
|
|
29788
|
+
* The combs of the stacks under one card.
|
|
29789
|
+
*
|
|
29790
|
+
* treedb_layout.js lays a run of leaf children out as two columns
|
|
29791
|
+
* with a corridor between them. A card in the first row is reached
|
|
29792
|
+
* from the channel like any other; one in a lower row cannot be --
|
|
29793
|
+
* the card above it stands in the way -- so its edge runs down
|
|
29794
|
+
* the corridor in a LANE of its own and turns into the gap above
|
|
29795
|
+
* its card, which it shares only with the other card of its row,
|
|
29796
|
+
* reached from the other side.
|
|
29797
|
+
*
|
|
29798
|
+
* targets [{id, box}]: the forward edges leaving one card,
|
|
29799
|
+
* each with the box of the card it reaches
|
|
29800
|
+
* vertical as in elbow_points; false swaps the boxes
|
|
29801
|
+
*
|
|
29802
|
+
* Returns Map id -> {lane, z, top}: the lane, the height of the
|
|
29803
|
+
* gap it turns into, and the top of the stack's first row (where
|
|
29804
|
+
* the channel over the stack ends). Only for a card that stands
|
|
29805
|
+
* under another of the group, within a stack gap and lined up
|
|
29806
|
+
* with it on the corridor side -- what a stack looks like.
|
|
29807
|
+
*
|
|
29808
|
+
* Lanes go outermost first, row by row: a line into a higher row
|
|
29809
|
+
* keeps outside the lines going deeper, and none crosses another.
|
|
29810
|
+
************************************************************/
|
|
29811
|
+
function elbow_combs(targets, vertical) {
|
|
29812
|
+
let list = vertical ? targets : targets.map((it) => ({
|
|
29813
|
+
id: it.id,
|
|
29814
|
+
box: swap_box(it.box)
|
|
29815
|
+
}));
|
|
29816
|
+
let cy = (b) => (b.y1 + b.y2) / 2;
|
|
29817
|
+
let near = (a, b) => Math.abs(a - b) < 1.5;
|
|
29818
|
+
let under = [];
|
|
29819
|
+
for (let it of list) {
|
|
29820
|
+
let b = it.box;
|
|
29821
|
+
let above = null;
|
|
29822
|
+
for (let o of list) {
|
|
29823
|
+
let a = o.box;
|
|
29824
|
+
if (o === it || a.y2 > b.y1 || b.y1 - a.y2 > 40) continue;
|
|
29825
|
+
if (!(near(a.x2, b.x2) || near(a.x1, b.x1))) continue;
|
|
29826
|
+
if (!above || a.y2 > above.y2) above = a;
|
|
29827
|
+
}
|
|
29828
|
+
if (!above) continue;
|
|
29829
|
+
let side;
|
|
29830
|
+
if (near(above.x2, b.x2) && !near(above.x1, b.x1)) side = 0;
|
|
29831
|
+
else if (near(above.x1, b.x1) && !near(above.x2, b.x2)) side = 1;
|
|
29832
|
+
else side = list.some((o) => o !== it && near(cy(o.box), cy(b)) && o.box.x2 <= b.x1) ? 1 : 0;
|
|
29833
|
+
under.push({
|
|
29834
|
+
id: it.id,
|
|
29835
|
+
box: b,
|
|
29836
|
+
above,
|
|
29837
|
+
side
|
|
29838
|
+
});
|
|
29839
|
+
}
|
|
29840
|
+
let corridor = (u) => {
|
|
29841
|
+
if (u.side === 0) {
|
|
29842
|
+
let l = u.box.x2;
|
|
29843
|
+
let col = list.filter((o) => near(o.box.x2, l));
|
|
29844
|
+
let r = Infinity;
|
|
29845
|
+
for (let c of col) for (let o of list) if (o !== c && near(cy(o.box), cy(c.box)) && o.box.x1 >= l - .5) r = Math.min(r, o.box.x1);
|
|
29846
|
+
return {
|
|
29847
|
+
l,
|
|
29848
|
+
r: isFinite(r) ? r : l + 36,
|
|
29849
|
+
col
|
|
29850
|
+
};
|
|
29851
|
+
}
|
|
29852
|
+
let r = u.box.x1;
|
|
29853
|
+
let col = list.filter((o) => near(o.box.x1, r));
|
|
29854
|
+
let l = -Infinity;
|
|
29855
|
+
for (let c of col) for (let o of list) if (o !== c && near(cy(o.box), cy(c.box)) && o.box.x2 <= r + .5) l = Math.max(l, o.box.x2);
|
|
29856
|
+
return {
|
|
29857
|
+
l: isFinite(l) ? l : r - 36,
|
|
29858
|
+
r,
|
|
29859
|
+
col
|
|
29860
|
+
};
|
|
29861
|
+
};
|
|
29862
|
+
let groups = /* @__PURE__ */ new Map();
|
|
29863
|
+
for (let u of under) {
|
|
29864
|
+
let c = corridor(u);
|
|
29865
|
+
u.top = Math.min(...c.col.map((o) => o.box.y1));
|
|
29866
|
+
let key = `${Math.round(c.l)}|${Math.round(c.r)}`;
|
|
29867
|
+
if (!groups.has(key)) groups.set(key, {
|
|
29868
|
+
l: c.l,
|
|
29869
|
+
r: c.r,
|
|
29870
|
+
left: [],
|
|
29871
|
+
right: []
|
|
29872
|
+
});
|
|
29873
|
+
groups.get(key)[u.side === 0 ? "left" : "right"].push(u);
|
|
29874
|
+
}
|
|
29875
|
+
let out = /* @__PURE__ */ new Map();
|
|
29876
|
+
for (let g of groups.values()) {
|
|
29877
|
+
g.left.sort((a, b) => a.box.y1 - b.box.y1);
|
|
29878
|
+
g.right.sort((a, b) => a.box.y1 - b.box.y1);
|
|
29879
|
+
let n = g.left.length + g.right.length;
|
|
29880
|
+
let room = g.r - g.l - 20;
|
|
29881
|
+
let step = n > 1 ? Math.max(0, Math.min(6, room / (n - 1))) : 0;
|
|
29882
|
+
g.left.forEach((u, i) => {
|
|
29883
|
+
out.set(u.id, {
|
|
29884
|
+
lane: g.l + 10 + i * step,
|
|
29885
|
+
z: (u.above.y2 + u.box.y1) / 2,
|
|
29886
|
+
top: u.top
|
|
29887
|
+
});
|
|
29888
|
+
});
|
|
29889
|
+
g.right.forEach((u, j) => {
|
|
29890
|
+
out.set(u.id, {
|
|
29891
|
+
lane: g.r - 10 - j * step,
|
|
29892
|
+
z: (u.above.y2 + u.box.y1) / 2,
|
|
29893
|
+
top: u.top
|
|
29894
|
+
});
|
|
29895
|
+
});
|
|
29896
|
+
}
|
|
29897
|
+
return out;
|
|
29898
|
+
}
|
|
29654
29899
|
/************************************************************
|
|
29655
29900
|
* The control points of an elbow from the port `s` to the port
|
|
29656
29901
|
* `t` ([x, y] each), knowing the boxes of the two cards
|
|
@@ -29658,13 +29903,33 @@ function swap_box(b) {
|
|
|
29658
29903
|
*
|
|
29659
29904
|
* vertical the rows are stacked (top to bottom); false
|
|
29660
29905
|
* when they are side by side (left to right)
|
|
29661
|
-
|
|
29662
|
-
|
|
29663
|
-
|
|
29906
|
+
* stagger {dep, arr, comb}: the edge's rank among the
|
|
29907
|
+
* forward edges leaving its source card and among
|
|
29908
|
+
* those reaching its target card (elbow_rank), and
|
|
29909
|
+
* its comb when the target is in a lower row of a
|
|
29910
|
+
* stack (elbow_combs). Absent, the channel is the
|
|
29911
|
+
* middle.
|
|
29912
|
+
************************************************************/
|
|
29913
|
+
function elbow_points(s, t, box_s, box_t, lane, vertical, stagger) {
|
|
29914
|
+
if (!vertical) return elbow_points(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, stagger).map(swap);
|
|
29664
29915
|
let shift = lane * 10;
|
|
29665
29916
|
if (t[1] - s[1] > 20) {
|
|
29666
|
-
let
|
|
29667
|
-
|
|
29917
|
+
let st = stagger || {};
|
|
29918
|
+
let lo = Math.max(s[1], box_s.y2);
|
|
29919
|
+
if (st.comb) {
|
|
29920
|
+
let c = st.comb;
|
|
29921
|
+
let turn = staggered_turn(lo, c.top, { dep: st.dep }) + shift;
|
|
29922
|
+
turn = Math.min(Math.max(turn, lo + 4), c.top - 4);
|
|
29923
|
+
return [
|
|
29924
|
+
[s[0], turn],
|
|
29925
|
+
[c.lane, turn],
|
|
29926
|
+
[c.lane, c.z],
|
|
29927
|
+
[t[0], c.z]
|
|
29928
|
+
];
|
|
29929
|
+
}
|
|
29930
|
+
let hi = Math.min(t[1], box_t.y1);
|
|
29931
|
+
let mid = staggered_turn(lo, hi, st) + shift;
|
|
29932
|
+
mid = Math.min(Math.max(mid, lo + 4), hi - 4);
|
|
29668
29933
|
return [[s[0], mid], [t[0], mid]];
|
|
29669
29934
|
}
|
|
29670
29935
|
let out = 16 + Math.abs(shift);
|
|
@@ -29758,8 +30023,12 @@ function heap_pop(h) {
|
|
|
29758
30023
|
/************************************************************
|
|
29759
30024
|
* The shortest orthogonal line from `a` to `z` that enters none
|
|
29760
30025
|
* of `boxes` (already expanded by the clearance), a turn costing
|
|
29761
|
-
* ROUTE_BEND. The line leaves `a`
|
|
29762
|
-
*
|
|
30026
|
+
* ROUTE_BEND. The line leaves `a` SIDEWAYS and reaches `z`
|
|
30027
|
+
* SIDEWAYS: the column straight under a port and the one straight
|
|
30028
|
+
* over it belong to the forward edges that share that port, which
|
|
30029
|
+
* run along them to their staggered turns -- a route going down
|
|
30030
|
+
* that column lay on top of them. So a routed line shares only
|
|
30031
|
+
* the stub between the port and `a` (or `z`).
|
|
29763
30032
|
*
|
|
29764
30033
|
* The grid is SPARSE: only the lines of the boxes' borders and
|
|
29765
30034
|
* of the two ends, which is all an orthogonal shortest path ever
|
|
@@ -29825,7 +30094,8 @@ function orth_search(a, z, boxes) {
|
|
|
29825
30094
|
let k = state >> 2;
|
|
29826
30095
|
let dir = state & 3;
|
|
29827
30096
|
if (k === goal) {
|
|
29828
|
-
|
|
30097
|
+
if (dir >= 2) continue;
|
|
30098
|
+
let total = cost + 40;
|
|
29829
30099
|
if (total < found_cost) {
|
|
29830
30100
|
found_cost = total;
|
|
29831
30101
|
found = state;
|
|
@@ -29833,6 +30103,7 @@ function orth_search(a, z, boxes) {
|
|
|
29833
30103
|
continue;
|
|
29834
30104
|
}
|
|
29835
30105
|
for (let [nk, nd, len] of moves(k)) {
|
|
30106
|
+
if (k === start && nd >= 2) continue;
|
|
29836
30107
|
let c = cost + len + (nd === dir ? 0 : 40);
|
|
29837
30108
|
let ns = nk * 4 + nd;
|
|
29838
30109
|
if (c < best[ns]) {
|
|
@@ -29873,10 +30144,11 @@ function orth_search(a, z, boxes) {
|
|
|
29873
30144
|
* coincide. Nearby cards first; all of them if that finds no way;
|
|
29874
30145
|
* the simple elbow if nothing does.
|
|
29875
30146
|
************************************************************/
|
|
29876
|
-
function elbow_route(s, t, box_s, box_t, lane, vertical, boxes) {
|
|
30147
|
+
function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
|
|
29877
30148
|
let others = boxes || [];
|
|
29878
|
-
if (!vertical) return elbow_route(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, others.map(swap_box)).map(swap);
|
|
29879
|
-
|
|
30149
|
+
if (!vertical) return elbow_route(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, others.map(swap_box), stagger).map(swap);
|
|
30150
|
+
if (stagger && stagger.comb) return elbow_points(s, t, box_s, box_t, lane, true, stagger);
|
|
30151
|
+
let simple = elbow_points(s, t, box_s, box_t, lane, true, stagger);
|
|
29880
30152
|
if (!elbow_path_hits([
|
|
29881
30153
|
s,
|
|
29882
30154
|
...simple,
|
|
@@ -59277,8 +59549,9 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
|
|
|
59277
59549
|
* dragged card, a fold or a layout needs nothing else. `-v` runs
|
|
59278
59550
|
* between rows (top to bottom), `-h` between columns. An edge that
|
|
59279
59551
|
* does not run forward goes round the two cards, the edges joining
|
|
59280
|
-
* the same two cards take lanes,
|
|
59281
|
-
*
|
|
59552
|
+
* the same two cards take lanes, the edges sharing an end turn at
|
|
59553
|
+
* staggered heights, and a line that would cross any other card is
|
|
59554
|
+
* routed round it (treedb_elbow.js).
|
|
59282
59555
|
************************************************************/
|
|
59283
59556
|
var ELBOW_RADIUS = 6;
|
|
59284
59557
|
function elbow_box(node) {
|
|
@@ -59330,10 +59603,55 @@ function elbow_lane_of(edge) {
|
|
|
59330
59603
|
return 0;
|
|
59331
59604
|
}
|
|
59332
59605
|
}
|
|
59606
|
+
function elbow_stagger_of(edge, vertical) {
|
|
59607
|
+
let graph = edge.context && edge.context.graph;
|
|
59608
|
+
let element = edge.context && edge.context.element;
|
|
59609
|
+
let s = edge.sourceNode && edge.sourceNode.id;
|
|
59610
|
+
let t = edge.targetNode && edge.targetNode.id;
|
|
59611
|
+
if (!graph || !element || s === void 0 || t === void 0) return null;
|
|
59612
|
+
let across = vertical ? 0 : 1;
|
|
59613
|
+
let along = vertical ? 1 : 0;
|
|
59614
|
+
let pos = (id) => graph.getElementPosition(id);
|
|
59615
|
+
let port_of = (node_id, key) => {
|
|
59616
|
+
let node = element.getElement(node_id);
|
|
59617
|
+
let ports = node && typeof node.getPorts === "function" ? node.getPorts() : {};
|
|
59618
|
+
let port = key ? ports[key] : null;
|
|
59619
|
+
return port ? port.getPosition() : pos(node_id);
|
|
59620
|
+
};
|
|
59621
|
+
try {
|
|
59622
|
+
let ps = pos(s);
|
|
59623
|
+
let pt = pos(t);
|
|
59624
|
+
let leaving = graph.getRelatedEdgesData(s, "out").filter((d) => d.source === s && pos(d.target)[along] > ps[along]);
|
|
59625
|
+
let combs = elbow_combs(leaving.map((d) => ({
|
|
59626
|
+
id: d.id,
|
|
59627
|
+
box: elbow_box(element.getElement(d.target))
|
|
59628
|
+
})), vertical);
|
|
59629
|
+
let dep = leaving.map((d) => {
|
|
59630
|
+
let comb = combs.get(d.id);
|
|
59631
|
+
let far = comb ? comb.lane : pos(d.target)[across];
|
|
59632
|
+
return {
|
|
59633
|
+
id: d.id,
|
|
59634
|
+
span: Math.abs(far - port_of(s, d.style && d.style.sourcePort)[across])
|
|
59635
|
+
};
|
|
59636
|
+
});
|
|
59637
|
+
let arr = graph.getRelatedEdgesData(t, "in").filter((d) => d.target === t && pos(d.source)[along] < pt[along]).map((d) => ({
|
|
59638
|
+
id: d.id,
|
|
59639
|
+
span: Math.abs(port_of(d.source, d.style && d.style.sourcePort)[across] - pt[across])
|
|
59640
|
+
}));
|
|
59641
|
+
return {
|
|
59642
|
+
dep: elbow_rank(dep, edge.id),
|
|
59643
|
+
arr: elbow_rank(arr, edge.id),
|
|
59644
|
+
comb: combs.get(edge.id) || null
|
|
59645
|
+
};
|
|
59646
|
+
} catch (e) {
|
|
59647
|
+
(0, _yuneta_gobj_js.log_error)(`elbow edge ${edge.id}: cannot read the edges sharing its ends: ${e}`);
|
|
59648
|
+
return null;
|
|
59649
|
+
}
|
|
59650
|
+
}
|
|
59333
59651
|
var TreedbElbowV = class extends _antv_g6.Polyline {
|
|
59334
59652
|
getControlPoints(attributes) {
|
|
59335
59653
|
let [s, t] = this.getEndpoints(attributes, false);
|
|
59336
|
-
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), true, elbow_obstacles(this));
|
|
59654
|
+
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), true, elbow_obstacles(this), elbow_stagger_of(this, true));
|
|
59337
59655
|
}
|
|
59338
59656
|
getKeyPath(attributes) {
|
|
59339
59657
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|
|
@@ -59342,7 +59660,7 @@ var TreedbElbowV = class extends _antv_g6.Polyline {
|
|
|
59342
59660
|
var TreedbElbowH = class extends _antv_g6.Polyline {
|
|
59343
59661
|
getControlPoints(attributes) {
|
|
59344
59662
|
let [s, t] = this.getEndpoints(attributes, false);
|
|
59345
|
-
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), false, elbow_obstacles(this));
|
|
59663
|
+
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), false, elbow_obstacles(this), elbow_stagger_of(this, false));
|
|
59346
59664
|
}
|
|
59347
59665
|
getKeyPath(attributes) {
|
|
59348
59666
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|