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