@almadar/ui 5.118.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 +166 -100
- package/dist/avl/index.js +166 -100
- package/dist/components/index.cjs +166 -100
- package/dist/components/index.d.cts +9 -7
- package/dist/components/index.d.ts +9 -7
- package/dist/components/index.js +166 -100
- package/dist/providers/index.cjs +166 -100
- package/dist/providers/index.js +166 -100
- package/dist/runtime/index.cjs +166 -100
- package/dist/runtime/index.js +166 -100
- package/package.json +1 -1
package/dist/avl/index.js
CHANGED
|
@@ -37191,11 +37191,11 @@ var init_DocumentViewer = __esm({
|
|
|
37191
37191
|
DocumentViewer.displayName = "DocumentViewer";
|
|
37192
37192
|
}
|
|
37193
37193
|
});
|
|
37194
|
-
function measureLabelWidth(text) {
|
|
37194
|
+
function measureLabelWidth(text, fontFamily = "system-ui") {
|
|
37195
37195
|
if (typeof document === "undefined") return text.length * 6;
|
|
37196
37196
|
if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
|
|
37197
37197
|
if (!labelMeasureCtx) return text.length * 6;
|
|
37198
|
-
labelMeasureCtx.font =
|
|
37198
|
+
labelMeasureCtx.font = `12px ${fontFamily}`;
|
|
37199
37199
|
return labelMeasureCtx.measureText(text).width + 4;
|
|
37200
37200
|
}
|
|
37201
37201
|
function getGroupColor(group, groups) {
|
|
@@ -37220,6 +37220,9 @@ function mulberry32(a) {
|
|
|
37220
37220
|
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
37221
37221
|
};
|
|
37222
37222
|
}
|
|
37223
|
+
function edgeKeyOf(a, b) {
|
|
37224
|
+
return a < b ? `${a}\0${b}` : `${b}\0${a}`;
|
|
37225
|
+
}
|
|
37223
37226
|
function resolveColor3(color, el) {
|
|
37224
37227
|
const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
|
|
37225
37228
|
if (!m) return color;
|
|
@@ -37351,8 +37354,12 @@ var init_GraphCanvas = __esm({
|
|
|
37351
37354
|
useEffect(() => {
|
|
37352
37355
|
const canvas = canvasRef.current;
|
|
37353
37356
|
if (!canvas || propNodes.length === 0) return;
|
|
37354
|
-
const
|
|
37355
|
-
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;
|
|
37362
|
+
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
37356
37363
|
const prevPos = /* @__PURE__ */ new Map();
|
|
37357
37364
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
37358
37365
|
const simNodes = propNodes.map((n, idx) => {
|
|
@@ -37387,133 +37394,192 @@ var init_GraphCanvas = __esm({
|
|
|
37387
37394
|
const fullRelayout = !laidOutRef.current || overlap < 0.5;
|
|
37388
37395
|
if (layout === "force") {
|
|
37389
37396
|
const maxIterations = 300;
|
|
37390
|
-
const
|
|
37397
|
+
const COOL = 0.12;
|
|
37398
|
+
const COLLIDE_PASSES = 6;
|
|
37399
|
+
const LABEL_GAP = 12;
|
|
37400
|
+
const LABEL_H = 16;
|
|
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;
|
|
37391
37429
|
const nodes = nodesRef.current;
|
|
37392
37430
|
const centerX = w / 2;
|
|
37393
37431
|
const centerY = h / 2;
|
|
37432
|
+
const temp = skipForces ? 0 : Math.max(COOL, 1 - iter / maxIterations);
|
|
37394
37433
|
for (const node of nodes) {
|
|
37395
37434
|
node.fx = 0;
|
|
37396
37435
|
node.fy = 0;
|
|
37397
37436
|
}
|
|
37398
|
-
|
|
37399
|
-
for (let
|
|
37400
|
-
|
|
37401
|
-
|
|
37402
|
-
|
|
37403
|
-
|
|
37404
|
-
|
|
37405
|
-
|
|
37406
|
-
|
|
37407
|
-
|
|
37408
|
-
|
|
37409
|
-
|
|
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
|
+
}
|
|
37410
37451
|
}
|
|
37411
|
-
|
|
37412
|
-
|
|
37413
|
-
|
|
37414
|
-
|
|
37415
|
-
const source = nodeById.get(pair.source);
|
|
37416
|
-
const target = nodeById.get(pair.target);
|
|
37417
|
-
if (!source || !target) continue;
|
|
37418
|
-
const dx = target.x - source.x;
|
|
37419
|
-
const dy = target.y - source.y;
|
|
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;
|
|
37420
37456
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37421
|
-
const
|
|
37422
|
-
const linkTarget = linkDistance * (1 - w2);
|
|
37423
|
-
const force = (dist - linkTarget) * (0.04 + 0.1 * w2);
|
|
37457
|
+
const force = (dist - rest) * k * temp;
|
|
37424
37458
|
const fx = dx / dist * force;
|
|
37425
37459
|
const fy = dy / dist * force;
|
|
37426
|
-
|
|
37427
|
-
|
|
37428
|
-
|
|
37429
|
-
|
|
37430
|
-
}
|
|
37431
|
-
} else {
|
|
37460
|
+
a.fx += fx;
|
|
37461
|
+
a.fy += fy;
|
|
37462
|
+
b.fx -= fx;
|
|
37463
|
+
b.fy -= fy;
|
|
37464
|
+
};
|
|
37432
37465
|
for (const edge of propEdges) {
|
|
37433
37466
|
const source = nodeById.get(edge.source);
|
|
37434
37467
|
const target = nodeById.get(edge.target);
|
|
37435
37468
|
if (!source || !target) continue;
|
|
37436
|
-
|
|
37437
|
-
const dy = target.y - source.y;
|
|
37438
|
-
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37469
|
+
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37439
37470
|
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37440
|
-
|
|
37441
|
-
const force = (dist - linkTarget) * (0.04 + 0.1 * w2);
|
|
37442
|
-
const fx = dx / dist * force;
|
|
37443
|
-
const fy = dy / dist * force;
|
|
37444
|
-
source.fx += fx;
|
|
37445
|
-
source.fy += fy;
|
|
37446
|
-
target.fx -= fx;
|
|
37447
|
-
target.fy -= fy;
|
|
37471
|
+
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37448
37472
|
}
|
|
37449
|
-
|
|
37450
|
-
|
|
37451
|
-
|
|
37452
|
-
|
|
37453
|
-
|
|
37454
|
-
|
|
37455
|
-
c = { x: 0, y: 0, n: 0 };
|
|
37456
|
-
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);
|
|
37457
37479
|
}
|
|
37458
|
-
|
|
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
|
+
}
|
|
37503
|
+
} else {
|
|
37504
|
+
node.fx += (centerX - node.x) * 8e-3 * temp;
|
|
37505
|
+
node.fy += (centerY - node.y) * 8e-3 * temp;
|
|
37506
|
+
}
|
|
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;
|
|
37470
37514
|
}
|
|
37471
37515
|
}
|
|
37472
|
-
const damping = 0.9;
|
|
37473
37516
|
for (const node of nodes) {
|
|
37474
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
37475
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
37476
|
-
node.x += node.vx;
|
|
37477
|
-
node.y += node.vy;
|
|
37478
37517
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
37479
37518
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
37480
37519
|
}
|
|
37481
|
-
const LABEL_GAP = 12;
|
|
37482
|
-
const LABEL_H = 16;
|
|
37483
37520
|
const pad = nodeSpacing / 2;
|
|
37484
|
-
|
|
37485
|
-
|
|
37486
|
-
|
|
37487
|
-
|
|
37488
|
-
|
|
37489
|
-
|
|
37490
|
-
|
|
37491
|
-
|
|
37492
|
-
|
|
37493
|
-
|
|
37494
|
-
|
|
37495
|
-
|
|
37496
|
-
|
|
37497
|
-
|
|
37498
|
-
|
|
37499
|
-
|
|
37500
|
-
|
|
37501
|
-
|
|
37502
|
-
|
|
37503
|
-
|
|
37504
|
-
|
|
37505
|
-
|
|
37506
|
-
|
|
37507
|
-
const
|
|
37508
|
-
|
|
37509
|
-
|
|
37521
|
+
const rectsOf = (n) => {
|
|
37522
|
+
const r2 = n.size || 8;
|
|
37523
|
+
const lw = showLabels ? n.labelW ?? (n.labelW = n.label ? measureLabelWidth(n.label, labelFont) : 0) : 0;
|
|
37524
|
+
return {
|
|
37525
|
+
circle: [n.x - r2 - pad, n.y - r2 - pad, n.x + r2 + pad, n.y + r2 + pad],
|
|
37526
|
+
label: [n.x - lw / 2 - pad, n.y + r2 + LABEL_GAP - 8, n.x + lw / 2 + pad, n.y + r2 + LABEL_GAP + LABEL_H]
|
|
37527
|
+
};
|
|
37528
|
+
};
|
|
37529
|
+
const sep = (r1, r2) => {
|
|
37530
|
+
const ox = Math.min(r1[2], r2[2]) - Math.max(r1[0], r2[0]);
|
|
37531
|
+
const oy = Math.min(r1[3], r2[3]) - Math.max(r1[1], r2[1]);
|
|
37532
|
+
if (ox <= 0 || oy <= 0) return null;
|
|
37533
|
+
return ox <= oy ? { axis: "x", depth: ox, sign: r1[0] + r1[2] < r2[0] + r2[2] ? 1 : -1 } : { axis: "y", depth: oy, sign: r1[1] + r1[3] < r2[1] + r2[3] ? 1 : -1 };
|
|
37534
|
+
};
|
|
37535
|
+
for (let pass = 0; pass < COLLIDE_PASSES; pass++) {
|
|
37536
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
37537
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
37538
|
+
const a = nodes[i];
|
|
37539
|
+
const b = nodes[j];
|
|
37540
|
+
const ra = rectsOf(a);
|
|
37541
|
+
const rb = rectsOf(b);
|
|
37542
|
+
let best = null;
|
|
37543
|
+
for (const [r1, r2] of [[ra.circle, rb.circle], [ra.circle, rb.label], [ra.label, rb.circle], [ra.label, rb.label]]) {
|
|
37544
|
+
const s = sep(r1, r2);
|
|
37545
|
+
if (s && (!best || s.depth < best.depth)) best = s;
|
|
37546
|
+
}
|
|
37547
|
+
if (best) {
|
|
37548
|
+
const push = best.depth / 2;
|
|
37549
|
+
if (best.axis === "x") {
|
|
37550
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - push * best.sign));
|
|
37551
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + push * best.sign));
|
|
37552
|
+
a.vx = 0;
|
|
37553
|
+
b.vx = 0;
|
|
37554
|
+
} else {
|
|
37555
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - push * best.sign));
|
|
37556
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + push * best.sign));
|
|
37557
|
+
a.vy = 0;
|
|
37558
|
+
b.vy = 0;
|
|
37559
|
+
}
|
|
37510
37560
|
}
|
|
37511
37561
|
}
|
|
37512
37562
|
}
|
|
37513
37563
|
}
|
|
37514
37564
|
};
|
|
37515
37565
|
if (fullRelayout) {
|
|
37516
|
-
for (let i = 0; i < maxIterations; i++) tick();
|
|
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 });
|
|
37517
37583
|
laidOutRef.current = true;
|
|
37518
37584
|
} else {
|
|
37519
37585
|
const centroids = /* @__PURE__ */ new Map();
|