@almadar/ui 5.119.0 → 5.120.0
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/dist/avl/index.cjs +120 -72
- package/dist/avl/index.js +120 -72
- package/dist/components/index.cjs +120 -72
- package/dist/components/index.js +120 -72
- package/dist/providers/index.cjs +120 -72
- package/dist/providers/index.js +120 -72
- package/dist/runtime/index.cjs +120 -72
- package/dist/runtime/index.js +120 -72
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -37400,8 +37400,11 @@ var init_GraphCanvas = __esm({
|
|
|
37400
37400
|
React90.useEffect(() => {
|
|
37401
37401
|
const canvas = canvasRef.current;
|
|
37402
37402
|
if (!canvas || propNodes.length === 0) return;
|
|
37403
|
-
const
|
|
37404
|
-
const
|
|
37403
|
+
const viewW = logicalW;
|
|
37404
|
+
const viewH = height;
|
|
37405
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
37406
|
+
const w = viewW * layoutScale;
|
|
37407
|
+
const h = viewH * layoutScale;
|
|
37405
37408
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
37406
37409
|
const prevPos = /* @__PURE__ */ new Map();
|
|
37407
37410
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
@@ -37441,93 +37444,122 @@ var init_GraphCanvas = __esm({
|
|
|
37441
37444
|
const COLLIDE_PASSES = 6;
|
|
37442
37445
|
const LABEL_GAP = 12;
|
|
37443
37446
|
const LABEL_H = 16;
|
|
37444
|
-
const
|
|
37447
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
37448
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
37449
|
+
const drawnPairs = /* @__PURE__ */ new Set();
|
|
37450
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37451
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
37452
|
+
{
|
|
37453
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
37454
|
+
for (const pair of propSimilarity) {
|
|
37455
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
37456
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
37457
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
37458
|
+
arr.push(pair);
|
|
37459
|
+
bySource.set(pair.source, arr);
|
|
37460
|
+
}
|
|
37461
|
+
for (const [id, arr] of bySource) {
|
|
37462
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
37463
|
+
const keep = new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target));
|
|
37464
|
+
similarityNeighbors.set(id, keep);
|
|
37465
|
+
}
|
|
37466
|
+
}
|
|
37467
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
37468
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
37469
|
+
const a = similarityNeighbors.get(pair.source);
|
|
37470
|
+
const b = similarityNeighbors.get(pair.target);
|
|
37471
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
37472
|
+
});
|
|
37473
|
+
const tick = (iter, options) => {
|
|
37474
|
+
const skipForces = options?.skipForces ?? false;
|
|
37445
37475
|
const nodes = nodesRef.current;
|
|
37446
37476
|
const centerX = w / 2;
|
|
37447
37477
|
const centerY = h / 2;
|
|
37448
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
37478
|
+
const temp = skipForces ? 0 : Math.max(COOL, 1 - iter / maxIterations);
|
|
37449
37479
|
for (const node of nodes) {
|
|
37450
37480
|
node.fx = 0;
|
|
37451
37481
|
node.fy = 0;
|
|
37452
37482
|
}
|
|
37453
|
-
|
|
37454
|
-
for (let
|
|
37455
|
-
|
|
37456
|
-
|
|
37483
|
+
if (!skipForces) {
|
|
37484
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
37485
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
37486
|
+
const dx = nodes[j].x - nodes[i].x;
|
|
37487
|
+
const dy = nodes[j].y - nodes[i].y;
|
|
37488
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37489
|
+
const force = repulsion / (dist * dist) * temp;
|
|
37490
|
+
const fx = dx / dist * force;
|
|
37491
|
+
const fy = dy / dist * force;
|
|
37492
|
+
nodes[i].fx -= fx;
|
|
37493
|
+
nodes[i].fy -= fy;
|
|
37494
|
+
nodes[j].fx += fx;
|
|
37495
|
+
nodes[j].fy += fy;
|
|
37496
|
+
}
|
|
37497
|
+
}
|
|
37498
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
37499
|
+
const spring = (a, b, rest, k) => {
|
|
37500
|
+
const dx = b.x - a.x;
|
|
37501
|
+
const dy = b.y - a.y;
|
|
37457
37502
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37458
|
-
const force =
|
|
37503
|
+
const force = (dist - rest) * k * temp;
|
|
37459
37504
|
const fx = dx / dist * force;
|
|
37460
37505
|
const fy = dy / dist * force;
|
|
37461
|
-
|
|
37462
|
-
|
|
37463
|
-
|
|
37464
|
-
|
|
37506
|
+
a.fx += fx;
|
|
37507
|
+
a.fy += fy;
|
|
37508
|
+
b.fx -= fx;
|
|
37509
|
+
b.fy -= fy;
|
|
37510
|
+
};
|
|
37511
|
+
for (const edge of propEdges) {
|
|
37512
|
+
const source = nodeById.get(edge.source);
|
|
37513
|
+
const target = nodeById.get(edge.target);
|
|
37514
|
+
if (!source || !target) continue;
|
|
37515
|
+
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37516
|
+
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37517
|
+
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37465
37518
|
}
|
|
37466
|
-
|
|
37467
|
-
|
|
37468
|
-
|
|
37469
|
-
|
|
37470
|
-
|
|
37471
|
-
|
|
37472
|
-
const force = (dist - rest) * k * temp;
|
|
37473
|
-
const fx = dx / dist * force;
|
|
37474
|
-
const fy = dy / dist * force;
|
|
37475
|
-
a.fx += fx;
|
|
37476
|
-
a.fy += fy;
|
|
37477
|
-
b.fx -= fx;
|
|
37478
|
-
b.fy -= fy;
|
|
37479
|
-
};
|
|
37480
|
-
const drawnPairs = /* @__PURE__ */ new Set();
|
|
37481
|
-
for (const edge of propEdges) {
|
|
37482
|
-
const source = nodeById.get(edge.source);
|
|
37483
|
-
const target = nodeById.get(edge.target);
|
|
37484
|
-
if (!source || !target) continue;
|
|
37485
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37486
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37487
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37488
|
-
}
|
|
37489
|
-
for (const pair of propSimilarity) {
|
|
37490
|
-
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
37491
|
-
const source = nodeById.get(pair.source);
|
|
37492
|
-
const target = nodeById.get(pair.target);
|
|
37493
|
-
if (!source || !target) continue;
|
|
37494
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
37495
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
37496
|
-
}
|
|
37497
|
-
const centroids = /* @__PURE__ */ new Map();
|
|
37498
|
-
for (const node of nodes) {
|
|
37499
|
-
const g = node.group ?? "__none__";
|
|
37500
|
-
let c = centroids.get(g);
|
|
37501
|
-
if (!c) {
|
|
37502
|
-
c = { x: 0, y: 0, n: 0 };
|
|
37503
|
-
centroids.set(g, c);
|
|
37519
|
+
for (const pair of activeSimilarity) {
|
|
37520
|
+
const source = nodeById.get(pair.source);
|
|
37521
|
+
const target = nodeById.get(pair.target);
|
|
37522
|
+
if (!source || !target) continue;
|
|
37523
|
+
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
37524
|
+
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
37504
37525
|
}
|
|
37505
|
-
|
|
37506
|
-
|
|
37507
|
-
|
|
37508
|
-
|
|
37509
|
-
|
|
37510
|
-
|
|
37511
|
-
|
|
37512
|
-
|
|
37513
|
-
|
|
37514
|
-
|
|
37515
|
-
|
|
37526
|
+
const centroids = /* @__PURE__ */ new Map();
|
|
37527
|
+
for (const node of nodes) {
|
|
37528
|
+
const g = node.group ?? "__none__";
|
|
37529
|
+
let c = centroids.get(g);
|
|
37530
|
+
if (!c) {
|
|
37531
|
+
c = { x: 0, y: 0, n: 0 };
|
|
37532
|
+
centroids.set(g, c);
|
|
37533
|
+
}
|
|
37534
|
+
c.x += node.x;
|
|
37535
|
+
c.y += node.y;
|
|
37536
|
+
c.n += 1;
|
|
37537
|
+
}
|
|
37538
|
+
const multiCluster = centroids.size > 1;
|
|
37539
|
+
for (const node of nodes) {
|
|
37540
|
+
if (multiCluster) {
|
|
37541
|
+
const c = centroids.get(node.group ?? "__none__");
|
|
37542
|
+
if (c && c.n > 1) {
|
|
37543
|
+
node.fx += (c.x / c.n - node.x) * 0.06 * temp;
|
|
37544
|
+
node.fy += (c.y / c.n - node.y) * 0.06 * temp;
|
|
37545
|
+
} else {
|
|
37546
|
+
node.fx += (centerX - node.x) * 0.01 * temp;
|
|
37547
|
+
node.fy += (centerY - node.y) * 0.01 * temp;
|
|
37548
|
+
}
|
|
37516
37549
|
} else {
|
|
37517
|
-
node.fx += (centerX - node.x) *
|
|
37518
|
-
node.fy += (centerY - node.y) *
|
|
37550
|
+
node.fx += (centerX - node.x) * 8e-3 * temp;
|
|
37551
|
+
node.fy += (centerY - node.y) * 8e-3 * temp;
|
|
37519
37552
|
}
|
|
37520
|
-
}
|
|
37521
|
-
|
|
37522
|
-
|
|
37553
|
+
}
|
|
37554
|
+
const damping = 0.9;
|
|
37555
|
+
for (const node of nodes) {
|
|
37556
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
37557
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
37558
|
+
node.x += node.vx;
|
|
37559
|
+
node.y += node.vy;
|
|
37523
37560
|
}
|
|
37524
37561
|
}
|
|
37525
|
-
const damping = 0.9;
|
|
37526
37562
|
for (const node of nodes) {
|
|
37527
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
37528
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
37529
|
-
node.x += node.vx;
|
|
37530
|
-
node.y += node.vy;
|
|
37531
37563
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
37532
37564
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
37533
37565
|
}
|
|
@@ -37578,6 +37610,22 @@ var init_GraphCanvas = __esm({
|
|
|
37578
37610
|
};
|
|
37579
37611
|
if (fullRelayout) {
|
|
37580
37612
|
for (let i = 0; i < maxIterations; i++) tick(i);
|
|
37613
|
+
for (let i = 0; i < 4; i++) tick(maxIterations, { skipForces: true });
|
|
37614
|
+
const fitPad = 40;
|
|
37615
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
37616
|
+
for (const node of nodesRef.current) {
|
|
37617
|
+
const r2 = node.size || 8;
|
|
37618
|
+
const lw = showLabels ? node.labelW ?? (node.labelW = node.label ? measureLabelWidth(node.label, labelFont) : 0) : 0;
|
|
37619
|
+
minX = Math.min(minX, node.x - r2, node.x - lw / 2);
|
|
37620
|
+
minY = Math.min(minY, node.y - r2);
|
|
37621
|
+
maxX = Math.max(maxX, node.x + r2, node.x + lw / 2);
|
|
37622
|
+
maxY = Math.max(maxY, node.y + r2 + LABEL_GAP + LABEL_H);
|
|
37623
|
+
}
|
|
37624
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
37625
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
37626
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
37627
|
+
setZoom(nextZoom);
|
|
37628
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
37581
37629
|
laidOutRef.current = true;
|
|
37582
37630
|
} else {
|
|
37583
37631
|
const centroids = /* @__PURE__ */ new Map();
|
package/dist/avl/index.js
CHANGED
|
@@ -37354,8 +37354,11 @@ var init_GraphCanvas = __esm({
|
|
|
37354
37354
|
useEffect(() => {
|
|
37355
37355
|
const canvas = canvasRef.current;
|
|
37356
37356
|
if (!canvas || propNodes.length === 0) return;
|
|
37357
|
-
const
|
|
37358
|
-
const
|
|
37357
|
+
const viewW = logicalW;
|
|
37358
|
+
const viewH = height;
|
|
37359
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
37360
|
+
const w = viewW * layoutScale;
|
|
37361
|
+
const h = viewH * layoutScale;
|
|
37359
37362
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
37360
37363
|
const prevPos = /* @__PURE__ */ new Map();
|
|
37361
37364
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
@@ -37395,93 +37398,122 @@ var init_GraphCanvas = __esm({
|
|
|
37395
37398
|
const COLLIDE_PASSES = 6;
|
|
37396
37399
|
const LABEL_GAP = 12;
|
|
37397
37400
|
const LABEL_H = 16;
|
|
37398
|
-
const
|
|
37401
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
37402
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
37403
|
+
const drawnPairs = /* @__PURE__ */ new Set();
|
|
37404
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37405
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
37406
|
+
{
|
|
37407
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
37408
|
+
for (const pair of propSimilarity) {
|
|
37409
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
37410
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
37411
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
37412
|
+
arr.push(pair);
|
|
37413
|
+
bySource.set(pair.source, arr);
|
|
37414
|
+
}
|
|
37415
|
+
for (const [id, arr] of bySource) {
|
|
37416
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
37417
|
+
const keep = new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target));
|
|
37418
|
+
similarityNeighbors.set(id, keep);
|
|
37419
|
+
}
|
|
37420
|
+
}
|
|
37421
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
37422
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
37423
|
+
const a = similarityNeighbors.get(pair.source);
|
|
37424
|
+
const b = similarityNeighbors.get(pair.target);
|
|
37425
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
37426
|
+
});
|
|
37427
|
+
const tick = (iter, options) => {
|
|
37428
|
+
const skipForces = options?.skipForces ?? false;
|
|
37399
37429
|
const nodes = nodesRef.current;
|
|
37400
37430
|
const centerX = w / 2;
|
|
37401
37431
|
const centerY = h / 2;
|
|
37402
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
37432
|
+
const temp = skipForces ? 0 : Math.max(COOL, 1 - iter / maxIterations);
|
|
37403
37433
|
for (const node of nodes) {
|
|
37404
37434
|
node.fx = 0;
|
|
37405
37435
|
node.fy = 0;
|
|
37406
37436
|
}
|
|
37407
|
-
|
|
37408
|
-
for (let
|
|
37409
|
-
|
|
37410
|
-
|
|
37437
|
+
if (!skipForces) {
|
|
37438
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
37439
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
37440
|
+
const dx = nodes[j].x - nodes[i].x;
|
|
37441
|
+
const dy = nodes[j].y - nodes[i].y;
|
|
37442
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37443
|
+
const force = repulsion / (dist * dist) * temp;
|
|
37444
|
+
const fx = dx / dist * force;
|
|
37445
|
+
const fy = dy / dist * force;
|
|
37446
|
+
nodes[i].fx -= fx;
|
|
37447
|
+
nodes[i].fy -= fy;
|
|
37448
|
+
nodes[j].fx += fx;
|
|
37449
|
+
nodes[j].fy += fy;
|
|
37450
|
+
}
|
|
37451
|
+
}
|
|
37452
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
37453
|
+
const spring = (a, b, rest, k) => {
|
|
37454
|
+
const dx = b.x - a.x;
|
|
37455
|
+
const dy = b.y - a.y;
|
|
37411
37456
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37412
|
-
const force =
|
|
37457
|
+
const force = (dist - rest) * k * temp;
|
|
37413
37458
|
const fx = dx / dist * force;
|
|
37414
37459
|
const fy = dy / dist * force;
|
|
37415
|
-
|
|
37416
|
-
|
|
37417
|
-
|
|
37418
|
-
|
|
37460
|
+
a.fx += fx;
|
|
37461
|
+
a.fy += fy;
|
|
37462
|
+
b.fx -= fx;
|
|
37463
|
+
b.fy -= fy;
|
|
37464
|
+
};
|
|
37465
|
+
for (const edge of propEdges) {
|
|
37466
|
+
const source = nodeById.get(edge.source);
|
|
37467
|
+
const target = nodeById.get(edge.target);
|
|
37468
|
+
if (!source || !target) continue;
|
|
37469
|
+
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37470
|
+
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37471
|
+
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37419
37472
|
}
|
|
37420
|
-
|
|
37421
|
-
|
|
37422
|
-
|
|
37423
|
-
|
|
37424
|
-
|
|
37425
|
-
|
|
37426
|
-
const force = (dist - rest) * k * temp;
|
|
37427
|
-
const fx = dx / dist * force;
|
|
37428
|
-
const fy = dy / dist * force;
|
|
37429
|
-
a.fx += fx;
|
|
37430
|
-
a.fy += fy;
|
|
37431
|
-
b.fx -= fx;
|
|
37432
|
-
b.fy -= fy;
|
|
37433
|
-
};
|
|
37434
|
-
const drawnPairs = /* @__PURE__ */ new Set();
|
|
37435
|
-
for (const edge of propEdges) {
|
|
37436
|
-
const source = nodeById.get(edge.source);
|
|
37437
|
-
const target = nodeById.get(edge.target);
|
|
37438
|
-
if (!source || !target) continue;
|
|
37439
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37440
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37441
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37442
|
-
}
|
|
37443
|
-
for (const pair of propSimilarity) {
|
|
37444
|
-
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
37445
|
-
const source = nodeById.get(pair.source);
|
|
37446
|
-
const target = nodeById.get(pair.target);
|
|
37447
|
-
if (!source || !target) continue;
|
|
37448
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
37449
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
37450
|
-
}
|
|
37451
|
-
const centroids = /* @__PURE__ */ new Map();
|
|
37452
|
-
for (const node of nodes) {
|
|
37453
|
-
const g = node.group ?? "__none__";
|
|
37454
|
-
let c = centroids.get(g);
|
|
37455
|
-
if (!c) {
|
|
37456
|
-
c = { x: 0, y: 0, n: 0 };
|
|
37457
|
-
centroids.set(g, c);
|
|
37473
|
+
for (const pair of activeSimilarity) {
|
|
37474
|
+
const source = nodeById.get(pair.source);
|
|
37475
|
+
const target = nodeById.get(pair.target);
|
|
37476
|
+
if (!source || !target) continue;
|
|
37477
|
+
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
37478
|
+
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
37458
37479
|
}
|
|
37459
|
-
|
|
37460
|
-
|
|
37461
|
-
|
|
37462
|
-
|
|
37463
|
-
|
|
37464
|
-
|
|
37465
|
-
|
|
37466
|
-
|
|
37467
|
-
|
|
37468
|
-
|
|
37469
|
-
|
|
37480
|
+
const centroids = /* @__PURE__ */ new Map();
|
|
37481
|
+
for (const node of nodes) {
|
|
37482
|
+
const g = node.group ?? "__none__";
|
|
37483
|
+
let c = centroids.get(g);
|
|
37484
|
+
if (!c) {
|
|
37485
|
+
c = { x: 0, y: 0, n: 0 };
|
|
37486
|
+
centroids.set(g, c);
|
|
37487
|
+
}
|
|
37488
|
+
c.x += node.x;
|
|
37489
|
+
c.y += node.y;
|
|
37490
|
+
c.n += 1;
|
|
37491
|
+
}
|
|
37492
|
+
const multiCluster = centroids.size > 1;
|
|
37493
|
+
for (const node of nodes) {
|
|
37494
|
+
if (multiCluster) {
|
|
37495
|
+
const c = centroids.get(node.group ?? "__none__");
|
|
37496
|
+
if (c && c.n > 1) {
|
|
37497
|
+
node.fx += (c.x / c.n - node.x) * 0.06 * temp;
|
|
37498
|
+
node.fy += (c.y / c.n - node.y) * 0.06 * temp;
|
|
37499
|
+
} else {
|
|
37500
|
+
node.fx += (centerX - node.x) * 0.01 * temp;
|
|
37501
|
+
node.fy += (centerY - node.y) * 0.01 * temp;
|
|
37502
|
+
}
|
|
37470
37503
|
} else {
|
|
37471
|
-
node.fx += (centerX - node.x) *
|
|
37472
|
-
node.fy += (centerY - node.y) *
|
|
37504
|
+
node.fx += (centerX - node.x) * 8e-3 * temp;
|
|
37505
|
+
node.fy += (centerY - node.y) * 8e-3 * temp;
|
|
37473
37506
|
}
|
|
37474
|
-
}
|
|
37475
|
-
|
|
37476
|
-
|
|
37507
|
+
}
|
|
37508
|
+
const damping = 0.9;
|
|
37509
|
+
for (const node of nodes) {
|
|
37510
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
37511
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
37512
|
+
node.x += node.vx;
|
|
37513
|
+
node.y += node.vy;
|
|
37477
37514
|
}
|
|
37478
37515
|
}
|
|
37479
|
-
const damping = 0.9;
|
|
37480
37516
|
for (const node of nodes) {
|
|
37481
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
37482
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
37483
|
-
node.x += node.vx;
|
|
37484
|
-
node.y += node.vy;
|
|
37485
37517
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
37486
37518
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
37487
37519
|
}
|
|
@@ -37532,6 +37564,22 @@ var init_GraphCanvas = __esm({
|
|
|
37532
37564
|
};
|
|
37533
37565
|
if (fullRelayout) {
|
|
37534
37566
|
for (let i = 0; i < maxIterations; i++) tick(i);
|
|
37567
|
+
for (let i = 0; i < 4; i++) tick(maxIterations, { skipForces: true });
|
|
37568
|
+
const fitPad = 40;
|
|
37569
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
37570
|
+
for (const node of nodesRef.current) {
|
|
37571
|
+
const r2 = node.size || 8;
|
|
37572
|
+
const lw = showLabels ? node.labelW ?? (node.labelW = node.label ? measureLabelWidth(node.label, labelFont) : 0) : 0;
|
|
37573
|
+
minX = Math.min(minX, node.x - r2, node.x - lw / 2);
|
|
37574
|
+
minY = Math.min(minY, node.y - r2);
|
|
37575
|
+
maxX = Math.max(maxX, node.x + r2, node.x + lw / 2);
|
|
37576
|
+
maxY = Math.max(maxY, node.y + r2 + LABEL_GAP + LABEL_H);
|
|
37577
|
+
}
|
|
37578
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
37579
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
37580
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
37581
|
+
setZoom(nextZoom);
|
|
37582
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
37535
37583
|
laidOutRef.current = true;
|
|
37536
37584
|
} else {
|
|
37537
37585
|
const centroids = /* @__PURE__ */ new Map();
|