@yuneta/gobj-ui 7.23.154 → 7.23.156
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 +21 -3
- package/dist/gobj-ui.cjs.js +365 -72
- package/dist/gobj-ui.es.js +366 -73
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +61 -5
- package/src/treedb_elbow.js +113 -0
- package/src/treedb_elbow.test.js +45 -1
- package/src/treedb_layout.js +274 -83
- package/src/treedb_layout.test.js +95 -2
package/README.md
CHANGED
|
@@ -1419,7 +1419,8 @@ layouts by three thin adapters in `c_g6_nodes_tree.js`:
|
|
|
1419
1419
|
gained nothing on a whole level opened with the stepper, where every parent
|
|
1420
1420
|
still needed the row of its children beside it. Against `tree`: regions
|
|
1421
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;
|
|
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.
|
|
1423
1424
|
- **`radial`** (`treedb-radial`) — the root in the middle, a ring per depth,
|
|
1424
1425
|
every subtree an angular **sector** proportional to its leaves, and the
|
|
1425
1426
|
radius of each ring the largest of three: one `ranksep` out from the ring
|
|
@@ -1429,7 +1430,15 @@ layouts by three thin adapters in `c_g6_nodes_tree.js`:
|
|
|
1429
1430
|
cards touching, where the tidy tree's `ranksep` is a gap between COLUMNS
|
|
1430
1431
|
and a column carries its own width. A fan that cannot overlap by
|
|
1431
1432
|
construction, across the ring or along the radius; several roots share the
|
|
1432
|
-
circle around an empty centre.
|
|
1433
|
+
circle around an empty centre. Since `7.23.156` a run of three or more
|
|
1434
|
+
**leaf** children is **stacked**, as in the compact tree: it asks its ring
|
|
1435
|
+
for one row of about the square root of its cards instead of one slot per
|
|
1436
|
+
leaf, and lays them in rows going outward, each as full as its room allows
|
|
1437
|
+
— rings round the parent when it is alone, a fan inside its sector when
|
|
1438
|
+
not. Measured over the arc it covers (a card is wider slanted), and a
|
|
1439
|
+
neighbour of the outer rings by the angle it covers, so nothing overlaps.
|
|
1440
|
+
On a real-shaped treedb it is 53–63% of the radial it was; `stack: false`
|
|
1441
|
+
keeps the old one.
|
|
1433
1442
|
|
|
1434
1443
|
**Elbow edges** (`7.23.149`) are an option of the edges, not a layout: the
|
|
1435
1444
|
toolbar's `GRAPH_EDGE_ELBOW` toggle sets `edge_shape` to `elbow`, and every
|
|
@@ -1481,7 +1490,16 @@ port run. Only the stub at the port is shared. Into a lower row of a stack of
|
|
|
1481
1490
|
the compact tree an edge runs a **comb** (`7.23.154`): along the channel to a
|
|
1482
1491
|
lane of its own in the stack's corridor, down it, and into the gap above its
|
|
1483
1492
|
card; lanes go outermost first by row, so none crosses another, and a comb is
|
|
1484
|
-
drawn as laid out, never routed.
|
|
1493
|
+
drawn as laid out, never routed.
|
|
1494
|
+
|
|
1495
|
+
**Curved edges keep off the cards as well** (`7.23.155`). On a layout with
|
|
1496
|
+
rows a curve is `treedb-curve-v` / `-h`, a subclass of G6's cubic: the cubic
|
|
1497
|
+
as before, unless that very curve — the path G6 would draw, sampled, not the
|
|
1498
|
+
rectangle round it — would cross a card other than its own two, or the edge
|
|
1499
|
+
does not run forward and so would cross its own. Then it takes the way its
|
|
1500
|
+
elbow would (comb, detour, route, the same lanes and staggered turns) with
|
|
1501
|
+
corners rounded to 24px. On a layout with no rows the edges stay G6's plain
|
|
1502
|
+
cubic. G6's `shortest-path` router is not used: it is
|
|
1485
1503
|
not exported, it
|
|
1486
1504
|
falls back in silence to a route that crosses cards, and it rewrites its
|
|
1487
1505
|
module defaults with every config it is given.
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -29423,6 +29423,56 @@ function stack_trunk_width(k) {
|
|
|
29423
29423
|
let lanes = Math.max(0, k - 2);
|
|
29424
29424
|
return Math.max(36, 20 + Math.max(0, lanes - 1) * 6);
|
|
29425
29425
|
}
|
|
29426
|
+
/************************************************************
|
|
29427
|
+
* The children of every node, with each run of STACK_MIN_RUN or
|
|
29428
|
+
* more consecutive LEAF children replaced by one STACK. Runs, not
|
|
29429
|
+
* all the leaves of a parent: the children keep their order. A
|
|
29430
|
+
* stack's key is an OBJECT, so it can never be taken for a node id,
|
|
29431
|
+
* which is a string. Shared by the compact tree and the radial.
|
|
29432
|
+
*
|
|
29433
|
+
* Returns {kids_of: Map<id, [id | stack]>, stacks: Map<stack, {ids, depth}>}
|
|
29434
|
+
************************************************************/
|
|
29435
|
+
function leaf_runs(t) {
|
|
29436
|
+
let kids_of = /* @__PURE__ */ new Map();
|
|
29437
|
+
let stacks = /* @__PURE__ */ new Map();
|
|
29438
|
+
for (let [id, kids] of t.children) {
|
|
29439
|
+
let out = [];
|
|
29440
|
+
let run = [];
|
|
29441
|
+
let flush = () => {
|
|
29442
|
+
if (run.length >= 3) {
|
|
29443
|
+
let key = { stack: stacks.size };
|
|
29444
|
+
stacks.set(key, {
|
|
29445
|
+
ids: run,
|
|
29446
|
+
depth: t.depth.get(run[0])
|
|
29447
|
+
});
|
|
29448
|
+
out.push(key);
|
|
29449
|
+
} else out.push(...run);
|
|
29450
|
+
run = [];
|
|
29451
|
+
};
|
|
29452
|
+
for (let kid of kids) if ((t.children.get(kid) || []).length === 0) run.push(kid);
|
|
29453
|
+
else {
|
|
29454
|
+
flush();
|
|
29455
|
+
out.push(kid);
|
|
29456
|
+
}
|
|
29457
|
+
flush();
|
|
29458
|
+
kids_of.set(id, out);
|
|
29459
|
+
}
|
|
29460
|
+
return {
|
|
29461
|
+
kids_of,
|
|
29462
|
+
stacks
|
|
29463
|
+
};
|
|
29464
|
+
}
|
|
29465
|
+
function stacked_order(t, kids_of) {
|
|
29466
|
+
let order = [];
|
|
29467
|
+
let todo = t.roots.slice().reverse();
|
|
29468
|
+
while (todo.length) {
|
|
29469
|
+
let id = todo.pop();
|
|
29470
|
+
order.push(id);
|
|
29471
|
+
let kids = kids_of.get(id) || [];
|
|
29472
|
+
for (let i = kids.length - 1; i >= 0; i--) todo.push(kids[i]);
|
|
29473
|
+
}
|
|
29474
|
+
return order;
|
|
29475
|
+
}
|
|
29426
29476
|
function stack_geometry(t, st, col_x, col_w) {
|
|
29427
29477
|
let d = st.depth;
|
|
29428
29478
|
let k = st.ids.length;
|
|
@@ -29462,38 +29512,8 @@ function place_stack(t, st, g, top, pos) {
|
|
|
29462
29512
|
function compact_tree_lr(nodes, edges, o) {
|
|
29463
29513
|
let t = spanning_tree(nodes, edges);
|
|
29464
29514
|
let pos = /* @__PURE__ */ new Map();
|
|
29465
|
-
let kids_of
|
|
29466
|
-
let
|
|
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
|
-
}
|
|
29515
|
+
let { kids_of, stacks } = leaf_runs(t);
|
|
29516
|
+
let order = stacked_order(t, kids_of);
|
|
29497
29517
|
let col_w = [];
|
|
29498
29518
|
for (let [id, d] of t.depth) col_w[d] = Math.max(col_w[d] || 0, t.by_id.get(id).w);
|
|
29499
29519
|
let col_x = [];
|
|
@@ -29630,56 +29650,103 @@ function extent_at(n, a) {
|
|
|
29630
29650
|
*
|
|
29631
29651
|
* ranksep the step between rings
|
|
29632
29652
|
* nodesep the gap between neighbours on a ring
|
|
29653
|
+
* stack (default true) a run of three or more LEAF children
|
|
29654
|
+
* is a STACK, as in the compact tree: it asks its
|
|
29655
|
+
* ring for one row of about the square root of its
|
|
29656
|
+
* cards, not for every leaf -- a hall with a hundred
|
|
29657
|
+
* devices no longer blows the ring up -- and lays
|
|
29658
|
+
* them in rows going OUTWARD, each row as full as
|
|
29659
|
+
* the room it has: rings round the parent when it is
|
|
29660
|
+
* alone, a fan inside its sector when it is not.
|
|
29661
|
+
* false keeps every leaf on the ring.
|
|
29633
29662
|
************************************************************/
|
|
29634
29663
|
function layout_radial(nodes, edges, opts) {
|
|
29635
|
-
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
29664
|
+
let o = Object.assign({}, DEFAULTS, { stack: true }, opts || {});
|
|
29636
29665
|
let t = spanning_tree(nodes, edges);
|
|
29637
29666
|
let pos = /* @__PURE__ */ new Map();
|
|
29638
29667
|
if (!t.roots.length) return pos;
|
|
29639
|
-
let
|
|
29640
|
-
|
|
29668
|
+
let runs = o.stack ? leaf_runs(t) : {
|
|
29669
|
+
kids_of: t.children,
|
|
29670
|
+
stacks: /* @__PURE__ */ new Map()
|
|
29671
|
+
};
|
|
29672
|
+
let kids_of = runs.kids_of;
|
|
29673
|
+
let stacks = runs.stacks;
|
|
29674
|
+
let order = stacked_order(t, kids_of);
|
|
29675
|
+
for (let st of stacks.values()) {
|
|
29676
|
+
st.per_row = Math.ceil(Math.sqrt(st.ids.length));
|
|
29677
|
+
st.cards = st.ids.map((id) => t.by_id.get(id));
|
|
29678
|
+
}
|
|
29679
|
+
let stack_across = (st, a) => {
|
|
29680
|
+
let w = 0;
|
|
29681
|
+
for (let c of st.cards) w = Math.max(w, extent_at(c, a + Math.PI / 2));
|
|
29682
|
+
return {
|
|
29683
|
+
card: w,
|
|
29684
|
+
row: st.per_row * w + (st.per_row - 1) * o.nodesep
|
|
29685
|
+
};
|
|
29686
|
+
};
|
|
29687
|
+
let widest_along = (cards, a, half) => {
|
|
29688
|
+
let e = 0;
|
|
29689
|
+
for (let k = 0; k <= 16; k++) {
|
|
29690
|
+
let th = a - half + 2 * half * k / 16;
|
|
29691
|
+
for (let c of cards) e = Math.max(e, extent_at(c, th));
|
|
29692
|
+
}
|
|
29693
|
+
return e;
|
|
29694
|
+
};
|
|
29695
|
+
let depth_of = (id) => stacks.has(id) ? stacks.get(id).depth : t.depth.get(id);
|
|
29696
|
+
let circ = (a, b) => {
|
|
29697
|
+
let d = Math.abs(a - b) % (2 * Math.PI);
|
|
29698
|
+
return d > Math.PI ? 2 * Math.PI - d : d;
|
|
29699
|
+
};
|
|
29700
|
+
let weight = /* @__PURE__ */ new Map();
|
|
29641
29701
|
for (let i = order.length - 1; i >= 0; i--) {
|
|
29642
29702
|
let id = order[i];
|
|
29643
|
-
let
|
|
29703
|
+
let st = stacks.get(id);
|
|
29704
|
+
if (st) {
|
|
29705
|
+
weight.set(id, st.per_row);
|
|
29706
|
+
continue;
|
|
29707
|
+
}
|
|
29708
|
+
let kids = kids_of.get(id) || [];
|
|
29644
29709
|
if (!kids.length) {
|
|
29645
|
-
|
|
29710
|
+
weight.set(id, 1);
|
|
29646
29711
|
continue;
|
|
29647
29712
|
}
|
|
29648
29713
|
let n = 0;
|
|
29649
|
-
for (let kid of kids) n +=
|
|
29650
|
-
|
|
29714
|
+
for (let kid of kids) n += weight.get(kid);
|
|
29715
|
+
weight.set(id, n);
|
|
29651
29716
|
}
|
|
29652
29717
|
let total = 0;
|
|
29653
|
-
for (let root of t.roots) total +=
|
|
29718
|
+
for (let root of t.roots) total += weight.get(root);
|
|
29654
29719
|
let single = t.roots.length === 1;
|
|
29655
|
-
let ring_of = (id) =>
|
|
29720
|
+
let ring_of = (id) => depth_of(id) + (single ? 0 : 1);
|
|
29656
29721
|
let angle = /* @__PURE__ */ new Map();
|
|
29657
29722
|
let rings = [];
|
|
29658
29723
|
let sector = (root_id, root_from, root_span, root_parent) => {
|
|
29659
|
-
let
|
|
29724
|
+
let todo = [{
|
|
29660
29725
|
id: root_id,
|
|
29661
29726
|
from: root_from,
|
|
29662
29727
|
span: root_span,
|
|
29663
29728
|
parent: root_parent
|
|
29664
29729
|
}];
|
|
29665
|
-
while (
|
|
29666
|
-
let { id, from, span, parent } =
|
|
29730
|
+
while (todo.length) {
|
|
29731
|
+
let { id, from, span, parent } = todo.pop();
|
|
29667
29732
|
let a = from + span / 2;
|
|
29668
29733
|
angle.set(id, a);
|
|
29669
29734
|
let ring = ring_of(id);
|
|
29670
29735
|
if (!rings[ring]) rings[ring] = [];
|
|
29671
|
-
let
|
|
29736
|
+
let st = stacks.get(id);
|
|
29737
|
+
let n = st ? null : t.by_id.get(id);
|
|
29672
29738
|
rings[ring].push({
|
|
29673
29739
|
id,
|
|
29674
29740
|
angle: a,
|
|
29675
|
-
|
|
29676
|
-
|
|
29677
|
-
|
|
29741
|
+
span,
|
|
29742
|
+
diag: st ? stack_across(st, a).row : Math.hypot(n.w, n.h),
|
|
29743
|
+
ext: st ? widest_along(st.cards, a, Math.min(span / 2, Math.PI)) : extent_at(n, a),
|
|
29744
|
+
parent_ext: !parent ? 0 : st ? widest_along([t.by_id.get(parent)], a, Math.min(span / 2, Math.PI)) : extent_at(t.by_id.get(parent), a)
|
|
29678
29745
|
});
|
|
29679
29746
|
let cursor = from;
|
|
29680
|
-
for (let kid of
|
|
29681
|
-
let part = span *
|
|
29682
|
-
|
|
29747
|
+
for (let kid of kids_of.get(id) || []) {
|
|
29748
|
+
let part = span * weight.get(kid) / weight.get(id);
|
|
29749
|
+
todo.push({
|
|
29683
29750
|
id: kid,
|
|
29684
29751
|
from: cursor,
|
|
29685
29752
|
span: part,
|
|
@@ -29693,38 +29760,120 @@ function layout_radial(nodes, edges, opts) {
|
|
|
29693
29760
|
let root = t.roots[0];
|
|
29694
29761
|
angle.set(root, 0);
|
|
29695
29762
|
let cursor = -Math.PI / 2;
|
|
29696
|
-
for (let kid of
|
|
29697
|
-
let part = 2 * Math.PI *
|
|
29763
|
+
for (let kid of kids_of.get(root) || []) {
|
|
29764
|
+
let part = 2 * Math.PI * weight.get(kid) / weight.get(root);
|
|
29698
29765
|
sector(kid, cursor, part, root);
|
|
29699
29766
|
cursor += part;
|
|
29700
29767
|
}
|
|
29701
29768
|
} else {
|
|
29702
29769
|
let cursor = -Math.PI / 2;
|
|
29703
29770
|
for (let root of t.roots) {
|
|
29704
|
-
let part = 2 * Math.PI *
|
|
29771
|
+
let part = 2 * Math.PI * weight.get(root) / total;
|
|
29705
29772
|
sector(root, cursor, part, null);
|
|
29706
29773
|
cursor += part;
|
|
29707
29774
|
}
|
|
29708
29775
|
}
|
|
29776
|
+
let fit = (list, r0) => {
|
|
29777
|
+
let r = r0;
|
|
29778
|
+
let sorted = list.slice().sort((a, b) => a.angle - b.angle);
|
|
29779
|
+
for (let i = 0; i < sorted.length && sorted.length > 1; i++) {
|
|
29780
|
+
let a = sorted[i];
|
|
29781
|
+
let b = sorted[(i + 1) % sorted.length];
|
|
29782
|
+
let gap = i + 1 < sorted.length ? b.angle - a.angle : b.angle + 2 * Math.PI - a.angle;
|
|
29783
|
+
if (gap > 1e-9) r = Math.max(r, (a.diag / 2 + b.diag / 2 + o.nodesep) / gap);
|
|
29784
|
+
}
|
|
29785
|
+
return r;
|
|
29786
|
+
};
|
|
29709
29787
|
let radius = [0];
|
|
29788
|
+
let reaching = [];
|
|
29710
29789
|
for (let ring = 1; ring < rings.length; ring++) {
|
|
29790
|
+
let members = rings[ring] || [];
|
|
29711
29791
|
let r = radius[ring - 1] + o.ranksep;
|
|
29712
|
-
|
|
29713
|
-
|
|
29714
|
-
|
|
29715
|
-
|
|
29716
|
-
|
|
29717
|
-
|
|
29718
|
-
|
|
29792
|
+
let band = 0;
|
|
29793
|
+
for (let n of members) {
|
|
29794
|
+
r = Math.max(r, radius[ring - 1] + (n.parent_ext + n.ext) / 2 + o.nodesep);
|
|
29795
|
+
band = Math.max(band, n.ext);
|
|
29796
|
+
}
|
|
29797
|
+
r = fit(members, r);
|
|
29798
|
+
for (let pass = 0; pass < 2; pass++) for (let g of reaching) {
|
|
29799
|
+
if (g.reach < r - band / 2 - o.nodesep) continue;
|
|
29800
|
+
for (let m of members) {
|
|
29801
|
+
let d = circ(g.angle, m.angle);
|
|
29802
|
+
if (d > g.half + 1e-9) r = Math.max(r, (m.diag / 2 + o.nodesep) / (d - g.half));
|
|
29803
|
+
else r = Math.max(r, g.reach + m.ext / 2 + o.nodesep);
|
|
29804
|
+
}
|
|
29719
29805
|
}
|
|
29720
29806
|
radius[ring] = r;
|
|
29807
|
+
let sorted = members.slice().sort((a, b) => a.angle - b.angle);
|
|
29808
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
29809
|
+
let m = sorted[i];
|
|
29810
|
+
let st = stacks.get(m.id);
|
|
29811
|
+
if (!st) continue;
|
|
29812
|
+
let room = m.span / 2;
|
|
29813
|
+
if (sorted.length > 1) {
|
|
29814
|
+
let left = sorted[(i - 1 + sorted.length) % sorted.length];
|
|
29815
|
+
let right = sorted[(i + 1) % sorted.length];
|
|
29816
|
+
room = Math.min(room, circ(m.angle, left.angle) - (left.diag / 2 + o.nodesep) / r, circ(m.angle, right.angle) - (right.diag / 2 + o.nodesep) / r);
|
|
29817
|
+
}
|
|
29818
|
+
room = Math.min(room, Math.PI);
|
|
29819
|
+
let across = 0;
|
|
29820
|
+
let along = 0;
|
|
29821
|
+
for (let k = 0; k <= 16; k++) {
|
|
29822
|
+
let th = m.angle - room + 2 * room * k / 16;
|
|
29823
|
+
for (let c of st.cards) {
|
|
29824
|
+
across = Math.max(across, extent_at(c, th + Math.PI / 2));
|
|
29825
|
+
along = Math.max(along, extent_at(c, th));
|
|
29826
|
+
}
|
|
29827
|
+
}
|
|
29828
|
+
let rows = [];
|
|
29829
|
+
let left_to_place = st.ids.length;
|
|
29830
|
+
let rr = r;
|
|
29831
|
+
let half = 0;
|
|
29832
|
+
while (left_to_place > 0) {
|
|
29833
|
+
let fits = Math.floor(2 * room * rr / (across + o.nodesep));
|
|
29834
|
+
let cnt = Math.max(1, Math.min(left_to_place, fits));
|
|
29835
|
+
rows.push({
|
|
29836
|
+
rr,
|
|
29837
|
+
cnt
|
|
29838
|
+
});
|
|
29839
|
+
half = Math.max(half, (cnt * (across + o.nodesep) - o.nodesep) / 2 / rr);
|
|
29840
|
+
left_to_place -= cnt;
|
|
29841
|
+
rr += along + 40;
|
|
29842
|
+
}
|
|
29843
|
+
st.plan = {
|
|
29844
|
+
angle: m.angle,
|
|
29845
|
+
across,
|
|
29846
|
+
rows
|
|
29847
|
+
};
|
|
29848
|
+
reaching.push({
|
|
29849
|
+
angle: m.angle,
|
|
29850
|
+
half,
|
|
29851
|
+
reach: rows[rows.length - 1].rr + along / 2
|
|
29852
|
+
});
|
|
29853
|
+
}
|
|
29721
29854
|
}
|
|
29722
29855
|
for (let [id, a] of angle) {
|
|
29723
|
-
let
|
|
29724
|
-
|
|
29725
|
-
|
|
29726
|
-
|
|
29727
|
-
|
|
29856
|
+
let st = stacks.get(id);
|
|
29857
|
+
if (!st) {
|
|
29858
|
+
let r0 = radius[ring_of(id)] || 0;
|
|
29859
|
+
pos.set(id, {
|
|
29860
|
+
x: r0 * Math.cos(a),
|
|
29861
|
+
y: r0 * Math.sin(a)
|
|
29862
|
+
});
|
|
29863
|
+
continue;
|
|
29864
|
+
}
|
|
29865
|
+
let i = 0;
|
|
29866
|
+
for (let row of st.plan.rows) {
|
|
29867
|
+
let step = (st.plan.across + o.nodesep) / row.rr;
|
|
29868
|
+
for (let j = 0; j < row.cnt; j++) {
|
|
29869
|
+
let th = a + (j - (row.cnt - 1) / 2) * step;
|
|
29870
|
+
pos.set(st.ids[i], {
|
|
29871
|
+
x: row.rr * Math.cos(th),
|
|
29872
|
+
y: row.rr * Math.sin(th)
|
|
29873
|
+
});
|
|
29874
|
+
i++;
|
|
29875
|
+
}
|
|
29876
|
+
}
|
|
29728
29877
|
}
|
|
29729
29878
|
return pos;
|
|
29730
29879
|
}
|
|
@@ -30168,6 +30317,112 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
|
|
|
30168
30317
|
if (!route && near.length < others.length) route = orth_search(a, z, others.map((b) => box_expand(b, m)));
|
|
30169
30318
|
return route || simple;
|
|
30170
30319
|
}
|
|
30320
|
+
function path_points(path) {
|
|
30321
|
+
let pts = [];
|
|
30322
|
+
let cur = null;
|
|
30323
|
+
for (let c of path) if (c[0] === "M" || c[0] === "L") {
|
|
30324
|
+
cur = [c[1], c[2]];
|
|
30325
|
+
pts.push(cur);
|
|
30326
|
+
} else if (c[0] === "C" && cur) {
|
|
30327
|
+
let [x0, y0] = cur;
|
|
30328
|
+
for (let k = 1; k <= 16; k++) {
|
|
30329
|
+
let u = k / 16;
|
|
30330
|
+
let v = 1 - u;
|
|
30331
|
+
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]]);
|
|
30332
|
+
}
|
|
30333
|
+
cur = [c[5], c[6]];
|
|
30334
|
+
} else if (c[0] === "Q" && cur) {
|
|
30335
|
+
let [x0, y0] = cur;
|
|
30336
|
+
for (let k = 1; k <= 16; k++) {
|
|
30337
|
+
let u = k / 16;
|
|
30338
|
+
let v = 1 - u;
|
|
30339
|
+
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]]);
|
|
30340
|
+
}
|
|
30341
|
+
cur = [c[3], c[4]];
|
|
30342
|
+
}
|
|
30343
|
+
return pts;
|
|
30344
|
+
}
|
|
30345
|
+
/************************************************************
|
|
30346
|
+
* Does the G6 path `path` of a curved edge cross a card other than
|
|
30347
|
+
* its own two? Measured on the curve itself -- the path G6 would
|
|
30348
|
+
* draw, sampled -- and not on the rectangle round it, which took
|
|
30349
|
+
* every card the curve merely passed near: the ports of a row
|
|
30350
|
+
* stick well into the space above it. Its own two cards are left
|
|
30351
|
+
* out: the curve starts and ends on their ports.
|
|
30352
|
+
************************************************************/
|
|
30353
|
+
function curve_hits(path, boxes, box_s, box_t) {
|
|
30354
|
+
let pts = path_points(path);
|
|
30355
|
+
if (pts.length < 2) return false;
|
|
30356
|
+
let bb = {
|
|
30357
|
+
x1: Infinity,
|
|
30358
|
+
y1: Infinity,
|
|
30359
|
+
x2: -Infinity,
|
|
30360
|
+
y2: -Infinity
|
|
30361
|
+
};
|
|
30362
|
+
for (let p of pts) {
|
|
30363
|
+
bb.x1 = Math.min(bb.x1, p[0]);
|
|
30364
|
+
bb.y1 = Math.min(bb.y1, p[1]);
|
|
30365
|
+
bb.x2 = Math.max(bb.x2, p[0]);
|
|
30366
|
+
bb.y2 = Math.max(bb.y2, p[1]);
|
|
30367
|
+
}
|
|
30368
|
+
for (let b of boxes || []) {
|
|
30369
|
+
if (same_box(b, box_s) || same_box(b, box_t) || !box_overlaps(b, box_expand(bb, 1))) continue;
|
|
30370
|
+
let inner = box_expand(b, -1);
|
|
30371
|
+
for (let k = 0; k + 1 < pts.length; k++) if (segment_hits(pts[k], pts[k + 1], inner)) return true;
|
|
30372
|
+
}
|
|
30373
|
+
return false;
|
|
30374
|
+
}
|
|
30375
|
+
/************************************************************
|
|
30376
|
+
* A G6 path (['M'|'L'|'Q', ...]) along `points` with every corner
|
|
30377
|
+
* rounded -- by `radius`, or by half the shorter of its two
|
|
30378
|
+
* segments, so a short run is never overshot. The rounding is the
|
|
30379
|
+
* quadratic G6's own polyline uses.
|
|
30380
|
+
************************************************************/
|
|
30381
|
+
function rounded_path(points, radius) {
|
|
30382
|
+
let path = [[
|
|
30383
|
+
"M",
|
|
30384
|
+
points[0][0],
|
|
30385
|
+
points[0][1]
|
|
30386
|
+
]];
|
|
30387
|
+
for (let i = 1; i + 1 < points.length; i++) {
|
|
30388
|
+
let a = points[i - 1];
|
|
30389
|
+
let m = points[i];
|
|
30390
|
+
let b = points[i + 1];
|
|
30391
|
+
let len_in = Math.hypot(m[0] - a[0], m[1] - a[1]);
|
|
30392
|
+
let len_out = Math.hypot(b[0] - m[0], b[1] - m[1]);
|
|
30393
|
+
let r = Math.min(radius, len_in / 2, len_out / 2);
|
|
30394
|
+
let collinear = Math.abs((m[0] - a[0]) * (b[1] - m[1]) - (m[1] - a[1]) * (b[0] - m[0])) < 1e-9;
|
|
30395
|
+
if (r <= 0 || collinear) {
|
|
30396
|
+
path.push([
|
|
30397
|
+
"L",
|
|
30398
|
+
m[0],
|
|
30399
|
+
m[1]
|
|
30400
|
+
]);
|
|
30401
|
+
continue;
|
|
30402
|
+
}
|
|
30403
|
+
let p1 = [m[0] - (m[0] - a[0]) / len_in * r, m[1] - (m[1] - a[1]) / len_in * r];
|
|
30404
|
+
let p2 = [m[0] + (b[0] - m[0]) / len_out * r, m[1] + (b[1] - m[1]) / len_out * r];
|
|
30405
|
+
path.push([
|
|
30406
|
+
"L",
|
|
30407
|
+
p1[0],
|
|
30408
|
+
p1[1]
|
|
30409
|
+
]);
|
|
30410
|
+
path.push([
|
|
30411
|
+
"Q",
|
|
30412
|
+
m[0],
|
|
30413
|
+
m[1],
|
|
30414
|
+
p2[0],
|
|
30415
|
+
p2[1]
|
|
30416
|
+
]);
|
|
30417
|
+
}
|
|
30418
|
+
let last = points[points.length - 1];
|
|
30419
|
+
path.push([
|
|
30420
|
+
"L",
|
|
30421
|
+
last[0],
|
|
30422
|
+
last[1]
|
|
30423
|
+
]);
|
|
30424
|
+
return path;
|
|
30425
|
+
}
|
|
30171
30426
|
//#endregion
|
|
30172
30427
|
//#region node_modules/@babel/runtime/helpers/esm/typeof.js
|
|
30173
30428
|
function _typeof(o) {
|
|
@@ -55055,7 +55310,7 @@ Easing Functions from anime.js, they are tried and true, so, its better to use t
|
|
|
55055
55310
|
var Quad = function Quad(t) {
|
|
55056
55311
|
return Math.pow(t, 2);
|
|
55057
55312
|
};
|
|
55058
|
-
var Cubic = function Cubic(t) {
|
|
55313
|
+
var Cubic$1 = function Cubic(t) {
|
|
55059
55314
|
return Math.pow(t, 3);
|
|
55060
55315
|
};
|
|
55061
55316
|
var Quart = function Quart(t) {
|
|
@@ -55192,10 +55447,10 @@ var EasingFunctions = {
|
|
|
55192
55447
|
"out-quad": EaseOut(Quad),
|
|
55193
55448
|
"in-out-quad": EaseInOut(Quad),
|
|
55194
55449
|
"out-in-quad": EaseOutIn(Quad),
|
|
55195
|
-
"in-cubic": Cubic,
|
|
55196
|
-
"out-cubic": EaseOut(Cubic),
|
|
55197
|
-
"in-out-cubic": EaseInOut(Cubic),
|
|
55198
|
-
"out-in-cubic": EaseOutIn(Cubic),
|
|
55450
|
+
"in-cubic": Cubic$1,
|
|
55451
|
+
"out-cubic": EaseOut(Cubic$1),
|
|
55452
|
+
"in-out-cubic": EaseInOut(Cubic$1),
|
|
55453
|
+
"out-in-cubic": EaseOutIn(Cubic$1),
|
|
55199
55454
|
"in-quart": Quart,
|
|
55200
55455
|
"out-quart": EaseOut(Quart),
|
|
55201
55456
|
"in-out-quart": EaseInOut(Quart),
|
|
@@ -57368,6 +57623,8 @@ function register_layouts(gobj) {
|
|
|
57368
57623
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-compact", TreedbCompactLayout);
|
|
57369
57624
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-v", TreedbElbowV);
|
|
57370
57625
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-h", TreedbElbowH);
|
|
57626
|
+
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-curve-v", TreedbCurveV);
|
|
57627
|
+
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-curve-h", TreedbCurveH);
|
|
57371
57628
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
|
|
57372
57629
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
|
|
57373
57630
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "treedb-card", TreedbCard);
|
|
@@ -58062,7 +58319,9 @@ function layout_direction(gobj) {
|
|
|
58062
58319
|
function edge_type_for(gobj) {
|
|
58063
58320
|
let lr = layout_direction(gobj) === "LR";
|
|
58064
58321
|
let rowless = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "rowless_layouts") || [];
|
|
58065
|
-
|
|
58322
|
+
let rows = !(0, _yuneta_gobj_js.str_in_list)(rowless, gobj.priv.layout);
|
|
58323
|
+
if (rows && (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow") return lr ? "treedb-elbow-h" : "treedb-elbow-v";
|
|
58324
|
+
if (rows) return lr ? "treedb-curve-h" : "treedb-curve-v";
|
|
58066
58325
|
return lr ? "cubic-horizontal" : "cubic";
|
|
58067
58326
|
}
|
|
58068
58327
|
/************************************************************
|
|
@@ -59666,6 +59925,40 @@ var TreedbElbowH = class extends _antv_g6.Polyline {
|
|
|
59666
59925
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|
|
59667
59926
|
}
|
|
59668
59927
|
};
|
|
59928
|
+
/************************************************************
|
|
59929
|
+
* A CURVED edge that keeps off the cards. G6's cubic, as before,
|
|
59930
|
+
* unless that very curve -- sampled, not guessed from the
|
|
59931
|
+
* rectangle round it -- would cross a card other than its own two,
|
|
59932
|
+
* or when it does not run forward and so would cross its own:
|
|
59933
|
+
* the card above a lower row of a stack, a row between a parent
|
|
59934
|
+
* and a far child. Then it goes the way an elbow would (the comb,
|
|
59935
|
+
* the detour, the route: the same lanes and staggered turns) with
|
|
59936
|
+
* round corners, so it still reads as a curve. `-v` for rows
|
|
59937
|
+
* stacked top to bottom, `-h` for columns.
|
|
59938
|
+
************************************************************/
|
|
59939
|
+
function curve_key_path(edge, attributes, vertical, plain) {
|
|
59940
|
+
let [s, t] = edge.getEndpoints(attributes, false);
|
|
59941
|
+
let along = vertical ? 1 : 0;
|
|
59942
|
+
let box_s = elbow_box(edge.sourceNode);
|
|
59943
|
+
let box_t = elbow_box(edge.targetNode);
|
|
59944
|
+
let boxes = elbow_obstacles(edge);
|
|
59945
|
+
if (t[along] - s[along] > 20 && !curve_hits(plain, boxes, box_s, box_t)) return plain;
|
|
59946
|
+
return rounded_path([
|
|
59947
|
+
s,
|
|
59948
|
+
...elbow_route(s, t, box_s, box_t, elbow_lane_of(edge), vertical, boxes, elbow_stagger_of(edge, vertical)),
|
|
59949
|
+
t
|
|
59950
|
+
], 24);
|
|
59951
|
+
}
|
|
59952
|
+
var TreedbCurveV = class extends _antv_g6.Cubic {
|
|
59953
|
+
getKeyPath(attributes) {
|
|
59954
|
+
return curve_key_path(this, attributes, true, super.getKeyPath(attributes));
|
|
59955
|
+
}
|
|
59956
|
+
};
|
|
59957
|
+
var TreedbCurveH = class extends _antv_g6.CubicHorizontal {
|
|
59958
|
+
getKeyPath(attributes) {
|
|
59959
|
+
return curve_key_path(this, attributes, false, super.getKeyPath(attributes));
|
|
59960
|
+
}
|
|
59961
|
+
};
|
|
59669
59962
|
var TreedbCompactLayout = class extends _antv_g6.BaseLayout {
|
|
59670
59963
|
async execute(data, options) {
|
|
59671
59964
|
let input = treedb_layout_input(data);
|