@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.
@@ -6,7 +6,7 @@ import { createJSONEditor } from "vanilla-jsoneditor";
6
6
  import { TabulatorFull } from "tabulator-tables";
7
7
  import * as maplibregl from "maplibre-gl";
8
8
  import uPlot from "uplot";
9
- import { BaseLayout, BrushSelect, CanvasEvent, Circle, CommonEvent, DragCanvas, EdgeEvent, ExtensionCategory, Graph, HTML, HistoryEvent, NodeEvent, Polyline, Toolbar, ZoomCanvas, register } from "@antv/g6";
9
+ import { BaseLayout, BrushSelect, CanvasEvent, Circle, CommonEvent, Cubic, CubicHorizontal, DragCanvas, EdgeEvent, ExtensionCategory, Graph, HTML, HistoryEvent, NodeEvent, Polyline, Toolbar, ZoomCanvas, register } from "@antv/g6";
10
10
  //#region \0rolldown/runtime.js
11
11
  var __create = Object.create;
12
12
  var __defProp = Object.defineProperty;
@@ -29418,6 +29418,56 @@ function stack_trunk_width(k) {
29418
29418
  let lanes = Math.max(0, k - 2);
29419
29419
  return Math.max(36, 20 + Math.max(0, lanes - 1) * 6);
29420
29420
  }
