@yuneta/gobj-ui 7.23.151 → 7.23.152
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 +5 -2
- package/dist/gobj-ui.cjs.js +31 -12
- package/dist/gobj-ui.es.js +31 -12
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +8 -2
- package/src/treedb_elbow.js +34 -11
- package/src/treedb_elbow.test.js +37 -0
package/README.md
CHANGED
|
@@ -1457,8 +1457,11 @@ the lane, plus the two ends; a turn costs 40px of line), over the cards within
|
|
|
1457
1457
|
400px first and all of them if that finds no way; with no way at all the
|
|
1458
1458
|
simple elbow stays. A parent and the row of children under it keep their bus;
|
|
1459
1459
|
what gets routed is a detour with a third card in its way, an edge dropping
|
|
1460
|
-
several rows, an edge between two cards of one row.
|
|
1461
|
-
|
|
1460
|
+
several rows, an edge between two cards of one row. Since `7.23.152` a node is
|
|
1461
|
+
measured **whole** — card, ports and label — so a line keeps clear of the
|
|
1462
|
+
ports as well; the edge's own ports stick out of its own cards, so its first
|
|
1463
|
+
and last segments are not tested against their own box. G6's `shortest-path`
|
|
1464
|
+
router is not used: it is not exported, it
|
|
1462
1465
|
falls back in silence to a route that crosses cards, and it rewrites its
|
|
1463
1466
|
module defaults with every config it is given.
|
|
1464
1467
|
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -29669,8 +29669,8 @@ function elbow_points(s, t, box_s, box_t, lane, vertical) {
|
|
|
29669
29669
|
}
|
|
29670
29670
|
let out = 16 + Math.abs(shift);
|
|
29671
29671
|
let side = lane < 0 ? Math.min(box_s.x1, box_t.x1) - 24 - Math.abs(shift) : Math.max(box_s.x2, box_t.x2) + 24 + Math.abs(shift);
|
|
29672
|
-
let y1 = s[1] + out;
|
|
29673
|
-
let y2 = t[1] - out;
|
|
29672
|
+
let y1 = Math.max(s[1], box_s.y2) + out;
|
|
29673
|
+
let y2 = Math.min(t[1], box_t.y1) - out;
|
|
29674
29674
|
return [
|
|
29675
29675
|
[s[0], y1],
|
|
29676
29676
|
[side, y1],
|
|
@@ -29699,15 +29699,30 @@ function segment_hits(a, c, b) {
|
|
|
29699
29699
|
let y2 = Math.max(a[1], c[1]);
|
|
29700
29700
|
return x1 < b.x2 && x2 > b.x1 && y1 < b.y2 && y2 > b.y1;
|
|
29701
29701
|
}
|
|
29702
|
+
function same_box(a, b) {
|
|
29703
|
+
return !!a && !!b && a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2;
|
|
29704
|
+
}
|
|
29702
29705
|
/************************************************************
|
|
29703
29706
|
* Does the polyline `points` (its ends included) cross any of
|
|
29704
|
-
* `boxes`? A
|
|
29705
|
-
*
|
|
29707
|
+
* `boxes`? A box is shrunk by a pixel, so a line along its
|
|
29708
|
+
* border is not a hit.
|
|
29709
|
+
*
|
|
29710
|
+
* A box is a whole node, its ports included, and the edge's own
|
|
29711
|
+
* ports stick out of its own two cards: its first segment starts
|
|
29712
|
+
* inside `box_s` and its last one ends inside `box_t`. Those two
|
|
29713
|
+
* segments are not tested against their own box; every other
|
|
29714
|
+
* segment is, so a line may not run back over its own cards.
|
|
29706
29715
|
************************************************************/
|
|
29707
|
-
function elbow_path_hits(points, boxes) {
|
|
29716
|
+
function elbow_path_hits(points, boxes, box_s, box_t) {
|
|
29717
|
+
let last = points.length - 2;
|
|
29708
29718
|
for (let b of boxes) {
|
|
29709
29719
|
let inner = box_expand(b, -1);
|
|
29710
|
-
|
|
29720
|
+
let own_s = same_box(b, box_s);
|
|
29721
|
+
let own_t = same_box(b, box_t);
|
|
29722
|
+
for (let i = 0; i <= last; i++) {
|
|
29723
|
+
if (own_s && i === 0 || own_t && i === last) continue;
|
|
29724
|
+
if (segment_hits(points[i], points[i + 1], inner)) return true;
|
|
29725
|
+
}
|
|
29711
29726
|
}
|
|
29712
29727
|
return false;
|
|
29713
29728
|
}
|
|
@@ -29849,8 +29864,11 @@ function orth_search(a, z, boxes) {
|
|
|
29849
29864
|
* port, the shortest way along the gaps between the cards, in.
|
|
29850
29865
|
* A parent and the row of children under it keep their bus.
|
|
29851
29866
|
*
|
|
29852
|
-
* `boxes` are all the
|
|
29853
|
-
* included
|
|
29867
|
+
* `boxes` are all the nodes on screen, the two of the edge
|
|
29868
|
+
* included, each as the box of the WHOLE node -- card, ports and
|
|
29869
|
+
* label -- so a line clears the ports too. `box_s` and `box_t`
|
|
29870
|
+
* are the edge's own two, measured the same way. The route keeps
|
|
29871
|
+
* a clearance from every box, which
|
|
29854
29872
|
* grows with the lane so that two routed edges of one pair do not
|
|
29855
29873
|
* coincide. Nearby cards first; all of them if that finds no way;
|
|
29856
29874
|
* the simple elbow if nothing does.
|
|
@@ -29863,10 +29881,10 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes) {
|
|
|
29863
29881
|
s,
|
|
29864
29882
|
...simple,
|
|
29865
29883
|
t
|
|
29866
|
-
], others)) return simple;
|
|
29884
|
+
], others, box_s, box_t)) return simple;
|
|
29867
29885
|
let m = 12 + Math.abs(lane) * 10;
|
|
29868
|
-
let a = [s[0], s[1] + m +
|
|
29869
|
-
let z = [t[0], t[1] - m -
|
|
29886
|
+
let a = [s[0], Math.max(s[1], box_s.y2) + m + 1];
|
|
29887
|
+
let z = [t[0], Math.min(t[1], box_t.y1) - m - 1];
|
|
29870
29888
|
let region = box_expand({
|
|
29871
29889
|
x1: Math.min(a[0], z[0], box_s.x1, box_t.x1),
|
|
29872
29890
|
y1: Math.min(a[1], z[1], box_s.y1, box_t.y1),
|
|
@@ -59265,7 +59283,8 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
|
|
|
59265
59283
|
var ELBOW_RADIUS = 6;
|
|
59266
59284
|
function elbow_box(node) {
|
|
59267
59285
|
try {
|
|
59268
|
-
let b = node.
|
|
59286
|
+
let b = node.getRenderBounds();
|
|
59287
|
+
if (!b || b.isEmpty && b.isEmpty()) b = node.getShape("key").getBounds();
|
|
59269
59288
|
return {
|
|
59270
59289
|
x1: b.min[0],
|
|
59271
59290
|
y1: b.min[1],
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -29664,8 +29664,8 @@ function elbow_points(s, t, box_s, box_t, lane, vertical) {
|
|
|
29664
29664
|
}
|
|
29665
29665
|
let out = 16 + Math.abs(shift);
|
|
29666
29666
|
let side = lane < 0 ? Math.min(box_s.x1, box_t.x1) - 24 - Math.abs(shift) : Math.max(box_s.x2, box_t.x2) + 24 + Math.abs(shift);
|
|
29667
|
-
let y1 = s[1] + out;
|
|
29668
|
-
let y2 = t[1] - out;
|
|
29667
|
+
let y1 = Math.max(s[1], box_s.y2) + out;
|
|
29668
|
+
let y2 = Math.min(t[1], box_t.y1) - out;
|
|
29669
29669
|
return [
|
|
29670
29670
|
[s[0], y1],
|
|
29671
29671
|
[side, y1],
|
|
@@ -29694,15 +29694,30 @@ function segment_hits(a, c, b) {
|
|
|
29694
29694
|
let y2 = Math.max(a[1], c[1]);
|
|
29695
29695
|
return x1 < b.x2 && x2 > b.x1 && y1 < b.y2 && y2 > b.y1;
|
|
29696
29696
|
}
|
|
29697
|
+
function same_box(a, b) {
|
|
29698
|
+
return !!a && !!b && a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2;
|
|
29699
|
+
}
|
|
29697
29700
|
/************************************************************
|
|
29698
29701
|
* Does the polyline `points` (its ends included) cross any of
|
|
29699
|
-
* `boxes`? A
|
|
29700
|
-
*
|
|
29702
|
+
* `boxes`? A box is shrunk by a pixel, so a line along its
|
|
29703
|
+
* border is not a hit.
|
|
29704
|
+
*
|
|
29705
|
+
* A box is a whole node, its ports included, and the edge's own
|
|
29706
|
+
* ports stick out of its own two cards: its first segment starts
|
|
29707
|
+
* inside `box_s` and its last one ends inside `box_t`. Those two
|
|
29708
|
+
* segments are not tested against their own box; every other
|
|
29709
|
+
* segment is, so a line may not run back over its own cards.
|
|
29701
29710
|
************************************************************/
|
|
29702
|
-
function elbow_path_hits(points, boxes) {
|
|
29711
|
+
function elbow_path_hits(points, boxes, box_s, box_t) {
|
|
29712
|
+
let last = points.length - 2;
|
|
29703
29713
|
for (let b of boxes) {
|
|
29704
29714
|
let inner = box_expand(b, -1);
|
|
29705
|
-
|
|
29715
|
+
let own_s = same_box(b, box_s);
|
|
29716
|
+
let own_t = same_box(b, box_t);
|
|
29717
|
+
for (let i = 0; i <= last; i++) {
|
|
29718
|
+
if (own_s && i === 0 || own_t && i === last) continue;
|
|
29719
|
+
if (segment_hits(points[i], points[i + 1], inner)) return true;
|
|
29720
|
+
}
|
|
29706
29721
|
}
|
|
29707
29722
|
return false;
|
|
29708
29723
|
}
|
|
@@ -29844,8 +29859,11 @@ function orth_search(a, z, boxes) {
|
|
|
29844
29859
|
* port, the shortest way along the gaps between the cards, in.
|
|
29845
29860
|
* A parent and the row of children under it keep their bus.
|
|
29846
29861
|
*
|
|
29847
|
-
* `boxes` are all the
|
|
29848
|
-
* included
|
|
29862
|
+
* `boxes` are all the nodes on screen, the two of the edge
|
|
29863
|
+
* included, each as the box of the WHOLE node -- card, ports and
|
|
29864
|
+
* label -- so a line clears the ports too. `box_s` and `box_t`
|
|
29865
|
+
* are the edge's own two, measured the same way. The route keeps
|
|
29866
|
+
* a clearance from every box, which
|
|
29849
29867
|
* grows with the lane so that two routed edges of one pair do not
|
|
29850
29868
|
* coincide. Nearby cards first; all of them if that finds no way;
|
|
29851
29869
|
* the simple elbow if nothing does.
|
|
@@ -29858,10 +29876,10 @@ function elbow_route(s, t, box_s, box_t, lane, vertical, boxes) {
|
|
|
29858
29876
|
s,
|
|
29859
29877
|
...simple,
|
|
29860
29878
|
t
|
|
29861
|
-
], others)) return simple;
|
|
29879
|
+
], others, box_s, box_t)) return simple;
|
|
29862
29880
|
let m = 12 + Math.abs(lane) * 10;
|
|
29863
|
-
let a = [s[0], s[1] + m +
|
|
29864
|
-
let z = [t[0], t[1] - m -
|
|
29881
|
+
let a = [s[0], Math.max(s[1], box_s.y2) + m + 1];
|
|
29882
|
+
let z = [t[0], Math.min(t[1], box_t.y1) - m - 1];
|
|
29865
29883
|
let region = box_expand({
|
|
29866
29884
|
x1: Math.min(a[0], z[0], box_s.x1, box_t.x1),
|
|
29867
29885
|
y1: Math.min(a[1], z[1], box_s.y1, box_t.y1),
|
|
@@ -59260,7 +59278,8 @@ var TreedbTreeLayout = class extends BaseLayout {
|
|
|
59260
59278
|
var ELBOW_RADIUS = 6;
|
|
59261
59279
|
function elbow_box(node) {
|
|
59262
59280
|
try {
|
|
59263
|
-
let b = node.
|
|
59281
|
+
let b = node.getRenderBounds();
|
|
59282
|
+
if (!b || b.isEmpty && b.isEmpty()) b = node.getShape("key").getBounds();
|
|
59264
59283
|
return {
|
|
59265
59284
|
x1: b.min[0],
|
|
59266
59285
|
y1: b.min[1],
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -4229,11 +4229,17 @@ class TreedbTreeLayout extends BaseLayout
|
|
|
4229
4229
|
************************************************************/
|
|
4230
4230
|
const ELBOW_RADIUS = 6;
|
|
4231
4231
|
|
|
4232
|
-
/* The box of a
|
|
4232
|
+
/* The box of a WHOLE node on the canvas -- the card, its ports and
|
|
4233
|
+
* its label -- for an elbow to keep clear of. The ports are the
|
|
4234
|
+
* reason it is not the key shape's box: they stick out of the
|
|
4235
|
+
* card, and a line over a port reads as a link to it. */
|
|
4233
4236
|
function elbow_box(node)
|
|
4234
4237
|
{
|
|
4235
4238
|
try {
|
|
4236
|
-
let b = node.
|
|
4239
|
+
let b = node.getRenderBounds();
|
|
4240
|
+
if(!b || b.isEmpty && b.isEmpty()) {
|
|
4241
|
+
b = node.getShape('key').getBounds();
|
|
4242
|
+
}
|
|
4237
4243
|
return {x1: b.min[0], y1: b.min[1], x2: b.max[0], y2: b.max[1]};
|
|
4238
4244
|
} catch(e) {
|
|
4239
4245
|
log_error(`elbow edge: no bounds for node ${node && node.id}: ${e}`);
|
package/src/treedb_elbow.js
CHANGED
|
@@ -96,8 +96,10 @@ export function elbow_points(s, t, box_s, box_t, lane, vertical)
|
|
|
96
96
|
let side = (lane < 0)
|
|
97
97
|
? Math.min(box_s.x1, box_t.x1) - ELBOW_CLEAR - Math.abs(shift)
|
|
98
98
|
: Math.max(box_s.x2, box_t.x2) + ELBOW_CLEAR + Math.abs(shift);
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
/* From the border of the whole box, which holds the ports: a
|
|
100
|
+
* port sticks out of its card, and the run has to clear it. */
|
|
101
|
+
let y1 = Math.max(s[1], box_s.y2) + out; /* a hook port is on the bottom edge */
|
|
102
|
+
let y2 = Math.min(t[1], box_t.y1) - out; /* an fkey port is on the top edge */
|
|
101
103
|
return [[s[0], y1], [side, y1], [side, y2], [t[0], y2]];
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -133,16 +135,33 @@ function segment_hits(a, c, b)
|
|
|
133
135
|
return x1 < b.x2 && x2 > b.x1 && y1 < b.y2 && y2 > b.y1;
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
function same_box(a, b)
|
|
139
|
+
{
|
|
140
|
+
return !!a && !!b && a.x1 === b.x1 && a.y1 === b.y1 && a.x2 === b.x2 && a.y2 === b.y2;
|
|
141
|
+
}
|
|
142
|
+
|
|
136
143
|
/************************************************************
|
|
137
144
|
* Does the polyline `points` (its ends included) cross any of
|
|
138
|
-
* `boxes`? A
|
|
139
|
-
*
|
|
145
|
+
* `boxes`? A box is shrunk by a pixel, so a line along its
|
|
146
|
+
* border is not a hit.
|
|
147
|
+
*
|
|
148
|
+
* A box is a whole node, its ports included, and the edge's own
|
|
149
|
+
* ports stick out of its own two cards: its first segment starts
|
|
150
|
+
* inside `box_s` and its last one ends inside `box_t`. Those two
|
|
151
|
+
* segments are not tested against their own box; every other
|
|
152
|
+
* segment is, so a line may not run back over its own cards.
|
|
140
153
|
************************************************************/
|
|
141
|
-
export function elbow_path_hits(points, boxes)
|
|
154
|
+
export function elbow_path_hits(points, boxes, box_s, box_t)
|
|
142
155
|
{
|
|
156
|
+
let last = points.length - 2;
|
|
143
157
|
for(let b of boxes) {
|
|
144
158
|
let inner = box_expand(b, -1);
|
|
145
|
-
|
|
159
|
+
let own_s = same_box(b, box_s);
|
|
160
|
+
let own_t = same_box(b, box_t);
|
|
161
|
+
for(let i = 0; i <= last; i++) {
|
|
162
|
+
if((own_s && i === 0) || (own_t && i === last)) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
146
165
|
if(segment_hits(points[i], points[i + 1], inner)) {
|
|
147
166
|
return true;
|
|
148
167
|
}
|
|
@@ -332,8 +351,11 @@ function orth_search(a, z, boxes)
|
|
|
332
351
|
* port, the shortest way along the gaps between the cards, in.
|
|
333
352
|
* A parent and the row of children under it keep their bus.
|
|
334
353
|
*
|
|
335
|
-
* `boxes` are all the
|
|
336
|
-
* included
|
|
354
|
+
* `boxes` are all the nodes on screen, the two of the edge
|
|
355
|
+
* included, each as the box of the WHOLE node -- card, ports and
|
|
356
|
+
* label -- so a line clears the ports too. `box_s` and `box_t`
|
|
357
|
+
* are the edge's own two, measured the same way. The route keeps
|
|
358
|
+
* a clearance from every box, which
|
|
337
359
|
* grows with the lane so that two routed edges of one pair do not
|
|
338
360
|
* coincide. Nearby cards first; all of them if that finds no way;
|
|
339
361
|
* the simple elbow if nothing does.
|
|
@@ -347,13 +369,14 @@ export function elbow_route(s, t, box_s, box_t, lane, vertical, boxes)
|
|
|
347
369
|
}
|
|
348
370
|
|
|
349
371
|
let simple = elbow_points(s, t, box_s, box_t, lane, true);
|
|
350
|
-
if(!elbow_path_hits([s, ...simple, t], others)) {
|
|
372
|
+
if(!elbow_path_hits([s, ...simple, t], others, box_s, box_t)) {
|
|
351
373
|
return simple;
|
|
352
374
|
}
|
|
353
375
|
|
|
354
376
|
let m = ELBOW_CLEAR / 2 + Math.abs(lane) * ELBOW_STEP;
|
|
355
|
-
|
|
356
|
-
let
|
|
377
|
+
/* Just outside the grown box of each end, which holds its ports. */
|
|
378
|
+
let a = [s[0], Math.max(s[1], box_s.y2) + m + 1]; /* out of a bottom port */
|
|
379
|
+
let z = [t[0], Math.min(t[1], box_t.y1) - m - 1]; /* into a top port */
|
|
357
380
|
let region = box_expand({
|
|
358
381
|
x1: Math.min(a[0], z[0], box_s.x1, box_t.x1),
|
|
359
382
|
y1: Math.min(a[1], z[1], box_s.y1, box_t.y1),
|
package/src/treedb_elbow.test.js
CHANGED
|
@@ -165,6 +165,43 @@ describe("the route round the other cards", () => {
|
|
|
165
165
|
});
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
+
describe("the ports are obstacles too", () => {
|
|
169
|
+
/* Whole-node boxes: a port of 14px sticks 7px out of the bottom
|
|
170
|
+
* and the top of each card. */
|
|
171
|
+
const AP = {x1: 0, y1: -7, x2: 100, y2: 47};
|
|
172
|
+
const BP = {x1: 350, y1: 123, x2: 450, y2: 177};
|
|
173
|
+
const S = [50, 40];
|
|
174
|
+
const T2 = [400, 130];
|
|
175
|
+
|
|
176
|
+
test("an edge's own ports do not make its line a hit", () => {
|
|
177
|
+
let simple = elbow_points(S, T2, AP, BP, 0, true);
|
|
178
|
+
expect(elbow_path_hits([S, ...simple, T2], [AP, BP], AP, BP)).toBe(false);
|
|
179
|
+
expect(elbow_route(S, T2, AP, BP, 0, true, [AP, BP])).toEqual(simple);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("a port of a third card in the channel is gone round", () => {
|
|
183
|
+
/* F's card ends at y 80, above the channel (85); its port
|
|
184
|
+
* reaches down to 95, into it. */
|
|
185
|
+
const F_CARD = {x1: 200, y1: 0, x2: 300, y2: 80};
|
|
186
|
+
const F = {x1: 200, y1: -7, x2: 300, y2: 95};
|
|
187
|
+
let simple = elbow_points(S, T2, AP, BP, 0, true);
|
|
188
|
+
expect(elbow_path_hits([S, ...simple, T2], [AP, BP, F_CARD], AP, BP)).toBe(false);
|
|
189
|
+
expect(elbow_path_hits([S, ...simple, T2], [AP, BP, F], AP, BP)).toBe(true);
|
|
190
|
+
let route = elbow_route(S, T2, AP, BP, 0, true, [AP, BP, F]);
|
|
191
|
+
expect(elbow_path_hits([S, ...route, T2], [AP, BP, F], AP, BP)).toBe(false);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("a detour clears the ports of its own two cards", () => {
|
|
195
|
+
/* B below A, both with their ports: B -> A goes round. */
|
|
196
|
+
const AB = {x1: 0, y1: -7, x2: 100, y2: 47};
|
|
197
|
+
const BB = {x1: 0, y1: 123, x2: 100, y2: 177};
|
|
198
|
+
let pts = elbow_points([60, 170], [50, 0], BB, AB, 0, true);
|
|
199
|
+
expect(pts[0][1]).toBeGreaterThan(BB.y2);
|
|
200
|
+
expect(pts[3][1]).toBeLessThan(AB.y1);
|
|
201
|
+
expect(elbow_path_hits([[60, 170], ...pts, [50, 0]], [AB, BB], BB, AB)).toBe(false);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
168
205
|
describe("read left to right", () => {
|
|
169
206
|
test("is the same geometry with the axes swapped", () => {
|
|
170
207
|
let sw = (p) => [p[1], p[0]];
|