@opendata-ai/openchart-vanilla 8.2.1 → 8.2.3
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/{chunk-XOZ6AM7C.js → chunk-2CEKMIJH.js} +33 -10
- package/dist/chunk-2CEKMIJH.js.map +1 -0
- package/dist/{chunk-N5KDVZU7.js → chunk-WG6NOQVC.js} +179 -836
- package/dist/chunk-WG6NOQVC.js.map +1 -0
- package/dist/{chunk-BGJT3GTB.js → chunk-ZKASH7AX.js} +2 -2
- package/dist/index.js +261 -870
- package/dist/index.js.map +1 -1
- package/dist/simulation-worker.js +8 -6
- package/dist/static.js +2 -2
- package/dist/story/index.js +2 -2
- package/dist/styles.css.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-N5KDVZU7.js.map +0 -1
- package/dist/chunk-XOZ6AM7C.js.map +0 -1
- /package/dist/{chunk-BGJT3GTB.js.map → chunk-ZKASH7AX.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-DCODCLWI.js";
|
|
7
7
|
import {
|
|
8
8
|
renderTileMapSVG
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZKASH7AX.js";
|
|
10
10
|
import {
|
|
11
11
|
AnimationScheduler,
|
|
12
12
|
CANVAS_DEFAULT_UPDATE_MAX_MARKS,
|
|
@@ -25,15 +25,13 @@ import {
|
|
|
25
25
|
materializeCanvasModeSVG,
|
|
26
26
|
observeResize,
|
|
27
27
|
prefersReducedMotion,
|
|
28
|
-
quadtree,
|
|
29
28
|
resolveDarkMode,
|
|
30
29
|
resolveEase,
|
|
31
30
|
resolveFontFamily,
|
|
32
31
|
scheduleFontReload,
|
|
33
32
|
setupAnimationCleanup,
|
|
34
|
-
setupTableAnimationCleanup
|
|
35
|
-
|
|
36
|
-
} from "./chunk-N5KDVZU7.js";
|
|
33
|
+
setupTableAnimationCleanup
|
|
34
|
+
} from "./chunk-WG6NOQVC.js";
|
|
37
35
|
import {
|
|
38
36
|
embedFonts,
|
|
39
37
|
ensureSVGDimensions,
|
|
@@ -51,7 +49,7 @@ import {
|
|
|
51
49
|
registerMarkRenderer,
|
|
52
50
|
renderChartSVG,
|
|
53
51
|
stampAnimationVars
|
|
54
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-2CEKMIJH.js";
|
|
55
53
|
import {
|
|
56
54
|
injectThemeStyleBlock
|
|
57
55
|
} from "./chunk-RM5XS6NR.js";
|
|
@@ -103,12 +101,12 @@ function renderWatermark(parent, layout) {
|
|
|
103
101
|
const rightEdge = width - padding;
|
|
104
102
|
const bottomEdge = height - padding;
|
|
105
103
|
const fill = theme.colors.axis;
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
const a = createSVGElement("a");
|
|
105
|
+
a.setAttribute("href", BRAND_URL);
|
|
106
|
+
a.setAttributeNS(XLINK_NS, "xlink:href", BRAND_URL);
|
|
107
|
+
a.setAttribute("target", "_blank");
|
|
108
|
+
a.setAttribute("rel", "noopener");
|
|
109
|
+
a.setAttribute("class", "oc-chrome-ref");
|
|
112
110
|
const text = createSVGElement("text");
|
|
113
111
|
setAttrs(text, {
|
|
114
112
|
x: rightEdge,
|
|
@@ -132,8 +130,8 @@ function renderWatermark(parent, layout) {
|
|
|
132
130
|
text.appendChild(trySpan);
|
|
133
131
|
text.appendChild(openDataSpan);
|
|
134
132
|
text.appendChild(aiSpan);
|
|
135
|
-
|
|
136
|
-
parent.appendChild(
|
|
133
|
+
a.appendChild(text);
|
|
134
|
+
parent.appendChild(a);
|
|
137
135
|
}
|
|
138
136
|
function renderRows(parent, rows, animation) {
|
|
139
137
|
const g = createSVGElement("g");
|
|
@@ -310,9 +308,9 @@ function createBarList(container, spec, options) {
|
|
|
310
308
|
const mouseEvent = e;
|
|
311
309
|
if (content && tooltipManager && options?.tooltip !== false) {
|
|
312
310
|
const svgRect = svg.getBoundingClientRect();
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
tooltipManager.show(content,
|
|
311
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
312
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
313
|
+
tooltipManager.show(content, x, y);
|
|
316
314
|
}
|
|
317
315
|
if (row) {
|
|
318
316
|
options?.onRowHover?.({
|
|
@@ -326,9 +324,9 @@ function createBarList(container, spec, options) {
|
|
|
326
324
|
if (content && tooltipManager && options?.tooltip !== false) {
|
|
327
325
|
const mouseEvent = e;
|
|
328
326
|
const svgRect = svg.getBoundingClientRect();
|
|
329
|
-
const
|
|
330
|
-
const
|
|
331
|
-
tooltipManager.show(content,
|
|
327
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
328
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
329
|
+
tooltipManager.show(content, x, y);
|
|
332
330
|
}
|
|
333
331
|
};
|
|
334
332
|
const handleMouseLeave = () => {
|
|
@@ -597,8 +595,8 @@ async function exportSpecSequence(specs, options) {
|
|
|
597
595
|
const globalPalette = paletteFromCanvas(frames[frames.length - 1].canvas, quantize);
|
|
598
596
|
const gif = GIFEncoder();
|
|
599
597
|
frames.forEach(({ canvas, delayMs }, i) => {
|
|
600
|
-
const
|
|
601
|
-
gif.writeFrame(
|
|
598
|
+
const index = applyPalette(readCanvasSRGB(canvas), globalPalette);
|
|
599
|
+
gif.writeFrame(index, canvas.width, canvas.height, {
|
|
602
600
|
palette: globalPalette,
|
|
603
601
|
delay: delayMs,
|
|
604
602
|
// `repeat` writes the loop extension; only meaningful on the first frame.
|
|
@@ -621,11 +619,14 @@ function createSimulationWorker() {
|
|
|
621
619
|
// src/graph-mount.ts
|
|
622
620
|
import { buildEdgeTooltip, compileGraph } from "@opendata-ai/openchart-engine";
|
|
623
621
|
|
|
622
|
+
// src/graph/camera.ts
|
|
623
|
+
import { interpolateZoom } from "d3-interpolate";
|
|
624
|
+
|
|
624
625
|
// src/graph/zoom.ts
|
|
625
626
|
var ZoomTransform = class _ZoomTransform {
|
|
626
|
-
constructor(
|
|
627
|
-
this.x =
|
|
628
|
-
this.y =
|
|
627
|
+
constructor(x, y, k) {
|
|
628
|
+
this.x = x;
|
|
629
|
+
this.y = y;
|
|
629
630
|
this.k = k;
|
|
630
631
|
}
|
|
631
632
|
/** Convert screen coordinates to graph coordinates. */
|
|
@@ -735,9 +736,9 @@ function transformToView(t, viewport) {
|
|
|
735
736
|
function viewToTransform(view, viewport) {
|
|
736
737
|
const [cx, cy, width] = view;
|
|
737
738
|
const k = clampK(viewport.width / width);
|
|
738
|
-
const
|
|
739
|
-
const
|
|
740
|
-
return new ZoomTransform(
|
|
739
|
+
const x = viewport.width / 2 - cx * k;
|
|
740
|
+
const y = viewport.height / 2 - cy * k;
|
|
741
|
+
return new ZoomTransform(x, y, k);
|
|
741
742
|
}
|
|
742
743
|
function clampK(k) {
|
|
743
744
|
if (!Number.isFinite(k) || k <= 0) return K_MIN;
|
|
@@ -752,12 +753,12 @@ function createCameraFlight(inputs) {
|
|
|
752
753
|
const to = isProvider ? inputs.to() : inputs.to;
|
|
753
754
|
return transformToView(to, viewport);
|
|
754
755
|
}
|
|
755
|
-
let interp =
|
|
756
|
+
let interp = interpolateZoom(fromView, targetView());
|
|
756
757
|
const resolvedDuration = resolveDuration(opts?.duration, interp.duration);
|
|
757
758
|
let startTime = null;
|
|
758
759
|
let finished = false;
|
|
759
760
|
function applyAt(t) {
|
|
760
|
-
if (isProvider) interp =
|
|
761
|
+
if (isProvider) interp = interpolateZoom(fromView, targetView());
|
|
761
762
|
const view = interp(t);
|
|
762
763
|
if (view.some((v) => !Number.isFinite(v))) {
|
|
763
764
|
apply(viewToTransform(targetView(), viewport));
|
|
@@ -766,10 +767,10 @@ function createCameraFlight(inputs) {
|
|
|
766
767
|
apply(viewToTransform(view, viewport));
|
|
767
768
|
}
|
|
768
769
|
return {
|
|
769
|
-
tick(
|
|
770
|
+
tick(now) {
|
|
770
771
|
if (finished) return false;
|
|
771
|
-
if (startTime === null) startTime =
|
|
772
|
-
const raw = resolvedDuration <= 0 ? 1 : Math.min(1, (
|
|
772
|
+
if (startTime === null) startTime = now;
|
|
773
|
+
const raw = resolvedDuration <= 0 ? 1 : Math.min(1, (now - startTime) / resolvedDuration);
|
|
773
774
|
applyAt(ease(raw));
|
|
774
775
|
if (raw >= 1) {
|
|
775
776
|
finished = true;
|
|
@@ -819,9 +820,9 @@ function resolveDuration(duration, interpDuration) {
|
|
|
819
820
|
import { BRAND_FONT_SIZE, BRAND_MIN_WIDTH } from "@opendata-ai/openchart-core";
|
|
820
821
|
|
|
821
822
|
// src/graph/entrance.ts
|
|
822
|
-
function nodeEnterProgress(globalT,
|
|
823
|
+
function nodeEnterProgress(globalT, index, total, buckets = 8) {
|
|
823
824
|
const g = globalT <= 0 ? 0 : globalT >= 1 ? 1 : globalT;
|
|
824
|
-
const start = total > 0 ?
|
|
825
|
+
const start = total > 0 ? index / total * 0.4 : 0;
|
|
825
826
|
const local = (g - start) / 0.6;
|
|
826
827
|
const clamped = local <= 0 ? 0 : local >= 1 ? 1 : local;
|
|
827
828
|
const b = Math.max(1, Math.floor(buckets));
|
|
@@ -851,10 +852,10 @@ function hashId(id) {
|
|
|
851
852
|
function entranceOrder(nodes) {
|
|
852
853
|
const rank = /* @__PURE__ */ new Map();
|
|
853
854
|
if (nodes.length === 0) return rank;
|
|
854
|
-
const sorted = [...nodes].sort((
|
|
855
|
-
const ha = hashId(
|
|
855
|
+
const sorted = [...nodes].sort((a, b) => {
|
|
856
|
+
const ha = hashId(a.id);
|
|
856
857
|
const hb = hashId(b.id);
|
|
857
|
-
return ha - hb || (
|
|
858
|
+
return ha - hb || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
858
859
|
});
|
|
859
860
|
for (let i = 0; i < sorted.length; i++) rank.set(sorted[i].id, i);
|
|
860
861
|
return rank;
|
|
@@ -884,8 +885,8 @@ function popScale(t) {
|
|
|
884
885
|
return 1 + c3 * u * u * u + c1 * u * u;
|
|
885
886
|
}
|
|
886
887
|
function popAlpha(t) {
|
|
887
|
-
const
|
|
888
|
-
return
|
|
888
|
+
const a = t / 0.6;
|
|
889
|
+
return a >= 1 ? 1 : a <= 0 ? 0 : a;
|
|
889
890
|
}
|
|
890
891
|
function driftFactor(t) {
|
|
891
892
|
const u = 1 - (t <= 0 ? 0 : t >= 1 ? 1 : t);
|
|
@@ -927,8 +928,8 @@ function nodeTierAlpha(tier, dimOpacity) {
|
|
|
927
928
|
return 1;
|
|
928
929
|
}
|
|
929
930
|
}
|
|
930
|
-
function lerp(
|
|
931
|
-
return
|
|
931
|
+
function lerp(a, b, t) {
|
|
932
|
+
return a + (b - a) * t;
|
|
932
933
|
}
|
|
933
934
|
var ZERO_SHIFT = { x: 0, y: 0 };
|
|
934
935
|
function makeEntranceReveal(entrance, total) {
|
|
@@ -978,12 +979,12 @@ function labelThreshold(zoom) {
|
|
|
978
979
|
return 1 - t;
|
|
979
980
|
}
|
|
980
981
|
function visibleRect(canvasWidth, canvasHeight, transform, margin = CULL_MARGIN) {
|
|
981
|
-
const { x
|
|
982
|
+
const { x, y, k } = transform;
|
|
982
983
|
return {
|
|
983
|
-
minX: (-
|
|
984
|
-
minY: (-
|
|
985
|
-
maxX: (canvasWidth -
|
|
986
|
-
maxY: (canvasHeight -
|
|
984
|
+
minX: (-x - margin) / k,
|
|
985
|
+
minY: (-y - margin) / k,
|
|
986
|
+
maxX: (canvasWidth - x + margin) / k,
|
|
987
|
+
maxY: (canvasHeight - y + margin) / k
|
|
987
988
|
};
|
|
988
989
|
}
|
|
989
990
|
function nodeInView(node, rect) {
|
|
@@ -1128,14 +1129,14 @@ var GraphCanvasRenderer = class {
|
|
|
1128
1129
|
ctx.save();
|
|
1129
1130
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
1130
1131
|
const padding = theme.spacing.padding;
|
|
1131
|
-
const
|
|
1132
|
-
const
|
|
1132
|
+
const x = w - padding;
|
|
1133
|
+
const y = h - padding;
|
|
1133
1134
|
ctx.font = `600 ${BRAND_FONT_SIZE}px ${theme.fonts.family}`;
|
|
1134
1135
|
ctx.fillStyle = theme.colors.axis;
|
|
1135
1136
|
ctx.globalAlpha = 0.55;
|
|
1136
1137
|
ctx.textAlign = "right";
|
|
1137
1138
|
ctx.textBaseline = "alphabetic";
|
|
1138
|
-
ctx.fillText("tryOpenData.ai",
|
|
1139
|
+
ctx.fillText("tryOpenData.ai", x, y);
|
|
1139
1140
|
ctx.restore();
|
|
1140
1141
|
}
|
|
1141
1142
|
// -------------------------------------------------------------------------
|
|
@@ -1208,7 +1209,7 @@ var GraphCanvasRenderer = class {
|
|
|
1208
1209
|
const [prevTier, nextTier] = key.split("|");
|
|
1209
1210
|
const alpha = lerp(edgeTierAlpha(prevTier, dimOpacity), edgeTierAlpha(nextTier, dimOpacity), t) * ea;
|
|
1210
1211
|
return { alpha, bucket };
|
|
1211
|
-
}).sort((
|
|
1212
|
+
}).sort((a, b) => a.alpha - b.alpha);
|
|
1212
1213
|
for (const { alpha, bucket } of ordered) {
|
|
1213
1214
|
this.drawEdgeGroupBatched(ctx, bucket, alpha, searchMatches, enterAlphaFor);
|
|
1214
1215
|
}
|
|
@@ -1533,7 +1534,7 @@ function brighten(color) {
|
|
|
1533
1534
|
return `rgb(${r},${g},${b})`;
|
|
1534
1535
|
}
|
|
1535
1536
|
const hex = color.replace("#", "");
|
|
1536
|
-
const full = hex.length === 3 ? hex.split("").map((
|
|
1537
|
+
const full = hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex;
|
|
1537
1538
|
if (full.length === 6) {
|
|
1538
1539
|
const r = Math.min(255, parseInt(full.slice(0, 2), 16) + 40);
|
|
1539
1540
|
const g = Math.min(255, parseInt(full.slice(2, 4), 16) + 40);
|
|
@@ -1544,17 +1545,17 @@ function brighten(color) {
|
|
|
1544
1545
|
}
|
|
1545
1546
|
|
|
1546
1547
|
// src/graph/focus-transition.ts
|
|
1547
|
-
function focusSnapshotsEqual(
|
|
1548
|
-
return
|
|
1548
|
+
function focusSnapshotsEqual(a, b) {
|
|
1549
|
+
return a.hasActive === b.hasActive && setsEqual(a.connected, b.connected) && nullableSetsEqual(a.searchMatches, b.searchMatches) && setsEqual(a.selected, b.selected);
|
|
1549
1550
|
}
|
|
1550
|
-
function setsEqual(
|
|
1551
|
-
if (
|
|
1552
|
-
for (const v of
|
|
1551
|
+
function setsEqual(a, b) {
|
|
1552
|
+
if (a.size !== b.size) return false;
|
|
1553
|
+
for (const v of a) if (!b.has(v)) return false;
|
|
1553
1554
|
return true;
|
|
1554
1555
|
}
|
|
1555
|
-
function nullableSetsEqual(
|
|
1556
|
-
if (
|
|
1557
|
-
return setsEqual(
|
|
1556
|
+
function nullableSetsEqual(a, b) {
|
|
1557
|
+
if (a === null || b === null) return a === b;
|
|
1558
|
+
return setsEqual(a, b);
|
|
1558
1559
|
}
|
|
1559
1560
|
var FocusTransition = class {
|
|
1560
1561
|
prev;
|
|
@@ -1562,10 +1563,10 @@ var FocusTransition = class {
|
|
|
1562
1563
|
startTime;
|
|
1563
1564
|
duration;
|
|
1564
1565
|
ease;
|
|
1565
|
-
constructor(initial, duration, ease,
|
|
1566
|
+
constructor(initial, duration, ease, now) {
|
|
1566
1567
|
this.prev = initial;
|
|
1567
1568
|
this.next = initial;
|
|
1568
|
-
this.startTime =
|
|
1569
|
+
this.startTime = now;
|
|
1569
1570
|
this.duration = Math.max(0, duration);
|
|
1570
1571
|
this.ease = ease;
|
|
1571
1572
|
}
|
|
@@ -1574,25 +1575,25 @@ var FocusTransition = class {
|
|
|
1574
1575
|
* current display as the new `prev` (the `p < 0.5` rule). A no-op when
|
|
1575
1576
|
* `target` already equals `next`.
|
|
1576
1577
|
*/
|
|
1577
|
-
retarget(target,
|
|
1578
|
+
retarget(target, now) {
|
|
1578
1579
|
if (focusSnapshotsEqual(target, this.next)) return;
|
|
1579
|
-
const p = this.rawProgress(
|
|
1580
|
+
const p = this.rawProgress(now);
|
|
1580
1581
|
this.prev = p < 0.5 ? this.prev : this.next;
|
|
1581
1582
|
this.next = target;
|
|
1582
|
-
this.startTime =
|
|
1583
|
+
this.startTime = now;
|
|
1583
1584
|
}
|
|
1584
1585
|
/** Raw (un-eased) 0..1 progress. */
|
|
1585
|
-
rawProgress(
|
|
1586
|
+
rawProgress(now) {
|
|
1586
1587
|
if (this.duration <= 0) return 1;
|
|
1587
|
-
return Math.min(1, Math.max(0, (
|
|
1588
|
+
return Math.min(1, Math.max(0, (now - this.startTime) / this.duration));
|
|
1588
1589
|
}
|
|
1589
1590
|
/** Eased 0..1 progress toward `next`. */
|
|
1590
|
-
progress(
|
|
1591
|
-
return this.ease(this.rawProgress(
|
|
1591
|
+
progress(now) {
|
|
1592
|
+
return this.ease(this.rawProgress(now));
|
|
1592
1593
|
}
|
|
1593
1594
|
/** True once the transition has fully settled onto `next`. */
|
|
1594
|
-
isSettled(
|
|
1595
|
-
return this.rawProgress(
|
|
1595
|
+
isSettled(now) {
|
|
1596
|
+
return this.rawProgress(now) >= 1;
|
|
1596
1597
|
}
|
|
1597
1598
|
};
|
|
1598
1599
|
function composeStandingFocus(highlight, searchMatches, selected, adjacency) {
|
|
@@ -1632,8 +1633,8 @@ function layerHoverFocus(standing, hoveredId, hoverConnected) {
|
|
|
1632
1633
|
selected: standing.selected
|
|
1633
1634
|
};
|
|
1634
1635
|
}
|
|
1635
|
-
function intersect(
|
|
1636
|
-
const [small, large] =
|
|
1636
|
+
function intersect(a, b) {
|
|
1637
|
+
const [small, large] = a.size <= b.size ? [a, b] : [b, a];
|
|
1637
1638
|
const out = /* @__PURE__ */ new Set();
|
|
1638
1639
|
for (const v of small) if (large.has(v)) out.add(v);
|
|
1639
1640
|
return out;
|
|
@@ -1733,31 +1734,31 @@ var GraphInteractionManager = class {
|
|
|
1733
1734
|
}
|
|
1734
1735
|
onWheel(e) {
|
|
1735
1736
|
e.preventDefault();
|
|
1736
|
-
const { x
|
|
1737
|
+
const { x, y } = this.canvasXY(e);
|
|
1737
1738
|
const factor = e.deltaY * ZOOM_STEP;
|
|
1738
1739
|
const newK = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, this.transform.k * (1 + factor)));
|
|
1739
|
-
this.transform = this.transform.zoomAt(newK,
|
|
1740
|
+
this.transform = this.transform.zoomAt(newK, x, y);
|
|
1740
1741
|
this.callbacks.onTransformChange(this.transform);
|
|
1741
1742
|
}
|
|
1742
1743
|
onMouseDown(e) {
|
|
1743
|
-
const { x
|
|
1744
|
-
const hitId = this.hitTest(
|
|
1744
|
+
const { x, y } = this.canvasXY(e);
|
|
1745
|
+
const hitId = this.hitTest(x, y);
|
|
1745
1746
|
if (hitId) {
|
|
1746
1747
|
this.dragState = { nodeId: hitId, started: false };
|
|
1747
1748
|
this.mousedownNodeId = hitId;
|
|
1748
1749
|
} else {
|
|
1749
|
-
this.panState = { startX:
|
|
1750
|
+
this.panState = { startX: x, startY: y };
|
|
1750
1751
|
this.mousedownNodeId = null;
|
|
1751
1752
|
}
|
|
1752
1753
|
}
|
|
1753
1754
|
onMouseMove(e) {
|
|
1754
|
-
const { x
|
|
1755
|
+
const { x, y } = this.canvasXY(e);
|
|
1755
1756
|
if (this.callbacks.onPointerMove) {
|
|
1756
|
-
const gp = this.transform.screenToGraph(
|
|
1757
|
+
const gp = this.transform.screenToGraph(x, y);
|
|
1757
1758
|
this.callbacks.onPointerMove(gp.x, gp.y);
|
|
1758
1759
|
}
|
|
1759
1760
|
if (this.dragState) {
|
|
1760
|
-
const graph = this.transform.screenToGraph(
|
|
1761
|
+
const graph = this.transform.screenToGraph(x, y);
|
|
1761
1762
|
if (!this.dragState.started) {
|
|
1762
1763
|
this.dragState.started = true;
|
|
1763
1764
|
this.callbacks.onNodeDragStart(this.dragState.nodeId);
|
|
@@ -1766,23 +1767,23 @@ var GraphInteractionManager = class {
|
|
|
1766
1767
|
return;
|
|
1767
1768
|
}
|
|
1768
1769
|
if (this.panState) {
|
|
1769
|
-
const dx =
|
|
1770
|
-
const dy =
|
|
1770
|
+
const dx = x - this.panState.startX;
|
|
1771
|
+
const dy = y - this.panState.startY;
|
|
1771
1772
|
this.transform = this.transform.pan(dx, dy);
|
|
1772
|
-
this.panState = { startX:
|
|
1773
|
+
this.panState = { startX: x, startY: y };
|
|
1773
1774
|
this.callbacks.onTransformChange(this.transform);
|
|
1774
1775
|
return;
|
|
1775
1776
|
}
|
|
1776
|
-
const hitId = this.hitTest(
|
|
1777
|
+
const hitId = this.hitTest(x, y);
|
|
1777
1778
|
this.callbacks.onHoverChange(hitId);
|
|
1778
1779
|
if (!hitId) {
|
|
1779
|
-
const graph = this.transform.screenToGraph(
|
|
1780
|
-
this.callbacks.onBackgroundHover?.(graph.x, graph.y,
|
|
1780
|
+
const graph = this.transform.screenToGraph(x, y);
|
|
1781
|
+
this.callbacks.onBackgroundHover?.(graph.x, graph.y, x, y);
|
|
1781
1782
|
}
|
|
1782
1783
|
this.canvas.style.cursor = hitId ? "pointer" : "default";
|
|
1783
1784
|
}
|
|
1784
1785
|
onMouseUp(e) {
|
|
1785
|
-
const { x
|
|
1786
|
+
const { x, y } = this.canvasXY(e);
|
|
1786
1787
|
if (this.dragState) {
|
|
1787
1788
|
if (this.dragState.started) {
|
|
1788
1789
|
this.callbacks.onNodeDragEnd(this.dragState.nodeId);
|
|
@@ -1795,7 +1796,7 @@ var GraphInteractionManager = class {
|
|
|
1795
1796
|
if (this.panState) {
|
|
1796
1797
|
this.panState = null;
|
|
1797
1798
|
if (!this.mousedownNodeId) {
|
|
1798
|
-
const hitId = this.hitTest(
|
|
1799
|
+
const hitId = this.hitTest(x, y);
|
|
1799
1800
|
if (!hitId) {
|
|
1800
1801
|
this.selectedIds.clear();
|
|
1801
1802
|
this.callbacks.onSelectionChange([]);
|
|
@@ -1805,8 +1806,8 @@ var GraphInteractionManager = class {
|
|
|
1805
1806
|
}
|
|
1806
1807
|
}
|
|
1807
1808
|
onDblClick(e) {
|
|
1808
|
-
const { x
|
|
1809
|
-
const hitId = this.hitTest(
|
|
1809
|
+
const { x, y } = this.canvasXY(e);
|
|
1810
|
+
const hitId = this.hitTest(x, y);
|
|
1810
1811
|
if (hitId) {
|
|
1811
1812
|
this.callbacks.onDoubleClick(hitId);
|
|
1812
1813
|
}
|
|
@@ -1847,13 +1848,13 @@ var GraphInteractionManager = class {
|
|
|
1847
1848
|
} else if (e.touches.length === 1) {
|
|
1848
1849
|
const touch = e.touches[0];
|
|
1849
1850
|
const rect = this.canvas.getBoundingClientRect();
|
|
1850
|
-
const
|
|
1851
|
-
const
|
|
1852
|
-
const hitId = this.hitTest(
|
|
1851
|
+
const x = touch.clientX - rect.left;
|
|
1852
|
+
const y = touch.clientY - rect.top;
|
|
1853
|
+
const hitId = this.hitTest(x, y);
|
|
1853
1854
|
if (hitId) {
|
|
1854
1855
|
this.mousedownNodeId = hitId;
|
|
1855
1856
|
} else {
|
|
1856
|
-
this.panState = { startX:
|
|
1857
|
+
this.panState = { startX: x, startY: y };
|
|
1857
1858
|
this.mousedownNodeId = null;
|
|
1858
1859
|
}
|
|
1859
1860
|
}
|
|
@@ -1883,12 +1884,12 @@ var GraphInteractionManager = class {
|
|
|
1883
1884
|
} else if (e.touches.length === 1 && this.panState) {
|
|
1884
1885
|
const touch = e.touches[0];
|
|
1885
1886
|
const rect = this.canvas.getBoundingClientRect();
|
|
1886
|
-
const
|
|
1887
|
-
const
|
|
1888
|
-
const dx =
|
|
1889
|
-
const dy =
|
|
1887
|
+
const x = touch.clientX - rect.left;
|
|
1888
|
+
const y = touch.clientY - rect.top;
|
|
1889
|
+
const dx = x - this.panState.startX;
|
|
1890
|
+
const dy = y - this.panState.startY;
|
|
1890
1891
|
this.transform = this.transform.pan(dx, dy);
|
|
1891
|
-
this.panState = { startX:
|
|
1892
|
+
this.panState = { startX: x, startY: y };
|
|
1892
1893
|
this.callbacks.onTransformChange(this.transform);
|
|
1893
1894
|
}
|
|
1894
1895
|
}
|
|
@@ -1934,9 +1935,9 @@ function attachGraphKeyboardNav(options) {
|
|
|
1934
1935
|
if (candidates.length === 0) return null;
|
|
1935
1936
|
let best = null;
|
|
1936
1937
|
let bestScore = -Infinity;
|
|
1937
|
-
for (const
|
|
1938
|
-
const dx =
|
|
1939
|
-
const dy =
|
|
1938
|
+
for (const c of candidates) {
|
|
1939
|
+
const dx = c.x - fromNode.x;
|
|
1940
|
+
const dy = c.y - fromNode.y;
|
|
1940
1941
|
let score;
|
|
1941
1942
|
switch (direction) {
|
|
1942
1943
|
case "right":
|
|
@@ -1954,7 +1955,7 @@ function attachGraphKeyboardNav(options) {
|
|
|
1954
1955
|
}
|
|
1955
1956
|
if (score > bestScore) {
|
|
1956
1957
|
bestScore = score;
|
|
1957
|
-
best =
|
|
1958
|
+
best = c;
|
|
1958
1959
|
}
|
|
1959
1960
|
}
|
|
1960
1961
|
return best?.id ?? null;
|
|
@@ -2193,634 +2194,16 @@ function seedNodePositions(nodes, seed) {
|
|
|
2193
2194
|
}
|
|
2194
2195
|
}
|
|
2195
2196
|
|
|
2196
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/center.js
|
|
2197
|
-
function center_default(x3, y3) {
|
|
2198
|
-
var nodes, strength = 1;
|
|
2199
|
-
if (x3 == null) x3 = 0;
|
|
2200
|
-
if (y3 == null) y3 = 0;
|
|
2201
|
-
function force() {
|
|
2202
|
-
var i, n = nodes.length, node, sx = 0, sy = 0;
|
|
2203
|
-
for (i = 0; i < n; ++i) {
|
|
2204
|
-
node = nodes[i], sx += node.x, sy += node.y;
|
|
2205
|
-
}
|
|
2206
|
-
for (sx = (sx / n - x3) * strength, sy = (sy / n - y3) * strength, i = 0; i < n; ++i) {
|
|
2207
|
-
node = nodes[i], node.x -= sx, node.y -= sy;
|
|
2208
|
-
}
|
|
2209
|
-
}
|
|
2210
|
-
force.initialize = function(_) {
|
|
2211
|
-
nodes = _;
|
|
2212
|
-
};
|
|
2213
|
-
force.x = function(_) {
|
|
2214
|
-
return arguments.length ? (x3 = +_, force) : x3;
|
|
2215
|
-
};
|
|
2216
|
-
force.y = function(_) {
|
|
2217
|
-
return arguments.length ? (y3 = +_, force) : y3;
|
|
2218
|
-
};
|
|
2219
|
-
force.strength = function(_) {
|
|
2220
|
-
return arguments.length ? (strength = +_, force) : strength;
|
|
2221
|
-
};
|
|
2222
|
-
return force;
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/constant.js
|
|
2226
|
-
function constant_default(x3) {
|
|
2227
|
-
return function() {
|
|
2228
|
-
return x3;
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
|
|
2232
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/jiggle.js
|
|
2233
|
-
function jiggle_default(random) {
|
|
2234
|
-
return (random() - 0.5) * 1e-6;
|
|
2235
|
-
}
|
|
2236
|
-
|
|
2237
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/collide.js
|
|
2238
|
-
function x(d) {
|
|
2239
|
-
return d.x + d.vx;
|
|
2240
|
-
}
|
|
2241
|
-
function y(d) {
|
|
2242
|
-
return d.y + d.vy;
|
|
2243
|
-
}
|
|
2244
|
-
function collide_default(radius) {
|
|
2245
|
-
var nodes, radii, random, strength = 1, iterations = 1;
|
|
2246
|
-
if (typeof radius !== "function") radius = constant_default(radius == null ? 1 : +radius);
|
|
2247
|
-
function force() {
|
|
2248
|
-
var i, n = nodes.length, tree, node, xi, yi, ri, ri2;
|
|
2249
|
-
for (var k = 0; k < iterations; ++k) {
|
|
2250
|
-
tree = quadtree(nodes, x, y).visitAfter(prepare);
|
|
2251
|
-
for (i = 0; i < n; ++i) {
|
|
2252
|
-
node = nodes[i];
|
|
2253
|
-
ri = radii[node.index], ri2 = ri * ri;
|
|
2254
|
-
xi = node.x + node.vx;
|
|
2255
|
-
yi = node.y + node.vy;
|
|
2256
|
-
tree.visit(apply);
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
|
-
function apply(quad, x0, y0, x1, y1) {
|
|
2260
|
-
var data = quad.data, rj = quad.r, r = ri + rj;
|
|
2261
|
-
if (data) {
|
|
2262
|
-
if (data.index > node.index) {
|
|
2263
|
-
var x3 = xi - data.x - data.vx, y3 = yi - data.y - data.vy, l = x3 * x3 + y3 * y3;
|
|
2264
|
-
if (l < r * r) {
|
|
2265
|
-
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
2266
|
-
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
2267
|
-
l = (r - (l = Math.sqrt(l))) / l * strength;
|
|
2268
|
-
node.vx += (x3 *= l) * (r = (rj *= rj) / (ri2 + rj));
|
|
2269
|
-
node.vy += (y3 *= l) * r;
|
|
2270
|
-
data.vx -= x3 * (r = 1 - r);
|
|
2271
|
-
data.vy -= y3 * r;
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
return;
|
|
2275
|
-
}
|
|
2276
|
-
return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
|
|
2277
|
-
}
|
|
2278
|
-
}
|
|
2279
|
-
function prepare(quad) {
|
|
2280
|
-
if (quad.data) return quad.r = radii[quad.data.index];
|
|
2281
|
-
for (var i = quad.r = 0; i < 4; ++i) {
|
|
2282
|
-
if (quad[i] && quad[i].r > quad.r) {
|
|
2283
|
-
quad.r = quad[i].r;
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
function initialize() {
|
|
2288
|
-
if (!nodes) return;
|
|
2289
|
-
var i, n = nodes.length, node;
|
|
2290
|
-
radii = new Array(n);
|
|
2291
|
-
for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
|
|
2292
|
-
}
|
|
2293
|
-
force.initialize = function(_nodes, _random) {
|
|
2294
|
-
nodes = _nodes;
|
|
2295
|
-
random = _random;
|
|
2296
|
-
initialize();
|
|
2297
|
-
};
|
|
2298
|
-
force.iterations = function(_) {
|
|
2299
|
-
return arguments.length ? (iterations = +_, force) : iterations;
|
|
2300
|
-
};
|
|
2301
|
-
force.strength = function(_) {
|
|
2302
|
-
return arguments.length ? (strength = +_, force) : strength;
|
|
2303
|
-
};
|
|
2304
|
-
force.radius = function(_) {
|
|
2305
|
-
return arguments.length ? (radius = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : radius;
|
|
2306
|
-
};
|
|
2307
|
-
return force;
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/link.js
|
|
2311
|
-
function index(d) {
|
|
2312
|
-
return d.index;
|
|
2313
|
-
}
|
|
2314
|
-
function find(nodeById, nodeId) {
|
|
2315
|
-
var node = nodeById.get(nodeId);
|
|
2316
|
-
if (!node) throw new Error("node not found: " + nodeId);
|
|
2317
|
-
return node;
|
|
2318
|
-
}
|
|
2319
|
-
function link_default(links) {
|
|
2320
|
-
var id = index, strength = defaultStrength, strengths, distance = constant_default(30), distances, nodes, count, bias, random, iterations = 1;
|
|
2321
|
-
if (links == null) links = [];
|
|
2322
|
-
function defaultStrength(link) {
|
|
2323
|
-
return 1 / Math.min(count[link.source.index], count[link.target.index]);
|
|
2324
|
-
}
|
|
2325
|
-
function force(alpha) {
|
|
2326
|
-
for (var k = 0, n = links.length; k < iterations; ++k) {
|
|
2327
|
-
for (var i = 0, link, source, target, x3, y3, l, b; i < n; ++i) {
|
|
2328
|
-
link = links[i], source = link.source, target = link.target;
|
|
2329
|
-
x3 = target.x + target.vx - source.x - source.vx || jiggle_default(random);
|
|
2330
|
-
y3 = target.y + target.vy - source.y - source.vy || jiggle_default(random);
|
|
2331
|
-
l = Math.sqrt(x3 * x3 + y3 * y3);
|
|
2332
|
-
l = (l - distances[i]) / l * alpha * strengths[i];
|
|
2333
|
-
x3 *= l, y3 *= l;
|
|
2334
|
-
target.vx -= x3 * (b = bias[i]);
|
|
2335
|
-
target.vy -= y3 * b;
|
|
2336
|
-
source.vx += x3 * (b = 1 - b);
|
|
2337
|
-
source.vy += y3 * b;
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
function initialize() {
|
|
2342
|
-
if (!nodes) return;
|
|
2343
|
-
var i, n = nodes.length, m2 = links.length, nodeById = new Map(nodes.map((d, i2) => [id(d, i2, nodes), d])), link;
|
|
2344
|
-
for (i = 0, count = new Array(n); i < m2; ++i) {
|
|
2345
|
-
link = links[i], link.index = i;
|
|
2346
|
-
if (typeof link.source !== "object") link.source = find(nodeById, link.source);
|
|
2347
|
-
if (typeof link.target !== "object") link.target = find(nodeById, link.target);
|
|
2348
|
-
count[link.source.index] = (count[link.source.index] || 0) + 1;
|
|
2349
|
-
count[link.target.index] = (count[link.target.index] || 0) + 1;
|
|
2350
|
-
}
|
|
2351
|
-
for (i = 0, bias = new Array(m2); i < m2; ++i) {
|
|
2352
|
-
link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
|
|
2353
|
-
}
|
|
2354
|
-
strengths = new Array(m2), initializeStrength();
|
|
2355
|
-
distances = new Array(m2), initializeDistance();
|
|
2356
|
-
}
|
|
2357
|
-
function initializeStrength() {
|
|
2358
|
-
if (!nodes) return;
|
|
2359
|
-
for (var i = 0, n = links.length; i < n; ++i) {
|
|
2360
|
-
strengths[i] = +strength(links[i], i, links);
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
function initializeDistance() {
|
|
2364
|
-
if (!nodes) return;
|
|
2365
|
-
for (var i = 0, n = links.length; i < n; ++i) {
|
|
2366
|
-
distances[i] = +distance(links[i], i, links);
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
force.initialize = function(_nodes, _random) {
|
|
2370
|
-
nodes = _nodes;
|
|
2371
|
-
random = _random;
|
|
2372
|
-
initialize();
|
|
2373
|
-
};
|
|
2374
|
-
force.links = function(_) {
|
|
2375
|
-
return arguments.length ? (links = _, initialize(), force) : links;
|
|
2376
|
-
};
|
|
2377
|
-
force.id = function(_) {
|
|
2378
|
-
return arguments.length ? (id = _, force) : id;
|
|
2379
|
-
};
|
|
2380
|
-
force.iterations = function(_) {
|
|
2381
|
-
return arguments.length ? (iterations = +_, force) : iterations;
|
|
2382
|
-
};
|
|
2383
|
-
force.strength = function(_) {
|
|
2384
|
-
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initializeStrength(), force) : strength;
|
|
2385
|
-
};
|
|
2386
|
-
force.distance = function(_) {
|
|
2387
|
-
return arguments.length ? (distance = typeof _ === "function" ? _ : constant_default(+_), initializeDistance(), force) : distance;
|
|
2388
|
-
};
|
|
2389
|
-
return force;
|
|
2390
|
-
}
|
|
2391
|
-
|
|
2392
|
-
// ../../node_modules/.bun/d3-dispatch@3.0.1/node_modules/d3-dispatch/src/dispatch.js
|
|
2393
|
-
var noop = { value: () => {
|
|
2394
|
-
} };
|
|
2395
|
-
function dispatch() {
|
|
2396
|
-
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
|
|
2397
|
-
if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
|
|
2398
|
-
_[t] = [];
|
|
2399
|
-
}
|
|
2400
|
-
return new Dispatch(_);
|
|
2401
|
-
}
|
|
2402
|
-
function Dispatch(_) {
|
|
2403
|
-
this._ = _;
|
|
2404
|
-
}
|
|
2405
|
-
function parseTypenames(typenames, types) {
|
|
2406
|
-
return typenames.trim().split(/^|\s+/).map(function(t) {
|
|
2407
|
-
var name = "", i = t.indexOf(".");
|
|
2408
|
-
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
|
|
2409
|
-
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
|
|
2410
|
-
return { type: t, name };
|
|
2411
|
-
});
|
|
2412
|
-
}
|
|
2413
|
-
Dispatch.prototype = dispatch.prototype = {
|
|
2414
|
-
constructor: Dispatch,
|
|
2415
|
-
on: function(typename, callback) {
|
|
2416
|
-
var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length;
|
|
2417
|
-
if (arguments.length < 2) {
|
|
2418
|
-
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
|
|
2419
|
-
return;
|
|
2420
|
-
}
|
|
2421
|
-
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
|
|
2422
|
-
while (++i < n) {
|
|
2423
|
-
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
|
|
2424
|
-
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
|
|
2425
|
-
}
|
|
2426
|
-
return this;
|
|
2427
|
-
},
|
|
2428
|
-
copy: function() {
|
|
2429
|
-
var copy = {}, _ = this._;
|
|
2430
|
-
for (var t in _) copy[t] = _[t].slice();
|
|
2431
|
-
return new Dispatch(copy);
|
|
2432
|
-
},
|
|
2433
|
-
call: function(type, that) {
|
|
2434
|
-
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
|
|
2435
|
-
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
2436
|
-
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
|
|
2437
|
-
},
|
|
2438
|
-
apply: function(type, that, args) {
|
|
2439
|
-
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
2440
|
-
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
|
|
2441
|
-
}
|
|
2442
|
-
};
|
|
2443
|
-
function get(type, name) {
|
|
2444
|
-
for (var i = 0, n = type.length, c2; i < n; ++i) {
|
|
2445
|
-
if ((c2 = type[i]).name === name) {
|
|
2446
|
-
return c2.value;
|
|
2447
|
-
}
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
function set(type, name, callback) {
|
|
2451
|
-
for (var i = 0, n = type.length; i < n; ++i) {
|
|
2452
|
-
if (type[i].name === name) {
|
|
2453
|
-
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
|
|
2454
|
-
break;
|
|
2455
|
-
}
|
|
2456
|
-
}
|
|
2457
|
-
if (callback != null) type.push({ name, value: callback });
|
|
2458
|
-
return type;
|
|
2459
|
-
}
|
|
2460
|
-
var dispatch_default = dispatch;
|
|
2461
|
-
|
|
2462
|
-
// ../../node_modules/.bun/d3-timer@3.0.1/node_modules/d3-timer/src/timer.js
|
|
2463
|
-
var frame = 0;
|
|
2464
|
-
var timeout = 0;
|
|
2465
|
-
var interval = 0;
|
|
2466
|
-
var pokeDelay = 1e3;
|
|
2467
|
-
var taskHead;
|
|
2468
|
-
var taskTail;
|
|
2469
|
-
var clockLast = 0;
|
|
2470
|
-
var clockNow = 0;
|
|
2471
|
-
var clockSkew = 0;
|
|
2472
|
-
var clock = typeof performance === "object" && performance.now ? performance : Date;
|
|
2473
|
-
var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) {
|
|
2474
|
-
setTimeout(f, 17);
|
|
2475
|
-
};
|
|
2476
|
-
function now() {
|
|
2477
|
-
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
|
|
2478
|
-
}
|
|
2479
|
-
function clearNow() {
|
|
2480
|
-
clockNow = 0;
|
|
2481
|
-
}
|
|
2482
|
-
function Timer() {
|
|
2483
|
-
this._call = this._time = this._next = null;
|
|
2484
|
-
}
|
|
2485
|
-
Timer.prototype = timer.prototype = {
|
|
2486
|
-
constructor: Timer,
|
|
2487
|
-
restart: function(callback, delay, time) {
|
|
2488
|
-
if (typeof callback !== "function") throw new TypeError("callback is not a function");
|
|
2489
|
-
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
|
|
2490
|
-
if (!this._next && taskTail !== this) {
|
|
2491
|
-
if (taskTail) taskTail._next = this;
|
|
2492
|
-
else taskHead = this;
|
|
2493
|
-
taskTail = this;
|
|
2494
|
-
}
|
|
2495
|
-
this._call = callback;
|
|
2496
|
-
this._time = time;
|
|
2497
|
-
sleep();
|
|
2498
|
-
},
|
|
2499
|
-
stop: function() {
|
|
2500
|
-
if (this._call) {
|
|
2501
|
-
this._call = null;
|
|
2502
|
-
this._time = Infinity;
|
|
2503
|
-
sleep();
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
};
|
|
2507
|
-
function timer(callback, delay, time) {
|
|
2508
|
-
var t = new Timer();
|
|
2509
|
-
t.restart(callback, delay, time);
|
|
2510
|
-
return t;
|
|
2511
|
-
}
|
|
2512
|
-
function timerFlush() {
|
|
2513
|
-
now();
|
|
2514
|
-
++frame;
|
|
2515
|
-
var t = taskHead, e;
|
|
2516
|
-
while (t) {
|
|
2517
|
-
if ((e = clockNow - t._time) >= 0) t._call.call(void 0, e);
|
|
2518
|
-
t = t._next;
|
|
2519
|
-
}
|
|
2520
|
-
--frame;
|
|
2521
|
-
}
|
|
2522
|
-
function wake() {
|
|
2523
|
-
clockNow = (clockLast = clock.now()) + clockSkew;
|
|
2524
|
-
frame = timeout = 0;
|
|
2525
|
-
try {
|
|
2526
|
-
timerFlush();
|
|
2527
|
-
} finally {
|
|
2528
|
-
frame = 0;
|
|
2529
|
-
nap();
|
|
2530
|
-
clockNow = 0;
|
|
2531
|
-
}
|
|
2532
|
-
}
|
|
2533
|
-
function poke() {
|
|
2534
|
-
var now2 = clock.now(), delay = now2 - clockLast;
|
|
2535
|
-
if (delay > pokeDelay) clockSkew -= delay, clockLast = now2;
|
|
2536
|
-
}
|
|
2537
|
-
function nap() {
|
|
2538
|
-
var t0, t1 = taskHead, t2, time = Infinity;
|
|
2539
|
-
while (t1) {
|
|
2540
|
-
if (t1._call) {
|
|
2541
|
-
if (time > t1._time) time = t1._time;
|
|
2542
|
-
t0 = t1, t1 = t1._next;
|
|
2543
|
-
} else {
|
|
2544
|
-
t2 = t1._next, t1._next = null;
|
|
2545
|
-
t1 = t0 ? t0._next = t2 : taskHead = t2;
|
|
2546
|
-
}
|
|
2547
|
-
}
|
|
2548
|
-
taskTail = t0;
|
|
2549
|
-
sleep(time);
|
|
2550
|
-
}
|
|
2551
|
-
function sleep(time) {
|
|
2552
|
-
if (frame) return;
|
|
2553
|
-
if (timeout) timeout = clearTimeout(timeout);
|
|
2554
|
-
var delay = time - clockNow;
|
|
2555
|
-
if (delay > 24) {
|
|
2556
|
-
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
|
|
2557
|
-
if (interval) interval = clearInterval(interval);
|
|
2558
|
-
} else {
|
|
2559
|
-
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
|
|
2560
|
-
frame = 1, setFrame(wake);
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2563
|
-
|
|
2564
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/lcg.js
|
|
2565
|
-
var a = 1664525;
|
|
2566
|
-
var c = 1013904223;
|
|
2567
|
-
var m = 4294967296;
|
|
2568
|
-
function lcg_default() {
|
|
2569
|
-
let s = 1;
|
|
2570
|
-
return () => (s = (a * s + c) % m) / m;
|
|
2571
|
-
}
|
|
2572
|
-
|
|
2573
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/simulation.js
|
|
2574
|
-
function x2(d) {
|
|
2575
|
-
return d.x;
|
|
2576
|
-
}
|
|
2577
|
-
function y2(d) {
|
|
2578
|
-
return d.y;
|
|
2579
|
-
}
|
|
2580
|
-
var initialRadius = 10;
|
|
2581
|
-
var initialAngle = Math.PI * (3 - Math.sqrt(5));
|
|
2582
|
-
function simulation_default(nodes) {
|
|
2583
|
-
var simulation, alpha = 1, alphaMin = 1e-3, alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), alphaTarget = 0, velocityDecay = 0.6, forces = /* @__PURE__ */ new Map(), stepper = timer(step), event = dispatch_default("tick", "end"), random = lcg_default();
|
|
2584
|
-
if (nodes == null) nodes = [];
|
|
2585
|
-
function step() {
|
|
2586
|
-
tick();
|
|
2587
|
-
event.call("tick", simulation);
|
|
2588
|
-
if (alpha < alphaMin) {
|
|
2589
|
-
stepper.stop();
|
|
2590
|
-
event.call("end", simulation);
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
function tick(iterations) {
|
|
2594
|
-
var i, n = nodes.length, node;
|
|
2595
|
-
if (iterations === void 0) iterations = 1;
|
|
2596
|
-
for (var k = 0; k < iterations; ++k) {
|
|
2597
|
-
alpha += (alphaTarget - alpha) * alphaDecay;
|
|
2598
|
-
forces.forEach(function(force) {
|
|
2599
|
-
force(alpha);
|
|
2600
|
-
});
|
|
2601
|
-
for (i = 0; i < n; ++i) {
|
|
2602
|
-
node = nodes[i];
|
|
2603
|
-
if (node.fx == null) node.x += node.vx *= velocityDecay;
|
|
2604
|
-
else node.x = node.fx, node.vx = 0;
|
|
2605
|
-
if (node.fy == null) node.y += node.vy *= velocityDecay;
|
|
2606
|
-
else node.y = node.fy, node.vy = 0;
|
|
2607
|
-
}
|
|
2608
|
-
}
|
|
2609
|
-
return simulation;
|
|
2610
|
-
}
|
|
2611
|
-
function initializeNodes() {
|
|
2612
|
-
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
2613
|
-
node = nodes[i], node.index = i;
|
|
2614
|
-
if (node.fx != null) node.x = node.fx;
|
|
2615
|
-
if (node.fy != null) node.y = node.fy;
|
|
2616
|
-
if (isNaN(node.x) || isNaN(node.y)) {
|
|
2617
|
-
var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle;
|
|
2618
|
-
node.x = radius * Math.cos(angle);
|
|
2619
|
-
node.y = radius * Math.sin(angle);
|
|
2620
|
-
}
|
|
2621
|
-
if (isNaN(node.vx) || isNaN(node.vy)) {
|
|
2622
|
-
node.vx = node.vy = 0;
|
|
2623
|
-
}
|
|
2624
|
-
}
|
|
2625
|
-
}
|
|
2626
|
-
function initializeForce(force) {
|
|
2627
|
-
if (force.initialize) force.initialize(nodes, random);
|
|
2628
|
-
return force;
|
|
2629
|
-
}
|
|
2630
|
-
initializeNodes();
|
|
2631
|
-
return simulation = {
|
|
2632
|
-
tick,
|
|
2633
|
-
restart: function() {
|
|
2634
|
-
return stepper.restart(step), simulation;
|
|
2635
|
-
},
|
|
2636
|
-
stop: function() {
|
|
2637
|
-
return stepper.stop(), simulation;
|
|
2638
|
-
},
|
|
2639
|
-
nodes: function(_) {
|
|
2640
|
-
return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
|
|
2641
|
-
},
|
|
2642
|
-
alpha: function(_) {
|
|
2643
|
-
return arguments.length ? (alpha = +_, simulation) : alpha;
|
|
2644
|
-
},
|
|
2645
|
-
alphaMin: function(_) {
|
|
2646
|
-
return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
|
|
2647
|
-
},
|
|
2648
|
-
alphaDecay: function(_) {
|
|
2649
|
-
return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
|
|
2650
|
-
},
|
|
2651
|
-
alphaTarget: function(_) {
|
|
2652
|
-
return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
|
|
2653
|
-
},
|
|
2654
|
-
velocityDecay: function(_) {
|
|
2655
|
-
return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
|
|
2656
|
-
},
|
|
2657
|
-
randomSource: function(_) {
|
|
2658
|
-
return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random;
|
|
2659
|
-
},
|
|
2660
|
-
force: function(name, _) {
|
|
2661
|
-
return arguments.length > 1 ? (_ == null ? forces.delete(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
|
|
2662
|
-
},
|
|
2663
|
-
find: function(x3, y3, radius) {
|
|
2664
|
-
var i = 0, n = nodes.length, dx, dy, d2, node, closest;
|
|
2665
|
-
if (radius == null) radius = Infinity;
|
|
2666
|
-
else radius *= radius;
|
|
2667
|
-
for (i = 0; i < n; ++i) {
|
|
2668
|
-
node = nodes[i];
|
|
2669
|
-
dx = x3 - node.x;
|
|
2670
|
-
dy = y3 - node.y;
|
|
2671
|
-
d2 = dx * dx + dy * dy;
|
|
2672
|
-
if (d2 < radius) closest = node, radius = d2;
|
|
2673
|
-
}
|
|
2674
|
-
return closest;
|
|
2675
|
-
},
|
|
2676
|
-
on: function(name, _) {
|
|
2677
|
-
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
|
|
2678
|
-
}
|
|
2679
|
-
};
|
|
2680
|
-
}
|
|
2681
|
-
|
|
2682
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/manyBody.js
|
|
2683
|
-
function manyBody_default() {
|
|
2684
|
-
var nodes, node, random, alpha, strength = constant_default(-30), strengths, distanceMin2 = 1, distanceMax2 = Infinity, theta2 = 0.81;
|
|
2685
|
-
function force(_) {
|
|
2686
|
-
var i, n = nodes.length, tree = quadtree(nodes, x2, y2).visitAfter(accumulate);
|
|
2687
|
-
for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
|
|
2688
|
-
}
|
|
2689
|
-
function initialize() {
|
|
2690
|
-
if (!nodes) return;
|
|
2691
|
-
var i, n = nodes.length, node2;
|
|
2692
|
-
strengths = new Array(n);
|
|
2693
|
-
for (i = 0; i < n; ++i) node2 = nodes[i], strengths[node2.index] = +strength(node2, i, nodes);
|
|
2694
|
-
}
|
|
2695
|
-
function accumulate(quad) {
|
|
2696
|
-
var strength2 = 0, q, c2, weight = 0, x3, y3, i;
|
|
2697
|
-
if (quad.length) {
|
|
2698
|
-
for (x3 = y3 = i = 0; i < 4; ++i) {
|
|
2699
|
-
if ((q = quad[i]) && (c2 = Math.abs(q.value))) {
|
|
2700
|
-
strength2 += q.value, weight += c2, x3 += c2 * q.x, y3 += c2 * q.y;
|
|
2701
|
-
}
|
|
2702
|
-
}
|
|
2703
|
-
quad.x = x3 / weight;
|
|
2704
|
-
quad.y = y3 / weight;
|
|
2705
|
-
} else {
|
|
2706
|
-
q = quad;
|
|
2707
|
-
q.x = q.data.x;
|
|
2708
|
-
q.y = q.data.y;
|
|
2709
|
-
do
|
|
2710
|
-
strength2 += strengths[q.data.index];
|
|
2711
|
-
while (q = q.next);
|
|
2712
|
-
}
|
|
2713
|
-
quad.value = strength2;
|
|
2714
|
-
}
|
|
2715
|
-
function apply(quad, x1, _, x22) {
|
|
2716
|
-
if (!quad.value) return true;
|
|
2717
|
-
var x3 = quad.x - node.x, y3 = quad.y - node.y, w = x22 - x1, l = x3 * x3 + y3 * y3;
|
|
2718
|
-
if (w * w / theta2 < l) {
|
|
2719
|
-
if (l < distanceMax2) {
|
|
2720
|
-
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
2721
|
-
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
2722
|
-
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
|
|
2723
|
-
node.vx += x3 * quad.value * alpha / l;
|
|
2724
|
-
node.vy += y3 * quad.value * alpha / l;
|
|
2725
|
-
}
|
|
2726
|
-
return true;
|
|
2727
|
-
} else if (quad.length || l >= distanceMax2) return;
|
|
2728
|
-
if (quad.data !== node || quad.next) {
|
|
2729
|
-
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
2730
|
-
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
2731
|
-
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
|
|
2732
|
-
}
|
|
2733
|
-
do
|
|
2734
|
-
if (quad.data !== node) {
|
|
2735
|
-
w = strengths[quad.data.index] * alpha / l;
|
|
2736
|
-
node.vx += x3 * w;
|
|
2737
|
-
node.vy += y3 * w;
|
|
2738
|
-
}
|
|
2739
|
-
while (quad = quad.next);
|
|
2740
|
-
}
|
|
2741
|
-
force.initialize = function(_nodes, _random) {
|
|
2742
|
-
nodes = _nodes;
|
|
2743
|
-
random = _random;
|
|
2744
|
-
initialize();
|
|
2745
|
-
};
|
|
2746
|
-
force.strength = function(_) {
|
|
2747
|
-
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
2748
|
-
};
|
|
2749
|
-
force.distanceMin = function(_) {
|
|
2750
|
-
return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
|
|
2751
|
-
};
|
|
2752
|
-
force.distanceMax = function(_) {
|
|
2753
|
-
return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
|
|
2754
|
-
};
|
|
2755
|
-
force.theta = function(_) {
|
|
2756
|
-
return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
|
|
2757
|
-
};
|
|
2758
|
-
return force;
|
|
2759
|
-
}
|
|
2760
|
-
|
|
2761
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/x.js
|
|
2762
|
-
function x_default(x3) {
|
|
2763
|
-
var strength = constant_default(0.1), nodes, strengths, xz;
|
|
2764
|
-
if (typeof x3 !== "function") x3 = constant_default(x3 == null ? 0 : +x3);
|
|
2765
|
-
function force(alpha) {
|
|
2766
|
-
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
2767
|
-
node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
function initialize() {
|
|
2771
|
-
if (!nodes) return;
|
|
2772
|
-
var i, n = nodes.length;
|
|
2773
|
-
strengths = new Array(n);
|
|
2774
|
-
xz = new Array(n);
|
|
2775
|
-
for (i = 0; i < n; ++i) {
|
|
2776
|
-
strengths[i] = isNaN(xz[i] = +x3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
|
|
2777
|
-
}
|
|
2778
|
-
}
|
|
2779
|
-
force.initialize = function(_) {
|
|
2780
|
-
nodes = _;
|
|
2781
|
-
initialize();
|
|
2782
|
-
};
|
|
2783
|
-
force.strength = function(_) {
|
|
2784
|
-
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
2785
|
-
};
|
|
2786
|
-
force.x = function(_) {
|
|
2787
|
-
return arguments.length ? (x3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : x3;
|
|
2788
|
-
};
|
|
2789
|
-
return force;
|
|
2790
|
-
}
|
|
2791
|
-
|
|
2792
|
-
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/y.js
|
|
2793
|
-
function y_default(y3) {
|
|
2794
|
-
var strength = constant_default(0.1), nodes, strengths, yz;
|
|
2795
|
-
if (typeof y3 !== "function") y3 = constant_default(y3 == null ? 0 : +y3);
|
|
2796
|
-
function force(alpha) {
|
|
2797
|
-
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
2798
|
-
node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
function initialize() {
|
|
2802
|
-
if (!nodes) return;
|
|
2803
|
-
var i, n = nodes.length;
|
|
2804
|
-
strengths = new Array(n);
|
|
2805
|
-
yz = new Array(n);
|
|
2806
|
-
for (i = 0; i < n; ++i) {
|
|
2807
|
-
strengths[i] = isNaN(yz[i] = +y3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
force.initialize = function(_) {
|
|
2811
|
-
nodes = _;
|
|
2812
|
-
initialize();
|
|
2813
|
-
};
|
|
2814
|
-
force.strength = function(_) {
|
|
2815
|
-
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
2816
|
-
};
|
|
2817
|
-
force.y = function(_) {
|
|
2818
|
-
return arguments.length ? (y3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : y3;
|
|
2819
|
-
};
|
|
2820
|
-
return force;
|
|
2821
|
-
}
|
|
2822
|
-
|
|
2823
2197
|
// src/graph/simulation.ts
|
|
2198
|
+
import {
|
|
2199
|
+
forceCenter,
|
|
2200
|
+
forceCollide,
|
|
2201
|
+
forceLink,
|
|
2202
|
+
forceManyBody,
|
|
2203
|
+
forceSimulation,
|
|
2204
|
+
forceX,
|
|
2205
|
+
forceY
|
|
2206
|
+
} from "d3-force";
|
|
2824
2207
|
var SYNC_TICKS_PER_BATCH = 15;
|
|
2825
2208
|
var SYNC_MAX_TICKS_CEIL = 800;
|
|
2826
2209
|
var DEFAULT_ALPHA_MIN = 1e-3;
|
|
@@ -2837,14 +2220,14 @@ function forceCluster(nodes, strength) {
|
|
|
2837
2220
|
const count = /* @__PURE__ */ new Map();
|
|
2838
2221
|
for (const node of nodes) {
|
|
2839
2222
|
if (!node.community) continue;
|
|
2840
|
-
const
|
|
2841
|
-
cx.set(
|
|
2842
|
-
cy.set(
|
|
2843
|
-
count.set(
|
|
2223
|
+
const c = node.community;
|
|
2224
|
+
cx.set(c, (cx.get(c) ?? 0) + (node.x ?? 0));
|
|
2225
|
+
cy.set(c, (cy.get(c) ?? 0) + (node.y ?? 0));
|
|
2226
|
+
count.set(c, (count.get(c) ?? 0) + 1);
|
|
2844
2227
|
}
|
|
2845
|
-
for (const [
|
|
2846
|
-
cx.set(
|
|
2847
|
-
cy.set(
|
|
2228
|
+
for (const [c, n] of count) {
|
|
2229
|
+
cx.set(c, cx.get(c) / n);
|
|
2230
|
+
cy.set(c, cy.get(c) / n);
|
|
2848
2231
|
}
|
|
2849
2232
|
const k = strength * alpha;
|
|
2850
2233
|
for (const node of nodes) {
|
|
@@ -2946,17 +2329,17 @@ var SimulationManager = class _SimulationManager {
|
|
|
2946
2329
|
* pinned node's neighbors follow springily. Omitting it posts a byte-identical
|
|
2947
2330
|
* legacy message and leaves alpha untouched.
|
|
2948
2331
|
*/
|
|
2949
|
-
pinNode(id,
|
|
2332
|
+
pinNode(id, x, y, alphaTarget) {
|
|
2950
2333
|
if (this.destroyed) return;
|
|
2951
2334
|
if (this.worker) {
|
|
2952
2335
|
this.worker.postMessage(
|
|
2953
|
-
alphaTarget != null ? { type: "pin", nodeId: id, x
|
|
2336
|
+
alphaTarget != null ? { type: "pin", nodeId: id, x, y, alphaTarget } : { type: "pin", nodeId: id, x, y }
|
|
2954
2337
|
);
|
|
2955
2338
|
} else {
|
|
2956
2339
|
const node = this.syncNodeMap.get(id);
|
|
2957
2340
|
if (node) {
|
|
2958
|
-
node.fx =
|
|
2959
|
-
node.fy =
|
|
2341
|
+
node.fx = x;
|
|
2342
|
+
node.fy = y;
|
|
2960
2343
|
}
|
|
2961
2344
|
if (alphaTarget != null && this.syncSim) {
|
|
2962
2345
|
this.dragAlphaTarget = alphaTarget;
|
|
@@ -2999,14 +2382,14 @@ var SimulationManager = class _SimulationManager {
|
|
|
2999
2382
|
* Feed the cursor-repulsion force a pointer position. `active: false` clears
|
|
3000
2383
|
* the force. No-op when the graph has no cursor force configured (radius 0).
|
|
3001
2384
|
*/
|
|
3002
|
-
setPointer(
|
|
2385
|
+
setPointer(x, y, active) {
|
|
3003
2386
|
if (this.destroyed) return;
|
|
3004
2387
|
if (this.worker) {
|
|
3005
|
-
this.worker.postMessage({ type: "pointer", x
|
|
2388
|
+
this.worker.postMessage({ type: "pointer", x, y, active });
|
|
3006
2389
|
} else {
|
|
3007
2390
|
if (this.pointer.radius <= 0) return;
|
|
3008
|
-
this.pointer.x =
|
|
3009
|
-
this.pointer.y =
|
|
2391
|
+
this.pointer.x = x;
|
|
2392
|
+
this.pointer.y = y;
|
|
3010
2393
|
this.pointer.active = active;
|
|
3011
2394
|
this.cursorAlphaTarget = active ? 0.03 : 0;
|
|
3012
2395
|
if (this.syncSim) {
|
|
@@ -3024,15 +2407,15 @@ var SimulationManager = class _SimulationManager {
|
|
|
3024
2407
|
this.syncSim.alphaTarget(Math.max(this.dragAlphaTarget, this.cursorAlphaTarget));
|
|
3025
2408
|
}
|
|
3026
2409
|
/** Drag a node (pins it and reheats slightly). */
|
|
3027
|
-
dragNode(id,
|
|
2410
|
+
dragNode(id, x, y) {
|
|
3028
2411
|
if (this.destroyed) return;
|
|
3029
2412
|
if (this.worker) {
|
|
3030
|
-
this.worker.postMessage({ type: "drag", nodeId: id, x
|
|
2413
|
+
this.worker.postMessage({ type: "drag", nodeId: id, x, y });
|
|
3031
2414
|
} else {
|
|
3032
2415
|
const node = this.syncNodeMap.get(id);
|
|
3033
2416
|
if (node) {
|
|
3034
|
-
node.fx =
|
|
3035
|
-
node.fy =
|
|
2417
|
+
node.fx = x;
|
|
2418
|
+
node.fy = y;
|
|
3036
2419
|
}
|
|
3037
2420
|
if (this.syncSim && this.syncSim.alpha() < 0.1) {
|
|
3038
2421
|
this.syncSim.alpha(0.1).restart();
|
|
@@ -3128,17 +2511,17 @@ var SimulationManager = class _SimulationManager {
|
|
|
3128
2511
|
community: n.community
|
|
3129
2512
|
}));
|
|
3130
2513
|
this.syncNodeMap = new Map(this.syncNodes.map((n) => [n.id, n]));
|
|
3131
|
-
const linkForce =
|
|
2514
|
+
const linkForce = forceLink(edges.map((e) => ({ ...e }))).id((d) => d.id).distance(config.linkDistance);
|
|
3132
2515
|
if (config.linkStrength != null) {
|
|
3133
2516
|
linkForce.strength(config.linkStrength);
|
|
3134
2517
|
}
|
|
3135
2518
|
const padding = config.collisionPadding ?? 2;
|
|
3136
|
-
this.syncSim =
|
|
2519
|
+
this.syncSim = forceSimulation(this.syncNodes).force("link", linkForce).force("charge", forceManyBody().strength(config.chargeStrength)).force(
|
|
3137
2520
|
"collide",
|
|
3138
|
-
|
|
3139
|
-
).force("gravityX",
|
|
2521
|
+
forceCollide().radius((d) => d.radius + padding)
|
|
2522
|
+
).force("gravityX", forceX(0).strength(0.05)).force("gravityY", forceY(0).strength(0.05)).alphaDecay(config.alphaDecay).velocityDecay(config.velocityDecay).stop();
|
|
3140
2523
|
if (config.centerForce !== false) {
|
|
3141
|
-
this.syncSim.force("center",
|
|
2524
|
+
this.syncSim.force("center", forceCenter(0, 0));
|
|
3142
2525
|
}
|
|
3143
2526
|
if (config.clustering) {
|
|
3144
2527
|
const clusterFn = forceCluster(this.syncNodes, config.clustering.strength);
|
|
@@ -3239,24 +2622,24 @@ var SpatialIndex2 = class extends SpatialIndex {
|
|
|
3239
2622
|
};
|
|
3240
2623
|
|
|
3241
2624
|
// src/graph/update-diff-config.ts
|
|
3242
|
-
function stableKey(
|
|
2625
|
+
function stableKey(c) {
|
|
3243
2626
|
return JSON.stringify([
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
2627
|
+
c.chargeStrength,
|
|
2628
|
+
c.linkDistance,
|
|
2629
|
+
c.clustering ? [c.clustering.field, c.clustering.strength] : null,
|
|
2630
|
+
c.alphaDecay,
|
|
2631
|
+
c.velocityDecay,
|
|
2632
|
+
c.collisionRadius,
|
|
2633
|
+
c.collisionPadding ?? null,
|
|
2634
|
+
c.linkStrength ?? null,
|
|
2635
|
+
c.centerForce ?? null,
|
|
2636
|
+
c.seed ?? null,
|
|
2637
|
+
c.warmupTicks ?? null,
|
|
2638
|
+
c.warmupBudgetMs ?? null
|
|
3256
2639
|
]);
|
|
3257
2640
|
}
|
|
3258
|
-
function simulationConfigEqual(
|
|
3259
|
-
return stableKey(
|
|
2641
|
+
function simulationConfigEqual(a, b) {
|
|
2642
|
+
return stableKey(a) === stableKey(b);
|
|
3260
2643
|
}
|
|
3261
2644
|
|
|
3262
2645
|
// src/graph/update-diff.ts
|
|
@@ -3297,9 +2680,9 @@ function diffGraphUpdate(prevNodes, prevEdges, next, prevConfig, seed) {
|
|
|
3297
2680
|
const remainingPrev = new Map(prevEdgeCounts);
|
|
3298
2681
|
for (const e of next.edges) {
|
|
3299
2682
|
const k = `${e.source} ${e.target}`;
|
|
3300
|
-
const
|
|
3301
|
-
if (
|
|
3302
|
-
remainingPrev.set(k,
|
|
2683
|
+
const c = remainingPrev.get(k);
|
|
2684
|
+
if (c && c > 0) {
|
|
2685
|
+
remainingPrev.set(k, c - 1);
|
|
3303
2686
|
} else {
|
|
3304
2687
|
enteringEdgeCount++;
|
|
3305
2688
|
}
|
|
@@ -3339,10 +2722,10 @@ function diffGraphUpdate(prevNodes, prevEdges, next, prevConfig, seed) {
|
|
|
3339
2722
|
}
|
|
3340
2723
|
function buildAdjacency(edges) {
|
|
3341
2724
|
const map = /* @__PURE__ */ new Map();
|
|
3342
|
-
const push = (
|
|
3343
|
-
const list = map.get(
|
|
2725
|
+
const push = (a, b) => {
|
|
2726
|
+
const list = map.get(a);
|
|
3344
2727
|
if (list) list.push(b);
|
|
3345
|
-
else map.set(
|
|
2728
|
+
else map.set(a, [b]);
|
|
3346
2729
|
};
|
|
3347
2730
|
for (const e of edges) {
|
|
3348
2731
|
push(e.source, e.target);
|
|
@@ -3370,9 +2753,9 @@ function edgeSetsEqual(prev, next) {
|
|
|
3370
2753
|
}
|
|
3371
2754
|
for (const e of next) {
|
|
3372
2755
|
const k = key(e);
|
|
3373
|
-
const
|
|
3374
|
-
if (!
|
|
3375
|
-
counts.set(k,
|
|
2756
|
+
const c = counts.get(k);
|
|
2757
|
+
if (!c) return false;
|
|
2758
|
+
counts.set(k, c - 1);
|
|
3376
2759
|
}
|
|
3377
2760
|
return true;
|
|
3378
2761
|
}
|
|
@@ -3696,9 +3079,9 @@ function createGraph(container, spec, options) {
|
|
|
3696
3079
|
for (const p of positions) {
|
|
3697
3080
|
posMap.set(p.id, { x: p.x, y: p.y });
|
|
3698
3081
|
}
|
|
3699
|
-
positionedNodes = compilation.nodes.map((node,
|
|
3082
|
+
positionedNodes = compilation.nodes.map((node, index) => {
|
|
3700
3083
|
const pos = posMap.get(node.id) ?? { x: 0, y: 0 };
|
|
3701
|
-
return { ...node, x: pos.x, y: pos.y, index
|
|
3084
|
+
return { ...node, x: pos.x, y: pos.y, index };
|
|
3702
3085
|
});
|
|
3703
3086
|
positionedEdges = compilation.edges.map((edge) => {
|
|
3704
3087
|
const src = posMap.get(edge.source) ?? { x: 0, y: 0 };
|
|
@@ -3801,16 +3184,16 @@ function createGraph(container, spec, options) {
|
|
|
3801
3184
|
if (nodeId === null) return null;
|
|
3802
3185
|
if (compilation.interaction.hoverMode === "category") {
|
|
3803
3186
|
const cat = nodeCategory.get(nodeId);
|
|
3804
|
-
const
|
|
3187
|
+
const set2 = /* @__PURE__ */ new Set([nodeId]);
|
|
3805
3188
|
if (cat !== void 0) {
|
|
3806
|
-
for (const [id,
|
|
3189
|
+
for (const [id, c] of nodeCategory) if (c === cat) set2.add(id);
|
|
3807
3190
|
}
|
|
3808
|
-
return
|
|
3191
|
+
return set2;
|
|
3809
3192
|
}
|
|
3810
|
-
const
|
|
3193
|
+
const set = /* @__PURE__ */ new Set([nodeId]);
|
|
3811
3194
|
const neighbors = adjacencyMap.get(nodeId);
|
|
3812
|
-
if (neighbors) for (const nid of neighbors)
|
|
3813
|
-
return
|
|
3195
|
+
if (neighbors) for (const nid of neighbors) set.add(nid);
|
|
3196
|
+
return set;
|
|
3814
3197
|
}
|
|
3815
3198
|
function standingSnapshot() {
|
|
3816
3199
|
return composeStandingFocus(
|
|
@@ -3823,16 +3206,16 @@ function createGraph(container, spec, options) {
|
|
|
3823
3206
|
function targetSnapshot() {
|
|
3824
3207
|
return layerHoverFocus(standingSnapshot(), hoveredNodeId, hoverConnectedSet(hoveredNodeId));
|
|
3825
3208
|
}
|
|
3826
|
-
function armFocus(
|
|
3209
|
+
function armFocus(now) {
|
|
3827
3210
|
const target = targetSnapshot();
|
|
3828
3211
|
const hoverCfg = compilation.animation?.hover ?? null;
|
|
3829
3212
|
const duration = hoverCfg && !prefersReducedMotion() ? hoverCfg.duration : 0;
|
|
3830
3213
|
const ease = resolveEase(hoverCfg?.ease ?? "smooth");
|
|
3831
3214
|
if (!focusTransition) {
|
|
3832
|
-
focusTransition = new FocusTransition(target, duration, ease,
|
|
3215
|
+
focusTransition = new FocusTransition(target, duration, ease, now);
|
|
3833
3216
|
return;
|
|
3834
3217
|
}
|
|
3835
|
-
focusTransition.retarget(target,
|
|
3218
|
+
focusTransition.retarget(target, now);
|
|
3836
3219
|
if (focusAnim) scheduler.remove(focusAnim);
|
|
3837
3220
|
focusAnim = {
|
|
3838
3221
|
tick: (t) => {
|
|
@@ -3857,28 +3240,28 @@ function createGraph(container, spec, options) {
|
|
|
3857
3240
|
function resolveHighlightTarget(target) {
|
|
3858
3241
|
if ("nodeIds" in target) return new Set(target.nodeIds);
|
|
3859
3242
|
if ("neighborsOf" in target) {
|
|
3860
|
-
const
|
|
3861
|
-
if (target.includeSelf !== false)
|
|
3243
|
+
const set2 = /* @__PURE__ */ new Set();
|
|
3244
|
+
if (target.includeSelf !== false) set2.add(target.neighborsOf);
|
|
3862
3245
|
const neighbors = adjacencyMap.get(target.neighborsOf);
|
|
3863
|
-
if (neighbors) for (const nid of neighbors)
|
|
3864
|
-
return
|
|
3246
|
+
if (neighbors) for (const nid of neighbors) set2.add(nid);
|
|
3247
|
+
return set2;
|
|
3865
3248
|
}
|
|
3866
3249
|
const values = new Set(
|
|
3867
3250
|
Array.isArray(target.category.value) ? target.category.value : [target.category.value]
|
|
3868
3251
|
);
|
|
3869
3252
|
const field = target.category.field;
|
|
3870
|
-
const
|
|
3253
|
+
const set = /* @__PURE__ */ new Set();
|
|
3871
3254
|
for (const n of compilation.nodes) {
|
|
3872
3255
|
const v = n.data?.[field];
|
|
3873
|
-
if (v != null && values.has(String(v)))
|
|
3256
|
+
if (v != null && values.has(String(v))) set.add(n.id);
|
|
3874
3257
|
}
|
|
3875
|
-
return
|
|
3258
|
+
return set;
|
|
3876
3259
|
}
|
|
3877
3260
|
function categoryHighlightSet() {
|
|
3878
3261
|
if (activeCategories.size === 0) return null;
|
|
3879
|
-
const
|
|
3880
|
-
for (const [id, cat] of nodeCategory) if (activeCategories.has(cat))
|
|
3881
|
-
return
|
|
3262
|
+
const set = /* @__PURE__ */ new Set();
|
|
3263
|
+
for (const [id, cat] of nodeCategory) if (activeCategories.has(cat)) set.add(id);
|
|
3264
|
+
return set;
|
|
3882
3265
|
}
|
|
3883
3266
|
function recomputeHighlight() {
|
|
3884
3267
|
const filter = categoryHighlightSet();
|
|
@@ -3967,23 +3350,23 @@ function createGraph(container, spec, options) {
|
|
|
3967
3350
|
const t = options?.tooltip;
|
|
3968
3351
|
return t && typeof t === "object" ? t.formatter ?? null : null;
|
|
3969
3352
|
}
|
|
3970
|
-
function applyFormatterResult(result,
|
|
3353
|
+
function applyFormatterResult(result, x, y) {
|
|
3971
3354
|
if (!tooltipManager) return;
|
|
3972
3355
|
if (result === null) {
|
|
3973
3356
|
tooltipManager.hide();
|
|
3974
3357
|
} else if (typeof result === "string") {
|
|
3975
|
-
tooltipManager.show({ text: result },
|
|
3358
|
+
tooltipManager.show({ text: result }, x, y);
|
|
3976
3359
|
} else if (result instanceof HTMLElement) {
|
|
3977
|
-
tooltipManager.show({ element: result },
|
|
3360
|
+
tooltipManager.show({ element: result }, x, y);
|
|
3978
3361
|
} else {
|
|
3979
|
-
tooltipManager.show(result,
|
|
3362
|
+
tooltipManager.show(result, x, y);
|
|
3980
3363
|
}
|
|
3981
3364
|
}
|
|
3982
|
-
function buildRenderState(
|
|
3365
|
+
function buildRenderState(now) {
|
|
3983
3366
|
const transform = interactionManager.getTransform();
|
|
3984
|
-
if (!focusTransition) armFocus(
|
|
3367
|
+
if (!focusTransition) armFocus(now);
|
|
3985
3368
|
const ft = focusTransition;
|
|
3986
|
-
const t = ft.progress(
|
|
3369
|
+
const t = ft.progress(now);
|
|
3987
3370
|
const focus = t < 1 ? { t, prev: ft.prev, next: ft.next } : void 0;
|
|
3988
3371
|
const settledNext = ft.next;
|
|
3989
3372
|
const hoverRadiusScale = hoverRadiusTween ? /* @__PURE__ */ new Map([[hoverRadiusTween.nodeId, hoverRadiusTween.scale]]) : void 0;
|
|
@@ -4013,13 +3396,13 @@ function createGraph(container, spec, options) {
|
|
|
4013
3396
|
exiting: exitingGhosts ?? void 0
|
|
4014
3397
|
};
|
|
4015
3398
|
}
|
|
4016
|
-
function renderFrame(
|
|
3399
|
+
function renderFrame(now) {
|
|
4017
3400
|
animFrameId = null;
|
|
4018
3401
|
if (destroyed || !renderer || !interactionManager) return;
|
|
4019
|
-
if (scheduler.tick(
|
|
3402
|
+
if (scheduler.tick(now)) needsRender = true;
|
|
4020
3403
|
if (needsRender) {
|
|
4021
3404
|
needsRender = false;
|
|
4022
|
-
renderer.render(buildRenderState(
|
|
3405
|
+
renderer.render(buildRenderState(now));
|
|
4023
3406
|
}
|
|
4024
3407
|
if (scheduler.active) scheduleRender();
|
|
4025
3408
|
if (cameraChangePending) {
|
|
@@ -4127,8 +3510,8 @@ function createGraph(container, spec, options) {
|
|
|
4127
3510
|
},
|
|
4128
3511
|
onBackgroundHover(graphX, graphY, screenX, screenY) {
|
|
4129
3512
|
if (hoveredNodeId) return;
|
|
4130
|
-
const
|
|
4131
|
-
if (
|
|
3513
|
+
const now = performance.now();
|
|
3514
|
+
if (now - lastEdgeHitTime < 32) {
|
|
4132
3515
|
if (hoveredEdgeId) {
|
|
4133
3516
|
hoveredEdgeId = null;
|
|
4134
3517
|
needsRender = true;
|
|
@@ -4138,7 +3521,7 @@ function createGraph(container, spec, options) {
|
|
|
4138
3521
|
}
|
|
4139
3522
|
return;
|
|
4140
3523
|
}
|
|
4141
|
-
lastEdgeHitTime =
|
|
3524
|
+
lastEdgeHitTime = now;
|
|
4142
3525
|
const transform = interactionManager?.getTransform();
|
|
4143
3526
|
const threshold = 5 / (transform?.k ?? 1);
|
|
4144
3527
|
const edgeId = hitTestEdge(graphX, graphY, threshold);
|
|
@@ -4169,13 +3552,13 @@ function createGraph(container, spec, options) {
|
|
|
4169
3552
|
},
|
|
4170
3553
|
onNodeDragStart(nodeId) {
|
|
4171
3554
|
const node = positionedNodes.find((n) => n.id === nodeId);
|
|
4172
|
-
const
|
|
4173
|
-
const
|
|
4174
|
-
simulation?.pinNode(nodeId,
|
|
3555
|
+
const x = node?.x ?? 0;
|
|
3556
|
+
const y = node?.y ?? 0;
|
|
3557
|
+
simulation?.pinNode(nodeId, x, y, springyDragEnabled() ? 0.3 : void 0);
|
|
4175
3558
|
canvas?.classList.add("oc-graph-canvas--dragging");
|
|
4176
3559
|
},
|
|
4177
|
-
onNodeDrag(nodeId,
|
|
4178
|
-
simulation?.dragNode(nodeId,
|
|
3560
|
+
onNodeDrag(nodeId, x, y) {
|
|
3561
|
+
simulation?.dragNode(nodeId, x, y);
|
|
4179
3562
|
},
|
|
4180
3563
|
onNodeDragEnd(nodeId) {
|
|
4181
3564
|
simulation?.unpinNode(nodeId, springyDragEnabled() ? 0 : void 0);
|
|
@@ -4183,9 +3566,9 @@ function createGraph(container, spec, options) {
|
|
|
4183
3566
|
},
|
|
4184
3567
|
onPointerMove(graphX, graphY) {
|
|
4185
3568
|
if (!cursorForceEnabled()) return;
|
|
4186
|
-
const
|
|
4187
|
-
if (
|
|
4188
|
-
lastPointerFeedTime =
|
|
3569
|
+
const now = performance.now();
|
|
3570
|
+
if (now - lastPointerFeedTime < CURSOR_POINTER_THROTTLE_MS) return;
|
|
3571
|
+
lastPointerFeedTime = now;
|
|
4189
3572
|
simulation?.setPointer(graphX, graphY, true);
|
|
4190
3573
|
},
|
|
4191
3574
|
onPointerLeave() {
|
|
@@ -4272,8 +3655,8 @@ function createGraph(container, spec, options) {
|
|
|
4272
3655
|
const k = clampK(target.k ?? interactionManager.getTransform().k);
|
|
4273
3656
|
flyCamera(new ZoomTransform(cw / 2 - target.x * k, ch / 2 - target.y * k, k), opts);
|
|
4274
3657
|
}
|
|
4275
|
-
function centerAt(
|
|
4276
|
-
flyTo({ x
|
|
3658
|
+
function centerAt(x, y, opts) {
|
|
3659
|
+
flyTo({ x, y }, opts);
|
|
4277
3660
|
}
|
|
4278
3661
|
function getCamera() {
|
|
4279
3662
|
const t = interactionManager?.getTransform() ?? ZoomTransform.identity();
|
|
@@ -4402,9 +3785,9 @@ function createGraph(container, spec, options) {
|
|
|
4402
3785
|
for (const node of positionedNodes) {
|
|
4403
3786
|
posMap.set(node.id, { x: node.x, y: node.y });
|
|
4404
3787
|
}
|
|
4405
|
-
positionedNodes = compilation.nodes.map((node,
|
|
3788
|
+
positionedNodes = compilation.nodes.map((node, index) => {
|
|
4406
3789
|
const pos = posMap.get(node.id) ?? { x: 0, y: 0 };
|
|
4407
|
-
return { ...node, x: pos.x, y: pos.y, index
|
|
3790
|
+
return { ...node, x: pos.x, y: pos.y, index };
|
|
4408
3791
|
});
|
|
4409
3792
|
positionedEdges = compilation.edges.map((edge) => {
|
|
4410
3793
|
const src = posMap.get(edge.source) ?? { x: 0, y: 0 };
|
|
@@ -4442,9 +3825,9 @@ function createGraph(container, spec, options) {
|
|
|
4442
3825
|
);
|
|
4443
3826
|
const changeRatio = Math.max(nodeRatio, edgeRatio);
|
|
4444
3827
|
const initialAlpha = Math.min(1, 0.3 + 0.7 * changeRatio);
|
|
4445
|
-
positionedNodes = compilation.nodes.map((node,
|
|
3828
|
+
positionedNodes = compilation.nodes.map((node, index) => {
|
|
4446
3829
|
const pos = positions.get(node.id) ?? { x: 0, y: 0 };
|
|
4447
|
-
return { ...node, x: pos.x, y: pos.y, index
|
|
3830
|
+
return { ...node, x: pos.x, y: pos.y, index };
|
|
4448
3831
|
});
|
|
4449
3832
|
positionedEdges = compilation.edges.map((edge) => {
|
|
4450
3833
|
const src = positions.get(edge.source) ?? { x: 0, y: 0 };
|
|
@@ -4651,7 +4034,7 @@ function applyCellStyle(td, cell) {
|
|
|
4651
4034
|
}
|
|
4652
4035
|
}
|
|
4653
4036
|
function countryToEmoji(code) {
|
|
4654
|
-
return [...code.toUpperCase()].map((
|
|
4037
|
+
return [...code.toUpperCase()].map((c) => String.fromCodePoint(c.charCodeAt(0) + 127397)).join("");
|
|
4655
4038
|
}
|
|
4656
4039
|
var COUNTRY_NAMES = {
|
|
4657
4040
|
US: "United States",
|
|
@@ -4852,11 +4235,11 @@ function renderSparklineCell(cell) {
|
|
|
4852
4235
|
const barW = Math.max(1, (innerW - gap * (barCount - 1)) / barCount);
|
|
4853
4236
|
for (let i = 0; i < barCount; i++) {
|
|
4854
4237
|
const barH = Math.max(1, sparklineData.bars[i] * innerH);
|
|
4855
|
-
const
|
|
4856
|
-
const
|
|
4238
|
+
const x = padding + i * (barW + gap);
|
|
4239
|
+
const y = padding + innerH - barH;
|
|
4857
4240
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4858
|
-
rect.setAttribute("x", String(
|
|
4859
|
-
rect.setAttribute("y", String(
|
|
4241
|
+
rect.setAttribute("x", String(x));
|
|
4242
|
+
rect.setAttribute("y", String(y));
|
|
4860
4243
|
rect.setAttribute("width", String(barW));
|
|
4861
4244
|
rect.setAttribute("height", String(barH));
|
|
4862
4245
|
rect.setAttribute("rx", "1.5");
|
|
@@ -4882,11 +4265,11 @@ function renderSparklineCell(cell) {
|
|
|
4882
4265
|
const barH = Math.max(1, (innerH - gap * (barCount - 1)) / barCount);
|
|
4883
4266
|
for (let i = 0; i < barCount; i++) {
|
|
4884
4267
|
const barW = Math.max(1, sparklineData.bars[i] * innerW);
|
|
4885
|
-
const
|
|
4886
|
-
const
|
|
4268
|
+
const x = padding;
|
|
4269
|
+
const y = padding + i * (barH + gap);
|
|
4887
4270
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4888
|
-
rect.setAttribute("x", String(
|
|
4889
|
-
rect.setAttribute("y", String(
|
|
4271
|
+
rect.setAttribute("x", String(x));
|
|
4272
|
+
rect.setAttribute("y", String(y));
|
|
4890
4273
|
rect.setAttribute("width", String(barW));
|
|
4891
4274
|
rect.setAttribute("height", String(barH));
|
|
4892
4275
|
rect.setAttribute("rx", "1.5");
|
|
@@ -5074,12 +4457,12 @@ function renderBrand(parent, layout) {
|
|
|
5074
4457
|
const { chrome } = layout;
|
|
5075
4458
|
const firstBottom = chrome.source ?? chrome.byline ?? chrome.footer;
|
|
5076
4459
|
const chromeY = firstBottom ? bottomOffset + firstBottom.y : bottomOffset + layout.theme.spacing.chartToFooter;
|
|
5077
|
-
const
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
4460
|
+
const a = createSVGElement2("a");
|
|
4461
|
+
a.setAttribute("href", BRAND_URL2);
|
|
4462
|
+
a.setAttributeNS(XLINK_NS2, "xlink:href", BRAND_URL2);
|
|
4463
|
+
a.setAttribute("target", "_blank");
|
|
4464
|
+
a.setAttribute("rel", "noopener");
|
|
4465
|
+
a.setAttribute("class", "oc-chrome-ref");
|
|
5083
4466
|
const BRAND_LARGE = 16;
|
|
5084
4467
|
const text = createSVGElement2("text");
|
|
5085
4468
|
setAttrs2(text, {
|
|
@@ -5104,8 +4487,8 @@ function renderBrand(parent, layout) {
|
|
|
5104
4487
|
text.appendChild(trySpan);
|
|
5105
4488
|
text.appendChild(openDataSpan);
|
|
5106
4489
|
text.appendChild(aiSpan);
|
|
5107
|
-
|
|
5108
|
-
parent.appendChild(
|
|
4490
|
+
a.appendChild(text);
|
|
4491
|
+
parent.appendChild(a);
|
|
5109
4492
|
}
|
|
5110
4493
|
function renderLegend(parent, legendLayout) {
|
|
5111
4494
|
if (!("entries" in legendLayout) || legendLayout.entries.length === 0) return;
|
|
@@ -5205,9 +4588,9 @@ function renderGradientDefs(defs, links, nodePositions) {
|
|
|
5205
4588
|
const sourcePos = nodePositions.get(link.sourceId);
|
|
5206
4589
|
const targetPos = nodePositions.get(link.targetId);
|
|
5207
4590
|
const x1 = sourcePos ? sourcePos.x + sourcePos.width : 0;
|
|
5208
|
-
const
|
|
4591
|
+
const x2 = targetPos ? targetPos.x : 0;
|
|
5209
4592
|
gradient.setAttribute("x1", String(x1));
|
|
5210
|
-
gradient.setAttribute("x2", String(
|
|
4593
|
+
gradient.setAttribute("x2", String(x2));
|
|
5211
4594
|
const stop0 = createSVGElement2("stop");
|
|
5212
4595
|
setAttrs2(stop0, { offset: "0%", "stop-color": link.sourceColor });
|
|
5213
4596
|
gradient.appendChild(stop0);
|
|
@@ -5409,20 +4792,24 @@ function createSankey(container, spec, options) {
|
|
|
5409
4792
|
}
|
|
5410
4793
|
function wireTooltipAndInteraction(svg, layout) {
|
|
5411
4794
|
const cleanups = [];
|
|
4795
|
+
const nodesById = /* @__PURE__ */ new Map();
|
|
4796
|
+
for (const n of layout.nodes) {
|
|
4797
|
+
if (!nodesById.has(n.nodeId)) nodesById.set(n.nodeId, n);
|
|
4798
|
+
}
|
|
5412
4799
|
const nodeElements = svg.querySelectorAll(".oc-sankey-node");
|
|
5413
4800
|
for (const el of nodeElements) {
|
|
5414
4801
|
const markId = el.getAttribute("data-mark-id");
|
|
5415
4802
|
if (!markId) continue;
|
|
5416
4803
|
const content = layout.tooltipDescriptors.get(markId);
|
|
5417
4804
|
const nodeId = el.getAttribute("data-node-id");
|
|
5418
|
-
const nodeData = nodeId ?
|
|
4805
|
+
const nodeData = nodeId ? nodesById.get(nodeId)?.data ?? {} : {};
|
|
5419
4806
|
const handleMouseEnter = (e) => {
|
|
5420
4807
|
const mouseEvent = e;
|
|
5421
4808
|
if (content && tooltipManager) {
|
|
5422
4809
|
const svgRect = svg.getBoundingClientRect();
|
|
5423
|
-
const
|
|
5424
|
-
const
|
|
5425
|
-
tooltipManager.show(content,
|
|
4810
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
4811
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
4812
|
+
tooltipManager.show(content, x, y);
|
|
5426
4813
|
}
|
|
5427
4814
|
options?.onNodeHover?.(nodeData);
|
|
5428
4815
|
if (nodeId) highlightConnectedLinks(svg, nodeId, layout);
|
|
@@ -5431,9 +4818,9 @@ function createSankey(container, spec, options) {
|
|
|
5431
4818
|
if (content && tooltipManager) {
|
|
5432
4819
|
const mouseEvent = e;
|
|
5433
4820
|
const svgRect = svg.getBoundingClientRect();
|
|
5434
|
-
const
|
|
5435
|
-
const
|
|
5436
|
-
tooltipManager.show(content,
|
|
4821
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
4822
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
4823
|
+
tooltipManager.show(content, x, y);
|
|
5437
4824
|
}
|
|
5438
4825
|
};
|
|
5439
4826
|
const handleMouseLeave = () => {
|
|
@@ -5467,9 +4854,9 @@ function createSankey(container, spec, options) {
|
|
|
5467
4854
|
const mouseEvent = e;
|
|
5468
4855
|
if (content && tooltipManager) {
|
|
5469
4856
|
const svgRect = svg.getBoundingClientRect();
|
|
5470
|
-
const
|
|
5471
|
-
const
|
|
5472
|
-
tooltipManager.show(content,
|
|
4857
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
4858
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
4859
|
+
tooltipManager.show(content, x, y);
|
|
5473
4860
|
}
|
|
5474
4861
|
options?.onLinkHover?.(linkData);
|
|
5475
4862
|
};
|
|
@@ -5477,9 +4864,9 @@ function createSankey(container, spec, options) {
|
|
|
5477
4864
|
if (content && tooltipManager) {
|
|
5478
4865
|
const mouseEvent = e;
|
|
5479
4866
|
const svgRect = svg.getBoundingClientRect();
|
|
5480
|
-
const
|
|
5481
|
-
const
|
|
5482
|
-
tooltipManager.show(content,
|
|
4867
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
4868
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
4869
|
+
tooltipManager.show(content, x, y);
|
|
5483
4870
|
}
|
|
5484
4871
|
};
|
|
5485
4872
|
const handleMouseLeave = () => {
|
|
@@ -5993,12 +5380,12 @@ function renderTbody(rows, columns) {
|
|
|
5993
5380
|
tr.setAttribute("role", "row");
|
|
5994
5381
|
tr.setAttribute("data-row-id", row.id);
|
|
5995
5382
|
tr.style.setProperty("--oc-row-index", String(r));
|
|
5996
|
-
for (let
|
|
5997
|
-
const cell = row.cells[
|
|
5383
|
+
for (let c = 0; c < columns.length; c++) {
|
|
5384
|
+
const cell = row.cells[c];
|
|
5998
5385
|
if (!cell) continue;
|
|
5999
5386
|
const td = renderCell(cell);
|
|
6000
5387
|
td.setAttribute("role", "gridcell");
|
|
6001
|
-
td.style.textAlign = columns[
|
|
5388
|
+
td.style.textAlign = columns[c].align;
|
|
6002
5389
|
tr.appendChild(td);
|
|
6003
5390
|
}
|
|
6004
5391
|
tbody.appendChild(tr);
|
|
@@ -6462,7 +5849,7 @@ function createTable(container, spec, options) {
|
|
|
6462
5849
|
search: state.search || void 0
|
|
6463
5850
|
// No page/pageSize: get all rows
|
|
6464
5851
|
});
|
|
6465
|
-
const headers = fullLayout.columns.map((
|
|
5852
|
+
const headers = fullLayout.columns.map((c) => c.label);
|
|
6466
5853
|
const csvRows = [headers.map(csvEscape).join(",")];
|
|
6467
5854
|
for (const row of fullLayout.rows) {
|
|
6468
5855
|
const values = row.cells.map((cell) => csvEscape(cell.formattedValue));
|
|
@@ -6595,19 +5982,23 @@ function createTileMap(container, spec, options) {
|
|
|
6595
5982
|
}
|
|
6596
5983
|
function wireTooltipAndInteraction(svg, layout) {
|
|
6597
5984
|
const cleanups = [];
|
|
5985
|
+
const tilesByStateCode = /* @__PURE__ */ new Map();
|
|
5986
|
+
for (const t of layout.tiles) {
|
|
5987
|
+
if (!tilesByStateCode.has(t.stateCode)) tilesByStateCode.set(t.stateCode, t);
|
|
5988
|
+
}
|
|
6598
5989
|
const tileElements = svg.querySelectorAll(".oc-tilemap-tile");
|
|
6599
5990
|
for (const el of tileElements) {
|
|
6600
5991
|
const stateCode = el.getAttribute("data-state");
|
|
6601
5992
|
if (!stateCode) continue;
|
|
6602
5993
|
const content = layout.tooltipDescriptors.get(stateCode);
|
|
6603
|
-
const tile =
|
|
5994
|
+
const tile = tilesByStateCode.get(stateCode);
|
|
6604
5995
|
const handleMouseEnter = (e) => {
|
|
6605
5996
|
const mouseEvent = e;
|
|
6606
5997
|
if (content && tooltipManager && options?.tooltip !== false) {
|
|
6607
5998
|
const svgRect = svg.getBoundingClientRect();
|
|
6608
|
-
const
|
|
6609
|
-
const
|
|
6610
|
-
tooltipManager.show(content,
|
|
5999
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
6000
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
6001
|
+
tooltipManager.show(content, x, y);
|
|
6611
6002
|
}
|
|
6612
6003
|
if (tile) {
|
|
6613
6004
|
options?.onTileHover?.({
|
|
@@ -6622,9 +6013,9 @@ function createTileMap(container, spec, options) {
|
|
|
6622
6013
|
if (content && tooltipManager && options?.tooltip !== false) {
|
|
6623
6014
|
const mouseEvent = e;
|
|
6624
6015
|
const svgRect = svg.getBoundingClientRect();
|
|
6625
|
-
const
|
|
6626
|
-
const
|
|
6627
|
-
tooltipManager.show(content,
|
|
6016
|
+
const x = mouseEvent.clientX - svgRect.left;
|
|
6017
|
+
const y = mouseEvent.clientY - svgRect.top;
|
|
6018
|
+
tooltipManager.show(content, x, y);
|
|
6628
6019
|
}
|
|
6629
6020
|
};
|
|
6630
6021
|
const handleMouseLeave = () => {
|