29421
+ /************************************************************
29422
+ * The children of every node, with each run of STACK_MIN_RUN or
29423
+ * more consecutive LEAF children replaced by one STACK. Runs, not
29424
+ * all the leaves of a parent: the children keep their order. A
29425
+ * stack's key is an OBJECT, so it can never be taken for a node id,
29426
+ * which is a string. Shared by the compact tree and the radial.
29427
+ *
29428
+ * Returns {kids_of: Map<id, [id | stack]>, stacks: Map<stack, {ids, depth}>}
29429
+ ************************************************************/
29430
+ function leaf_runs(t) {
29431
+ let kids_of = /* @__PURE__ */ new Map();
29432
+ let stacks = /* @__PURE__ */ new Map();
29433
+ for (let [id, kids] of t.children) {
29434
+ let out = [];
29435
+ let run = [];
29436
+ let flush = () => {
29437
+ if (run.length >= 3) {
29438
+ let key = { stack: stacks.size };
29439
+ stacks.set(key, {
29440
+ ids: run,
29441
+ depth: t.depth.get(run[0])
29442
+ });
29443
+ out.push(key);
29444
+ } else out.push(...run);
29445
+ run = [];
29446
+ };
29447
+ for (let kid of kids) if ((t.children.get(kid) || []).length === 0) run.push(kid);
29448
+ else {
29449
+ flush();
29450
+ out.push(kid);
29451
+ }
29452
+ flush();
29453
+ kids_of.set(id, out);
29454
+ }
29455
+ return {
29456
+ kids_of,
29457
+ stacks
29458
+ };
29459
+ }
29460
+ function stacked_order(t, kids_of) {
29461
+ let order = [];
29462
+ let todo = t.roots.slice().reverse();
29463
+ while (todo.length) {
29464
+ let id = todo.pop();
29465
+ order.push(id);
29466
+ let kids = kids_of.get(id) || [];
29467
+ for (let i = kids.length - 1; i >= 0; i--) todo.push(kids[i]);
29468
+ }
29469
+ return order;
29470
+ }
29421
29471
  function stack_geometry(t, st, col_x, col_w) {
29422
29472
  let d = st.depth;
29423
29473
  let k = st.ids.length;
@@ -29457,38 +29507,8 @@ function place_stack(t, st, g, top, pos) {
29457
29507
  function compact_tree_lr(nodes, edges, o) {
29458
29508
  let t = spanning_tree(nodes, edges);
29459
29509
  let pos = /* @__PURE__ */ new Map();
29460
- let kids_of = /* @__PURE__ */ new Map();
29461
- let stacks = /* @__PURE__ */ new Map();
29462
- for (let [id, kids] of t.children) {
29463
- let out = [];
29464
- let run = [];
29465
- let flush = () => {
29466
- if (run.length >= 3) {
29467
- let key = { stack: stacks.size };
29468
- stacks.set(key, {
29469
- ids: run,
29470
- depth: t.depth.get(run[0])
29471
- });
29472
- out.push(key);
29473
- } else out.push(...run);
29474
- run = [];
29475
- };
29476
- for (let kid of kids) if ((t.children.get(kid) || []).length === 0) run.push(kid);
29477
- else {
29478
- flush();
29479
- out.push(kid);
29480
- }
29481
- flush();
29482
- kids_of.set(id, out);
29483
- }
29484
- let order = [];
29485
- let todo = t.roots.slice().reverse();
29486
- while (todo.length) {
29487
- let id = todo.pop();
29488
- order.push(id);
29489
- let kids = kids_of.get(id) || [];
29490
- for (let i = kids.length - 1; i >= 0; i--) todo.push(kids[i]);
29491
- }
29510
+ let { kids_of, stacks } = leaf_runs(t);
29511
+ let order = stacked_order(t, kids_of);
29492
29512
  let col_w = [];
29493
29513
  for (let [id, d] of t.depth) col_w[d] = Math.max(col_w[d] || 0, t.by_id.get(id).w);
29494
29514
  let col_x = [];
@@ -29625,56 +29645,103 @@ function extent_at(n, a) {
29625
29645
  *
29626
29646
  * ranksep the step between rings
29627
29647
  * nodesep the gap between neighbours on a ring
29648
+ * stack (default true) a run of three or more LEAF children
29649
+ * is a STACK, as in the compact tree: it asks its
29650
+ * ring for one row of about the square root of its
29651
+ * cards, not for every leaf -- a hall with a hundred
29652
+ * devices no longer blows the ring up -- and lays
29653
+ * them in rows going OUTWARD, each row as full as
29654
+ * the room it has: rings round the parent when it is
29655
+ * alone, a fan inside its sector when it is not.
29656
+ * false keeps every leaf on the ring.
29628
29657
  ************************************************************/
29629
29658
  function layout_radial(nodes, edges, opts) {
29630
- let o = Object.assign({}, DEFAULTS, opts || {});
29659
+ let o = Object.assign({}, DEFAULTS, { stack: true }, opts || {});
29631
29660
  let t = spanning_tree(nodes, edges);
29632
29661
  let pos = /* @__PURE__ */ new Map();
29633
29662
  if (!t.roots.length) return pos;
29634
- let order = walk_order(t);
29635
- let leaves = /* @__PURE__ */ new Map();
29663
+ let runs = o.stack ? leaf_runs(t) : {
29664
+ kids_of: t.children,
29665
+ stacks: /* @__PURE__ */ new Map()
29666
+ };
29667
+ let kids_of = runs.kids_of;
29668
+ let stacks = runs.stacks;
29669
+ let order = stacked_order(t, kids_of);
29670
+ for (let st of stacks.values()) {
29671
+ st.per_row = Math.ceil(Math.sqrt(st.ids.length));
29672
+ st.cards = st.ids.map((id) => t.by_id.get(id));
29673
+ }
29674
+ let stack_across = (st, a) => {
29675
+ let w = 0;
29676
+ for (let c of st.cards) w = Math.max(w, extent_at(c, a + Math.PI / 2));
29677
+ return {
29678
+ card: w,
29679
+ row: st.per_row * w + (st.per_row - 1) * o.nodesep
29680
+ };
29681
+ };
29682
+ let widest_along = (cards, a, half) => {
29683
+ let e = 0;
29684
+ for (let k = 0; k <= 16; k++) {
29685
+ let th = a - half + 2 * half * k / 16;
29686
+ for (let c of cards) e = Math.max(e, extent_at(c, th));
29687
+ }
29688
+ return e;
29689
+ };
29690
+ let depth_of = (id) => stacks.has(id) ? stacks.get(id).depth : t.depth.get(id);
29691
+ let circ = (a, b) => {
29692
+ let d = Math.abs(a - b) % (2 * Math.PI);
29693
+ return d > Math.PI ? 2 * Math.PI - d : d;
29694
+ };
29695
+ let weight = /* @__PURE__ */ new Map();
29636
29696
  for (let i = order.length - 1; i >= 0; i--) {
29637
29697
  let id = order[i];
29638
- let kids = t.children.get(id) || [];
29698
+ let st = stacks.get(id);
29699
+ if (st) {
29700
+ weight.set(id, st.per_row);
29701
+ continue;
29702
+ }
29703
+ let kids = kids_of.get(id) || [];
29639
29704
  if (!kids.length) {
29640
- leaves.set(id, 1);
29705
+ weight.set(id, 1);
29641
29706
  continue;
29642
29707
  }
29643
29708
  let n = 0;
29644
- for (let kid of kids) n += leaves.get(kid);
29645
- leaves.set(id, n);
29709
+ for (let kid of kids) n += weight.get(kid);
29710
+ weight.set(id, n);
29646
29711
  }
29647
29712
  let total = 0;
29648
- for (let root of t.roots) total += leaves.get(root);
29713
+ for (let root of t.roots) total += weight.get(root);
29649
29714
  let single = t.roots.length === 1;
29650
- let ring_of = (id) => t.depth.get(id) + (single ? 0 : 1);
29715
+ let ring_of = (id) => depth_of(id) + (single ? 0 : 1);
29651
29716
  let angle = /* @__PURE__ */ new Map();
29652
29717
  let rings = [];
29653
29718
  let sector = (root_id, root_from, root_span, root_parent) => {
29654
- let stack = [{
29719
+ let todo = [{
29655
29720
  id: root_id,
29656
29721
  from: root_from,
29657
29722
  span: root_span,
29658
29723
  parent: root_parent
29659
29724
  }];
29660
- while (stack.length) {
29661
- let { id, from, span, parent } = stack.pop();
29725
+ while (todo.length) {
29726
+ let { id, from, span, parent } = todo.pop();
29662
29727
  let a = from + span / 2;
29663
29728
  angle.set(id, a);
29664
29729
  let ring = ring_of(id);
29665
29730
  if (!rings[ring]) rings[ring] = [];
29666
- let n = t.by_id.get(id);
29731
+ let st = stacks.get(id);
29732
+ let n = st ? null : t.by_id.get(id);
29667
29733
  rings[ring].push({
29668
29734
  id,
29669
29735
  angle: a,
29670
- diag: Math.hypot(n.w, n.h),
29671
- ext: extent_at(n, a),
29672
- parent_ext: parent ? extent_at(t.by_id.get(parent), a) : 0
29736
+ span,
29737
+ diag: st ? stack_across(st, a).row : Math.hypot(n.w, n.h),
29738
+ ext: st ? widest_along(st.cards, a, Math.min(span / 2, Math.PI)) : extent_at(n, a),
29739
+ 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)
29673
29740
  });
29674
29741
  let cursor = from;
29675
- for (let kid of t.children.get(id) || []) {
29676
- let part = span * leaves.get(kid) / leaves.get(id);
29677
- stack.push({
29742
+ for (let kid of kids_of.get(id) || []) {
29743
+ let part = span * weight.get(kid) / weight.get(id);
29744
+ todo.push({
29678
29745
  id: kid,
29679
29746
  from: cursor,
29680
29747
  span: part,
@@ -29688,38 +29755,120 @@ function layout_radial(nodes, edges, opts) {
29688
29755
  let root = t.roots[0];
29689
29756
  angle.set(root, 0);
29690
29757
  let cursor = -Math.PI / 2;
29691
- for (let kid of t.children.get(root) || []) {
29692
- let part = 2 * Math.PI * leaves.get(kid) / leaves.get(root);
29758
+ for (let kid of kids_of.get(root) || []) {
29759
+ let part = 2 * Math.PI * weight.get(kid) / weight.get(root);
29693
29760
  sector(kid, cursor, part, root);
29694
29761
  cursor += part;
29695
29762
  }
29696
29763
  } else {
29697
29764
  let cursor = -Math.PI / 2;
29698
29765
  for (let root of t.roots) {
29699
- let part = 2 * Math.PI * leaves.get(root) / total;
29766
+ let part = 2 * Math.PI * weight.get(root) / total;
29700
29767
  sector(root, cursor, part, null);
29701
29768
  cursor += part;
29702
29769
  }
29703
29770
  }
29771
+ let fit = (list, r0) => {
29772
+ let r = r0;
29773
+ let sorted = list.slice().sort((a, b) => a.angle - b.angle);
29774
+ for (let i = 0; i < sorted.length && sorted.length > 1; i++) {
29775
+ let a = sorted[i];
29776
+ let b = sorted[(i + 1) % sorted.length];
29777
+ let gap = i + 1 < sorted.length ? b.angle - a.angle : b.angle + 2 * Math.PI - a.angle;
29778
+ if (gap > 1e-9) r = Math.max(r, (a.diag / 2 + b.diag / 2 + o.nodesep) / gap);
29779
+ }
29780
+ return r;
29781
+ };
29704
29782
  let radius = [0];
29783
+ let reaching = [];
29705
29784
  for (let ring = 1; ring < rings.length; ring++) {
29785
+ let members = rings[ring] || [];
29706
29786
  let r = radius[ring - 1] + o.ranksep;
29707
- for (let n of rings[ring] || []) r = Math.max(r, radius[ring - 1] + (n.parent_ext + n.ext) / 2 + o.nodesep);
29708
- let list = (rings[ring] || []).slice().sort((a, b) => a.angle - b.angle);
29709
- for (let i = 0; i < list.length && list.length > 1; i++) {
29710
- let a = list[i];
29711
- let b = list[(i + 1) % list.length];
29712
- let gap = i + 1 < list.length ? b.angle - a.angle : b.angle + 2 * Math.PI - a.angle;
29713
- if (gap > 1e-9) r = Math.max(r, (a.diag / 2 + b.diag / 2 + o.nodesep) / gap);
29787
+ let band = 0;
29788
+ for (let n of members) {
29789
+ r = Math.max(r, radius[ring - 1] + (n.parent_ext + n.ext) / 2 + o.nodesep);
29790
+ band = Math.max(band, n.ext);
29791
+ }
29792
+ r = fit(members, r);
29793
+ for (let pass = 0; pass < 2; pass++) for (let g of reaching) {
29794
+ if (g.reach < r - band / 2 - o.nodesep) continue;
29795
+ for (let m of members) {
29796
+ let d = circ(g.angle, m.angle);
29797
+ if (d > g.half + 1e-9) r = Math.max(r, (m.diag / 2 + o.nodesep) / (d - g.half));
29798
+ else r = Math.max(r, g.reach + m.ext / 2 + o.nodesep);
29799
+ }
29714
29800
  }
29715
29801
  radius[ring] = r;
29802
+ let sorted = members.slice().sort((a, b) => a.angle - b.angle);
29803
+ for (let i = 0; i < sorted.length; i++) {
29804
+ let m = sorted[i];
29805
+ let st = stacks.get(m.id);
29806
+ if (!st) continue;
29807
+ let room = m.span / 2;
29808
+ if (sorted.length > 1) {
29809
+ let left = sorted[(i - 1 + sorted.length) % sorted.length];
29810
+ let right = sorted[(i + 1) % sorted.length];
29811
+ 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);
29812
+ }
29813
+ room = Math.min(room, Math.PI);
29814
+ let across = 0;
29815
+ let along = 0;
29816
+ for (let k = 0; k <= 16; k++) {
29817
+ let th = m.angle - room + 2 * room * k / 16;
29818
+ for (let c of st.cards) {
29819
+ across = Math.max(across, extent_at(c, th + Math.PI / 2));
29820
+ along = Math.max(along, extent_at(c, th));
29821
+ }
29822
+ }
29823
+ let rows = [];
29824
+ let left_to_place = st.ids.length;
29825
+ let rr = r;
29826
+ let half = 0;
29827
+ while (left_to_place > 0) {
29828
+ let fits = Math.floor(2 * room * rr / (across + o.nodesep));
29829
+ let cnt = Math.max(1, Math.min(left_to_place, fits));
29830
+ rows.push({
29831
+ rr,
29832
+ cnt
29833
+ });
29834
+ half = Math.max(half, (cnt * (across + o.nodesep) - o.nodesep) / 2 / rr);
29835
+ left_to_place -= cnt;
29836
+ rr += along + 40;
29837
+ }
29838
+ st.plan = {
29839
+ angle: m.angle,
29840
+ across,
29841
+ rows
29842
+ };
29843
+ reaching.push({
29844
+ angle: m.angle,
29845
+ half,
29846
+ reach: rows[rows.length - 1].rr + along / 2
29847
+ });
29848
+ }
29716
29849
  }
29717
29850
  for (let [id, a] of angle) {
29718
- let r = radius[ring_of(id)] || 0;
29719
- pos.set(id, {
29720
- x: r * Math.cos(a),
29721
- y: r * Math.sin(a)
29722
- });
29851
+ let st = stacks.get(id);
29852
+ if (!st) {
29853
+ let r0 = radius[ring_of(id)] || 0;
29854
+ pos.set(id, {
29855
+ x: r0 * Math.cos(a),
29856
+ y: r0 * Math.sin(a)
29857
+ });
29858
+ continue;
29859
+ }
29860
+ let i = 0;
29861
+ for (let row of st.plan.rows) {
29862
+ let step = (st.plan.across + o.nodesep) / row.rr;
29863
+ for (let j = 0; j < row.cnt; j++) {
29864
+ let th = a + (j - (row.cnt - 1) / 2) * step;
29865
+ pos.set(st.ids[i], {
29866
+ x: row.rr * Math.cos(th),
29867
+ y: row.rr * Math.sin(th)
29868
+ });
29869
+ i++;
29870
+ }
29871
+ }
29723
29872
  }
29724
29873
  return pos;
29725
29874
  }
@@ -30163,6 +30312,112 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes, stagger) {
30163
30312
  if (!route && near.length < others.length) route = orth_search(a, z, others.map((b) => box_expand(b, m)));
30164
30313
  return route || simple;
30165
30314
  }
30315
+ function path_points(path) {
30316
+ let pts = [];
30317
+ let cur = null;
30318
+ for (let c of path) if (c[0] === "M" || c[0] === "L") {
30319
+ cur = [c[1], c[2]];
30320
+ pts.push(cur);
30321
+ } else if (c[0] === "C" && cur) {
30322
+ let [x0, y0] = cur;
30323
+ for (let k = 1; k <= 16; k++) {
30324
+ let u = k / 16;
30325
+ let v = 1 - u;
30326
+ 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]]);
30327
+ }
30328
+ cur = [c[5], c[6]];
30329
+ } else if (c[0] === "Q" && cur) {
30330
+ let [x0, y0] = cur;
30331
+ for (let k = 1; k <= 16; k++) {
30332
+ let u = k / 16;
30333
+ let v = 1 - u;
30334
+ 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]]);
30335
+ }
30336
+ cur = [c[3], c[4]];
30337
+ }
30338
+ return pts;
30339
+ }
30340
+ /************************************************************
30341
+ * Does the G6 path `path` of a curved edge cross a card other than
30342
+ * its own two? Measured on the curve itself -- the path G6 would
30343
+ * draw, sampled -- and not on the rectangle round it, which took
30344
+ * every card the curve merely passed near: the ports of a row
30345
+ * stick well into the space above it. Its own two cards are left
30346
+ * out: the curve starts and ends on their ports.
30347
+ ************************************************************/
30348
+ function curve_hits(path, boxes, box_s, box_t) {
30349
+ let pts = path_points(path);
30350
+ if (pts.length < 2) return false;
30351
+ let bb = {
30352
+ x1: Infinity,
30353
+ y1: Infinity,
30354
+ x2: -Infinity,
30355
+ y2: -Infinity
30356
+ };
30357
+ for (let p of pts) {
30358
+ bb.x1 = Math.min(bb.x1, p[0]);
30359
+ bb.y1 = Math.min(bb.y1, p[1]);
30360
+ bb.x2 = Math.max(bb.x2, p[0]);
30361
+ bb.y2 = Math.max(bb.y2, p[1]);
30362
+ }
30363
+ for (let b of boxes || []) {
30364
+ if (same_box(b, box_s) || same_box(b, box_t) || !box_overlaps(b, box_expand(bb, 1))) continue;
30365
+ let inner = box_expand(b, -1);
30366
+ for (let k = 0; k + 1 < pts.length; k++) if (segment_hits(pts[k], pts[k + 1], inner)) return true;
30367
+ }
30368
+ return false;
30369
+ }
30370
+ /************************************************************
30371
+ * A G6 path (['M'|'L'|'Q', ...]) along `points` with every corner
30372
+ * rounded -- by `radius`, or by half the shorter of its two
30373
+ * segments, so a short run is never overshot. The rounding is the
30374
+ * quadratic G6's own polyline uses.
30375
+ ************************************************************/
30376
+ function rounded_path(points, radius) {
30377
+ let path = [[
30378
+ "M",
30379
+ points[0][0],
30380
+ points[0][1]
30381
+ ]];
30382
+ for (let i = 1; i + 1 < points.length; i++) {
30383
+ let a = points[i - 1];
30384
+ let m = points[i];
30385
+ let b = points[i + 1];
30386
+ let len_in = Math.hypot(m[0] - a[0], m[1] - a[1]);
30387
+ let len_out = Math.hypot(b[0] - m[0], b[1] - m[1]);
30388
+ let r = Math.min(radius, len_in / 2, len_out / 2);
30389
+ let collinear = Math.abs((m[0] - a[0]) * (b[1] - m[1]) - (m[1] - a[1]) * (b[0] - m[0])) < 1e-9;
30390
+ if (r <= 0 || collinear) {
30391
+ path.push([
30392
+ "L",
30393
+ m[0],
30394
+ m[1]
30395
+ ]);
30396
+ continue;
30397
+ }
30398
+ let p1 = [m[0] - (m[0] - a[0]) / len_in * r, m[1] - (m[1] - a[1]) / len_in * r];
30399
+ let p2 = [m[0] + (b[0] - m[0]) / len_out * r, m[1] + (b[1] - m[1]) / len_out * r];
30400
+ path.push([
30401
+ "L",
30402
+ p1[0],
30403
+ p1[1]
30404
+ ]);
30405
+ path.push([
30406
+ "Q",
30407
+ m[0],
30408
+ m[1],
30409
+ p2[0],
30410
+ p2[1]
30411
+ ]);
30412
+ }
30413
+ let last = points[points.length - 1];
30414
+ path.push([
30415
+ "L",
30416
+ last[0],
30417
+ last[1]
30418
+ ]);
30419
+ return path;
30420
+ }
30166
30421
  //#endregion
30167
30422
  //#region node_modules/@babel/runtime/helpers/esm/typeof.js
30168
30423
  function _typeof(o) {
@@ -55050,7 +55305,7 @@ Easing Functions from anime.js, they are tried and true, so, its better to use t
55050
55305
  var Quad = function Quad(t) {
55051
55306
  return Math.pow(t, 2);
55052
55307
  };
55053
- var Cubic = function Cubic(t) {
55308
+ var Cubic$1 = function Cubic(t) {
55054
55309
  return Math.pow(t, 3);
55055
55310
  };
55056
55311
  var Quart = function Quart(t) {
@@ -55187,10 +55442,10 @@ var EasingFunctions = {
55187
55442
  "out-quad": EaseOut(Quad),
55188
55443
  "in-out-quad": EaseInOut(Quad),
55189
55444
  "out-in-quad": EaseOutIn(Quad),
55190
- "in-cubic": Cubic,
55191
- "out-cubic": EaseOut(Cubic),
55192
- "in-out-cubic": EaseInOut(Cubic),
55193
- "out-in-cubic": EaseOutIn(Cubic),
55445
+ "in-cubic": Cubic$1,
55446
+ "out-cubic": EaseOut(Cubic$1),
55447
+ "in-out-cubic": EaseInOut(Cubic$1),
55448
+ "out-in-cubic": EaseOutIn(Cubic$1),
55194
55449
  "in-quart": Quart,
55195
55450
  "out-quart": EaseOut(Quart),
55196
55451
  "in-out-quart": EaseInOut(Quart),
@@ -57363,6 +57618,8 @@ function register_layouts(gobj) {
57363
57618
  register(ExtensionCategory.LAYOUT, "treedb-compact", TreedbCompactLayout);
57364
57619
  register(ExtensionCategory.EDGE, "treedb-elbow-v", TreedbElbowV);
57365
57620
  register(ExtensionCategory.EDGE, "treedb-elbow-h", TreedbElbowH);
57621
+ register(ExtensionCategory.EDGE, "treedb-curve-v", TreedbCurveV);
57622
+ register(ExtensionCategory.EDGE, "treedb-curve-h", TreedbCurveH);
57366
57623
  register(ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
57367
57624
  register(ExtensionCategory.NODE, "light", LightNode);
57368
57625
  register(ExtensionCategory.NODE, "treedb-card", TreedbCard);
@@ -58057,7 +58314,9 @@ function layout_direction(gobj) {
58057
58314
  function edge_type_for(gobj) {
58058
58315
  let lr = layout_direction(gobj) === "LR";
58059
58316
  let rowless = gobj_read_attr(gobj, "rowless_layouts") || [];
58060
- if (gobj_read_str_attr(gobj, "edge_shape") === "elbow" && !str_in_list(rowless, gobj.priv.layout)) return lr ? "treedb-elbow-h" : "treedb-elbow-v";
58317
+ let rows = !str_in_list(rowless, gobj.priv.layout);
58318
+ if (rows && gobj_read_str_attr(gobj, "edge_shape") === "elbow") return lr ? "treedb-elbow-h" : "treedb-elbow-v";
58319
+ if (rows) return lr ? "treedb-curve-h" : "treedb-curve-v";
58061
58320
  return lr ? "cubic-horizontal" : "cubic";
58062
58321
  }
58063
58322
  /************************************************************
@@ -59661,6 +59920,40 @@ var TreedbElbowH = class extends Polyline {
59661
59920
  return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
59662
59921
  }
59663
59922
  };
59923
+ /************************************************************
59924
+ * A CURVED edge that keeps off the cards. G6's cubic, as before,
59925
+ * unless that very curve -- sampled, not guessed from the
59926
+ * rectangle round it -- would cross a card other than its own two,
59927
+ * or when it does not run forward and so would cross its own:
59928
+ * the card above a lower row of a stack, a row between a parent
59929
+ * and a far child. Then it goes the way an elbow would (the comb,
59930
+ * the detour, the route: the same lanes and staggered turns) with
59931
+ * round corners, so it still reads as a curve. `-v` for rows
59932
+ * stacked top to bottom, `-h` for columns.
59933
+ ************************************************************/
59934
+ function curve_key_path(edge, attributes, vertical, plain) {
59935
+ let [s, t] = edge.getEndpoints(attributes, false);
59936
+ let along = vertical ? 1 : 0;
59937
+ let box_s = elbow_box(edge.sourceNode);
59938
+ let box_t = elbow_box(edge.targetNode);
59939
+ let boxes = elbow_obstacles(edge);
59940
+ if (t[along] - s[along] > 20 && !curve_hits(plain, boxes, box_s, box_t)) return plain;
59941
+ return rounded_path([
59942
+ s,
59943
+ ...elbow_route(s, t, box_s, box_t, elbow_lane_of(edge), vertical, boxes, elbow_stagger_of(edge, vertical)),
59944
+ t
59945
+ ], 24);
59946
+ }
59947
+ var TreedbCurveV = class extends Cubic {
59948
+ getKeyPath(attributes) {
59949
+ return curve_key_path(this, attributes, true, super.getKeyPath(attributes));
59950
+ }
59951
+ };
59952
+ var TreedbCurveH = class extends CubicHorizontal {
59953
+ getKeyPath(attributes) {
59954
+ return curve_key_path(this, attributes, false, super.getKeyPath(attributes));
59955
+ }
59956
+ };
59664
59957
  var TreedbCompactLayout = class extends BaseLayout {
59665
59958
  async execute(data, options) {
59666
59959
  let input = treedb_layout_input(data);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.154",
3
+ "version": "7.23.156",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -133,7 +133,10 @@ import {
133
133
  fold_root_group_key,
134
134
  } from "./treedb_fold_model.js";
135
135
  import {layout_tree, layout_radial, layout_compact} from "./treedb_layout.js";
136
- import {elbow_lane, elbow_rank, elbow_route, elbow_combs} from "./treedb_elbow.js";
136
+ import {
137
+ elbow_lane, elbow_rank, elbow_route, elbow_combs, curve_hits, rounded_path, CURVE_RADIUS,
138
+ ELBOW_STEP,
139
+ } from "./treedb_elbow.js";
137
140
 
138
141
  import {
139
142
  BaseLayout,
@@ -148,6 +151,8 @@ import {
148
151
  Toolbar,
149
152
  register,
150
153
  Polyline,
154
+ Cubic,
155
+ CubicHorizontal,
151
156
  } from '@antv/g6';
152
157
 
153
158
  import {Circle as CircleGeometry, Rect as RectGeometry} from '@antv/g';
@@ -942,6 +947,8 @@ function register_layouts(gobj)
942
947
  register(ExtensionCategory.LAYOUT, 'treedb-compact', TreedbCompactLayout);
943
948
  register(ExtensionCategory.EDGE, 'treedb-elbow-v', TreedbElbowV);
944
949
  register(ExtensionCategory.EDGE, 'treedb-elbow-h', TreedbElbowH);
950
+ register(ExtensionCategory.EDGE, 'treedb-curve-v', TreedbCurveV);
951
+ register(ExtensionCategory.EDGE, 'treedb-curve-h', TreedbCurveH);
945
952
  register(ExtensionCategory.LAYOUT, 'treedb-radial', TreedbRadialLayout);
946
953
  register(ExtensionCategory.NODE, 'light', LightNode);
947
954
  register(ExtensionCategory.NODE, 'treedb-card', TreedbCard);
@@ -2042,16 +2049,20 @@ function layout_direction(gobj)
2042
2049
  return str_in_list(LR_LAYOUTS, gobj.priv.layout)? "LR" : "TB";
2043
2050
  }
2044
2051
 
2045
- /* A curve, or an elbow when the reader asked for one and the layout
2046
- * has rows to run it between. */
2052
+ /* An elbow when the reader asked for one, a curve otherwise -- ours
2053
+ * where the layout has rows, which keeps off the cards; G6's plain
2054
+ * cubic on a layout with no rows to go round by. */
2047
2055
  function edge_type_for(gobj)
2048
2056
  {
2049
2057
  let lr = (layout_direction(gobj) === "LR");
2050
2058
  let rowless = gobj_read_attr(gobj, "rowless_layouts") || [];
2051
- if(gobj_read_str_attr(gobj, "edge_shape") === "elbow" &&
2052
- !str_in_list(rowless, gobj.priv.layout)) {
2059
+ let rows = !str_in_list(rowless, gobj.priv.layout);
2060
+ if(rows && gobj_read_str_attr(gobj, "edge_shape") === "elbow") {
2053
2061
  return lr? "treedb-elbow-h" : "treedb-elbow-v";
2054
2062
  }
2063
+ if(rows) {
2064
+ return lr? "treedb-curve-h" : "treedb-curve-v";
2065
+ }
2055
2066
  return lr? "cubic-horizontal" : "cubic";
2056
2067
  }
2057
2068
 
@@ -4388,6 +4399,51 @@ class TreedbElbowH extends Polyline
4388
4399
  }
4389
4400
  }
4390
4401
 
4402
+ /************************************************************
4403
+ * A CURVED edge that keeps off the cards. G6's cubic, as before,
4404
+ * unless that very curve -- sampled, not guessed from the
4405
+ * rectangle round it -- would cross a card other than its own two,
4406
+ * or when it does not run forward and so would cross its own:
4407
+ * the card above a lower row of a stack, a row between a parent
4408
+ * and a far child. Then it goes the way an elbow would (the comb,
4409
+ * the detour, the route: the same lanes and staggered turns) with
4410
+ * round corners, so it still reads as a curve. `-v` for rows
4411
+ * stacked top to bottom, `-h` for columns.
4412
+ ************************************************************/
4413
+ function curve_key_path(edge, attributes, vertical, plain)
4414
+ {
4415
+ let [s, t] = edge.getEndpoints(attributes, false);
4416
+ let along = vertical? 1 : 0;
4417
+ let box_s = elbow_box(edge.sourceNode);
4418
+ let box_t = elbow_box(edge.targetNode);
4419
+ let boxes = elbow_obstacles(edge);
4420
+ /* An edge that does not run forward -- one of every reciprocal
4421
+ * pair, an edge within one row -- runs through its OWN two cards
4422
+ * as a cubic, which curve_hits does not look at: it goes round
4423
+ * them, as its elbow does. */
4424
+ let forward = (t[along] - s[along] > 2 * ELBOW_STEP);
4425
+ if(forward && !curve_hits(plain, boxes, box_s, box_t)) {
4426
+ return plain;
4427
+ }
4428
+ let pts = elbow_route(s, t, box_s, box_t, elbow_lane_of(edge), vertical, boxes,
4429
+ elbow_stagger_of(edge, vertical));
4430
+ return rounded_path([s, ...pts, t], CURVE_RADIUS);
4431
+ }
4432
+
4433
+ class TreedbCurveV extends Cubic
4434
+ {
4435
+ getKeyPath(attributes) {
4436
+ return curve_key_path(this, attributes, true, super.getKeyPath(attributes));
4437
+ }
4438
+ }
4439
+
4440
+ class TreedbCurveH extends CubicHorizontal
4441
+ {
4442
+ getKeyPath(attributes) {
4443
+ return curve_key_path(this, attributes, false, super.getKeyPath(attributes));
4444
+ }
4445
+ }
4446
+
4391
4447
  class TreedbCompactLayout extends BaseLayout
4392
4448
  {
4393
4449
  async execute(data, options) {