@yuneta/gobj-ui 7.23.156 → 7.23.157
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 +6 -57
- package/dist/gobj-ui.cjs.js +55 -877
- package/dist/gobj-ui.es.js +56 -878
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +10 -148
- package/src/c_yui_treedb_graph.js +0 -2
- package/src/treedb_elbow.js +13 -344
- package/src/treedb_elbow.test.js +1 -236
- package/src/treedb_layout.js +39 -620
- package/src/treedb_layout.test.js +3 -269
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -29314,321 +29314,6 @@ function tidy_tree_lr(nodes, edges, o) {
|
|
|
29314
29314
|
}
|
|
29315
29315
|
return pos;
|
|
29316
29316
|
}
|
|
29317
|
-
/************************************************************
|
|
29318
|
-
* The compact tree.
|
|
29319
|
-
*
|
|
29320
|
-
* The tidy tree above gives every subtree its whole BLOCK: open a
|
|
29321
|
-
* hall with twenty-four devices and its block widens, and with it
|
|
29322
|
-
* every block above it, so the siblings of its ancestors move apart
|
|
29323
|
-
* at depths where nothing of theirs touches. This one keeps the
|
|
29324
|
-
* CONTOUR of each subtree instead -- its outline on each side, depth
|
|
29325
|
-
* by depth -- and slides every sibling against the outline of the
|
|
29326
|
-
* ones before it. A folded region then sits as close to an open one
|
|
29327
|
-
* as their cards allow at each depth, which is what a folded treedb
|
|
29328
|
-
* is: one branch open among closed ones.
|
|
29329
|
-
*
|
|
29330
|
-
* Same spanning tree, same order, same rows as the tidy tree: only
|
|
29331
|
-
* the packing across the depths differs, so switching between the
|
|
29332
|
-
* two moves cards sideways and never reorders them.
|
|
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
|
-
*
|
|
29342
|
-
* The contour arithmetic is Moen's ("Drawing dynamic trees", IEEE
|
|
29343
|
-
* Software, 1990) in the form mxGraph gave it in mxCompactTreeLayout
|
|
29344
|
-
* -- Copyright (c) 2006-2015 JGraph Ltd, Apache License 2.0 -- read in
|
|
29345
|
-
* maxGraph's CompactTreeLayout.ts: leaf, join, merge, offset and
|
|
29346
|
-
* bridge below follow that form. What is ours: it runs on the
|
|
29347
|
-
* spanning tree of a FOREST, every depth is a row as wide as its
|
|
29348
|
-
* widest card (mxGraph's `alignRanks`), several roots sit side by
|
|
29349
|
-
* side, and there is no recursion.
|
|
29350
|
-
************************************************************/
|
|
29351
|
-
function layout_compact(nodes, edges, opts) {
|
|
29352
|
-
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
29353
|
-
if (o.direction === "LR") return compact_tree_lr(nodes, edges, o);
|
|
29354
|
-
let lr = compact_tree_lr(nodes.map((n) => Object.assign({}, n, {
|
|
29355
|
-
w: n.h,
|
|
29356
|
-
h: n.w
|
|
29357
|
-
})), edges, o);
|
|
29358
|
-
let pos = /* @__PURE__ */ new Map();
|
|
29359
|
-
for (let [id, p] of lr) pos.set(id, {
|
|
29360
|
-
x: p.y,
|
|
29361
|
-
y: p.x
|
|
29362
|
-
});
|
|
29363
|
-
return pos;
|
|
29364
|
-
}
|
|
29365
|
-
function contour_line(dx, dy, next) {
|
|
29366
|
-
return {
|
|
29367
|
-
dx,
|
|
29368
|
-
dy,
|
|
29369
|
-
next: next || null
|
|
29370
|
-
};
|
|
29371
|
-
}
|
|
29372
|
-
function contour_offset(p1, p2, a1, a2, b1, b2) {
|
|
29373
|
-
if (b1 <= p1 || p1 + a1 <= 0) return 0;
|
|
29374
|
-
let d;
|
|
29375
|
-
if (b1 * a2 - a1 * b2 > 0) {
|
|
29376
|
-
if (p1 < 0) d = p1 * a2 / a1 - p2;
|
|
29377
|
-
else if (p1 > 0) d = p1 * b2 / b1 - p2;
|
|
29378
|
-
else d = -p2;
|
|
29379
|
-
} else if (b1 < p1 + a1) d = b2 - (p2 + (b1 - p1) * a2 / a1);
|
|
29380
|
-
else if (b1 > p1 + a1) d = (a1 + p1) * b2 / b1 - (p2 + a2);
|
|
29381
|
-
else d = b2 - (p2 + a2);
|
|
29382
|
-
return d > 0 ? d : 0;
|
|
29383
|
-
}
|
|
29384
|
-
function contour_bridge(line1, x1, y1, line2, x2, y2) {
|
|
29385
|
-
let dx = x2 + line2.dx - x1;
|
|
29386
|
-
let dy = line2.dx === 0 ? line2.dy : dx * line2.dy / line2.dx;
|
|
29387
|
-
let r = contour_line(dx, dy, line2.next);
|
|
29388
|
-
line1.next = contour_line(0, y2 + line2.dy - dy - y1, r);
|
|
29389
|
-
return r;
|
|
29390
|
-
}
|
|
29391
|
-
function contour_merge(p1, p2) {
|
|
29392
|
-
let x = 0;
|
|
29393
|
-
let y = 0;
|
|
29394
|
-
let total = 0;
|
|
29395
|
-
let upper = p1.lower_head;
|
|
29396
|
-
let lower = p2.upper_head;
|
|
29397
|
-
while (lower && upper) {
|
|
29398
|
-
let d = contour_offset(x, y, lower.dx, lower.dy, upper.dx, upper.dy);
|
|
29399
|
-
y += d;
|
|
29400
|
-
total += d;
|
|
29401
|
-
if (x + lower.dx <= upper.dx) {
|
|
29402
|
-
x += lower.dx;
|
|
29403
|
-
y += lower.dy;
|
|
29404
|
-
lower = lower.next;
|
|
29405
|
-
} else {
|
|
29406
|
-
x -= upper.dx;
|
|
29407
|
-
y -= upper.dy;
|
|
29408
|
-
upper = upper.next;
|
|
29409
|
-
}
|
|
29410
|
-
}
|
|
29411
|
-
if (lower) {
|
|
29412
|
-
let b = contour_bridge(p1.upper_tail, 0, 0, lower, x, y);
|
|
29413
|
-
p1.upper_tail = b.next ? p2.upper_tail : b;
|
|
29414
|
-
p1.lower_tail = p2.lower_tail;
|
|
29415
|
-
} else {
|
|
29416
|
-
let b = contour_bridge(p2.lower_tail, x, y, upper, 0, 0);
|
|
29417
|
-
if (!b.next) p1.lower_tail = b;
|
|
29418
|
-
}
|
|
29419
|
-
p1.lower_head = p2.lower_head;
|
|
29420
|
-
return total;
|
|
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
|
-
/************************************************************
|
|
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
|
-
}
|
|
29476
|
-
function stack_geometry(t, st, col_x, col_w) {
|
|
29477
|
-
let d = st.depth;
|
|
29478
|
-
let k = st.ids.length;
|
|
29479
|
-
let rows = Math.ceil(k / 2);
|
|
29480
|
-
let side = [0, 0];
|
|
29481
|
-
let row_len = [];
|
|
29482
|
-
for (let i = 0; i < k; i++) {
|
|
29483
|
-
let n = t.by_id.get(st.ids[i]);
|
|
29484
|
-
let r = Math.floor(i / 2);
|
|
29485
|
-
side[i % 2] = Math.max(side[i % 2], n.h);
|
|
29486
|
-
row_len[r] = Math.max(row_len[r] || 0, n.w);
|
|
29487
|
-
}
|
|
29488
|
-
row_len[0] = col_w[d];
|
|
29489
|
-
let trunk = stack_trunk_width(k);
|
|
29490
|
-
let starts = [col_x[d]];
|
|
29491
|
-
for (let r = 1; r < rows; r++) starts[r] = starts[r - 1] + row_len[r - 1] + 40;
|
|
29492
|
-
return {
|
|
29493
|
-
side,
|
|
29494
|
-
trunk,
|
|
29495
|
-
starts,
|
|
29496
|
-
row_len,
|
|
29497
|
-
len: starts[rows - 1] + row_len[rows - 1] - col_x[d],
|
|
29498
|
-
ext: side[0] + trunk + side[1]
|
|
29499
|
-
};
|
|
29500
|
-
}
|
|
29501
|
-
function place_stack(t, st, g, top, pos) {
|
|
29502
|
-
for (let i = 0; i < st.ids.length; i++) {
|
|
29503
|
-
let n = t.by_id.get(st.ids[i]);
|
|
29504
|
-
let r = Math.floor(i / 2);
|
|
29505
|
-
let across = i % 2 === 0 ? top + g.side[0] - n.h / 2 : top + g.side[0] + g.trunk + n.h / 2;
|
|
29506
|
-
pos.set(st.ids[i], {
|
|
29507
|
-
x: g.starts[r] + g.row_len[r] / 2,
|
|
29508
|
-
y: across
|
|
29509
|
-
});
|
|
29510
|
-
}
|
|
29511
|
-
}
|
|
29512
|
-
function compact_tree_lr(nodes, edges, o) {
|
|
29513
|
-
let t = spanning_tree(nodes, edges);
|
|
29514
|
-
let pos = /* @__PURE__ */ new Map();
|
|
29515
|
-
let { kids_of, stacks } = leaf_runs(t);
|
|
29516
|
-
let order = stacked_order(t, kids_of);
|
|
29517
|
-
let col_w = [];
|
|
29518
|
-
for (let [id, d] of t.depth) col_w[d] = Math.max(col_w[d] || 0, t.by_id.get(id).w);
|
|
29519
|
-
let col_x = [];
|
|
29520
|
-
let x = 0;
|
|
29521
|
-
for (let d = 0; d < col_w.length; d++) {
|
|
29522
|
-
col_x[d] = x;
|
|
29523
|
-
x += (col_w[d] || 0) + o.ranksep;
|
|
29524
|
-
}
|
|
29525
|
-
let pad = o.nodesep / 2;
|
|
29526
|
-
let dist = o.nodesep;
|
|
29527
|
-
let level_distance = o.ranksep - pad;
|
|
29528
|
-
let tn = /* @__PURE__ */ new Map();
|
|
29529
|
-
for (let id of order) {
|
|
29530
|
-
let st = stacks.get(id);
|
|
29531
|
-
if (st) {
|
|
29532
|
-
let g = stack_geometry(t, st, col_x, col_w);
|
|
29533
|
-
tn.set(id, {
|
|
29534
|
-
len: g.len,
|
|
29535
|
-
ext: g.ext,
|
|
29536
|
-
geom: g,
|
|
29537
|
-
off_x: 0,
|
|
29538
|
-
off_y: 0,
|
|
29539
|
-
y: 0,
|
|
29540
|
-
contour: null
|
|
29541
|
-
});
|
|
29542
|
-
} else tn.set(id, {
|
|
29543
|
-
len: col_w[t.depth.get(id)],
|
|
29544
|
-
ext: t.by_id.get(id).h,
|
|
29545
|
-
off_x: 0,
|
|
29546
|
-
off_y: 0,
|
|
29547
|
-
y: 0,
|
|
29548
|
-
contour: null
|
|
29549
|
-
});
|
|
29550
|
-
}
|
|
29551
|
-
for (let i = order.length - 1; i >= 0; i--) {
|
|
29552
|
-
let id = order[i];
|
|
29553
|
-
let n = tn.get(id);
|
|
29554
|
-
let kids = kids_of.get(id) || [];
|
|
29555
|
-
if (!kids.length) {
|
|
29556
|
-
let upper = contour_line(n.len + dist, 0);
|
|
29557
|
-
let lower_tail = contour_line(0, -n.ext - dist);
|
|
29558
|
-
n.contour = {
|
|
29559
|
-
upper_head: upper,
|
|
29560
|
-
upper_tail: upper,
|
|
29561
|
-
lower_tail,
|
|
29562
|
-
lower_head: contour_line(n.len + dist, 0, lower_tail)
|
|
29563
|
-
};
|
|
29564
|
-
continue;
|
|
29565
|
-
}
|
|
29566
|
-
let first = tn.get(kids[0]);
|
|
29567
|
-
n.contour = first.contour;
|
|
29568
|
-
let h = first.ext + dist;
|
|
29569
|
-
let span = h;
|
|
29570
|
-
for (let k = 1; k < kids.length; k++) {
|
|
29571
|
-
let kid = tn.get(kids[k]);
|
|
29572
|
-
let d = contour_merge(n.contour, kid.contour);
|
|
29573
|
-
kid.off_y = d + h;
|
|
29574
|
-
kid.off_x = 0;
|
|
29575
|
-
h = kid.ext + dist;
|
|
29576
|
-
span += d + h;
|
|
29577
|
-
}
|
|
29578
|
-
let gap = pad + level_distance;
|
|
29579
|
-
let y2 = (span - n.ext) / 2 - pad;
|
|
29580
|
-
let y1 = y2 + n.ext + 2 * pad - span;
|
|
29581
|
-
first.off_x = gap + n.len;
|
|
29582
|
-
first.off_y = y1;
|
|
29583
|
-
n.contour.upper_head = contour_line(n.len, 0, contour_line(gap, y1, n.contour.upper_head));
|
|
29584
|
-
n.contour.lower_head = contour_line(n.len, 0, contour_line(gap, y2, n.contour.lower_head));
|
|
29585
|
-
}
|
|
29586
|
-
let root_of = /* @__PURE__ */ new Map();
|
|
29587
|
-
for (let id of order) {
|
|
29588
|
-
let n = tn.get(id);
|
|
29589
|
-
if (!root_of.has(id)) root_of.set(id, id);
|
|
29590
|
-
let kids = kids_of.get(id) || [];
|
|
29591
|
-
if (!kids.length) continue;
|
|
29592
|
-
let running = n.y + tn.get(kids[0]).off_y;
|
|
29593
|
-
tn.get(kids[0]).y = running;
|
|
29594
|
-
root_of.set(kids[0], root_of.get(id));
|
|
29595
|
-
for (let k = 1; k < kids.length; k++) {
|
|
29596
|
-
let kid = tn.get(kids[k]);
|
|
29597
|
-
kid.y = running + kid.off_y;
|
|
29598
|
-
running = kid.y;
|
|
29599
|
-
root_of.set(kids[k], root_of.get(id));
|
|
29600
|
-
}
|
|
29601
|
-
}
|
|
29602
|
-
let lo = /* @__PURE__ */ new Map();
|
|
29603
|
-
let hi = /* @__PURE__ */ new Map();
|
|
29604
|
-
for (let id of order) {
|
|
29605
|
-
let r = root_of.get(id);
|
|
29606
|
-
let n = tn.get(id);
|
|
29607
|
-
lo.set(r, Math.min(lo.has(r) ? lo.get(r) : Infinity, n.y));
|
|
29608
|
-
hi.set(r, Math.max(hi.has(r) ? hi.get(r) : -Infinity, n.y + n.ext));
|
|
29609
|
-
}
|
|
29610
|
-
let shift = /* @__PURE__ */ new Map();
|
|
29611
|
-
let top = 0;
|
|
29612
|
-
for (let r of t.roots) {
|
|
29613
|
-
shift.set(r, top - lo.get(r));
|
|
29614
|
-
top += hi.get(r) - lo.get(r) + o.nodesep * 2;
|
|
29615
|
-
}
|
|
29616
|
-
for (let id of order) {
|
|
29617
|
-
let n = tn.get(id);
|
|
29618
|
-
let y = n.y + shift.get(root_of.get(id));
|
|
29619
|
-
let st = stacks.get(id);
|
|
29620
|
-
if (st) {
|
|
29621
|
-
place_stack(t, st, n.geom, y, pos);
|
|
29622
|
-
continue;
|
|
29623
|
-
}
|
|
29624
|
-
let d = t.depth.get(id);
|
|
29625
|
-
pos.set(id, {
|
|
29626
|
-
x: col_x[d] + col_w[d] / 2,
|
|
29627
|
-
y: y + n.ext / 2
|
|
29628
|
-
});
|
|
29629
|
-
}
|
|
29630
|
-
return pos;
|
|
29631
|
-
}
|
|
29632
29317
|
function extent_at(n, a) {
|
|
29633
29318
|
if (!n) return 0;
|
|
29634
29319
|
return Math.abs(n.w * Math.cos(a)) + Math.abs(n.h * Math.sin(a));
|
|
@@ -29650,103 +29335,56 @@ function extent_at(n, a) {
|
|
|
29650
29335
|
*
|
|
29651
29336
|
* ranksep the step between rings
|
|
29652
29337
|
* 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.
|
|
29662
29338
|
************************************************************/
|
|
29663
29339
|
function layout_radial(nodes, edges, opts) {
|
|
29664
|
-
let o = Object.assign({}, DEFAULTS,
|
|
29340
|
+
let o = Object.assign({}, DEFAULTS, opts || {});
|
|
29665
29341
|
let t = spanning_tree(nodes, edges);
|
|
29666
29342
|
let pos = /* @__PURE__ */ new Map();
|
|
29667
29343
|
if (!t.roots.length) return pos;
|
|
29668
|
-
let
|
|
29669
|
-
|
|
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();
|
|
29344
|
+
let order = walk_order(t);
|
|
29345
|
+
let leaves = /* @__PURE__ */ new Map();
|
|
29701
29346
|
for (let i = order.length - 1; i >= 0; i--) {
|
|
29702
29347
|
let id = order[i];
|
|
29703
|
-
let
|
|
29704
|
-
if (st) {
|
|
29705
|
-
weight.set(id, st.per_row);
|
|
29706
|
-
continue;
|
|
29707
|
-
}
|
|
29708
|
-
let kids = kids_of.get(id) || [];
|
|
29348
|
+
let kids = t.children.get(id) || [];
|
|
29709
29349
|
if (!kids.length) {
|
|
29710
|
-
|
|
29350
|
+
leaves.set(id, 1);
|
|
29711
29351
|
continue;
|
|
29712
29352
|
}
|
|
29713
29353
|
let n = 0;
|
|
29714
|
-
for (let kid of kids) n +=
|
|
29715
|
-
|
|
29354
|
+
for (let kid of kids) n += leaves.get(kid);
|
|
29355
|
+
leaves.set(id, n);
|
|
29716
29356
|
}
|
|
29717
29357
|
let total = 0;
|
|
29718
|
-
for (let root of t.roots) total +=
|
|
29358
|
+
for (let root of t.roots) total += leaves.get(root);
|
|
29719
29359
|
let single = t.roots.length === 1;
|
|
29720
|
-
let ring_of = (id) =>
|
|
29360
|
+
let ring_of = (id) => t.depth.get(id) + (single ? 0 : 1);
|
|
29721
29361
|
let angle = /* @__PURE__ */ new Map();
|
|
29722
29362
|
let rings = [];
|
|
29723
29363
|
let sector = (root_id, root_from, root_span, root_parent) => {
|
|
29724
|
-
let
|
|
29364
|
+
let stack = [{
|
|
29725
29365
|
id: root_id,
|
|
29726
29366
|
from: root_from,
|
|
29727
29367
|
span: root_span,
|
|
29728
29368
|
parent: root_parent
|
|
29729
29369
|
}];
|
|
29730
|
-
while (
|
|
29731
|
-
let { id, from, span, parent } =
|
|
29370
|
+
while (stack.length) {
|
|
29371
|
+
let { id, from, span, parent } = stack.pop();
|
|
29732
29372
|
let a = from + span / 2;
|
|
29733
29373
|
angle.set(id, a);
|
|
29734
29374
|
let ring = ring_of(id);
|
|
29735
29375
|
if (!rings[ring]) rings[ring] = [];
|
|
29736
|
-
let
|
|
29737
|
-
let n = st ? null : t.by_id.get(id);
|
|
29376
|
+
let n = t.by_id.get(id);
|
|
29738
29377
|
rings[ring].push({
|
|
29739
29378
|
id,
|
|
29740
29379
|
angle: a,
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
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)
|
|
29380
|
+
diag: Math.hypot(n.w, n.h),
|
|
29381
|
+
ext: extent_at(n, a),
|
|
29382
|
+
parent_ext: parent ? extent_at(t.by_id.get(parent), a) : 0
|
|
29745
29383
|
});
|
|
29746
29384
|
let cursor = from;
|
|
29747
|
-
for (let kid of
|
|
29748
|
-
let part = span *
|
|
29749
|
-
|
|
29385
|
+
for (let kid of t.children.get(id) || []) {
|
|
29386
|
+
let part = span * leaves.get(kid) / leaves.get(id);
|
|
29387
|
+
stack.push({
|
|
29750
29388
|
id: kid,
|
|
29751
29389
|
from: cursor,
|
|
29752
29390
|
span: part,
|
|
@@ -29760,120 +29398,38 @@ function layout_radial(nodes, edges, opts) {
|
|
|
29760
29398
|
let root = t.roots[0];
|
|
29761
29399
|
angle.set(root, 0);
|
|
29762
29400
|
let cursor = -Math.PI / 2;
|
|
29763
|
-
for (let kid of
|
|
29764
|
-
let part = 2 * Math.PI *
|
|
29401
|
+
for (let kid of t.children.get(root) || []) {
|
|
29402
|
+
let part = 2 * Math.PI * leaves.get(kid) / leaves.get(root);
|
|
29765
29403
|
sector(kid, cursor, part, root);
|
|
29766
29404
|
cursor += part;
|
|
29767
29405
|
}
|
|
29768
29406
|
} else {
|
|
29769
29407
|
let cursor = -Math.PI / 2;
|
|
29770
29408
|
for (let root of t.roots) {
|
|
29771
|
-
let part = 2 * Math.PI *
|
|
29409
|
+
let part = 2 * Math.PI * leaves.get(root) / total;
|
|
29772
29410
|
sector(root, cursor, part, null);
|
|
29773
29411
|
cursor += part;
|
|
29774
29412
|
}
|
|
29775
29413
|
}
|
|
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
|
-
};
|
|
29787
29414
|
let radius = [0];
|
|
29788
|
-
let reaching = [];
|
|
29789
29415
|
for (let ring = 1; ring < rings.length; ring++) {
|
|
29790
|
-
let members = rings[ring] || [];
|
|
29791
29416
|
let r = radius[ring - 1] + o.ranksep;
|
|
29792
|
-
let
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
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
|
-
}
|
|
29417
|
+
for (let n of rings[ring] || []) r = Math.max(r, radius[ring - 1] + (n.parent_ext + n.ext) / 2 + o.nodesep);
|
|
29418
|
+
let list = (rings[ring] || []).slice().sort((a, b) => a.angle - b.angle);
|
|
29419
|
+
for (let i = 0; i < list.length && list.length > 1; i++) {
|
|
29420
|
+
let a = list[i];
|
|
29421
|
+
let b = list[(i + 1) % list.length];
|
|
29422
|
+
let gap = i + 1 < list.length ? b.angle - a.angle : b.angle + 2 * Math.PI - a.angle;
|
|
29423
|
+
if (gap > 1e-9) r = Math.max(r, (a.diag / 2 + b.diag / 2 + o.nodesep) / gap);
|
|
29805
29424
|
}
|
|
29806
29425
|
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
|
-
}
|
|
29854
29426
|
}
|
|
29855
29427
|
for (let [id, a] of angle) {
|
|
29856
|
-
let
|
|
29857
|
-
|
|
29858
|
-
|
|
29859
|
-
|
|
29860
|
-
|
|
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
|
-
}
|
|
29428
|
+
let r = radius[ring_of(id)] || 0;
|
|
29429
|
+
pos.set(id, {
|
|
29430
|
+
x: r * Math.cos(a),
|
|
29431
|
+
y: r * Math.sin(a)
|
|
29432
|
+
});
|
|
29877
29433
|
}
|
|
29878
29434
|
return pos;
|
|
29879
29435
|
}
|
|
@@ -29887,23 +29443,6 @@ function elbow_lane(ids, id) {
|
|
|
29887
29443
|
if (k <= 0) return 0;
|
|
29888
29444
|
return (k % 2 ? 1 : -1) * Math.ceil(k / 2);
|
|
29889
29445
|
}
|
|
29890
|
-
/************************************************************
|
|
29891
|
-
* The rank of `id` among `items` ([{id, span}]): the forward
|
|
29892
|
-
* edges that share one end with it, each with how far it runs
|
|
29893
|
-
* ACROSS. Farthest first; a tie goes to the edge made first.
|
|
29894
|
-
* Returns {rank, count}.
|
|
29895
|
-
************************************************************/
|
|
29896
|
-
function elbow_rank(items, id) {
|
|
29897
|
-
let sorted = items.slice().sort((a, b) => {
|
|
29898
|
-
if (b.span !== a.span) return b.span - a.span;
|
|
29899
|
-
return String(a.id).localeCompare(String(b.id), void 0, { numeric: true });
|
|
29900
|
-
});
|
|
29901
|
-
let rank = sorted.findIndex((it) => it.id === id);
|
|
29902
|
-
return {
|
|
29903
|
-
rank: rank < 0 ? 0 : rank,
|
|
29904
|
-
count: sorted.length
|
|
29905
|
-
};
|
|
29906
|
-
}
|
|
29907
29446
|
function swap(p) {
|
|
29908
29447
|
return [p[1], p[0]];
|
|
29909
29448
|
}
|
|
@@ -29915,136 +29454,6 @@ function swap_box(b) {
|
|
|
29915
29454
|
y2: b.x2
|
|
29916
29455
|
};
|
|
29917
29456
|
}
|
|
29918
|
-
function staggered_turn(lo, hi, st) {
|
|
29919
|
-
let mid = (lo + hi) / 2;
|
|
29920
|
-
let group = null;
|
|
29921
|
-
let k = 0;
|
|
29922
|
-
if (st.dep && st.dep.count > 1) {
|
|
29923
|
-
group = st.dep;
|
|
29924
|
-
k = st.dep.rank;
|
|
29925
|
-
} else if (st.arr && st.arr.count > 1) {
|
|
29926
|
-
group = st.arr;
|
|
29927
|
-
k = st.arr.count - 1 - st.arr.rank;
|
|
29928
|
-
}
|
|
29929
|
-
if (group) {
|
|
29930
|
-
let room = Math.max(0, hi - lo - 12);
|
|
29931
|
-
let step = Math.min(10, room / (group.count - 1));
|
|
29932
|
-
mid = mid - (group.count - 1) * step / 2 + k * step;
|
|
29933
|
-
}
|
|
29934
|
-
return mid;
|
|
29935
|
-
}
|
|
29936
|
-
/************************************************************
|
|
29937
|
-
* The combs of the stacks under one card.
|
|
29938
|
-
*
|
|
29939
|
-
* treedb_layout.js lays a run of leaf children out as two columns
|
|
29940
|
-
* with a corridor between them. A card in the first row is reached
|
|
29941
|
-
* from the channel like any other; one in a lower row cannot be --
|
|
29942
|
-
* the card above it stands in the way -- so its edge runs down
|
|
29943
|
-
* the corridor in a LANE of its own and turns into the gap above
|
|
29944
|
-
* its card, which it shares only with the other card of its row,
|
|
29945
|
-
* reached from the other side.
|
|
29946
|
-
*
|
|
29947
|
-
* targets [{id, box}]: the forward edges leaving one card,
|
|
29948
|
-
* each with the box of the card it reaches
|
|
29949
|
-
* vertical as in elbow_points; false swaps the boxes
|
|
29950
|
-
*
|
|
29951
|
-
* Returns Map id -> {lane, z, top}: the lane, the height of the
|
|
29952
|
-
* gap it turns into, and the top of the stack's first row (where
|
|
29953
|
-
* the channel over the stack ends). Only for a card that stands
|
|
29954
|
-
* under another of the group, within a stack gap and lined up
|
|
29955
|
-
* with it on the corridor side -- what a stack looks like.
|
|
29956
|
-
*
|
|
29957
|
-
* Lanes go outermost first, row by row: a line into a higher row
|
|
29958
|
-
* keeps outside the lines going deeper, and none crosses another.
|
|
29959
|
-
************************************************************/
|
|
29960
|
-
function elbow_combs(targets, vertical) {
|
|
29961
|
-
let list = vertical ? targets : targets.map((it) => ({
|
|
29962
|
-
id: it.id,
|
|
29963
|
-
box: swap_box(it.box)
|
|
29964
|
-
}));
|
|
29965
|
-
let cy = (b) => (b.y1 + b.y2) / 2;
|
|
29966
|
-
let near = (a, b) => Math.abs(a - b) < 1.5;
|
|
29967
|
-
let under = [];
|
|
29968
|
-
for (let it of list) {
|
|
29969
|
-
let b = it.box;
|
|
29970
|
-
let above = null;
|
|
29971
|
-
for (let o of list) {
|
|
29972
|
-
let a = o.box;
|
|
29973
|
-
if (o === it || a.y2 > b.y1 || b.y1 - a.y2 > 40) continue;
|
|
29974
|
-
if (!(near(a.x2, b.x2) || near(a.x1, b.x1))) continue;
|
|
29975
|
-
if (!above || a.y2 > above.y2) above = a;
|
|
29976
|
-
}
|
|
29977
|
-
if (!above) continue;
|
|
29978
|
-
let side;
|
|
29979
|
-
if (near(above.x2, b.x2) && !near(above.x1, b.x1)) side = 0;
|
|
29980
|
-
else if (near(above.x1, b.x1) && !near(above.x2, b.x2)) side = 1;
|
|
29981
|
-
else side = list.some((o) => o !== it && near(cy(o.box), cy(b)) && o.box.x2 <= b.x1) ? 1 : 0;
|
|
29982
|
-
under.push({
|
|
29983
|
-
id: it.id,
|
|
29984
|
-
box: b,
|
|
29985
|
-
above,
|
|
29986
|
-
side
|
|
29987
|
-
});
|
|
29988
|
-
}
|
|
29989
|
-
let corridor = (u) => {
|
|
29990
|
-
if (u.side === 0) {
|
|
29991
|
-
let l = u.box.x2;
|
|
29992
|
-
let col = list.filter((o) => near(o.box.x2, l));
|
|
29993
|
-
let r = Infinity;
|
|
29994
|
-
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);
|
|
29995
|
-
return {
|
|
29996
|
-
l,
|
|
29997
|
-
r: isFinite(r) ? r : l + 36,
|
|
29998
|
-
col
|
|
29999
|
-
};
|
|
30000
|
-
}
|
|
30001
|
-
let r = u.box.x1;
|
|
30002
|
-
let col = list.filter((o) => near(o.box.x1, r));
|
|
30003
|
-
let l = -Infinity;
|
|
30004
|
-
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);
|
|
30005
|
-
return {
|
|
30006
|
-
l: isFinite(l) ? l : r - 36,
|
|
30007
|
-
r,
|
|
30008
|
-
col
|
|
30009
|
-
};
|
|
30010
|
-
};
|
|
30011
|
-
let groups = /* @__PURE__ */ new Map();
|
|
30012
|
-
for (let u of under) {
|
|
30013
|
-
let c = corridor(u);
|
|
30014
|
-
u.top = Math.min(...c.col.map((o) => o.box.y1));
|
|
30015
|
-
let key = `${Math.round(c.l)}|${Math.round(c.r)}`;
|
|
30016
|
-
if (!groups.has(key)) groups.set(key, {
|
|
30017
|
-
l: c.l,
|
|
30018
|
-
r: c.r,
|
|
30019
|
-
left: [],
|
|
30020
|
-
right: []
|
|
30021
|
-
});
|
|
30022
|
-
groups.get(key)[u.side === 0 ? "left" : "right"].push(u);
|
|
30023
|
-
}
|
|
30024
|
-
let out = /* @__PURE__ */ new Map();
|
|
30025
|
-
for (let g of groups.values()) {
|
|
30026
|
-
g.left.sort((a, b) => a.box.y1 - b.box.y1);
|
|
30027
|
-
g.right.sort((a, b) => a.box.y1 - b.box.y1);
|
|
30028
|
-
let n = g.left.length + g.right.length;
|
|
30029
|
-
let room = g.r - g.l - 20;
|
|
30030
|
-
let step = n > 1 ? Math.max(0, Math.min(6, room / (n - 1))) : 0;
|
|
30031
|
-
g.left.forEach((u, i) => {
|
|
30032
|
-
out.set(u.id, {
|
|
30033
|
-
lane: g.l + 10 + i * step,
|
|
30034
|
-
z: (u.above.y2 + u.box.y1) / 2,
|
|
30035
|
-
top: u.top
|
|
30036
|
-
});
|
|
30037
|
-
});
|
|
30038
|
-
g.right.forEach((u, j) => {
|
|
30039
|
-
out.set(u.id, {
|
|
30040
|
-
lane: g.r - 10 - j * step,
|
|
30041
|
-
z: (u.above.y2 + u.box.y1) / 2,
|
|
30042
|
-
top: u.top
|
|
30043
|
-
});
|
|
30044
|
-
});
|
|
30045
|
-
}
|
|
30046
|
-
return out;
|
|
30047
|
-
}
|
|
30048
29457
|
/************************************************************
|
|
30049
29458
|
* The control points of an elbow from the port `s` to the port
|
|
30050
29459
|
* `t` ([x, y] each), knowing the boxes of the two cards
|
|
@@ -30052,33 +29461,13 @@ function elbow_combs(targets, vertical) {
|
|
|
30052
29461
|
*
|
|
30053
29462
|
* vertical the rows are stacked (top to bottom); false
|
|
30054
29463
|
* when they are side by side (left to right)
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30058
|
-
* its comb when the target is in a lower row of a
|
|
30059
|
-
* stack (elbow_combs). Absent, the channel is the
|
|
30060
|
-
* middle.
|
|
30061
|
-
************************************************************/
|
|
30062
|
-
function elbow_points(s, t, box_s, box_t, lane, vertical, stagger) {
|
|
30063
|
-
if (!vertical) return elbow_points(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, stagger).map(swap);
|
|
29464
|
+
************************************************************/
|
|
29465
|
+
function elbow_points(s, t, box_s, box_t, lane, vertical) {
|
|
29466
|
+
if (!vertical) return elbow_points(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true).map(swap);
|
|
30064
29467
|
let shift = lane * 10;
|
|
30065
29468
|
if (t[1] - s[1] > 20) {
|
|
30066
|
-
let
|
|
30067
|
-
|
|
30068
|
-
if (st.comb) {
|
|
30069
|
-
let c = st.comb;
|
|
30070
|
-
let turn = staggered_turn(lo, c.top, { dep: st.dep }) + shift;
|
|
30071
|
-
turn = Math.min(Math.max(turn, lo + 4), c.top - 4);
|
|
30072
|
-
return [
|
|
30073
|
-
[s[0], turn],
|
|
30074
|
-
[c.lane, turn],
|
|
30075
|
-
[c.lane, c.z],
|
|
30076
|
-
[t[0], c.z]
|
|
30077
|
-
];
|
|
30078
|
-
}
|
|
30079
|
-
let hi = Math.min(t[1], box_t.y1);
|
|
30080
|
-
let mid = staggered_turn(lo, hi, st) + shift;
|
|
30081
|
-
mid = Math.min(Math.max(mid, lo + 4), hi - 4);
|
|
29469
|
+
let mid = (s[1] + t[1]) / 2 + shift;
|
|
29470
|
+
mid = Math.min(Math.max(mid, s[1] + 10), t[1] - 10);
|
|
30082
29471
|
return [[s[0], mid], [t[0], mid]];
|
|
30083
29472
|
}
|
|
30084
29473
|
let out = 16 + Math.abs(shift);
|
|
@@ -30172,12 +29561,8 @@ function heap_pop(h) {
|
|
|
30172
29561
|
/************************************************************
|
|
30173
29562
|
* The shortest orthogonal line from `a` to `z` that enters none
|
|
30174
29563
|
* of `boxes` (already expanded by the clearance), a turn costing
|
|
30175
|
-
* ROUTE_BEND. The line leaves `a`
|
|
30176
|
-
*
|
|
30177
|
-
* over it belong to the forward edges that share that port, which
|
|
30178
|
-
* run along them to their staggered turns -- a route going down
|
|
30179
|
-
* that column lay on top of them. So a routed line shares only
|
|
30180
|
-
* the stub between the port and `a` (or `z`).
|
|
29564
|
+
* ROUTE_BEND. The line leaves `a` going down and ends at `z`
|
|
29565
|
+
* going down, since after `z` it drops into a port.
|
|
30181
29566
|
*
|
|
30182
29567
|
* The grid is SPARSE: only the lines of the boxes' borders and
|
|
30183
29568
|
* of the two ends, which is all an orthogonal shortest path ever
|
|
@@ -30243,8 +29628,7 @@ function orth_search(a, z, boxes) {
|
|
|
30243
29628
|
let k = state >> 2;
|
|
30244
29629
|
let dir = state & 3;
|
|
30245
29630
|
if (k === goal) {
|
|
30246
|
-
|
|
30247
|
-
let total = cost + 40;
|
|
29631
|
+
let total = cost + (dir === 2 ? 0 : 40);
|
|
30248
29632
|
if (total < found_cost) {
|
|
30249
29633
|
found_cost = total;
|
|
30250
29634
|
found = state;
|
|
@@ -30252,7 +29636,6 @@ function orth_search(a, z, boxes) {
|
|
|
30252
29636
|
continue;
|
|
30253
29637
|
}
|
|
30254
29638
|
for (let [nk, nd, len] of moves(k)) {
|
|
30255
|
-
if (k === start && nd >= 2) continue;
|
|
30256
29639
|
let c = cost + len + (nd === dir ? 0 : 40);
|
|
30257
29640
|
let ns = nk * 4 + nd;
|
|
30258
29641
|
if (c < best[ns]) {
|
|
@@ -30293,11 +29676,10 @@ function orth_search(a, z, boxes) {
|
|
|
30293
29676
|
* coincide. Nearby cards first; all of them if that finds no way;
|
|
30294
29677
|
* the simple elbow if nothing does.
|
|
30295
29678
|
************************************************************/
|
|
30296
|
-
function elbow_route(s, t, box_s, box_t, lane, vertical, boxes
|
|
29679
|
+
function elbow_route(s, t, box_s, box_t, lane, vertical, boxes) {
|
|
30297
29680
|
let others = boxes || [];
|
|
30298
|
-
if (!vertical) return elbow_route(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true, others.map(swap_box)
|
|
30299
|
-
|
|
30300
|
-
let simple = elbow_points(s, t, box_s, box_t, lane, true, stagger);
|
|
29681
|
+
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);
|
|
29682
|
+
let simple = elbow_points(s, t, box_s, box_t, lane, true);
|
|
30301
29683
|
if (!elbow_path_hits([
|
|
30302
29684
|
s,
|
|
30303
29685
|
...simple,
|
|
@@ -30317,112 +29699,6 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
|
|
|
30317
29699
|
if (!route && near.length < others.length) route = orth_search(a, z, others.map((b) => box_expand(b, m)));
|
|
30318
29700
|
return route || simple;
|
|
30319
29701
|
}
|
|
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
|
-
}
|
|
30426
29702
|
//#endregion
|
|
30427
29703
|
//#region node_modules/@babel/runtime/helpers/esm/typeof.js
|
|
30428
29704
|
function _typeof(o) {
|
|
@@ -55310,7 +54586,7 @@ Easing Functions from anime.js, they are tried and true, so, its better to use t
|
|
|
55310
54586
|
var Quad = function Quad(t) {
|
|
55311
54587
|
return Math.pow(t, 2);
|
|
55312
54588
|
};
|
|
55313
|
-
var Cubic
|
|
54589
|
+
var Cubic = function Cubic(t) {
|
|
55314
54590
|
return Math.pow(t, 3);
|
|
55315
54591
|
};
|
|
55316
54592
|
var Quart = function Quart(t) {
|
|
@@ -55447,10 +54723,10 @@ var EasingFunctions = {
|
|
|
55447
54723
|
"out-quad": EaseOut(Quad),
|
|
55448
54724
|
"in-out-quad": EaseInOut(Quad),
|
|
55449
54725
|
"out-in-quad": EaseOutIn(Quad),
|
|
55450
|
-
"in-cubic": Cubic
|
|
55451
|
-
"out-cubic": EaseOut(Cubic
|
|
55452
|
-
"in-out-cubic": EaseInOut(Cubic
|
|
55453
|
-
"out-in-cubic": EaseOutIn(Cubic
|
|
54726
|
+
"in-cubic": Cubic,
|
|
54727
|
+
"out-cubic": EaseOut(Cubic),
|
|
54728
|
+
"in-out-cubic": EaseInOut(Cubic),
|
|
54729
|
+
"out-in-cubic": EaseOutIn(Cubic),
|
|
55454
54730
|
"in-quart": Quart,
|
|
55455
54731
|
"out-quart": EaseOut(Quart),
|
|
55456
54732
|
"in-out-quart": EaseInOut(Quart),
|
|
@@ -57287,12 +56563,6 @@ var _layouts = {
|
|
|
57287
56563
|
nodesep: 18,
|
|
57288
56564
|
ranksep: 90
|
|
57289
56565
|
},
|
|
57290
|
-
"compact-tree": {
|
|
57291
|
-
type: "treedb-compact",
|
|
57292
|
-
direction: "TB",
|
|
57293
|
-
nodesep: 18,
|
|
57294
|
-
ranksep: 90
|
|
57295
|
-
},
|
|
57296
56566
|
"dagre": {
|
|
57297
56567
|
type: "dagre",
|
|
57298
56568
|
rankdir: "LR",
|
|
@@ -57620,11 +56890,8 @@ function register_layouts(gobj) {
|
|
|
57620
56890
|
_g6_extensions_registered = true;
|
|
57621
56891
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "manual", ManualLayout);
|
|
57622
56892
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-tree", TreedbTreeLayout);
|
|
57623
|
-
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-compact", TreedbCompactLayout);
|
|
57624
56893
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-v", TreedbElbowV);
|
|
57625
56894
|
(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);
|
|
57628
56895
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
|
|
57629
56896
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
|
|
57630
56897
|
(0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "treedb-card", TreedbCard);
|
|
@@ -58319,9 +57586,7 @@ function layout_direction(gobj) {
|
|
|
58319
57586
|
function edge_type_for(gobj) {
|
|
58320
57587
|
let lr = layout_direction(gobj) === "LR";
|
|
58321
57588
|
let rowless = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "rowless_layouts") || [];
|
|
58322
|
-
|
|
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";
|
|
57589
|
+
if ((0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow" && !(0, _yuneta_gobj_js.str_in_list)(rowless, gobj.priv.layout)) return lr ? "treedb-elbow-h" : "treedb-elbow-v";
|
|
58325
57590
|
return lr ? "cubic-horizontal" : "cubic";
|
|
58326
57591
|
}
|
|
58327
57592
|
/************************************************************
|
|
@@ -59808,9 +59073,8 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
|
|
|
59808
59073
|
* dragged card, a fold or a layout needs nothing else. `-v` runs
|
|
59809
59074
|
* between rows (top to bottom), `-h` between columns. An edge that
|
|
59810
59075
|
* does not run forward goes round the two cards, the edges joining
|
|
59811
|
-
* the same two cards take lanes,
|
|
59812
|
-
*
|
|
59813
|
-
* routed round it (treedb_elbow.js).
|
|
59076
|
+
* the same two cards take lanes, and a line that would cross any
|
|
59077
|
+
* other card is routed round it (treedb_elbow.js).
|
|
59814
59078
|
************************************************************/
|
|
59815
59079
|
var ELBOW_RADIUS = 6;
|
|
59816
59080
|
function elbow_box(node) {
|
|
@@ -59862,55 +59126,10 @@ function elbow_lane_of(edge) {
|
|
|
59862
59126
|
return 0;
|
|
59863
59127
|
}
|
|
59864
59128
|
}
|
|
59865
|
-
function elbow_stagger_of(edge, vertical) {
|
|
59866
|
-
let graph = edge.context && edge.context.graph;
|
|
59867
|
-
let element = edge.context && edge.context.element;
|
|
59868
|
-
let s = edge.sourceNode && edge.sourceNode.id;
|
|
59869
|
-
let t = edge.targetNode && edge.targetNode.id;
|
|
59870
|
-
if (!graph || !element || s === void 0 || t === void 0) return null;
|
|
59871
|
-
let across = vertical ? 0 : 1;
|
|
59872
|
-
let along = vertical ? 1 : 0;
|
|
59873
|
-
let pos = (id) => graph.getElementPosition(id);
|
|
59874
|
-
let port_of = (node_id, key) => {
|
|
59875
|
-
let node = element.getElement(node_id);
|
|
59876
|
-
let ports = node && typeof node.getPorts === "function" ? node.getPorts() : {};
|
|
59877
|
-
let port = key ? ports[key] : null;
|
|
59878
|
-
return port ? port.getPosition() : pos(node_id);
|
|
59879
|
-
};
|
|
59880
|
-
try {
|
|
59881
|
-
let ps = pos(s);
|
|
59882
|
-
let pt = pos(t);
|
|
59883
|
-
let leaving = graph.getRelatedEdgesData(s, "out").filter((d) => d.source === s && pos(d.target)[along] > ps[along]);
|
|
59884
|
-
let combs = elbow_combs(leaving.map((d) => ({
|
|
59885
|
-
id: d.id,
|
|
59886
|
-
box: elbow_box(element.getElement(d.target))
|
|
59887
|
-
})), vertical);
|
|
59888
|
-
let dep = leaving.map((d) => {
|
|
59889
|
-
let comb = combs.get(d.id);
|
|
59890
|
-
let far = comb ? comb.lane : pos(d.target)[across];
|
|
59891
|
-
return {
|
|
59892
|
-
id: d.id,
|
|
59893
|
-
span: Math.abs(far - port_of(s, d.style && d.style.sourcePort)[across])
|
|
59894
|
-
};
|
|
59895
|
-
});
|
|
59896
|
-
let arr = graph.getRelatedEdgesData(t, "in").filter((d) => d.target === t && pos(d.source)[along] < pt[along]).map((d) => ({
|
|
59897
|
-
id: d.id,
|
|
59898
|
-
span: Math.abs(port_of(d.source, d.style && d.style.sourcePort)[across] - pt[across])
|
|
59899
|
-
}));
|
|
59900
|
-
return {
|
|
59901
|
-
dep: elbow_rank(dep, edge.id),
|
|
59902
|
-
arr: elbow_rank(arr, edge.id),
|
|
59903
|
-
comb: combs.get(edge.id) || null
|
|
59904
|
-
};
|
|
59905
|
-
} catch (e) {
|
|
59906
|
-
(0, _yuneta_gobj_js.log_error)(`elbow edge ${edge.id}: cannot read the edges sharing its ends: ${e}`);
|
|
59907
|
-
return null;
|
|
59908
|
-
}
|
|
59909
|
-
}
|
|
59910
59129
|
var TreedbElbowV = class extends _antv_g6.Polyline {
|
|
59911
59130
|
getControlPoints(attributes) {
|
|
59912
59131
|
let [s, t] = this.getEndpoints(attributes, false);
|
|
59913
|
-
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), true, elbow_obstacles(this)
|
|
59132
|
+
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), true, elbow_obstacles(this));
|
|
59914
59133
|
}
|
|
59915
59134
|
getKeyPath(attributes) {
|
|
59916
59135
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|
|
@@ -59919,52 +59138,12 @@ var TreedbElbowV = class extends _antv_g6.Polyline {
|
|
|
59919
59138
|
var TreedbElbowH = class extends _antv_g6.Polyline {
|
|
59920
59139
|
getControlPoints(attributes) {
|
|
59921
59140
|
let [s, t] = this.getEndpoints(attributes, false);
|
|
59922
|
-
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), false, elbow_obstacles(this)
|
|
59141
|
+
return elbow_route(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), false, elbow_obstacles(this));
|
|
59923
59142
|
}
|
|
59924
59143
|
getKeyPath(attributes) {
|
|
59925
59144
|
return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
|
|
59926
59145
|
}
|
|
59927
59146
|
};
|
|
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
|
-
};
|
|
59962
|
-
var TreedbCompactLayout = class extends _antv_g6.BaseLayout {
|
|
59963
|
-
async execute(data, options) {
|
|
59964
|
-
let input = treedb_layout_input(data);
|
|
59965
|
-
return treedb_layout_output(layout_compact(input.nodes, input.edges, options));
|
|
59966
|
-
}
|
|
59967
|
-
};
|
|
59968
59147
|
var TreedbRadialLayout = class extends _antv_g6.BaseLayout {
|
|
59969
59148
|
async execute(data, options) {
|
|
59970
59149
|
let input = treedb_layout_input(data);
|
|
@@ -65458,7 +64637,6 @@ function option_label(name) {
|
|
|
65458
64637
|
case "edition": return (0, i18next.t)("edition");
|
|
65459
64638
|
case "manual": return (0, i18next.t)("manual");
|
|
65460
64639
|
case "treedb-tree": return (0, i18next.t)("treedb-tree");
|
|
65461
|
-
case "compact-tree": return (0, i18next.t)("compact-tree");
|
|
65462
64640
|
case "radial": return (0, i18next.t)("radial");
|
|
65463
64641
|
case "dagre": return (0, i18next.t)("dagre");
|
|
65464
64642
|
case "antv-dagre": return (0, i18next.t)("antv-dagre");
|