@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/providers/index.cjs
CHANGED
|
@@ -35530,8 +35530,11 @@ var init_GraphCanvas = __esm({
|
|
|
35530
35530
|
React83.useEffect(() => {
|
|
35531
35531
|
const canvas = canvasRef.current;
|
|
35532
35532
|
if (!canvas || propNodes.length === 0) return;
|
|
35533
|
-
const
|
|
35534
|
-
const
|
|
35533
|
+
const viewW = logicalW;
|
|
35534
|
+
const viewH = height;
|
|
35535
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
35536
|
+
const w = viewW * layoutScale;
|
|
35537
|
+
const h = viewH * layoutScale;
|
|
35535
35538
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
35536
35539
|
const prevPos = /* @__PURE__ */ new Map();
|
|
35537
35540
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
@@ -35571,93 +35574,122 @@ var init_GraphCanvas = __esm({
|
|
|
35571
35574
|
const COLLIDE_PASSES = 6;
|
|
35572
35575
|
const LABEL_GAP = 12;
|
|
35573
35576
|
const LABEL_H = 16;
|
|
35574
|
-
const
|
|
35577
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
35578
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
35579
|
+
const drawnPairs = /* @__PURE__ */ new Set();
|
|
35580
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35581
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
35582
|
+
{
|
|
35583
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
35584
|
+
for (const pair of propSimilarity) {
|
|
35585
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
35586
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
35587
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
35588
|
+
arr.push(pair);
|
|
35589
|
+
bySource.set(pair.source, arr);
|
|
35590
|
+
}
|
|
35591
|
+
for (const [id, arr] of bySource) {
|
|
35592
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
35593
|
+
const keep = new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target));
|
|
35594
|
+
similarityNeighbors.set(id, keep);
|
|
35595
|
+
}
|
|
35596
|
+
}
|
|
35597
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
35598
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
35599
|
+
const a = similarityNeighbors.get(pair.source);
|
|
35600
|
+
const b = similarityNeighbors.get(pair.target);
|
|
35601
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
35602
|
+
});
|
|
35603
|
+
const tick = (iter, options) => {
|
|
35604
|
+
const skipForces = options?.skipForces ?? false;
|
|
35575
35605
|
const nodes = nodesRef.current;
|
|
35576
35606
|
const centerX = w / 2;
|
|
35577
35607
|
const centerY = h / 2;
|
|
35578
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
35608
|
+
const temp = skipForces ? 0 : Math.max(COOL, 1 - iter / maxIterations);
|
|
35579
35609
|
for (const node of nodes) {
|
|
35580
35610
|
node.fx = 0;
|
|
35581
35611
|
node.fy = 0;
|
|
35582
35612
|
}
|
|
35583
|
-
|
|
35584
|
-
for (let
|
|
35585
|
-
|
|
35586
|
-
|
|
35613
|
+
if (!skipForces) {
|
|
35614
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
35615
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
35616
|
+
const dx = nodes[j].x - nodes[i].x;
|
|
35617
|
+
const dy = nodes[j].y - nodes[i].y;
|
|
35618
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35619
|
+
const force = repulsion / (dist * dist) * temp;
|
|
35620
|
+
const fx = dx / dist * force;
|
|
35621
|
+
const fy = dy / dist * force;
|
|
35622
|
+
nodes[i].fx -= fx;
|
|
35623
|
+
nodes[i].fy -= fy;
|
|
35624
|
+
nodes[j].fx += fx;
|
|
35625
|
+
nodes[j].fy += fy;
|
|
35626
|
+
}
|
|
35627
|
+
}
|
|
35628
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
35629
|
+
const spring = (a, b, rest, k) => {
|
|
35630
|
+
const dx = b.x - a.x;
|
|
35631
|
+
const dy = b.y - a.y;
|
|
35587
35632
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35588
|
-
const force =
|
|
35633
|
+
const force = (dist - rest) * k * temp;
|
|
35589
35634
|
const fx = dx / dist * force;
|
|
35590
35635
|
const fy = dy / dist * force;
|
|
35591
|
-
|
|
35592
|
-
|
|
35593
|
-
|
|
35594
|
-
|
|
35636
|
+
a.fx += fx;
|
|
35637
|
+
a.fy += fy;
|
|
35638
|
+
b.fx -= fx;
|
|
35639
|
+
b.fy -= fy;
|
|
35640
|
+
};
|
|
35641
|
+
for (const edge of propEdges) {
|
|
35642
|
+
const source = nodeById.get(edge.source);
|
|
35643
|
+
const target = nodeById.get(edge.target);
|
|
35644
|
+
if (!source || !target) continue;
|
|
35645
|
+
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35646
|
+
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
35647
|
+
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
35595
35648
|
}
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35600
|
-
|
|
35601
|
-
|
|
35602
|
-
const force = (dist - rest) * k * temp;
|
|
35603
|
-
const fx = dx / dist * force;
|
|
35604
|
-
const fy = dy / dist * force;
|
|
35605
|
-
a.fx += fx;
|
|
35606
|
-
a.fy += fy;
|
|
35607
|
-
b.fx -= fx;
|
|
35608
|
-
b.fy -= fy;
|
|
35609
|
-
};
|
|
35610
|
-
const drawnPairs = /* @__PURE__ */ new Set();
|
|
35611
|
-
for (const edge of propEdges) {
|
|
35612
|
-
const source = nodeById.get(edge.source);
|
|
35613
|
-
const target = nodeById.get(edge.target);
|
|
35614
|
-
if (!source || !target) continue;
|
|
35615
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35616
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
35617
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
35618
|
-
}
|
|
35619
|
-
for (const pair of propSimilarity) {
|
|
35620
|
-
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
35621
|
-
const source = nodeById.get(pair.source);
|
|
35622
|
-
const target = nodeById.get(pair.target);
|
|
35623
|
-
if (!source || !target) continue;
|
|
35624
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
35625
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
35626
|
-
}
|
|
35627
|
-
const centroids = /* @__PURE__ */ new Map();
|
|
35628
|
-
for (const node of nodes) {
|
|
35629
|
-
const g = node.group ?? "__none__";
|
|
35630
|
-
let c = centroids.get(g);
|
|
35631
|
-
if (!c) {
|
|
35632
|
-
c = { x: 0, y: 0, n: 0 };
|
|
35633
|
-
centroids.set(g, c);
|
|
35649
|
+
for (const pair of activeSimilarity) {
|
|
35650
|
+
const source = nodeById.get(pair.source);
|
|
35651
|
+
const target = nodeById.get(pair.target);
|
|
35652
|
+
if (!source || !target) continue;
|
|
35653
|
+
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
35654
|
+
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
35634
35655
|
}
|
|
35635
|
-
|
|
35636
|
-
|
|
35637
|
-
|
|
35638
|
-
|
|
35639
|
-
|
|
35640
|
-
|
|
35641
|
-
|
|
35642
|
-
|
|
35643
|
-
|
|
35644
|
-
|
|
35645
|
-
|
|
35656
|
+
const centroids = /* @__PURE__ */ new Map();
|
|
35657
|
+
for (const node of nodes) {
|
|
35658
|
+
const g = node.group ?? "__none__";
|
|
35659
|
+
let c = centroids.get(g);
|
|
35660
|
+
if (!c) {
|
|
35661
|
+
c = { x: 0, y: 0, n: 0 };
|
|
35662
|
+
centroids.set(g, c);
|
|
35663
|
+
}
|
|
35664
|
+
c.x += node.x;
|
|
35665
|
+
c.y += node.y;
|
|
35666
|
+
c.n += 1;
|
|
35667
|
+
}
|
|
35668
|
+
const multiCluster = centroids.size > 1;
|
|
35669
|
+
for (const node of nodes) {
|
|
35670
|
+
if (multiCluster) {
|
|
35671
|
+
const c = centroids.get(node.group ?? "__none__");
|
|
35672
|
+
if (c && c.n > 1) {
|
|
35673
|
+
node.fx += (c.x / c.n - node.x) * 0.06 * temp;
|
|
35674
|
+
node.fy += (c.y / c.n - node.y) * 0.06 * temp;
|
|
35675
|
+
} else {
|
|
35676
|
+
node.fx += (centerX - node.x) * 0.01 * temp;
|
|
35677
|
+
node.fy += (centerY - node.y) * 0.01 * temp;
|
|
35678
|
+
}
|
|
35646
35679
|
} else {
|
|
35647
|
-
node.fx += (centerX - node.x) *
|
|
35648
|
-
node.fy += (centerY - node.y) *
|
|
35680
|
+
node.fx += (centerX - node.x) * 8e-3 * temp;
|
|
35681
|
+
node.fy += (centerY - node.y) * 8e-3 * temp;
|
|
35649
35682
|
}
|
|
35650
|
-
}
|
|
35651
|
-
|
|
35652
|
-
|
|
35683
|
+
}
|
|
35684
|
+
const damping = 0.9;
|
|
35685
|
+
for (const node of nodes) {
|
|
35686
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
35687
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
35688
|
+
node.x += node.vx;
|
|
35689
|
+
node.y += node.vy;
|
|
35653
35690
|
}
|
|
35654
35691
|
}
|
|
35655
|
-
const damping = 0.9;
|
|
35656
35692
|
for (const node of nodes) {
|
|
35657
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
35658
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
35659
|
-
node.x += node.vx;
|
|
35660
|
-
node.y += node.vy;
|
|
35661
35693
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
35662
35694
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
35663
35695
|
}
|
|
@@ -35708,6 +35740,22 @@ var init_GraphCanvas = __esm({
|
|
|
35708
35740
|
};
|
|
35709
35741
|
if (fullRelayout) {
|
|
35710
35742
|
for (let i = 0; i < maxIterations; i++) tick(i);
|
|
35743
|
+
for (let i = 0; i < 4; i++) tick(maxIterations, { skipForces: true });
|
|
35744
|
+
const fitPad = 40;
|
|
35745
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
35746
|
+
for (const node of nodesRef.current) {
|
|
35747
|
+
const r = node.size || 8;
|
|
35748
|
+
const lw = showLabels ? node.labelW ?? (node.labelW = node.label ? measureLabelWidth(node.label, labelFont) : 0) : 0;
|
|
35749
|
+
minX = Math.min(minX, node.x - r, node.x - lw / 2);
|
|
35750
|
+
minY = Math.min(minY, node.y - r);
|
|
35751
|
+
maxX = Math.max(maxX, node.x + r, node.x + lw / 2);
|
|
35752
|
+
maxY = Math.max(maxY, node.y + r + LABEL_GAP + LABEL_H);
|
|
35753
|
+
}
|
|
35754
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
35755
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
35756
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
35757
|
+
setZoom(nextZoom);
|
|
35758
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
35711
35759
|
laidOutRef.current = true;
|
|
35712
35760
|
} else {
|
|
35713
35761
|
const centroids = /* @__PURE__ */ new Map();
|
package/dist/providers/index.js
CHANGED
|
@@ -35485,8 +35485,11 @@ var init_GraphCanvas = __esm({
|
|
|
35485
35485
|
useEffect(() => {
|
|
35486
35486
|
const canvas = canvasRef.current;
|
|
35487
35487
|
if (!canvas || propNodes.length === 0) return;
|
|
35488
|
-
const
|
|
35489
|
-
const
|
|
35488
|
+
const viewW = logicalW;
|
|
35489
|
+
const viewH = height;
|
|
35490
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
35491
|
+
const w = viewW * layoutScale;
|
|
35492
|
+
const h = viewH * layoutScale;
|
|
35490
35493
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
35491
35494
|
const prevPos = /* @__PURE__ */ new Map();
|
|
35492
35495
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
@@ -35526,93 +35529,122 @@ var init_GraphCanvas = __esm({
|
|
|
35526
35529
|
const COLLIDE_PASSES = 6;
|
|
35527
35530
|
const LABEL_GAP = 12;
|
|
35528
35531
|
const LABEL_H = 16;
|
|
35529
|
-
const
|
|
35532
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
35533
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
35534
|
+
const drawnPairs = /* @__PURE__ */ new Set();
|
|
35535
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35536
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
35537
|
+
{
|
|
35538
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
35539
|
+
for (const pair of propSimilarity) {
|
|
35540
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
35541
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
35542
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
35543
|
+
arr.push(pair);
|
|
35544
|
+
bySource.set(pair.source, arr);
|
|
35545
|
+
}
|
|
35546
|
+
for (const [id, arr] of bySource) {
|
|
35547
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
35548
|
+
const keep = new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target));
|
|
35549
|
+
similarityNeighbors.set(id, keep);
|
|
35550
|
+
}
|
|
35551
|
+
}
|
|
35552
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
35553
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
35554
|
+
const a = similarityNeighbors.get(pair.source);
|
|
35555
|
+
const b = similarityNeighbors.get(pair.target);
|
|
35556
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
35557
|
+
});
|
|
35558
|
+
const tick = (iter, options) => {
|
|
35559
|
+
const skipForces = options?.skipForces ?? false;
|
|
35530
35560
|
const nodes = nodesRef.current;
|
|
35531
35561
|
const centerX = w / 2;
|
|
35532
35562
|
const centerY = h / 2;
|
|
35533
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
35563
|
+
const temp = skipForces ? 0 : Math.max(COOL, 1 - iter / maxIterations);
|
|
35534
35564
|
for (const node of nodes) {
|
|
35535
35565
|
node.fx = 0;
|
|
35536
35566
|
node.fy = 0;
|
|
35537
35567
|
}
|
|
35538
|
-
|
|
35539
|
-
for (let
|
|
35540
|
-
|
|
35541
|
-
|
|
35568
|
+
if (!skipForces) {
|
|
35569
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
35570
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
35571
|
+
const dx = nodes[j].x - nodes[i].x;
|
|
35572
|
+
const dy = nodes[j].y - nodes[i].y;
|
|
35573
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35574
|
+
const force = repulsion / (dist * dist) * temp;
|
|
35575
|
+
const fx = dx / dist * force;
|
|
35576
|
+
const fy = dy / dist * force;
|
|
35577
|
+
nodes[i].fx -= fx;
|
|
35578
|
+
nodes[i].fy -= fy;
|
|
35579
|
+
nodes[j].fx += fx;
|
|
35580
|
+
nodes[j].fy += fy;
|
|
35581
|
+
}
|
|
35582
|
+
}
|
|
35583
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
35584
|
+
const spring = (a, b, rest, k) => {
|
|
35585
|
+
const dx = b.x - a.x;
|
|
35586
|
+
const dy = b.y - a.y;
|
|
35542
35587
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35543
|
-
const force =
|
|
35588
|
+
const force = (dist - rest) * k * temp;
|
|
35544
35589
|
const fx = dx / dist * force;
|
|
35545
35590
|
const fy = dy / dist * force;
|
|
35546
|
-
|
|
35547
|
-
|
|
35548
|
-
|
|
35549
|
-
|
|
35591
|
+
a.fx += fx;
|
|
35592
|
+
a.fy += fy;
|
|
35593
|
+
b.fx -= fx;
|
|
35594
|
+
b.fy -= fy;
|
|
35595
|
+
};
|
|
35596
|
+
for (const edge of propEdges) {
|
|
35597
|
+
const source = nodeById.get(edge.source);
|
|
35598
|
+
const target = nodeById.get(edge.target);
|
|
35599
|
+
if (!source || !target) continue;
|
|
35600
|
+
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35601
|
+
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
35602
|
+
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
35550
35603
|
}
|
|
35551
|
-
|
|
35552
|
-
|
|
35553
|
-
|
|
35554
|
-
|
|
35555
|
-
|
|
35556
|
-
|
|
35557
|
-
const force = (dist - rest) * k * temp;
|
|
35558
|
-
const fx = dx / dist * force;
|
|
35559
|
-
const fy = dy / dist * force;
|
|
35560
|
-
a.fx += fx;
|
|
35561
|
-
a.fy += fy;
|
|
35562
|
-
b.fx -= fx;
|
|
35563
|
-
b.fy -= fy;
|
|
35564
|
-
};
|
|
35565
|
-
const drawnPairs = /* @__PURE__ */ new Set();
|
|
35566
|
-
for (const edge of propEdges) {
|
|
35567
|
-
const source = nodeById.get(edge.source);
|
|
35568
|
-
const target = nodeById.get(edge.target);
|
|
35569
|
-
if (!source || !target) continue;
|
|
35570
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35571
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
35572
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
35573
|
-
}
|
|
35574
|
-
for (const pair of propSimilarity) {
|
|
35575
|
-
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
35576
|
-
const source = nodeById.get(pair.source);
|
|
35577
|
-
const target = nodeById.get(pair.target);
|
|
35578
|
-
if (!source || !target) continue;
|
|
35579
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
35580
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
35581
|
-
}
|
|
35582
|
-
const centroids = /* @__PURE__ */ new Map();
|
|
35583
|
-
for (const node of nodes) {
|
|
35584
|
-
const g = node.group ?? "__none__";
|
|
35585
|
-
let c = centroids.get(g);
|
|
35586
|
-
if (!c) {
|
|
35587
|
-
c = { x: 0, y: 0, n: 0 };
|
|
35588
|
-
centroids.set(g, c);
|
|
35604
|
+
for (const pair of activeSimilarity) {
|
|
35605
|
+
const source = nodeById.get(pair.source);
|
|
35606
|
+
const target = nodeById.get(pair.target);
|
|
35607
|
+
if (!source || !target) continue;
|
|
35608
|
+
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
35609
|
+
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
35589
35610
|
}
|
|
35590
|
-
|
|
35591
|
-
|
|
35592
|
-
|
|
35593
|
-
|
|
35594
|
-
|
|
35595
|
-
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35600
|
-
|
|
35611
|
+
const centroids = /* @__PURE__ */ new Map();
|
|
35612
|
+
for (const node of nodes) {
|
|
35613
|
+
const g = node.group ?? "__none__";
|
|
35614
|
+
let c = centroids.get(g);
|
|
35615
|
+
if (!c) {
|
|
35616
|
+
c = { x: 0, y: 0, n: 0 };
|
|
35617
|
+
centroids.set(g, c);
|
|
35618
|
+
}
|
|
35619
|
+
c.x += node.x;
|
|
35620
|
+
c.y += node.y;
|
|
35621
|
+
c.n += 1;
|
|
35622
|
+
}
|
|
35623
|
+
const multiCluster = centroids.size > 1;
|
|
35624
|
+
for (const node of nodes) {
|
|
35625
|
+
if (multiCluster) {
|
|
35626
|
+
const c = centroids.get(node.group ?? "__none__");
|
|
35627
|
+
if (c && c.n > 1) {
|
|
35628
|
+
node.fx += (c.x / c.n - node.x) * 0.06 * temp;
|
|
35629
|
+
node.fy += (c.y / c.n - node.y) * 0.06 * temp;
|
|
35630
|
+
} else {
|
|
35631
|
+
node.fx += (centerX - node.x) * 0.01 * temp;
|
|
35632
|
+
node.fy += (centerY - node.y) * 0.01 * temp;
|
|
35633
|
+
}
|
|
35601
35634
|
} else {
|
|
35602
|
-
node.fx += (centerX - node.x) *
|
|
35603
|
-
node.fy += (centerY - node.y) *
|
|
35635
|
+
node.fx += (centerX - node.x) * 8e-3 * temp;
|
|
35636
|
+
node.fy += (centerY - node.y) * 8e-3 * temp;
|
|
35604
35637
|
}
|
|
35605
|
-
}
|
|
35606
|
-
|
|
35607
|
-
|
|
35638
|
+
}
|
|
35639
|
+
const damping = 0.9;
|
|
35640
|
+
for (const node of nodes) {
|
|
35641
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
35642
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
35643
|
+
node.x += node.vx;
|
|
35644
|
+
node.y += node.vy;
|
|
35608
35645
|
}
|
|
35609
35646
|
}
|
|
35610
|
-
const damping = 0.9;
|
|
35611
35647
|
for (const node of nodes) {
|
|
35612
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
35613
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
35614
|
-
node.x += node.vx;
|
|
35615
|
-
node.y += node.vy;
|
|
35616
35648
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
35617
35649
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
35618
35650
|
}
|
|
@@ -35663,6 +35695,22 @@ var init_GraphCanvas = __esm({
|
|
|
35663
35695
|
};
|
|
35664
35696
|
if (fullRelayout) {
|
|
35665
35697
|
for (let i = 0; i < maxIterations; i++) tick(i);
|
|
35698
|
+
for (let i = 0; i < 4; i++) tick(maxIterations, { skipForces: true });
|
|
35699
|
+
const fitPad = 40;
|
|
35700
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
35701
|
+
for (const node of nodesRef.current) {
|
|
35702
|
+
const r = node.size || 8;
|
|
35703
|
+
const lw = showLabels ? node.labelW ?? (node.labelW = node.label ? measureLabelWidth(node.label, labelFont) : 0) : 0;
|
|
35704
|
+
minX = Math.min(minX, node.x - r, node.x - lw / 2);
|
|
35705
|
+
minY = Math.min(minY, node.y - r);
|
|
35706
|
+
maxX = Math.max(maxX, node.x + r, node.x + lw / 2);
|
|
35707
|
+
maxY = Math.max(maxY, node.y + r + LABEL_GAP + LABEL_H);
|
|
35708
|
+
}
|
|
35709
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
35710
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
35711
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
35712
|
+
setZoom(nextZoom);
|
|
35713
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
35666
35714
|
laidOutRef.current = true;
|
|
35667
35715
|
} else {
|
|
35668
35716
|
const centroids = /* @__PURE__ */ new Map();
|