@yuneta/gobj-ui 7.23.153 → 7.23.155
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 +22 -2
- package/dist/gobj-ui.cjs.js +424 -43
- package/dist/gobj-ui.es.js +425 -44
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +81 -12
- package/src/treedb_elbow.js +292 -22
- package/src/treedb_elbow.test.js +130 -1
- package/src/treedb_layout.js +146 -14
- package/src/treedb_layout.test.js +84 -12
package/README.md
CHANGED
|
@@ -1413,7 +1413,14 @@ 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; with elbow edges or curves
|
|
1423
|
+
alike, since `7.23.155` a curve keeps off the cards too.
|
|
1417
1424
|
- **`radial`** (`treedb-radial`) — the root in the middle, a ring per depth,
|
|
1418
1425
|
every subtree an angular **sector** proportional to its leaves, and the
|
|
1419
1426
|
radius of each ring the largest of three: one `ranksep` out from the ring
|
|
@@ -1471,7 +1478,20 @@ is short. Leaving, the farthest turns highest; arriving, the farthest turns
|
|
|
1471
1478
|
lowest: the orders in which the lines of one end nest without crossing. A
|
|
1472
1479
|
routed line leaves its port and reaches the other one **sideways**, because
|
|
1473
1480
|
the column straight under or over a port is where the staggered edges of that
|
|
1474
|
-
port run. Only the stub at the port is shared.
|
|
1481
|
+
port run. Only the stub at the port is shared. Into a lower row of a stack of
|
|
1482
|
+
the compact tree an edge runs a **comb** (`7.23.154`): along the channel to a
|
|
1483
|
+
lane of its own in the stack's corridor, down it, and into the gap above its
|
|
1484
|
+
card; lanes go outermost first by row, so none crosses another, and a comb is
|
|
1485
|
+
drawn as laid out, never routed.
|
|
1486
|
+
|
|
1487
|
+
**Curved edges keep off the cards as well** (`7.23.155`). On a layout with
|
|
1488
|
+
rows a curve is `treedb-curve-v` / `-h`, a subclass of G6's cubic: the cubic
|
|
1489
|
+
as before, unless that very curve — the path G6 would draw, sampled, not the
|
|
1490
|
+
rectangle round it — would cross a card other than its own two, or the edge
|
|
1491
|
+
does not run forward and so would cross its own. Then it takes the way its
|
|
1492
|
+
elbow would (comb, detour, route, the same lanes and staggered turns) with
|
|
1493
|
+
corners rounded to 24px. On a layout with no rows the edges stay G6's plain
|
|
1494
|
+
cubic. G6's `shortest-path` router is not used: it is
|
|
1475
1495
|
not exported, it
|
|
1476
1496
|
falls back in silence to a route that crosses cards, and it rewrites its
|
|
1477
1497
|
module defaults with every config it is given.
|
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
|
|
@@ -29668,6 +29766,136 @@ function swap_box(b) {
|
|
|
29668
29766
|
y2: b.x2
|
|
29669
29767
|
};
|
|
29670
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
|
+
}
|
|
29671
29899
|
/************************************************************
|
|
29672
29900
|
* The control points of an elbow from the port `s` to the port
|
|
29673
29901
|
* `t` ([x, y] each), knowing the boxes of the two cards
|
|
@@ -29675,34 +29903,32 @@ function swap_box(b) {
|
|
|
29675
29903
|
*
|
|
29676
29904
|
* vertical the rows are stacked (top to bottom); false
|
|
29677
29905
|
* when they are side by side (left to right)
|
|
29678
|
-
* stagger {dep, arr}: the edge's rank among the
|
|
29679
|
-
* edges leaving its source card and among
|
|
29680
|
-
* reaching its target card (elbow_rank)
|
|
29681
|
-
* the
|
|
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.
|
|
29682
29912
|
************************************************************/
|
|
29683
29913
|
function elbow_points(s, t, box_s, box_t, lane, vertical, stagger) {
|
|
29684
29914
|
if (!vertical) return elbow_points(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, stagger).map(swap);
|
|
29685
29915
|
let shift = lane * 10;
|
|
29686
29916
|
if (t[1] - s[1] > 20) {
|
|
29917
|
+
let st = stagger || {};
|
|
29687
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
|
+
}
|
|
29688
29930
|
let hi = Math.min(t[1], box_t.y1);
|
|
29689
|
-
let mid = (lo
|
|
29690
|
-
let st = stagger || {};
|
|
29691
|
-
let group = null;
|
|
29692
|
-
let k = 0;
|
|
29693
|
-
if (st.dep && st.dep.count > 1) {
|
|
29694
|
-
group = st.dep;
|
|
29695
|
-
k = st.dep.rank;
|
|
29696
|
-
} else if (st.arr && st.arr.count > 1) {
|
|
29697
|
-
group = st.arr;
|
|
29698
|
-
k = st.arr.count - 1 - st.arr.rank;
|
|
29699
|
-
}
|
|
29700
|
-
if (group) {
|
|
29701
|
-
let room = Math.max(0, hi - lo - 12);
|
|
29702
|
-
let step = Math.min(10, room / (group.count - 1));
|
|
29703
|
-
mid = mid - (group.count - 1) * step / 2 + k * step;
|
|
29704
|
-
}
|
|
29705
|
-
mid += shift;
|
|
29931
|
+
let mid = staggered_turn(lo, hi, st) + shift;
|
|
29706
29932
|
mid = Math.min(Math.max(mid, lo + 4), hi - 4);
|
|
29707
29933
|
return [[s[0], mid], [t[0], mid]];
|
|
29708
29934
|
}
|
|
@@ -29921,6 +30147,7 @@ function orth_search(a, z, boxes) {
|
|
|
29921
30147
|
function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
|
|
29922
30148
|
let others = boxes || [];
|
|
29923
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);
|
|
29924
30151
|
let simple = elbow_points(s, t, box_s, box_t, lane, true, stagger);
|
|
29925
30152
|
if (!elbow_path_hits([
|
|
29926
30153
|
s,
|
|
@@ -29941,6 +30168,112 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
|
|
|
29941
30168
|
if (!route && near.length < others.length) route = orth_search(a, z, others.map((b) => box_expand(b, m)));
|
|
29942
30169
|
return route || simple;
|
|
29943
30170
|
}
|
|
30171
|
+
function path_points(path) {
|
|
30172
|
+
let pts = [];
|
|
30173
|
+
let cur = null;
|
|
30174
|
+
for (let c of path) if (c[0] === "M" || c[0] === "L") {
|
|
30175
|
+
cur = [c[1], c[2]];
|
|
30176
|
+
pts.push(cur);
|
|
30177
|
+
} else if (c[0] === "C" && cur) {
|
|
30178
|
+
let [x0, y0] = cur;
|
|
30179
|
+
for (let k = 1; k <= 16; k++) {
|
|
30180
|
+
let u = k / 16;
|
|
30181
|
+
let v = 1 - u;
|
|
30182
|
+
pts.push([v * v * v * x0 + 3 * v * v * u * c[1] + 3 * v * u * u * c[3] + u * u * u * c[5], v * v * v * y0 + 3 * v * v * u * c[2] + 3 * v * u * u * c[4] + u * u * u * c[6]]);
|
|
30183
|
+
}
|
|
30184
|
+
cur = [c[5], c[6]];
|
|
30185
|
+
} else if (c[0] === "Q" && cur) {
|
|
30186
|
+
let [x0, y0] = cur;
|
|
30187
|
+
for (let k = 1; k <= 16; k++) {
|
|
30188
|
+
let u = k / 16;
|
|
30189
|
+
let v = 1 - u;
|
|
30190
|
+
pts.push([v * v * x0 + 2 * v * u * c[1] + u * u * c[3], v * v * y0 + 2 * v * u * c[2] + u * u * c[4]]);
|
|
30191
|
+
}
|
|
30192
|
+
cur = [c[3], c[4]];
|
|
30193
|
+
}
|
|
30194
|
+
return pts;
|
|
30195
|
+
}
|
|
30196
|
+
/************************************************************
|
|
30197
|
+
* Does the G6 path `path` of a curved edge cross a card other than
|
|
30198
|
+
* its own two? Measured on the curve itself -- the path G6 would
|
|
30199
|
+
* draw, sampled -- and not on the rectangle round it, which took
|
|
30200
|
+
* every card the curve merely passed near: the ports of a row
|
|
30201
|
+
* stick well into the space above it. Its own two cards are left
|
|
30202
|
+
* out: the curve starts and ends on their ports.
|
|
30203
|
+
************************************************************/
|
|
30204
|
+
function curve_hits(path, boxes, box_s, box_t) {
|
|
30205
|
+
let pts = path_points(path);
|
|
30206
|
+
if (pts.length < 2) return false;
|
|
30207
|
+
let bb = {
|
|
30208
|
+
x1: Infinity,
|
|
30209
|
+
y1: Infinity,
|
|
30210
|
+
x2: -Infinity,
|
|
30211
|
+
y2: -Infinity
|
|
30212
|
+
};
|
|
30213
|
+
for (let p of pts) {
|
|
30214
|
+
bb.x1 = Math.min(bb.x1, p[0]);
|
|
30215
|
+
bb.y1 = Math.min(bb.y1, p[1]);
|
|
30216
|
+
bb.x2 = Math.max(bb.x2, p[0]);
|
|
30217
|
+
bb.y2 = Math.max(bb.y2, p[1]);
|
|
30218
|
+
}
|
|
30219
|
+
for (let b of boxes || []) {
|
|
30220
|
+
if (same_box(b, box_s) || same_box(b, box_t) || !box_overlaps(b, box_expand(bb, 1))) continue;
|
|
30221
|
+
let inner = box_expand(b, -1);
|
|
30222
|
+
for (let k = 0; k + 1 < pts.length; k++) if (segment_hits(pts[k], pts[k + 1], inner)) return true;
|
|
30223
|
+
}
|
|
30224
|
+
return false;
|
|
30225
|
+
}
|
|
30226
|
+
/************************************************************
|
|
30227
|
+
* A G6 path (['M'|'L'|'Q', ...]) along `points` with every corner
|
|
30228
|
+
* rounded -- by `radius`, or by half the shorter of its two
|
|
30229
|
+
* segments, so a short run is never overshot. The rounding is the
|
|
30230
|
+
* quadratic G6's own polyline uses.
|
|
30231
|
+
************************************************************/
|
|
30232
|
+
function rounded_path(points, radius) {
|
|
30233
|
+
let path = [[
|
|
30234
|
+
"M",
|
|
30235
|
+
points[0][0],
|
|
30236
|
+
points[0][1]
|
|
30237
|
+
]];
|
|
30238
|
+
for (let i = 1; i + 1 < points.length; i++) {
|
|
30239
|
+
let a = points[i - 1];
|
|
30240
|
+
let m = points[i];
|
|
30241
|
+
let b = points[i + 1];
|
|
30242
|
+
let len_in = Math.hypot(m[0] - a[0], m[1] - a[1]);
|
|
30243
|
+
let len_out = Math.hypot(b[0] - m[0], b[1] - m[1]);
|
|
30244
|
+
let r = Math.min(radius, len_in / 2, len_out / 2);
|
|
30245
|
+
let collinear = Math.abs((m[0] - a[0]) * (b[1] - m[1]) - (m[1] - a[1]) * (b[0] - m[0])) < 1e-9;
|
|
30246
|
+
if (r <= 0 || collinear) {
|
|
30247
|
+
path.push([
|
|
30248
|
+
"L",
|
|
30249
|
+
m[0],
|
|
30250
|
+
m[1]
|
|
30251
|
+
]);
|
|
30252
|
+
continue;
|
|
30253
|
+
}
|
|
30254
|
+
let p1 = [m[0] - (m[0] - a[0]) / len_in * r, m[1] - (m[1] - a[1]) / len_in * r];
|
|
30255
|
+
let p2 = [m[0] + (b[0] - m[0]) / len_out * r, m[1] + (b[1] - m[1]) / len_out * r];
|
|
30256
|
+
path.push([
|
|
30257
|
+
"L",
|
|
30258
|
+
p1[0],
|
|
30259
|
+
p1[1]
|
|
30260
|
+
]);
|
|
30261
|
+
path.push([
|
|
30262
|
+
"Q",
|
|
30263
|
+
m[0],
|
|
30264
|
+
m[1],
|
|
30265
|
+
p2[0],
|
|
30266
|
+
p2[1]
|
|
30267
|
+
]);
|
|
30268
|
+
}
|
|
30269
|
+
let last = points[points.length - 1];
|
|
30270
|
+
path.push([
|
|
30271
|
+
"L",
|
|
30272
|
+
last[0],
|
|
30273
|
+
last[1]
|
|
30274
|
+
]);
|
|
30275
|
+
return path;
|
|
30276
|
+
}
|
|
29944
30277
|
//#endregion
|
|
29945
30278
|
//#region node_modules/@babel/runtime/helpers/esm/typeof.js
|
|
29946
30279
|
function _typeof(o) {
|
|
@@ -54828,7 +55161,7 @@ Easing Functions from anime.js, they are tried and true, so, its better to use t
|
|
|
54828
55161
|
var Quad = function Quad(t) {
|
|
54829
55162
|
return Math.pow(t, 2);
|
|
54830
55163
|
};
|
|
54831
|
-
var Cubic = function Cubic(t) {
|
|
55164
|
+
var Cubic$1 = function Cubic(t) {
|
|
54832
55165
|
return Math.pow(t, 3);
|
|
54833
55166
|
};
|
|
54834
55167
|
var Quart = function Quart(t) {
|
|
@@ -54965,10 +55298,10 @@ var EasingFunctions = {
|
|
|
54965
55298
|
"out-quad": EaseOut(Quad),
|
|
54966
55299
|
"in-out-quad": EaseInOut(Quad),
|
|
54967
55300
|
"out-in-quad": EaseOutIn(Quad),
|
|
54968
|
-
"in-cubic": Cubic,
|
|
54969
|
-
"out-cubic": EaseOut(Cubic),
|
|
54970
|
-
"in-out-cubic": EaseInOut(Cubic),
|
|
54971
|
-
"out-in-cubic": EaseOutIn(Cubic),
|
|
55301
|
+
"in-cubic": Cubic$1,
|
|
55302
|
+
"out-cubic": EaseOut(Cubic$1),
|
|
55303
|
+
"in-out-cubic": EaseInOut(Cubic$1),
|
|
55304
|
+
"out-in-cubic": EaseOutIn(Cubic$1),
|
|
54972
55305
|
"in-quart": Quart,
|
|
54973
55306
|
"out-quart": EaseOut(Quart),
|
|
54974
55307
|
"in-out-quart": EaseInOut(Quart),
|
|
@@ -57141,6 +57474,8 @@ function register_layouts(gobj) {
|
|
|
57141
57474
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-compact", TreedbCompactLayout);
|
|
57142
57475
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-v", TreedbElbowV);
|
|
57143
57476
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-h", TreedbElbowH);
|
|
57477
|
+
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-curve-v", TreedbCurveV);
|
|
57478
|
+
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-curve-h", TreedbCurveH);
|
|
57144
57479
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
|
|
57145
57480
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
|
|
57146
57481
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "treedb-card", TreedbCard);
|
|
@@ -57835,7 +58170,9 @@ function layout_direction(gobj) {
|
|
|
57835
58170
|
function edge_type_for(gobj) {
|
|
57836
58171
|
let lr = layout_direction(gobj) === "LR";
|
|
57837
58172
|
let rowless = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "rowless_layouts") || [];
|
|
57838
|
-
|
|
58173
|
+
let rows = !(0, _yuneta_gobj_js.str_in_list)(rowless, gobj.priv.layout);
|
|
58174
|
+
if (rows && (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow") return lr ? "treedb-elbow-h" : "treedb-elbow-v";
|
|
58175
|
+
if (rows) return lr ? "treedb-curve-h" : "treedb-curve-v";
|
|
57839
58176
|
return lr ? "cubic-horizontal" : "cubic";
|
|
57840
58177
|
}
|
|
57841
58178
|
/************************************************************
|
|
@@ -59394,17 +59731,27 @@ function elbow_stagger_of(edge, vertical) {
|
|
|
59394
59731
|
try {
|
|
59395
59732
|
let ps = pos(s);
|
|
59396
59733
|
let pt = pos(t);
|
|
59397
|
-
let
|
|
59734
|
+
let leaving = graph.getRelatedEdgesData(s, "out").filter((d) => d.source === s && pos(d.target)[along] > ps[along]);
|
|
59735
|
+
let combs = elbow_combs(leaving.map((d) => ({
|
|
59398
59736
|
id: d.id,
|
|
59399
|
-
|
|
59400
|
-
}));
|
|
59737
|
+
box: elbow_box(element.getElement(d.target))
|
|
59738
|
+
})), vertical);
|
|
59739
|
+
let dep = leaving.map((d) => {
|
|
59740
|
+
let comb = combs.get(d.id);
|
|
59741
|
+
let far = comb ? comb.lane : pos(d.target)[across];
|
|
59742
|
+
return {
|
|
59743
|
+
id: d.id,
|
|
59744
|
+
span: Math.abs(far - port_of(s, d.style && d.style.sourcePort)[across])
|
|
59745
|
+
};
|
|
59746
|
+
});
|
|
59401
59747
|
let arr = graph.getRelatedEdgesData(t, "in").filter((d) => d.target === t && pos(d.source)[along] < pt[along]).map((d) => ({
|
|
59402
59748
|
id: d.id,
|
|
59403
59749
|
span: Math.abs(port_of(d.source, d.style && d.style.sourcePort)[across] - pt[across])
|
|
59404
59750
|
}));
|
|
59405
59751
|
return {
|
|
59406
59752
|
dep: elbow_rank(dep, edge.id),
|
|
59407
|
-
arr: elbow_rank(arr, edge.id)
|
|
59753
|
+
arr: elbow_rank(arr, edge.id),
|
|
59754
|
+
comb: combs.get(edge.id) || null
|
|
59408
59755
|
};
|
|
59409
59756
|
} catch (e) {
|
|
59410
59757
|
(0, _yuneta_gobj_js.log_error)(`elbow edge ${edge.id}: cannot read the edges sharing its ends: ${e}`);
|
|
@@ -59429,6 +59776,40 @@ var TreedbElbowH = class extends _antv_g6.Polyline {
|
|
|
59429
59776
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|
|
59430
59777
|
}
|
|
59431
59778
|
};
|
|
59779
|
+
/************************************************************
|
|
59780
|
+
* A CURVED edge that keeps off the cards. G6's cubic, as before,
|
|
59781
|
+
* unless that very curve -- sampled, not guessed from the
|
|
59782
|
+
* rectangle round it -- would cross a card other than its own two,
|
|
59783
|
+
* or when it does not run forward and so would cross its own:
|
|
59784
|
+
* the card above a lower row of a stack, a row between a parent
|
|
59785
|
+
* and a far child. Then it goes the way an elbow would (the comb,
|
|
59786
|
+
* the detour, the route: the same lanes and staggered turns) with
|
|
59787
|
+
* round corners, so it still reads as a curve. `-v` for rows
|
|
59788
|
+
* stacked top to bottom, `-h` for columns.
|
|
59789
|
+
************************************************************/
|
|
59790
|
+
function curve_key_path(edge, attributes, vertical, plain) {
|
|
59791
|
+
let [s, t] = edge.getEndpoints(attributes, false);
|
|
59792
|
+
let along = vertical ? 1 : 0;
|
|
59793
|
+
let box_s = elbow_box(edge.sourceNode);
|
|
59794
|
+
let box_t = elbow_box(edge.targetNode);
|
|
59795
|
+
let boxes = elbow_obstacles(edge);
|
|
59796
|
+
if (t[along] - s[along] > 20 && !curve_hits(plain, boxes, box_s, box_t)) return plain;
|
|
59797
|
+
return rounded_path([
|
|
59798
|
+
s,
|
|
59799
|
+
...elbow_route(s, t, box_s, box_t, elbow_lane_of(edge), vertical, boxes, elbow_stagger_of(edge, vertical)),
|
|
59800
|
+
t
|
|
59801
|
+
], 24);
|
|
59802
|
+
}
|
|
59803
|
+
var TreedbCurveV = class extends _antv_g6.Cubic {
|
|
59804
|
+
getKeyPath(attributes) {
|
|
59805
|
+
return curve_key_path(this, attributes, true, super.getKeyPath(attributes));
|
|
59806
|
+
}
|
|
59807
|
+
};
|
|
59808
|
+
var TreedbCurveH = class extends _antv_g6.CubicHorizontal {
|
|
59809
|
+
getKeyPath(attributes) {
|
|
59810
|
+
return curve_key_path(this, attributes, false, super.getKeyPath(attributes));
|
|
59811
|
+
}
|
|
59812
|
+
};
|
|
59432
59813
|
var TreedbCompactLayout = class extends _antv_g6.BaseLayout {
|
|
59433
59814
|
async execute(data, options) {
|
|
59434
59815
|
let input = treedb_layout_input(data);
|