@opendata-ai/openchart-vanilla 2.7.0 → 2.8.1
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/index.js +1132 -162
- package/dist/index.js.map +1 -1
- package/dist/styles.css +4 -2
- package/package.json +3 -3
- package/src/__tests__/svg-renderer.test.ts +40 -0
- package/src/graph-mount.ts +14 -1
- package/src/svg-renderer.ts +64 -1
package/dist/index.js
CHANGED
|
@@ -125,12 +125,12 @@ function labelThreshold(zoom) {
|
|
|
125
125
|
return 1 - t;
|
|
126
126
|
}
|
|
127
127
|
function visibleRect(canvasWidth, canvasHeight, transform, margin = CULL_MARGIN) {
|
|
128
|
-
const { x, y, k } = transform;
|
|
128
|
+
const { x: x3, y: y3, k } = transform;
|
|
129
129
|
return {
|
|
130
|
-
minX: (-
|
|
131
|
-
minY: (-
|
|
132
|
-
maxX: (canvasWidth -
|
|
133
|
-
maxY: (canvasHeight -
|
|
130
|
+
minX: (-x3 - margin) / k,
|
|
131
|
+
minY: (-y3 - margin) / k,
|
|
132
|
+
maxX: (canvasWidth - x3 + margin) / k,
|
|
133
|
+
maxY: (canvasHeight - y3 + margin) / k
|
|
134
134
|
};
|
|
135
135
|
}
|
|
136
136
|
function nodeInView(node, rect) {
|
|
@@ -252,14 +252,14 @@ var GraphCanvasRenderer = class {
|
|
|
252
252
|
ctx.save();
|
|
253
253
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
254
254
|
const padding = theme.spacing.padding;
|
|
255
|
-
const
|
|
256
|
-
const
|
|
255
|
+
const x3 = w - padding;
|
|
256
|
+
const y3 = h - padding;
|
|
257
257
|
ctx.font = `600 20px ${theme.fonts.family}`;
|
|
258
258
|
ctx.fillStyle = theme.colors.axis;
|
|
259
259
|
ctx.globalAlpha = 0.55;
|
|
260
260
|
ctx.textAlign = "right";
|
|
261
261
|
ctx.textBaseline = "alphabetic";
|
|
262
|
-
ctx.fillText("OpenData",
|
|
262
|
+
ctx.fillText("OpenData", x3, y3);
|
|
263
263
|
ctx.restore();
|
|
264
264
|
}
|
|
265
265
|
// -------------------------------------------------------------------------
|
|
@@ -583,7 +583,7 @@ function brighten(color) {
|
|
|
583
583
|
return `rgb(${r},${g},${b})`;
|
|
584
584
|
}
|
|
585
585
|
const hex = color.replace("#", "");
|
|
586
|
-
const full = hex.length === 3 ? hex.split("").map((
|
|
586
|
+
const full = hex.length === 3 ? hex.split("").map((c2) => c2 + c2).join("") : hex;
|
|
587
587
|
if (full.length === 6) {
|
|
588
588
|
const r = Math.min(255, parseInt(full.slice(0, 2), 16) + 40);
|
|
589
589
|
const g = Math.min(255, parseInt(full.slice(2, 4), 16) + 40);
|
|
@@ -594,20 +594,20 @@ function brighten(color) {
|
|
|
594
594
|
}
|
|
595
595
|
function isLightColor(color) {
|
|
596
596
|
const hex = color.replace("#", "");
|
|
597
|
-
const full = hex.length === 3 ? hex.split("").map((
|
|
597
|
+
const full = hex.length === 3 ? hex.split("").map((c2) => c2 + c2).join("") : hex;
|
|
598
598
|
if (full.length !== 6) return false;
|
|
599
599
|
const r = parseInt(full.slice(0, 2), 16) / 255;
|
|
600
600
|
const g = parseInt(full.slice(2, 4), 16) / 255;
|
|
601
601
|
const b = parseInt(full.slice(4, 6), 16) / 255;
|
|
602
|
-
const toLinear = (
|
|
602
|
+
const toLinear = (c2) => c2 <= 0.03928 ? c2 / 12.92 : ((c2 + 0.055) / 1.055) ** 2.4;
|
|
603
603
|
return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b) > 0.5;
|
|
604
604
|
}
|
|
605
605
|
|
|
606
606
|
// src/graph/zoom.ts
|
|
607
607
|
var ZoomTransform = class _ZoomTransform {
|
|
608
|
-
constructor(
|
|
609
|
-
this.x =
|
|
610
|
-
this.y =
|
|
608
|
+
constructor(x3, y3, k) {
|
|
609
|
+
this.x = x3;
|
|
610
|
+
this.y = y3;
|
|
611
611
|
this.k = k;
|
|
612
612
|
}
|
|
613
613
|
/** Convert screen coordinates to graph coordinates. */
|
|
@@ -761,27 +761,27 @@ var GraphInteractionManager = class {
|
|
|
761
761
|
}
|
|
762
762
|
onWheel(e) {
|
|
763
763
|
e.preventDefault();
|
|
764
|
-
const { x, y } = this.canvasXY(e);
|
|
764
|
+
const { x: x3, y: y3 } = this.canvasXY(e);
|
|
765
765
|
const factor = e.deltaY * ZOOM_STEP;
|
|
766
766
|
const newK = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, this.transform.k * (1 + factor)));
|
|
767
|
-
this.transform = this.transform.zoomAt(newK,
|
|
767
|
+
this.transform = this.transform.zoomAt(newK, x3, y3);
|
|
768
768
|
this.callbacks.onTransformChange(this.transform);
|
|
769
769
|
}
|
|
770
770
|
onMouseDown(e) {
|
|
771
|
-
const { x, y } = this.canvasXY(e);
|
|
772
|
-
const hitId = this.hitTest(
|
|
771
|
+
const { x: x3, y: y3 } = this.canvasXY(e);
|
|
772
|
+
const hitId = this.hitTest(x3, y3);
|
|
773
773
|
if (hitId) {
|
|
774
774
|
this.dragState = { nodeId: hitId, started: false };
|
|
775
775
|
this.mousedownNodeId = hitId;
|
|
776
776
|
} else {
|
|
777
|
-
this.panState = { startX:
|
|
777
|
+
this.panState = { startX: x3, startY: y3 };
|
|
778
778
|
this.mousedownNodeId = null;
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
781
|
onMouseMove(e) {
|
|
782
|
-
const { x, y } = this.canvasXY(e);
|
|
782
|
+
const { x: x3, y: y3 } = this.canvasXY(e);
|
|
783
783
|
if (this.dragState) {
|
|
784
|
-
const graph = this.transform.screenToGraph(
|
|
784
|
+
const graph = this.transform.screenToGraph(x3, y3);
|
|
785
785
|
if (!this.dragState.started) {
|
|
786
786
|
this.dragState.started = true;
|
|
787
787
|
this.callbacks.onNodeDragStart(this.dragState.nodeId);
|
|
@@ -790,23 +790,23 @@ var GraphInteractionManager = class {
|
|
|
790
790
|
return;
|
|
791
791
|
}
|
|
792
792
|
if (this.panState) {
|
|
793
|
-
const dx =
|
|
794
|
-
const dy =
|
|
793
|
+
const dx = x3 - this.panState.startX;
|
|
794
|
+
const dy = y3 - this.panState.startY;
|
|
795
795
|
this.transform = this.transform.pan(dx, dy);
|
|
796
|
-
this.panState = { startX:
|
|
796
|
+
this.panState = { startX: x3, startY: y3 };
|
|
797
797
|
this.callbacks.onTransformChange(this.transform);
|
|
798
798
|
return;
|
|
799
799
|
}
|
|
800
|
-
const hitId = this.hitTest(
|
|
800
|
+
const hitId = this.hitTest(x3, y3);
|
|
801
801
|
this.callbacks.onHoverChange(hitId);
|
|
802
802
|
if (!hitId) {
|
|
803
|
-
const graph = this.transform.screenToGraph(
|
|
804
|
-
this.callbacks.onBackgroundHover?.(graph.x, graph.y,
|
|
803
|
+
const graph = this.transform.screenToGraph(x3, y3);
|
|
804
|
+
this.callbacks.onBackgroundHover?.(graph.x, graph.y, x3, y3);
|
|
805
805
|
}
|
|
806
806
|
this.canvas.style.cursor = hitId ? "pointer" : "default";
|
|
807
807
|
}
|
|
808
808
|
onMouseUp(e) {
|
|
809
|
-
const { x, y } = this.canvasXY(e);
|
|
809
|
+
const { x: x3, y: y3 } = this.canvasXY(e);
|
|
810
810
|
if (this.dragState) {
|
|
811
811
|
if (this.dragState.started) {
|
|
812
812
|
this.callbacks.onNodeDragEnd(this.dragState.nodeId);
|
|
@@ -819,7 +819,7 @@ var GraphInteractionManager = class {
|
|
|
819
819
|
if (this.panState) {
|
|
820
820
|
this.panState = null;
|
|
821
821
|
if (!this.mousedownNodeId) {
|
|
822
|
-
const hitId = this.hitTest(
|
|
822
|
+
const hitId = this.hitTest(x3, y3);
|
|
823
823
|
if (!hitId) {
|
|
824
824
|
this.selectedIds.clear();
|
|
825
825
|
this.callbacks.onSelectionChange([]);
|
|
@@ -829,8 +829,8 @@ var GraphInteractionManager = class {
|
|
|
829
829
|
}
|
|
830
830
|
}
|
|
831
831
|
onDblClick(e) {
|
|
832
|
-
const { x, y } = this.canvasXY(e);
|
|
833
|
-
const hitId = this.hitTest(
|
|
832
|
+
const { x: x3, y: y3 } = this.canvasXY(e);
|
|
833
|
+
const hitId = this.hitTest(x3, y3);
|
|
834
834
|
if (hitId) {
|
|
835
835
|
this.callbacks.onDoubleClick(hitId);
|
|
836
836
|
}
|
|
@@ -870,13 +870,13 @@ var GraphInteractionManager = class {
|
|
|
870
870
|
} else if (e.touches.length === 1) {
|
|
871
871
|
const touch = e.touches[0];
|
|
872
872
|
const rect = this.canvas.getBoundingClientRect();
|
|
873
|
-
const
|
|
874
|
-
const
|
|
875
|
-
const hitId = this.hitTest(
|
|
873
|
+
const x3 = touch.clientX - rect.left;
|
|
874
|
+
const y3 = touch.clientY - rect.top;
|
|
875
|
+
const hitId = this.hitTest(x3, y3);
|
|
876
876
|
if (hitId) {
|
|
877
877
|
this.mousedownNodeId = hitId;
|
|
878
878
|
} else {
|
|
879
|
-
this.panState = { startX:
|
|
879
|
+
this.panState = { startX: x3, startY: y3 };
|
|
880
880
|
this.mousedownNodeId = null;
|
|
881
881
|
}
|
|
882
882
|
}
|
|
@@ -906,12 +906,12 @@ var GraphInteractionManager = class {
|
|
|
906
906
|
} else if (e.touches.length === 1 && this.panState) {
|
|
907
907
|
const touch = e.touches[0];
|
|
908
908
|
const rect = this.canvas.getBoundingClientRect();
|
|
909
|
-
const
|
|
910
|
-
const
|
|
911
|
-
const dx =
|
|
912
|
-
const dy =
|
|
909
|
+
const x3 = touch.clientX - rect.left;
|
|
910
|
+
const y3 = touch.clientY - rect.top;
|
|
911
|
+
const dx = x3 - this.panState.startX;
|
|
912
|
+
const dy = y3 - this.panState.startY;
|
|
913
913
|
this.transform = this.transform.pan(dx, dy);
|
|
914
|
-
this.panState = { startX:
|
|
914
|
+
this.panState = { startX: x3, startY: y3 };
|
|
915
915
|
this.callbacks.onTransformChange(this.transform);
|
|
916
916
|
}
|
|
917
917
|
}
|
|
@@ -957,9 +957,9 @@ function attachGraphKeyboardNav(options) {
|
|
|
957
957
|
if (candidates.length === 0) return null;
|
|
958
958
|
let best = null;
|
|
959
959
|
let bestScore = -Infinity;
|
|
960
|
-
for (const
|
|
961
|
-
const dx =
|
|
962
|
-
const dy =
|
|
960
|
+
for (const c2 of candidates) {
|
|
961
|
+
const dx = c2.x - fromNode.x;
|
|
962
|
+
const dy = c2.y - fromNode.y;
|
|
963
963
|
let score;
|
|
964
964
|
switch (direction) {
|
|
965
965
|
case "right":
|
|
@@ -977,7 +977,7 @@ function attachGraphKeyboardNav(options) {
|
|
|
977
977
|
}
|
|
978
978
|
if (score > bestScore) {
|
|
979
979
|
bestScore = score;
|
|
980
|
-
best =
|
|
980
|
+
best = c2;
|
|
981
981
|
}
|
|
982
982
|
}
|
|
983
983
|
return best?.id ?? null;
|
|
@@ -1108,16 +1108,929 @@ var GraphSearchManager = class {
|
|
|
1108
1108
|
}
|
|
1109
1109
|
};
|
|
1110
1110
|
|
|
1111
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/center.js
|
|
1112
|
+
function center_default(x3, y3) {
|
|
1113
|
+
var nodes, strength = 1;
|
|
1114
|
+
if (x3 == null) x3 = 0;
|
|
1115
|
+
if (y3 == null) y3 = 0;
|
|
1116
|
+
function force() {
|
|
1117
|
+
var i, n = nodes.length, node, sx = 0, sy = 0;
|
|
1118
|
+
for (i = 0; i < n; ++i) {
|
|
1119
|
+
node = nodes[i], sx += node.x, sy += node.y;
|
|
1120
|
+
}
|
|
1121
|
+
for (sx = (sx / n - x3) * strength, sy = (sy / n - y3) * strength, i = 0; i < n; ++i) {
|
|
1122
|
+
node = nodes[i], node.x -= sx, node.y -= sy;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
force.initialize = function(_) {
|
|
1126
|
+
nodes = _;
|
|
1127
|
+
};
|
|
1128
|
+
force.x = function(_) {
|
|
1129
|
+
return arguments.length ? (x3 = +_, force) : x3;
|
|
1130
|
+
};
|
|
1131
|
+
force.y = function(_) {
|
|
1132
|
+
return arguments.length ? (y3 = +_, force) : y3;
|
|
1133
|
+
};
|
|
1134
|
+
force.strength = function(_) {
|
|
1135
|
+
return arguments.length ? (strength = +_, force) : strength;
|
|
1136
|
+
};
|
|
1137
|
+
return force;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/add.js
|
|
1141
|
+
function add_default(d) {
|
|
1142
|
+
const x3 = +this._x.call(null, d), y3 = +this._y.call(null, d);
|
|
1143
|
+
return add(this.cover(x3, y3), x3, y3, d);
|
|
1144
|
+
}
|
|
1145
|
+
function add(tree, x3, y3, d) {
|
|
1146
|
+
if (isNaN(x3) || isNaN(y3)) return tree;
|
|
1147
|
+
var parent, node = tree._root, leaf = { data: d }, x0 = tree._x0, y0 = tree._y0, x1 = tree._x1, y1 = tree._y1, xm, ym, xp, yp, right, bottom, i, j;
|
|
1148
|
+
if (!node) return tree._root = leaf, tree;
|
|
1149
|
+
while (node.length) {
|
|
1150
|
+
if (right = x3 >= (xm = (x0 + x1) / 2)) x0 = xm;
|
|
1151
|
+
else x1 = xm;
|
|
1152
|
+
if (bottom = y3 >= (ym = (y0 + y1) / 2)) y0 = ym;
|
|
1153
|
+
else y1 = ym;
|
|
1154
|
+
if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
|
|
1155
|
+
}
|
|
1156
|
+
xp = +tree._x.call(null, node.data);
|
|
1157
|
+
yp = +tree._y.call(null, node.data);
|
|
1158
|
+
if (x3 === xp && y3 === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
|
|
1159
|
+
do {
|
|
1160
|
+
parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
|
|
1161
|
+
if (right = x3 >= (xm = (x0 + x1) / 2)) x0 = xm;
|
|
1162
|
+
else x1 = xm;
|
|
1163
|
+
if (bottom = y3 >= (ym = (y0 + y1) / 2)) y0 = ym;
|
|
1164
|
+
else y1 = ym;
|
|
1165
|
+
} while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | xp >= xm));
|
|
1166
|
+
return parent[j] = node, parent[i] = leaf, tree;
|
|
1167
|
+
}
|
|
1168
|
+
function addAll(data) {
|
|
1169
|
+
var d, i, n = data.length, x3, y3, xz = new Array(n), yz = new Array(n), x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
|
|
1170
|
+
for (i = 0; i < n; ++i) {
|
|
1171
|
+
if (isNaN(x3 = +this._x.call(null, d = data[i])) || isNaN(y3 = +this._y.call(null, d))) continue;
|
|
1172
|
+
xz[i] = x3;
|
|
1173
|
+
yz[i] = y3;
|
|
1174
|
+
if (x3 < x0) x0 = x3;
|
|
1175
|
+
if (x3 > x1) x1 = x3;
|
|
1176
|
+
if (y3 < y0) y0 = y3;
|
|
1177
|
+
if (y3 > y1) y1 = y3;
|
|
1178
|
+
}
|
|
1179
|
+
if (x0 > x1 || y0 > y1) return this;
|
|
1180
|
+
this.cover(x0, y0).cover(x1, y1);
|
|
1181
|
+
for (i = 0; i < n; ++i) {
|
|
1182
|
+
add(this, xz[i], yz[i], data[i]);
|
|
1183
|
+
}
|
|
1184
|
+
return this;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/cover.js
|
|
1188
|
+
function cover_default(x3, y3) {
|
|
1189
|
+
if (isNaN(x3 = +x3) || isNaN(y3 = +y3)) return this;
|
|
1190
|
+
var x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1;
|
|
1191
|
+
if (isNaN(x0)) {
|
|
1192
|
+
x1 = (x0 = Math.floor(x3)) + 1;
|
|
1193
|
+
y1 = (y0 = Math.floor(y3)) + 1;
|
|
1194
|
+
} else {
|
|
1195
|
+
var z = x1 - x0 || 1, node = this._root, parent, i;
|
|
1196
|
+
while (x0 > x3 || x3 >= x1 || y0 > y3 || y3 >= y1) {
|
|
1197
|
+
i = (y3 < y0) << 1 | x3 < x0;
|
|
1198
|
+
parent = new Array(4), parent[i] = node, node = parent, z *= 2;
|
|
1199
|
+
switch (i) {
|
|
1200
|
+
case 0:
|
|
1201
|
+
x1 = x0 + z, y1 = y0 + z;
|
|
1202
|
+
break;
|
|
1203
|
+
case 1:
|
|
1204
|
+
x0 = x1 - z, y1 = y0 + z;
|
|
1205
|
+
break;
|
|
1206
|
+
case 2:
|
|
1207
|
+
x1 = x0 + z, y0 = y1 - z;
|
|
1208
|
+
break;
|
|
1209
|
+
case 3:
|
|
1210
|
+
x0 = x1 - z, y0 = y1 - z;
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
if (this._root && this._root.length) this._root = node;
|
|
1215
|
+
}
|
|
1216
|
+
this._x0 = x0;
|
|
1217
|
+
this._y0 = y0;
|
|
1218
|
+
this._x1 = x1;
|
|
1219
|
+
this._y1 = y1;
|
|
1220
|
+
return this;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/data.js
|
|
1224
|
+
function data_default() {
|
|
1225
|
+
var data = [];
|
|
1226
|
+
this.visit(function(node) {
|
|
1227
|
+
if (!node.length) do
|
|
1228
|
+
data.push(node.data);
|
|
1229
|
+
while (node = node.next);
|
|
1230
|
+
});
|
|
1231
|
+
return data;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/extent.js
|
|
1235
|
+
function extent_default(_) {
|
|
1236
|
+
return arguments.length ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) : isNaN(this._x0) ? void 0 : [[this._x0, this._y0], [this._x1, this._y1]];
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/quad.js
|
|
1240
|
+
function quad_default(node, x0, y0, x1, y1) {
|
|
1241
|
+
this.node = node;
|
|
1242
|
+
this.x0 = x0;
|
|
1243
|
+
this.y0 = y0;
|
|
1244
|
+
this.x1 = x1;
|
|
1245
|
+
this.y1 = y1;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/find.js
|
|
1249
|
+
function find_default(x3, y3, radius) {
|
|
1250
|
+
var data, x0 = this._x0, y0 = this._y0, x1, y1, x22, y22, x32 = this._x1, y32 = this._y1, quads = [], node = this._root, q, i;
|
|
1251
|
+
if (node) quads.push(new quad_default(node, x0, y0, x32, y32));
|
|
1252
|
+
if (radius == null) radius = Infinity;
|
|
1253
|
+
else {
|
|
1254
|
+
x0 = x3 - radius, y0 = y3 - radius;
|
|
1255
|
+
x32 = x3 + radius, y32 = y3 + radius;
|
|
1256
|
+
radius *= radius;
|
|
1257
|
+
}
|
|
1258
|
+
while (q = quads.pop()) {
|
|
1259
|
+
if (!(node = q.node) || (x1 = q.x0) > x32 || (y1 = q.y0) > y32 || (x22 = q.x1) < x0 || (y22 = q.y1) < y0) continue;
|
|
1260
|
+
if (node.length) {
|
|
1261
|
+
var xm = (x1 + x22) / 2, ym = (y1 + y22) / 2;
|
|
1262
|
+
quads.push(
|
|
1263
|
+
new quad_default(node[3], xm, ym, x22, y22),
|
|
1264
|
+
new quad_default(node[2], x1, ym, xm, y22),
|
|
1265
|
+
new quad_default(node[1], xm, y1, x22, ym),
|
|
1266
|
+
new quad_default(node[0], x1, y1, xm, ym)
|
|
1267
|
+
);
|
|
1268
|
+
if (i = (y3 >= ym) << 1 | x3 >= xm) {
|
|
1269
|
+
q = quads[quads.length - 1];
|
|
1270
|
+
quads[quads.length - 1] = quads[quads.length - 1 - i];
|
|
1271
|
+
quads[quads.length - 1 - i] = q;
|
|
1272
|
+
}
|
|
1273
|
+
} else {
|
|
1274
|
+
var dx = x3 - +this._x.call(null, node.data), dy = y3 - +this._y.call(null, node.data), d2 = dx * dx + dy * dy;
|
|
1275
|
+
if (d2 < radius) {
|
|
1276
|
+
var d = Math.sqrt(radius = d2);
|
|
1277
|
+
x0 = x3 - d, y0 = y3 - d;
|
|
1278
|
+
x32 = x3 + d, y32 = y3 + d;
|
|
1279
|
+
data = node.data;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return data;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/remove.js
|
|
1287
|
+
function remove_default(d) {
|
|
1288
|
+
if (isNaN(x3 = +this._x.call(null, d)) || isNaN(y3 = +this._y.call(null, d))) return this;
|
|
1289
|
+
var parent, node = this._root, retainer, previous, next, x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1, x3, y3, xm, ym, right, bottom, i, j;
|
|
1290
|
+
if (!node) return this;
|
|
1291
|
+
if (node.length) while (true) {
|
|
1292
|
+
if (right = x3 >= (xm = (x0 + x1) / 2)) x0 = xm;
|
|
1293
|
+
else x1 = xm;
|
|
1294
|
+
if (bottom = y3 >= (ym = (y0 + y1) / 2)) y0 = ym;
|
|
1295
|
+
else y1 = ym;
|
|
1296
|
+
if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
|
|
1297
|
+
if (!node.length) break;
|
|
1298
|
+
if (parent[i + 1 & 3] || parent[i + 2 & 3] || parent[i + 3 & 3]) retainer = parent, j = i;
|
|
1299
|
+
}
|
|
1300
|
+
while (node.data !== d) if (!(previous = node, node = node.next)) return this;
|
|
1301
|
+
if (next = node.next) delete node.next;
|
|
1302
|
+
if (previous) return next ? previous.next = next : delete previous.next, this;
|
|
1303
|
+
if (!parent) return this._root = next, this;
|
|
1304
|
+
next ? parent[i] = next : delete parent[i];
|
|
1305
|
+
if ((node = parent[0] || parent[1] || parent[2] || parent[3]) && node === (parent[3] || parent[2] || parent[1] || parent[0]) && !node.length) {
|
|
1306
|
+
if (retainer) retainer[j] = node;
|
|
1307
|
+
else this._root = node;
|
|
1308
|
+
}
|
|
1309
|
+
return this;
|
|
1310
|
+
}
|
|
1311
|
+
function removeAll(data) {
|
|
1312
|
+
for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
|
|
1313
|
+
return this;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/root.js
|
|
1317
|
+
function root_default() {
|
|
1318
|
+
return this._root;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/size.js
|
|
1322
|
+
function size_default() {
|
|
1323
|
+
var size = 0;
|
|
1324
|
+
this.visit(function(node) {
|
|
1325
|
+
if (!node.length) do
|
|
1326
|
+
++size;
|
|
1327
|
+
while (node = node.next);
|
|
1328
|
+
});
|
|
1329
|
+
return size;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/visit.js
|
|
1333
|
+
function visit_default(callback) {
|
|
1334
|
+
var quads = [], q, node = this._root, child, x0, y0, x1, y1;
|
|
1335
|
+
if (node) quads.push(new quad_default(node, this._x0, this._y0, this._x1, this._y1));
|
|
1336
|
+
while (q = quads.pop()) {
|
|
1337
|
+
if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
|
|
1338
|
+
var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
|
|
1339
|
+
if (child = node[3]) quads.push(new quad_default(child, xm, ym, x1, y1));
|
|
1340
|
+
if (child = node[2]) quads.push(new quad_default(child, x0, ym, xm, y1));
|
|
1341
|
+
if (child = node[1]) quads.push(new quad_default(child, xm, y0, x1, ym));
|
|
1342
|
+
if (child = node[0]) quads.push(new quad_default(child, x0, y0, xm, ym));
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
return this;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/visitAfter.js
|
|
1349
|
+
function visitAfter_default(callback) {
|
|
1350
|
+
var quads = [], next = [], q;
|
|
1351
|
+
if (this._root) quads.push(new quad_default(this._root, this._x0, this._y0, this._x1, this._y1));
|
|
1352
|
+
while (q = quads.pop()) {
|
|
1353
|
+
var node = q.node;
|
|
1354
|
+
if (node.length) {
|
|
1355
|
+
var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
|
|
1356
|
+
if (child = node[0]) quads.push(new quad_default(child, x0, y0, xm, ym));
|
|
1357
|
+
if (child = node[1]) quads.push(new quad_default(child, xm, y0, x1, ym));
|
|
1358
|
+
if (child = node[2]) quads.push(new quad_default(child, x0, ym, xm, y1));
|
|
1359
|
+
if (child = node[3]) quads.push(new quad_default(child, xm, ym, x1, y1));
|
|
1360
|
+
}
|
|
1361
|
+
next.push(q);
|
|
1362
|
+
}
|
|
1363
|
+
while (q = next.pop()) {
|
|
1364
|
+
callback(q.node, q.x0, q.y0, q.x1, q.y1);
|
|
1365
|
+
}
|
|
1366
|
+
return this;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/x.js
|
|
1370
|
+
function defaultX(d) {
|
|
1371
|
+
return d[0];
|
|
1372
|
+
}
|
|
1373
|
+
function x_default(_) {
|
|
1374
|
+
return arguments.length ? (this._x = _, this) : this._x;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/y.js
|
|
1378
|
+
function defaultY(d) {
|
|
1379
|
+
return d[1];
|
|
1380
|
+
}
|
|
1381
|
+
function y_default(_) {
|
|
1382
|
+
return arguments.length ? (this._y = _, this) : this._y;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
// ../../node_modules/.bun/d3-quadtree@3.0.1/node_modules/d3-quadtree/src/quadtree.js
|
|
1386
|
+
function quadtree(nodes, x3, y3) {
|
|
1387
|
+
var tree = new Quadtree(x3 == null ? defaultX : x3, y3 == null ? defaultY : y3, NaN, NaN, NaN, NaN);
|
|
1388
|
+
return nodes == null ? tree : tree.addAll(nodes);
|
|
1389
|
+
}
|
|
1390
|
+
function Quadtree(x3, y3, x0, y0, x1, y1) {
|
|
1391
|
+
this._x = x3;
|
|
1392
|
+
this._y = y3;
|
|
1393
|
+
this._x0 = x0;
|
|
1394
|
+
this._y0 = y0;
|
|
1395
|
+
this._x1 = x1;
|
|
1396
|
+
this._y1 = y1;
|
|
1397
|
+
this._root = void 0;
|
|
1398
|
+
}
|
|
1399
|
+
function leaf_copy(leaf) {
|
|
1400
|
+
var copy = { data: leaf.data }, next = copy;
|
|
1401
|
+
while (leaf = leaf.next) next = next.next = { data: leaf.data };
|
|
1402
|
+
return copy;
|
|
1403
|
+
}
|
|
1404
|
+
var treeProto = quadtree.prototype = Quadtree.prototype;
|
|
1405
|
+
treeProto.copy = function() {
|
|
1406
|
+
var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), node = this._root, nodes, child;
|
|
1407
|
+
if (!node) return copy;
|
|
1408
|
+
if (!node.length) return copy._root = leaf_copy(node), copy;
|
|
1409
|
+
nodes = [{ source: node, target: copy._root = new Array(4) }];
|
|
1410
|
+
while (node = nodes.pop()) {
|
|
1411
|
+
for (var i = 0; i < 4; ++i) {
|
|
1412
|
+
if (child = node.source[i]) {
|
|
1413
|
+
if (child.length) nodes.push({ source: child, target: node.target[i] = new Array(4) });
|
|
1414
|
+
else node.target[i] = leaf_copy(child);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
return copy;
|
|
1419
|
+
};
|
|
1420
|
+
treeProto.add = add_default;
|
|
1421
|
+
treeProto.addAll = addAll;
|
|
1422
|
+
treeProto.cover = cover_default;
|
|
1423
|
+
treeProto.data = data_default;
|
|
1424
|
+
treeProto.extent = extent_default;
|
|
1425
|
+
treeProto.find = find_default;
|
|
1426
|
+
treeProto.remove = remove_default;
|
|
1427
|
+
treeProto.removeAll = removeAll;
|
|
1428
|
+
treeProto.root = root_default;
|
|
1429
|
+
treeProto.size = size_default;
|
|
1430
|
+
treeProto.visit = visit_default;
|
|
1431
|
+
treeProto.visitAfter = visitAfter_default;
|
|
1432
|
+
treeProto.x = x_default;
|
|
1433
|
+
treeProto.y = y_default;
|
|
1434
|
+
|
|
1435
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/constant.js
|
|
1436
|
+
function constant_default(x3) {
|
|
1437
|
+
return function() {
|
|
1438
|
+
return x3;
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/jiggle.js
|
|
1443
|
+
function jiggle_default(random) {
|
|
1444
|
+
return (random() - 0.5) * 1e-6;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/collide.js
|
|
1448
|
+
function x(d) {
|
|
1449
|
+
return d.x + d.vx;
|
|
1450
|
+
}
|
|
1451
|
+
function y(d) {
|
|
1452
|
+
return d.y + d.vy;
|
|
1453
|
+
}
|
|
1454
|
+
function collide_default(radius) {
|
|
1455
|
+
var nodes, radii, random, strength = 1, iterations = 1;
|
|
1456
|
+
if (typeof radius !== "function") radius = constant_default(radius == null ? 1 : +radius);
|
|
1457
|
+
function force() {
|
|
1458
|
+
var i, n = nodes.length, tree, node, xi, yi, ri, ri2;
|
|
1459
|
+
for (var k = 0; k < iterations; ++k) {
|
|
1460
|
+
tree = quadtree(nodes, x, y).visitAfter(prepare);
|
|
1461
|
+
for (i = 0; i < n; ++i) {
|
|
1462
|
+
node = nodes[i];
|
|
1463
|
+
ri = radii[node.index], ri2 = ri * ri;
|
|
1464
|
+
xi = node.x + node.vx;
|
|
1465
|
+
yi = node.y + node.vy;
|
|
1466
|
+
tree.visit(apply);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
function apply(quad, x0, y0, x1, y1) {
|
|
1470
|
+
var data = quad.data, rj = quad.r, r = ri + rj;
|
|
1471
|
+
if (data) {
|
|
1472
|
+
if (data.index > node.index) {
|
|
1473
|
+
var x3 = xi - data.x - data.vx, y3 = yi - data.y - data.vy, l = x3 * x3 + y3 * y3;
|
|
1474
|
+
if (l < r * r) {
|
|
1475
|
+
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
1476
|
+
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
1477
|
+
l = (r - (l = Math.sqrt(l))) / l * strength;
|
|
1478
|
+
node.vx += (x3 *= l) * (r = (rj *= rj) / (ri2 + rj));
|
|
1479
|
+
node.vy += (y3 *= l) * r;
|
|
1480
|
+
data.vx -= x3 * (r = 1 - r);
|
|
1481
|
+
data.vy -= y3 * r;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
function prepare(quad) {
|
|
1490
|
+
if (quad.data) return quad.r = radii[quad.data.index];
|
|
1491
|
+
for (var i = quad.r = 0; i < 4; ++i) {
|
|
1492
|
+
if (quad[i] && quad[i].r > quad.r) {
|
|
1493
|
+
quad.r = quad[i].r;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
function initialize() {
|
|
1498
|
+
if (!nodes) return;
|
|
1499
|
+
var i, n = nodes.length, node;
|
|
1500
|
+
radii = new Array(n);
|
|
1501
|
+
for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
|
|
1502
|
+
}
|
|
1503
|
+
force.initialize = function(_nodes, _random) {
|
|
1504
|
+
nodes = _nodes;
|
|
1505
|
+
random = _random;
|
|
1506
|
+
initialize();
|
|
1507
|
+
};
|
|
1508
|
+
force.iterations = function(_) {
|
|
1509
|
+
return arguments.length ? (iterations = +_, force) : iterations;
|
|
1510
|
+
};
|
|
1511
|
+
force.strength = function(_) {
|
|
1512
|
+
return arguments.length ? (strength = +_, force) : strength;
|
|
1513
|
+
};
|
|
1514
|
+
force.radius = function(_) {
|
|
1515
|
+
return arguments.length ? (radius = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : radius;
|
|
1516
|
+
};
|
|
1517
|
+
return force;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/link.js
|
|
1521
|
+
function index(d) {
|
|
1522
|
+
return d.index;
|
|
1523
|
+
}
|
|
1524
|
+
function find(nodeById, nodeId) {
|
|
1525
|
+
var node = nodeById.get(nodeId);
|
|
1526
|
+
if (!node) throw new Error("node not found: " + nodeId);
|
|
1527
|
+
return node;
|
|
1528
|
+
}
|
|
1529
|
+
function link_default(links) {
|
|
1530
|
+
var id = index, strength = defaultStrength, strengths, distance = constant_default(30), distances, nodes, count, bias, random, iterations = 1;
|
|
1531
|
+
if (links == null) links = [];
|
|
1532
|
+
function defaultStrength(link) {
|
|
1533
|
+
return 1 / Math.min(count[link.source.index], count[link.target.index]);
|
|
1534
|
+
}
|
|
1535
|
+
function force(alpha) {
|
|
1536
|
+
for (var k = 0, n = links.length; k < iterations; ++k) {
|
|
1537
|
+
for (var i = 0, link, source, target, x3, y3, l, b; i < n; ++i) {
|
|
1538
|
+
link = links[i], source = link.source, target = link.target;
|
|
1539
|
+
x3 = target.x + target.vx - source.x - source.vx || jiggle_default(random);
|
|
1540
|
+
y3 = target.y + target.vy - source.y - source.vy || jiggle_default(random);
|
|
1541
|
+
l = Math.sqrt(x3 * x3 + y3 * y3);
|
|
1542
|
+
l = (l - distances[i]) / l * alpha * strengths[i];
|
|
1543
|
+
x3 *= l, y3 *= l;
|
|
1544
|
+
target.vx -= x3 * (b = bias[i]);
|
|
1545
|
+
target.vy -= y3 * b;
|
|
1546
|
+
source.vx += x3 * (b = 1 - b);
|
|
1547
|
+
source.vy += y3 * b;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
function initialize() {
|
|
1552
|
+
if (!nodes) return;
|
|
1553
|
+
var i, n = nodes.length, m2 = links.length, nodeById = new Map(nodes.map((d, i2) => [id(d, i2, nodes), d])), link;
|
|
1554
|
+
for (i = 0, count = new Array(n); i < m2; ++i) {
|
|
1555
|
+
link = links[i], link.index = i;
|
|
1556
|
+
if (typeof link.source !== "object") link.source = find(nodeById, link.source);
|
|
1557
|
+
if (typeof link.target !== "object") link.target = find(nodeById, link.target);
|
|
1558
|
+
count[link.source.index] = (count[link.source.index] || 0) + 1;
|
|
1559
|
+
count[link.target.index] = (count[link.target.index] || 0) + 1;
|
|
1560
|
+
}
|
|
1561
|
+
for (i = 0, bias = new Array(m2); i < m2; ++i) {
|
|
1562
|
+
link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
|
|
1563
|
+
}
|
|
1564
|
+
strengths = new Array(m2), initializeStrength();
|
|
1565
|
+
distances = new Array(m2), initializeDistance();
|
|
1566
|
+
}
|
|
1567
|
+
function initializeStrength() {
|
|
1568
|
+
if (!nodes) return;
|
|
1569
|
+
for (var i = 0, n = links.length; i < n; ++i) {
|
|
1570
|
+
strengths[i] = +strength(links[i], i, links);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
function initializeDistance() {
|
|
1574
|
+
if (!nodes) return;
|
|
1575
|
+
for (var i = 0, n = links.length; i < n; ++i) {
|
|
1576
|
+
distances[i] = +distance(links[i], i, links);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
force.initialize = function(_nodes, _random) {
|
|
1580
|
+
nodes = _nodes;
|
|
1581
|
+
random = _random;
|
|
1582
|
+
initialize();
|
|
1583
|
+
};
|
|
1584
|
+
force.links = function(_) {
|
|
1585
|
+
return arguments.length ? (links = _, initialize(), force) : links;
|
|
1586
|
+
};
|
|
1587
|
+
force.id = function(_) {
|
|
1588
|
+
return arguments.length ? (id = _, force) : id;
|
|
1589
|
+
};
|
|
1590
|
+
force.iterations = function(_) {
|
|
1591
|
+
return arguments.length ? (iterations = +_, force) : iterations;
|
|
1592
|
+
};
|
|
1593
|
+
force.strength = function(_) {
|
|
1594
|
+
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initializeStrength(), force) : strength;
|
|
1595
|
+
};
|
|
1596
|
+
force.distance = function(_) {
|
|
1597
|
+
return arguments.length ? (distance = typeof _ === "function" ? _ : constant_default(+_), initializeDistance(), force) : distance;
|
|
1598
|
+
};
|
|
1599
|
+
return force;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
// ../../node_modules/.bun/d3-dispatch@3.0.1/node_modules/d3-dispatch/src/dispatch.js
|
|
1603
|
+
var noop = { value: () => {
|
|
1604
|
+
} };
|
|
1605
|
+
function dispatch() {
|
|
1606
|
+
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
|
|
1607
|
+
if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
|
|
1608
|
+
_[t] = [];
|
|
1609
|
+
}
|
|
1610
|
+
return new Dispatch(_);
|
|
1611
|
+
}
|
|
1612
|
+
function Dispatch(_) {
|
|
1613
|
+
this._ = _;
|
|
1614
|
+
}
|
|
1615
|
+
function parseTypenames(typenames, types) {
|
|
1616
|
+
return typenames.trim().split(/^|\s+/).map(function(t) {
|
|
1617
|
+
var name = "", i = t.indexOf(".");
|
|
1618
|
+
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
|
|
1619
|
+
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
|
|
1620
|
+
return { type: t, name };
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1623
|
+
Dispatch.prototype = dispatch.prototype = {
|
|
1624
|
+
constructor: Dispatch,
|
|
1625
|
+
on: function(typename, callback) {
|
|
1626
|
+
var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length;
|
|
1627
|
+
if (arguments.length < 2) {
|
|
1628
|
+
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
|
|
1632
|
+
while (++i < n) {
|
|
1633
|
+
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
|
|
1634
|
+
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
|
|
1635
|
+
}
|
|
1636
|
+
return this;
|
|
1637
|
+
},
|
|
1638
|
+
copy: function() {
|
|
1639
|
+
var copy = {}, _ = this._;
|
|
1640
|
+
for (var t in _) copy[t] = _[t].slice();
|
|
1641
|
+
return new Dispatch(copy);
|
|
1642
|
+
},
|
|
1643
|
+
call: function(type, that) {
|
|
1644
|
+
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
|
|
1645
|
+
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
1646
|
+
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
|
|
1647
|
+
},
|
|
1648
|
+
apply: function(type, that, args) {
|
|
1649
|
+
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
|
|
1650
|
+
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
function get(type, name) {
|
|
1654
|
+
for (var i = 0, n = type.length, c2; i < n; ++i) {
|
|
1655
|
+
if ((c2 = type[i]).name === name) {
|
|
1656
|
+
return c2.value;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
function set(type, name, callback) {
|
|
1661
|
+
for (var i = 0, n = type.length; i < n; ++i) {
|
|
1662
|
+
if (type[i].name === name) {
|
|
1663
|
+
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
|
|
1664
|
+
break;
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
if (callback != null) type.push({ name, value: callback });
|
|
1668
|
+
return type;
|
|
1669
|
+
}
|
|
1670
|
+
var dispatch_default = dispatch;
|
|
1671
|
+
|
|
1672
|
+
// ../../node_modules/.bun/d3-timer@3.0.1/node_modules/d3-timer/src/timer.js
|
|
1673
|
+
var frame = 0;
|
|
1674
|
+
var timeout = 0;
|
|
1675
|
+
var interval = 0;
|
|
1676
|
+
var pokeDelay = 1e3;
|
|
1677
|
+
var taskHead;
|
|
1678
|
+
var taskTail;
|
|
1679
|
+
var clockLast = 0;
|
|
1680
|
+
var clockNow = 0;
|
|
1681
|
+
var clockSkew = 0;
|
|
1682
|
+
var clock = typeof performance === "object" && performance.now ? performance : Date;
|
|
1683
|
+
var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) {
|
|
1684
|
+
setTimeout(f, 17);
|
|
1685
|
+
};
|
|
1686
|
+
function now() {
|
|
1687
|
+
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
|
|
1688
|
+
}
|
|
1689
|
+
function clearNow() {
|
|
1690
|
+
clockNow = 0;
|
|
1691
|
+
}
|
|
1692
|
+
function Timer() {
|
|
1693
|
+
this._call = this._time = this._next = null;
|
|
1694
|
+
}
|
|
1695
|
+
Timer.prototype = timer.prototype = {
|
|
1696
|
+
constructor: Timer,
|
|
1697
|
+
restart: function(callback, delay, time) {
|
|
1698
|
+
if (typeof callback !== "function") throw new TypeError("callback is not a function");
|
|
1699
|
+
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
|
|
1700
|
+
if (!this._next && taskTail !== this) {
|
|
1701
|
+
if (taskTail) taskTail._next = this;
|
|
1702
|
+
else taskHead = this;
|
|
1703
|
+
taskTail = this;
|
|
1704
|
+
}
|
|
1705
|
+
this._call = callback;
|
|
1706
|
+
this._time = time;
|
|
1707
|
+
sleep();
|
|
1708
|
+
},
|
|
1709
|
+
stop: function() {
|
|
1710
|
+
if (this._call) {
|
|
1711
|
+
this._call = null;
|
|
1712
|
+
this._time = Infinity;
|
|
1713
|
+
sleep();
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
function timer(callback, delay, time) {
|
|
1718
|
+
var t = new Timer();
|
|
1719
|
+
t.restart(callback, delay, time);
|
|
1720
|
+
return t;
|
|
1721
|
+
}
|
|
1722
|
+
function timerFlush() {
|
|
1723
|
+
now();
|
|
1724
|
+
++frame;
|
|
1725
|
+
var t = taskHead, e;
|
|
1726
|
+
while (t) {
|
|
1727
|
+
if ((e = clockNow - t._time) >= 0) t._call.call(void 0, e);
|
|
1728
|
+
t = t._next;
|
|
1729
|
+
}
|
|
1730
|
+
--frame;
|
|
1731
|
+
}
|
|
1732
|
+
function wake() {
|
|
1733
|
+
clockNow = (clockLast = clock.now()) + clockSkew;
|
|
1734
|
+
frame = timeout = 0;
|
|
1735
|
+
try {
|
|
1736
|
+
timerFlush();
|
|
1737
|
+
} finally {
|
|
1738
|
+
frame = 0;
|
|
1739
|
+
nap();
|
|
1740
|
+
clockNow = 0;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
function poke() {
|
|
1744
|
+
var now2 = clock.now(), delay = now2 - clockLast;
|
|
1745
|
+
if (delay > pokeDelay) clockSkew -= delay, clockLast = now2;
|
|
1746
|
+
}
|
|
1747
|
+
function nap() {
|
|
1748
|
+
var t0, t1 = taskHead, t2, time = Infinity;
|
|
1749
|
+
while (t1) {
|
|
1750
|
+
if (t1._call) {
|
|
1751
|
+
if (time > t1._time) time = t1._time;
|
|
1752
|
+
t0 = t1, t1 = t1._next;
|
|
1753
|
+
} else {
|
|
1754
|
+
t2 = t1._next, t1._next = null;
|
|
1755
|
+
t1 = t0 ? t0._next = t2 : taskHead = t2;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
taskTail = t0;
|
|
1759
|
+
sleep(time);
|
|
1760
|
+
}
|
|
1761
|
+
function sleep(time) {
|
|
1762
|
+
if (frame) return;
|
|
1763
|
+
if (timeout) timeout = clearTimeout(timeout);
|
|
1764
|
+
var delay = time - clockNow;
|
|
1765
|
+
if (delay > 24) {
|
|
1766
|
+
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
|
|
1767
|
+
if (interval) interval = clearInterval(interval);
|
|
1768
|
+
} else {
|
|
1769
|
+
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
|
|
1770
|
+
frame = 1, setFrame(wake);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/lcg.js
|
|
1775
|
+
var a = 1664525;
|
|
1776
|
+
var c = 1013904223;
|
|
1777
|
+
var m = 4294967296;
|
|
1778
|
+
function lcg_default() {
|
|
1779
|
+
let s = 1;
|
|
1780
|
+
return () => (s = (a * s + c) % m) / m;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/simulation.js
|
|
1784
|
+
function x2(d) {
|
|
1785
|
+
return d.x;
|
|
1786
|
+
}
|
|
1787
|
+
function y2(d) {
|
|
1788
|
+
return d.y;
|
|
1789
|
+
}
|
|
1790
|
+
var initialRadius = 10;
|
|
1791
|
+
var initialAngle = Math.PI * (3 - Math.sqrt(5));
|
|
1792
|
+
function simulation_default(nodes) {
|
|
1793
|
+
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();
|
|
1794
|
+
if (nodes == null) nodes = [];
|
|
1795
|
+
function step() {
|
|
1796
|
+
tick();
|
|
1797
|
+
event.call("tick", simulation);
|
|
1798
|
+
if (alpha < alphaMin) {
|
|
1799
|
+
stepper.stop();
|
|
1800
|
+
event.call("end", simulation);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
function tick(iterations) {
|
|
1804
|
+
var i, n = nodes.length, node;
|
|
1805
|
+
if (iterations === void 0) iterations = 1;
|
|
1806
|
+
for (var k = 0; k < iterations; ++k) {
|
|
1807
|
+
alpha += (alphaTarget - alpha) * alphaDecay;
|
|
1808
|
+
forces.forEach(function(force) {
|
|
1809
|
+
force(alpha);
|
|
1810
|
+
});
|
|
1811
|
+
for (i = 0; i < n; ++i) {
|
|
1812
|
+
node = nodes[i];
|
|
1813
|
+
if (node.fx == null) node.x += node.vx *= velocityDecay;
|
|
1814
|
+
else node.x = node.fx, node.vx = 0;
|
|
1815
|
+
if (node.fy == null) node.y += node.vy *= velocityDecay;
|
|
1816
|
+
else node.y = node.fy, node.vy = 0;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
return simulation;
|
|
1820
|
+
}
|
|
1821
|
+
function initializeNodes() {
|
|
1822
|
+
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
1823
|
+
node = nodes[i], node.index = i;
|
|
1824
|
+
if (node.fx != null) node.x = node.fx;
|
|
1825
|
+
if (node.fy != null) node.y = node.fy;
|
|
1826
|
+
if (isNaN(node.x) || isNaN(node.y)) {
|
|
1827
|
+
var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle;
|
|
1828
|
+
node.x = radius * Math.cos(angle);
|
|
1829
|
+
node.y = radius * Math.sin(angle);
|
|
1830
|
+
}
|
|
1831
|
+
if (isNaN(node.vx) || isNaN(node.vy)) {
|
|
1832
|
+
node.vx = node.vy = 0;
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
function initializeForce(force) {
|
|
1837
|
+
if (force.initialize) force.initialize(nodes, random);
|
|
1838
|
+
return force;
|
|
1839
|
+
}
|
|
1840
|
+
initializeNodes();
|
|
1841
|
+
return simulation = {
|
|
1842
|
+
tick,
|
|
1843
|
+
restart: function() {
|
|
1844
|
+
return stepper.restart(step), simulation;
|
|
1845
|
+
},
|
|
1846
|
+
stop: function() {
|
|
1847
|
+
return stepper.stop(), simulation;
|
|
1848
|
+
},
|
|
1849
|
+
nodes: function(_) {
|
|
1850
|
+
return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
|
|
1851
|
+
},
|
|
1852
|
+
alpha: function(_) {
|
|
1853
|
+
return arguments.length ? (alpha = +_, simulation) : alpha;
|
|
1854
|
+
},
|
|
1855
|
+
alphaMin: function(_) {
|
|
1856
|
+
return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
|
|
1857
|
+
},
|
|
1858
|
+
alphaDecay: function(_) {
|
|
1859
|
+
return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
|
|
1860
|
+
},
|
|
1861
|
+
alphaTarget: function(_) {
|
|
1862
|
+
return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
|
|
1863
|
+
},
|
|
1864
|
+
velocityDecay: function(_) {
|
|
1865
|
+
return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
|
|
1866
|
+
},
|
|
1867
|
+
randomSource: function(_) {
|
|
1868
|
+
return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random;
|
|
1869
|
+
},
|
|
1870
|
+
force: function(name, _) {
|
|
1871
|
+
return arguments.length > 1 ? (_ == null ? forces.delete(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
|
|
1872
|
+
},
|
|
1873
|
+
find: function(x3, y3, radius) {
|
|
1874
|
+
var i = 0, n = nodes.length, dx, dy, d2, node, closest;
|
|
1875
|
+
if (radius == null) radius = Infinity;
|
|
1876
|
+
else radius *= radius;
|
|
1877
|
+
for (i = 0; i < n; ++i) {
|
|
1878
|
+
node = nodes[i];
|
|
1879
|
+
dx = x3 - node.x;
|
|
1880
|
+
dy = y3 - node.y;
|
|
1881
|
+
d2 = dx * dx + dy * dy;
|
|
1882
|
+
if (d2 < radius) closest = node, radius = d2;
|
|
1883
|
+
}
|
|
1884
|
+
return closest;
|
|
1885
|
+
},
|
|
1886
|
+
on: function(name, _) {
|
|
1887
|
+
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
|
|
1888
|
+
}
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/manyBody.js
|
|
1893
|
+
function manyBody_default() {
|
|
1894
|
+
var nodes, node, random, alpha, strength = constant_default(-30), strengths, distanceMin2 = 1, distanceMax2 = Infinity, theta2 = 0.81;
|
|
1895
|
+
function force(_) {
|
|
1896
|
+
var i, n = nodes.length, tree = quadtree(nodes, x2, y2).visitAfter(accumulate);
|
|
1897
|
+
for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
|
|
1898
|
+
}
|
|
1899
|
+
function initialize() {
|
|
1900
|
+
if (!nodes) return;
|
|
1901
|
+
var i, n = nodes.length, node2;
|
|
1902
|
+
strengths = new Array(n);
|
|
1903
|
+
for (i = 0; i < n; ++i) node2 = nodes[i], strengths[node2.index] = +strength(node2, i, nodes);
|
|
1904
|
+
}
|
|
1905
|
+
function accumulate(quad) {
|
|
1906
|
+
var strength2 = 0, q, c2, weight = 0, x3, y3, i;
|
|
1907
|
+
if (quad.length) {
|
|
1908
|
+
for (x3 = y3 = i = 0; i < 4; ++i) {
|
|
1909
|
+
if ((q = quad[i]) && (c2 = Math.abs(q.value))) {
|
|
1910
|
+
strength2 += q.value, weight += c2, x3 += c2 * q.x, y3 += c2 * q.y;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
quad.x = x3 / weight;
|
|
1914
|
+
quad.y = y3 / weight;
|
|
1915
|
+
} else {
|
|
1916
|
+
q = quad;
|
|
1917
|
+
q.x = q.data.x;
|
|
1918
|
+
q.y = q.data.y;
|
|
1919
|
+
do
|
|
1920
|
+
strength2 += strengths[q.data.index];
|
|
1921
|
+
while (q = q.next);
|
|
1922
|
+
}
|
|
1923
|
+
quad.value = strength2;
|
|
1924
|
+
}
|
|
1925
|
+
function apply(quad, x1, _, x22) {
|
|
1926
|
+
if (!quad.value) return true;
|
|
1927
|
+
var x3 = quad.x - node.x, y3 = quad.y - node.y, w = x22 - x1, l = x3 * x3 + y3 * y3;
|
|
1928
|
+
if (w * w / theta2 < l) {
|
|
1929
|
+
if (l < distanceMax2) {
|
|
1930
|
+
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
1931
|
+
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
1932
|
+
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
|
|
1933
|
+
node.vx += x3 * quad.value * alpha / l;
|
|
1934
|
+
node.vy += y3 * quad.value * alpha / l;
|
|
1935
|
+
}
|
|
1936
|
+
return true;
|
|
1937
|
+
} else if (quad.length || l >= distanceMax2) return;
|
|
1938
|
+
if (quad.data !== node || quad.next) {
|
|
1939
|
+
if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
|
|
1940
|
+
if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
|
|
1941
|
+
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
|
|
1942
|
+
}
|
|
1943
|
+
do
|
|
1944
|
+
if (quad.data !== node) {
|
|
1945
|
+
w = strengths[quad.data.index] * alpha / l;
|
|
1946
|
+
node.vx += x3 * w;
|
|
1947
|
+
node.vy += y3 * w;
|
|
1948
|
+
}
|
|
1949
|
+
while (quad = quad.next);
|
|
1950
|
+
}
|
|
1951
|
+
force.initialize = function(_nodes, _random) {
|
|
1952
|
+
nodes = _nodes;
|
|
1953
|
+
random = _random;
|
|
1954
|
+
initialize();
|
|
1955
|
+
};
|
|
1956
|
+
force.strength = function(_) {
|
|
1957
|
+
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
1958
|
+
};
|
|
1959
|
+
force.distanceMin = function(_) {
|
|
1960
|
+
return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
|
|
1961
|
+
};
|
|
1962
|
+
force.distanceMax = function(_) {
|
|
1963
|
+
return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
|
|
1964
|
+
};
|
|
1965
|
+
force.theta = function(_) {
|
|
1966
|
+
return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
|
|
1967
|
+
};
|
|
1968
|
+
return force;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/x.js
|
|
1972
|
+
function x_default2(x3) {
|
|
1973
|
+
var strength = constant_default(0.1), nodes, strengths, xz;
|
|
1974
|
+
if (typeof x3 !== "function") x3 = constant_default(x3 == null ? 0 : +x3);
|
|
1975
|
+
function force(alpha) {
|
|
1976
|
+
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
1977
|
+
node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
function initialize() {
|
|
1981
|
+
if (!nodes) return;
|
|
1982
|
+
var i, n = nodes.length;
|
|
1983
|
+
strengths = new Array(n);
|
|
1984
|
+
xz = new Array(n);
|
|
1985
|
+
for (i = 0; i < n; ++i) {
|
|
1986
|
+
strengths[i] = isNaN(xz[i] = +x3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
force.initialize = function(_) {
|
|
1990
|
+
nodes = _;
|
|
1991
|
+
initialize();
|
|
1992
|
+
};
|
|
1993
|
+
force.strength = function(_) {
|
|
1994
|
+
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
1995
|
+
};
|
|
1996
|
+
force.x = function(_) {
|
|
1997
|
+
return arguments.length ? (x3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : x3;
|
|
1998
|
+
};
|
|
1999
|
+
return force;
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
// ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/y.js
|
|
2003
|
+
function y_default2(y3) {
|
|
2004
|
+
var strength = constant_default(0.1), nodes, strengths, yz;
|
|
2005
|
+
if (typeof y3 !== "function") y3 = constant_default(y3 == null ? 0 : +y3);
|
|
2006
|
+
function force(alpha) {
|
|
2007
|
+
for (var i = 0, n = nodes.length, node; i < n; ++i) {
|
|
2008
|
+
node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
function initialize() {
|
|
2012
|
+
if (!nodes) return;
|
|
2013
|
+
var i, n = nodes.length;
|
|
2014
|
+
strengths = new Array(n);
|
|
2015
|
+
yz = new Array(n);
|
|
2016
|
+
for (i = 0; i < n; ++i) {
|
|
2017
|
+
strengths[i] = isNaN(yz[i] = +y3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
force.initialize = function(_) {
|
|
2021
|
+
nodes = _;
|
|
2022
|
+
initialize();
|
|
2023
|
+
};
|
|
2024
|
+
force.strength = function(_) {
|
|
2025
|
+
return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
|
|
2026
|
+
};
|
|
2027
|
+
force.y = function(_) {
|
|
2028
|
+
return arguments.length ? (y3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : y3;
|
|
2029
|
+
};
|
|
2030
|
+
return force;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
1111
2033
|
// src/graph/simulation.ts
|
|
1112
|
-
import {
|
|
1113
|
-
forceCenter,
|
|
1114
|
-
forceCollide,
|
|
1115
|
-
forceLink,
|
|
1116
|
-
forceManyBody,
|
|
1117
|
-
forceSimulation,
|
|
1118
|
-
forceX,
|
|
1119
|
-
forceY
|
|
1120
|
-
} from "d3-force";
|
|
1121
2034
|
var SYNC_THRESHOLD = 200;
|
|
1122
2035
|
var SYNC_MAX_TICKS = 300;
|
|
1123
2036
|
function forceCluster(nodes, strength) {
|
|
@@ -1127,14 +2040,14 @@ function forceCluster(nodes, strength) {
|
|
|
1127
2040
|
const count = /* @__PURE__ */ new Map();
|
|
1128
2041
|
for (const node of nodes) {
|
|
1129
2042
|
if (!node.community) continue;
|
|
1130
|
-
const
|
|
1131
|
-
cx.set(
|
|
1132
|
-
cy.set(
|
|
1133
|
-
count.set(
|
|
2043
|
+
const c2 = node.community;
|
|
2044
|
+
cx.set(c2, (cx.get(c2) ?? 0) + (node.x ?? 0));
|
|
2045
|
+
cy.set(c2, (cy.get(c2) ?? 0) + (node.y ?? 0));
|
|
2046
|
+
count.set(c2, (count.get(c2) ?? 0) + 1);
|
|
1134
2047
|
}
|
|
1135
|
-
for (const [
|
|
1136
|
-
cx.set(
|
|
1137
|
-
cy.set(
|
|
2048
|
+
for (const [c2, n] of count) {
|
|
2049
|
+
cx.set(c2, cx.get(c2) / n);
|
|
2050
|
+
cy.set(c2, cy.get(c2) / n);
|
|
1138
2051
|
}
|
|
1139
2052
|
const k = strength * alpha;
|
|
1140
2053
|
for (const node of nodes) {
|
|
@@ -1193,15 +2106,15 @@ var SimulationManager = class _SimulationManager {
|
|
|
1193
2106
|
}
|
|
1194
2107
|
}
|
|
1195
2108
|
/** Pin a node to fixed x/y coordinates. */
|
|
1196
|
-
pinNode(id,
|
|
2109
|
+
pinNode(id, x3, y3) {
|
|
1197
2110
|
if (this.destroyed) return;
|
|
1198
2111
|
if (this.worker) {
|
|
1199
|
-
this.worker.postMessage({ type: "pin", nodeId: id, x, y });
|
|
2112
|
+
this.worker.postMessage({ type: "pin", nodeId: id, x: x3, y: y3 });
|
|
1200
2113
|
} else {
|
|
1201
2114
|
const node = this.syncNodeMap.get(id);
|
|
1202
2115
|
if (node) {
|
|
1203
|
-
node.fx =
|
|
1204
|
-
node.fy =
|
|
2116
|
+
node.fx = x3;
|
|
2117
|
+
node.fy = y3;
|
|
1205
2118
|
}
|
|
1206
2119
|
}
|
|
1207
2120
|
}
|
|
@@ -1219,15 +2132,15 @@ var SimulationManager = class _SimulationManager {
|
|
|
1219
2132
|
}
|
|
1220
2133
|
}
|
|
1221
2134
|
/** Drag a node (pins it and reheats slightly). */
|
|
1222
|
-
dragNode(id,
|
|
2135
|
+
dragNode(id, x3, y3) {
|
|
1223
2136
|
if (this.destroyed) return;
|
|
1224
2137
|
if (this.worker) {
|
|
1225
|
-
this.worker.postMessage({ type: "drag", nodeId: id, x, y });
|
|
2138
|
+
this.worker.postMessage({ type: "drag", nodeId: id, x: x3, y: y3 });
|
|
1226
2139
|
} else {
|
|
1227
2140
|
const node = this.syncNodeMap.get(id);
|
|
1228
2141
|
if (node) {
|
|
1229
|
-
node.fx =
|
|
1230
|
-
node.fy =
|
|
2142
|
+
node.fx = x3;
|
|
2143
|
+
node.fy = y3;
|
|
1231
2144
|
}
|
|
1232
2145
|
if (this.syncSim && this.syncSim.alpha() < 0.1) {
|
|
1233
2146
|
this.syncSim.alpha(0.1).restart();
|
|
@@ -1301,17 +2214,17 @@ var SimulationManager = class _SimulationManager {
|
|
|
1301
2214
|
community: n.community
|
|
1302
2215
|
}));
|
|
1303
2216
|
this.syncNodeMap = new Map(this.syncNodes.map((n) => [n.id, n]));
|
|
1304
|
-
const linkForce =
|
|
2217
|
+
const linkForce = link_default(edges.map((e) => ({ ...e }))).id((d) => d.id).distance(config.linkDistance);
|
|
1305
2218
|
if (config.linkStrength != null) {
|
|
1306
2219
|
linkForce.strength(config.linkStrength);
|
|
1307
2220
|
}
|
|
1308
2221
|
const padding = config.collisionPadding ?? 2;
|
|
1309
|
-
this.syncSim =
|
|
2222
|
+
this.syncSim = simulation_default(this.syncNodes).force("link", linkForce).force("charge", manyBody_default().strength(config.chargeStrength)).force(
|
|
1310
2223
|
"collide",
|
|
1311
|
-
|
|
1312
|
-
).force("gravityX",
|
|
2224
|
+
collide_default().radius((d) => d.radius + padding)
|
|
2225
|
+
).force("gravityX", x_default2(0).strength(0.05)).force("gravityY", y_default2(0).strength(0.05)).alphaDecay(config.alphaDecay).velocityDecay(config.velocityDecay).stop();
|
|
1313
2226
|
if (config.centerForce !== false) {
|
|
1314
|
-
this.syncSim.force("center",
|
|
2227
|
+
this.syncSim.force("center", center_default(0, 0));
|
|
1315
2228
|
}
|
|
1316
2229
|
if (config.clustering) {
|
|
1317
2230
|
const clusterFn = forceCluster(this.syncNodes, config.clustering.strength);
|
|
@@ -1355,7 +2268,6 @@ var SimulationManager = class _SimulationManager {
|
|
|
1355
2268
|
};
|
|
1356
2269
|
|
|
1357
2270
|
// src/graph/spatial-index.ts
|
|
1358
|
-
import { quadtree } from "d3-quadtree";
|
|
1359
2271
|
var SpatialIndex = class {
|
|
1360
2272
|
tree = null;
|
|
1361
2273
|
nodes = [];
|
|
@@ -1381,22 +2293,22 @@ var SpatialIndex = class {
|
|
|
1381
2293
|
* the node circle (distance to center < node.radius), or if the
|
|
1382
2294
|
* edge-to-edge distance is within maxDistance.
|
|
1383
2295
|
*/
|
|
1384
|
-
findNearest(
|
|
2296
|
+
findNearest(x3, y3, maxDistance = Infinity) {
|
|
1385
2297
|
if (!this.tree || this.nodes.length === 0) return null;
|
|
1386
2298
|
const searchRadius = maxDistance + this.maxRadius;
|
|
1387
2299
|
let best = null;
|
|
1388
2300
|
let bestEffectiveDist = maxDistance + this.maxRadius + 1;
|
|
1389
2301
|
this.tree.visit((node, x0, y0, x1, y1) => {
|
|
1390
|
-
const closestX = Math.max(x0, Math.min(
|
|
1391
|
-
const closestY = Math.max(y0, Math.min(
|
|
1392
|
-
const quadDist = Math.hypot(closestX -
|
|
2302
|
+
const closestX = Math.max(x0, Math.min(x3, x1));
|
|
2303
|
+
const closestY = Math.max(y0, Math.min(y3, y1));
|
|
2304
|
+
const quadDist = Math.hypot(closestX - x3, closestY - y3);
|
|
1393
2305
|
if (quadDist > searchRadius) return true;
|
|
1394
2306
|
if (!node.length) {
|
|
1395
2307
|
let current = node;
|
|
1396
2308
|
do {
|
|
1397
2309
|
const d = current.data;
|
|
1398
2310
|
if (d) {
|
|
1399
|
-
const dist = Math.hypot(d.x -
|
|
2311
|
+
const dist = Math.hypot(d.x - x3, d.y - y3);
|
|
1400
2312
|
const effectiveDist = Math.max(0, dist - d.radius);
|
|
1401
2313
|
if (effectiveDist <= maxDistance && effectiveDist < bestEffectiveDist) {
|
|
1402
2314
|
bestEffectiveDist = effectiveDist;
|
|
@@ -1410,12 +2322,12 @@ var SpatialIndex = class {
|
|
|
1410
2322
|
return best;
|
|
1411
2323
|
}
|
|
1412
2324
|
/** Find all nodes whose centers fall within the given rectangle. */
|
|
1413
|
-
findInRect(x1, y1,
|
|
2325
|
+
findInRect(x1, y1, x22, y22) {
|
|
1414
2326
|
if (!this.tree) return [];
|
|
1415
|
-
const minX = Math.min(x1,
|
|
1416
|
-
const minY = Math.min(y1,
|
|
1417
|
-
const maxX = Math.max(x1,
|
|
1418
|
-
const maxY = Math.max(y1,
|
|
2327
|
+
const minX = Math.min(x1, x22);
|
|
2328
|
+
const minY = Math.min(y1, y22);
|
|
2329
|
+
const maxX = Math.max(x1, x22);
|
|
2330
|
+
const maxY = Math.max(y1, y22);
|
|
1419
2331
|
const results = [];
|
|
1420
2332
|
this.tree.visit((node, qx0, qy0, qx1, qy1) => {
|
|
1421
2333
|
if (qx0 > maxX || qx1 < minX || qy0 > maxY || qy1 < minY) {
|
|
@@ -1475,7 +2387,7 @@ function createTooltipManager(container) {
|
|
|
1475
2387
|
}
|
|
1476
2388
|
};
|
|
1477
2389
|
document.addEventListener("touchstart", handleDocumentTouch);
|
|
1478
|
-
function show(content,
|
|
2390
|
+
function show(content, x3, y3) {
|
|
1479
2391
|
let html = "";
|
|
1480
2392
|
if (content.title) {
|
|
1481
2393
|
const titleColor = content.fields.find((f) => f.color)?.color;
|
|
@@ -1500,13 +2412,13 @@ function createTooltipManager(container) {
|
|
|
1500
2412
|
tooltip.style.display = "block";
|
|
1501
2413
|
const containerRect = container.getBoundingClientRect();
|
|
1502
2414
|
const tooltipRect = tooltip.getBoundingClientRect();
|
|
1503
|
-
let left =
|
|
1504
|
-
let top =
|
|
2415
|
+
let left = x3 + TOOLTIP_OFFSET;
|
|
2416
|
+
let top = y3 + TOOLTIP_OFFSET;
|
|
1505
2417
|
if (left + tooltipRect.width > containerRect.width) {
|
|
1506
|
-
left =
|
|
2418
|
+
left = x3 - tooltipRect.width - TOOLTIP_OFFSET;
|
|
1507
2419
|
}
|
|
1508
2420
|
if (top + tooltipRect.height > containerRect.height) {
|
|
1509
|
-
top =
|
|
2421
|
+
top = y3 - tooltipRect.height - TOOLTIP_OFFSET;
|
|
1510
2422
|
}
|
|
1511
2423
|
left = Math.max(0, Math.min(left, containerRect.width - tooltipRect.width));
|
|
1512
2424
|
top = Math.max(0, Math.min(top, containerRect.height - tooltipRect.height));
|
|
@@ -1654,12 +2566,21 @@ function createGraph(container, spec, options) {
|
|
|
1654
2566
|
const { width, height } = getContainerDimensions();
|
|
1655
2567
|
const isDark = resolveDarkMode(options?.darkMode);
|
|
1656
2568
|
wrapper = document.createElement("div");
|
|
1657
|
-
wrapper.className = "viz-graph-wrapper";
|
|
2569
|
+
wrapper.className = isDark ? "viz-graph-wrapper viz-dark" : "viz-graph-wrapper";
|
|
1658
2570
|
if (isDark) {
|
|
1659
2571
|
container.classList.add("viz-dark");
|
|
1660
2572
|
} else {
|
|
1661
2573
|
container.classList.remove("viz-dark");
|
|
1662
2574
|
}
|
|
2575
|
+
const resolvedTheme = compilation.theme;
|
|
2576
|
+
if (resolvedTheme) {
|
|
2577
|
+
const s = wrapper.style;
|
|
2578
|
+
s.setProperty("--viz-bg", resolvedTheme.colors.background);
|
|
2579
|
+
s.setProperty("--viz-text", resolvedTheme.colors.text);
|
|
2580
|
+
s.setProperty("--viz-text-secondary", resolvedTheme.colors.axis ?? resolvedTheme.colors.text);
|
|
2581
|
+
s.setProperty("--viz-font-family", resolvedTheme.fonts.family);
|
|
2582
|
+
s.fontFamily = resolvedTheme.fonts.family;
|
|
2583
|
+
}
|
|
1663
2584
|
chromeEl = document.createElement("div");
|
|
1664
2585
|
chromeEl.className = "viz-graph-chrome";
|
|
1665
2586
|
renderChrome2();
|
|
@@ -1873,13 +2794,13 @@ function createGraph(container, spec, options) {
|
|
|
1873
2794
|
},
|
|
1874
2795
|
onNodeDragStart(nodeId) {
|
|
1875
2796
|
const node = positionedNodes.find((n) => n.id === nodeId);
|
|
1876
|
-
const
|
|
1877
|
-
const
|
|
1878
|
-
simulation?.pinNode(nodeId,
|
|
2797
|
+
const x3 = node?.x ?? 0;
|
|
2798
|
+
const y3 = node?.y ?? 0;
|
|
2799
|
+
simulation?.pinNode(nodeId, x3, y3);
|
|
1879
2800
|
canvas?.classList.add("viz-graph-canvas--dragging");
|
|
1880
2801
|
},
|
|
1881
|
-
onNodeDrag(nodeId,
|
|
1882
|
-
simulation?.dragNode(nodeId,
|
|
2802
|
+
onNodeDrag(nodeId, x3, y3) {
|
|
2803
|
+
simulation?.dragNode(nodeId, x3, y3);
|
|
1883
2804
|
},
|
|
1884
2805
|
onNodeDragEnd(nodeId) {
|
|
1885
2806
|
simulation?.unpinNode(nodeId);
|
|
@@ -2158,13 +3079,62 @@ function applyTextStyle(el, style) {
|
|
|
2158
3079
|
el.setAttribute("font-variant", style.fontVariant);
|
|
2159
3080
|
}
|
|
2160
3081
|
}
|
|
3082
|
+
function wrapText(text, fontSize, fontWeight, maxWidth) {
|
|
3083
|
+
if (maxWidth <= 0) return [text];
|
|
3084
|
+
const AVG_CHAR_WIDTH = 0.55;
|
|
3085
|
+
const WEIGHT_FACTORS = {
|
|
3086
|
+
100: 0.9,
|
|
3087
|
+
200: 0.92,
|
|
3088
|
+
300: 0.95,
|
|
3089
|
+
400: 1,
|
|
3090
|
+
500: 1.02,
|
|
3091
|
+
600: 1.05,
|
|
3092
|
+
700: 1.08,
|
|
3093
|
+
800: 1.1,
|
|
3094
|
+
900: 1.12
|
|
3095
|
+
};
|
|
3096
|
+
const weightFactor = WEIGHT_FACTORS[fontWeight] ?? 1;
|
|
3097
|
+
const charWidth = fontSize * AVG_CHAR_WIDTH * weightFactor;
|
|
3098
|
+
const maxChars = Math.floor(maxWidth / charWidth);
|
|
3099
|
+
if (text.length <= maxChars) return [text];
|
|
3100
|
+
const words = text.split(" ");
|
|
3101
|
+
const lines = [];
|
|
3102
|
+
let current = "";
|
|
3103
|
+
for (const word of words) {
|
|
3104
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
3105
|
+
if (candidate.length > maxChars && current) {
|
|
3106
|
+
lines.push(current);
|
|
3107
|
+
current = word;
|
|
3108
|
+
} else {
|
|
3109
|
+
current = candidate;
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
if (current) lines.push(current);
|
|
3113
|
+
return lines;
|
|
3114
|
+
}
|
|
2161
3115
|
function renderChromeElement(parent, element, className, chromeKey) {
|
|
2162
3116
|
const text = createSVGElement("text");
|
|
2163
3117
|
setAttrs(text, { x: element.x, y: element.y });
|
|
2164
3118
|
applyTextStyle(text, element.style);
|
|
2165
3119
|
text.setAttribute("class", className);
|
|
2166
3120
|
text.setAttribute("data-chrome-key", chromeKey);
|
|
2167
|
-
|
|
3121
|
+
const lines = wrapText(
|
|
3122
|
+
element.text,
|
|
3123
|
+
element.style.fontSize,
|
|
3124
|
+
element.style.fontWeight,
|
|
3125
|
+
element.maxWidth
|
|
3126
|
+
);
|
|
3127
|
+
if (lines.length === 1) {
|
|
3128
|
+
text.textContent = element.text;
|
|
3129
|
+
} else {
|
|
3130
|
+
const lineHeight = element.style.fontSize * (element.style.lineHeight ?? 1.3);
|
|
3131
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3132
|
+
const tspan = createSVGElement("tspan");
|
|
3133
|
+
setAttrs(tspan, { x: element.x, dy: i === 0 ? 0 : lineHeight });
|
|
3134
|
+
tspan.textContent = lines[i];
|
|
3135
|
+
text.appendChild(tspan);
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
2168
3138
|
parent.appendChild(text);
|
|
2169
3139
|
}
|
|
2170
3140
|
function renderChrome(parent, layout) {
|
|
@@ -2336,9 +3306,9 @@ var markRenderers = {};
|
|
|
2336
3306
|
function registerMarkRenderer(type, renderer) {
|
|
2337
3307
|
markRenderers[type] = renderer;
|
|
2338
3308
|
}
|
|
2339
|
-
function renderLineMark(mark,
|
|
3309
|
+
function renderLineMark(mark, index2) {
|
|
2340
3310
|
const g = createSVGElement("g");
|
|
2341
|
-
g.setAttribute("data-mark-id", `line-${mark.seriesKey ??
|
|
3311
|
+
g.setAttribute("data-mark-id", `line-${mark.seriesKey ?? index2}`);
|
|
2342
3312
|
g.setAttribute("class", "viz-mark viz-mark-line");
|
|
2343
3313
|
if (mark.points.length > 1) {
|
|
2344
3314
|
const path = createSVGElement("path");
|
|
@@ -2384,9 +3354,9 @@ function renderLineMark(mark, index) {
|
|
|
2384
3354
|
}
|
|
2385
3355
|
return g;
|
|
2386
3356
|
}
|
|
2387
|
-
function renderAreaMark(mark,
|
|
3357
|
+
function renderAreaMark(mark, index2) {
|
|
2388
3358
|
const g = createSVGElement("g");
|
|
2389
|
-
g.setAttribute("data-mark-id", `area-${mark.seriesKey ??
|
|
3359
|
+
g.setAttribute("data-mark-id", `area-${mark.seriesKey ?? index2}`);
|
|
2390
3360
|
g.setAttribute("class", "viz-mark viz-mark-area");
|
|
2391
3361
|
if (mark.path) {
|
|
2392
3362
|
const fill = createSVGElement("path");
|
|
@@ -2410,9 +3380,9 @@ function renderAreaMark(mark, index) {
|
|
|
2410
3380
|
}
|
|
2411
3381
|
return g;
|
|
2412
3382
|
}
|
|
2413
|
-
function renderRectMark(mark,
|
|
3383
|
+
function renderRectMark(mark, index2) {
|
|
2414
3384
|
const g = createSVGElement("g");
|
|
2415
|
-
g.setAttribute("data-mark-id", `rect-${
|
|
3385
|
+
g.setAttribute("data-mark-id", `rect-${index2}`);
|
|
2416
3386
|
g.setAttribute("class", "viz-mark viz-mark-rect");
|
|
2417
3387
|
const rect = createSVGElement("rect");
|
|
2418
3388
|
setAttrs(rect, {
|
|
@@ -2442,9 +3412,9 @@ function renderRectMark(mark, index) {
|
|
|
2442
3412
|
}
|
|
2443
3413
|
return g;
|
|
2444
3414
|
}
|
|
2445
|
-
function renderArcMark(mark,
|
|
3415
|
+
function renderArcMark(mark, index2) {
|
|
2446
3416
|
const g = createSVGElement("g");
|
|
2447
|
-
g.setAttribute("data-mark-id", `arc-${
|
|
3417
|
+
g.setAttribute("data-mark-id", `arc-${index2}`);
|
|
2448
3418
|
g.setAttribute("class", "viz-mark viz-mark-arc");
|
|
2449
3419
|
g.setAttribute("transform", `translate(${mark.center.x},${mark.center.y})`);
|
|
2450
3420
|
const path = createSVGElement("path");
|
|
@@ -2468,9 +3438,9 @@ function renderArcMark(mark, index) {
|
|
|
2468
3438
|
}
|
|
2469
3439
|
return g;
|
|
2470
3440
|
}
|
|
2471
|
-
function renderPointMark(mark,
|
|
3441
|
+
function renderPointMark(mark, index2) {
|
|
2472
3442
|
const circle = createSVGElement("circle");
|
|
2473
|
-
circle.setAttribute("data-mark-id", `point-${
|
|
3443
|
+
circle.setAttribute("data-mark-id", `point-${index2}`);
|
|
2474
3444
|
circle.setAttribute("class", "viz-mark viz-mark-point");
|
|
2475
3445
|
setAttrs(circle, {
|
|
2476
3446
|
cx: mark.cx,
|
|
@@ -2574,10 +3544,10 @@ function renderCurvedArrow(parent, from, to, stroke) {
|
|
|
2574
3544
|
});
|
|
2575
3545
|
parent.appendChild(arrow);
|
|
2576
3546
|
}
|
|
2577
|
-
function renderAnnotation(parent, annotation,
|
|
3547
|
+
function renderAnnotation(parent, annotation, index2) {
|
|
2578
3548
|
const g = createSVGElement("g");
|
|
2579
3549
|
g.setAttribute("class", `viz-annotation viz-annotation-${annotation.type}`);
|
|
2580
|
-
g.setAttribute("data-annotation-index", String(
|
|
3550
|
+
g.setAttribute("data-annotation-index", String(index2));
|
|
2581
3551
|
if (annotation.rect) {
|
|
2582
3552
|
const rect = createSVGElement("rect");
|
|
2583
3553
|
rect.setAttribute("class", "viz-annotation-range");
|
|
@@ -2611,9 +3581,9 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2611
3581
|
}
|
|
2612
3582
|
if (annotation.label?.visible) {
|
|
2613
3583
|
if (annotation.label.connector) {
|
|
2614
|
-
const
|
|
2615
|
-
if (
|
|
2616
|
-
const pointsDown =
|
|
3584
|
+
const c2 = annotation.label.connector;
|
|
3585
|
+
if (c2.style === "caret") {
|
|
3586
|
+
const pointsDown = c2.to.y > c2.from.y;
|
|
2617
3587
|
const caretSize = 4;
|
|
2618
3588
|
const labelLines = annotation.label.text.split("\n");
|
|
2619
3589
|
const labelFontSize = annotation.label.style.fontSize ?? 12;
|
|
@@ -2621,8 +3591,8 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2621
3591
|
const textBottom = annotation.label.y + (labelLines.length - 1) * labelLineHeight + labelFontSize * 0.25;
|
|
2622
3592
|
const textTop = annotation.label.y - labelFontSize;
|
|
2623
3593
|
const gapEdge = pointsDown ? textBottom : textTop;
|
|
2624
|
-
const midY = (gapEdge +
|
|
2625
|
-
const tipX =
|
|
3594
|
+
const midY = (gapEdge + c2.to.y) / 2;
|
|
3595
|
+
const tipX = c2.to.x;
|
|
2626
3596
|
const tipY = pointsDown ? midY + caretSize / 2 : midY - caretSize / 2;
|
|
2627
3597
|
const baseY = pointsDown ? tipY - caretSize : tipY + caretSize;
|
|
2628
3598
|
const path = createSVGElement("path");
|
|
@@ -2630,24 +3600,24 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2630
3600
|
setAttrs(path, {
|
|
2631
3601
|
d: `M${tipX - caretSize},${baseY} L${tipX},${tipY} L${tipX + caretSize},${baseY}`,
|
|
2632
3602
|
fill: "none",
|
|
2633
|
-
stroke:
|
|
3603
|
+
stroke: c2.stroke,
|
|
2634
3604
|
"stroke-width": 1.5,
|
|
2635
3605
|
"stroke-opacity": 0.4,
|
|
2636
3606
|
"stroke-linecap": "round",
|
|
2637
3607
|
"stroke-linejoin": "round"
|
|
2638
3608
|
});
|
|
2639
3609
|
g.appendChild(path);
|
|
2640
|
-
} else if (
|
|
2641
|
-
renderCurvedArrow(g,
|
|
3610
|
+
} else if (c2.style === "curve") {
|
|
3611
|
+
renderCurvedArrow(g, c2.from, c2.to, c2.stroke);
|
|
2642
3612
|
} else {
|
|
2643
3613
|
const connector = createSVGElement("line");
|
|
2644
3614
|
connector.setAttribute("class", "viz-annotation-connector");
|
|
2645
3615
|
setAttrs(connector, {
|
|
2646
|
-
x1:
|
|
2647
|
-
y1:
|
|
2648
|
-
x2:
|
|
2649
|
-
y2:
|
|
2650
|
-
stroke:
|
|
3616
|
+
x1: c2.from.x,
|
|
3617
|
+
y1: c2.from.y,
|
|
3618
|
+
x2: c2.to.x,
|
|
3619
|
+
y2: c2.to.y,
|
|
3620
|
+
stroke: c2.stroke,
|
|
2651
3621
|
"stroke-width": 1,
|
|
2652
3622
|
"stroke-opacity": 0.5
|
|
2653
3623
|
});
|
|
@@ -2802,12 +3772,12 @@ function renderBrand(parent, layout) {
|
|
|
2802
3772
|
const bottomOffset = layout.area.y + layout.area.height + xAxisExtent;
|
|
2803
3773
|
const firstBottom = chrome.source ?? chrome.byline ?? chrome.footer;
|
|
2804
3774
|
const chromeY = firstBottom ? bottomOffset + firstBottom.y : bottomOffset + layout.theme.spacing.chartToFooter;
|
|
2805
|
-
const
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
3775
|
+
const a2 = createSVGElement("a");
|
|
3776
|
+
a2.setAttribute("href", BRAND_URL);
|
|
3777
|
+
a2.setAttributeNS(XLINK_NS, "xlink:href", BRAND_URL);
|
|
3778
|
+
a2.setAttribute("target", "_blank");
|
|
3779
|
+
a2.setAttribute("rel", "noopener");
|
|
3780
|
+
a2.setAttribute("class", "viz-chrome-ref");
|
|
2811
3781
|
const text = createSVGElement("text");
|
|
2812
3782
|
setAttrs(text, {
|
|
2813
3783
|
x: rightEdge,
|
|
@@ -2827,8 +3797,8 @@ function renderBrand(parent, layout) {
|
|
|
2827
3797
|
dataSpan.setAttribute("font-weight", "600");
|
|
2828
3798
|
dataSpan.textContent = "Data";
|
|
2829
3799
|
text.appendChild(dataSpan);
|
|
2830
|
-
|
|
2831
|
-
parent.appendChild(
|
|
3800
|
+
a2.appendChild(text);
|
|
3801
|
+
parent.appendChild(a2);
|
|
2832
3802
|
}
|
|
2833
3803
|
function renderChartSVG(layout, container) {
|
|
2834
3804
|
const { width, height } = layout.dimensions;
|
|
@@ -2916,16 +3886,16 @@ function wireTooltipEvents(svg, tooltipDescriptors, tooltipManager) {
|
|
|
2916
3886
|
const handleMouseEnter = (e) => {
|
|
2917
3887
|
const mouseEvent = e;
|
|
2918
3888
|
const svgRect = svg.getBoundingClientRect();
|
|
2919
|
-
const
|
|
2920
|
-
const
|
|
2921
|
-
tooltipManager.show(content,
|
|
3889
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
3890
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
3891
|
+
tooltipManager.show(content, x3, y3);
|
|
2922
3892
|
};
|
|
2923
3893
|
const handleMouseMove = (e) => {
|
|
2924
3894
|
const mouseEvent = e;
|
|
2925
3895
|
const svgRect = svg.getBoundingClientRect();
|
|
2926
|
-
const
|
|
2927
|
-
const
|
|
2928
|
-
tooltipManager.show(content,
|
|
3896
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
3897
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
3898
|
+
tooltipManager.show(content, x3, y3);
|
|
2929
3899
|
};
|
|
2930
3900
|
const handleMouseLeave = () => {
|
|
2931
3901
|
tooltipManager.hide();
|
|
@@ -2935,9 +3905,9 @@ function wireTooltipEvents(svg, tooltipDescriptors, tooltipManager) {
|
|
|
2935
3905
|
if (touchEvent.touches.length > 0) {
|
|
2936
3906
|
const touch = touchEvent.touches[0];
|
|
2937
3907
|
const svgRect = svg.getBoundingClientRect();
|
|
2938
|
-
const
|
|
2939
|
-
const
|
|
2940
|
-
tooltipManager.show(content,
|
|
3908
|
+
const x3 = touch.clientX - svgRect.left;
|
|
3909
|
+
const y3 = touch.clientY - svgRect.top;
|
|
3910
|
+
tooltipManager.show(content, x3, y3);
|
|
2941
3911
|
}
|
|
2942
3912
|
};
|
|
2943
3913
|
el.addEventListener("mouseenter", handleMouseEnter);
|
|
@@ -3211,8 +4181,8 @@ function wireAnnotationDrag(svg, specAnnotations, onAnnotationEdit, onEdit, setD
|
|
|
3211
4181
|
for (const el of annotationElements) {
|
|
3212
4182
|
const indexStr = el.getAttribute("data-annotation-index");
|
|
3213
4183
|
if (indexStr === null) continue;
|
|
3214
|
-
const
|
|
3215
|
-
const specAnnotation = specAnnotations[
|
|
4184
|
+
const index2 = Number(indexStr);
|
|
4185
|
+
const specAnnotation = specAnnotations[index2];
|
|
3216
4186
|
if (!specAnnotation || specAnnotation.type !== "text") continue;
|
|
3217
4187
|
const textAnnotation = specAnnotation;
|
|
3218
4188
|
const annotationG = el;
|
|
@@ -3276,8 +4246,8 @@ function wireConnectorEndpointDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
|
3276
4246
|
const annotationG = el;
|
|
3277
4247
|
const indexStr = annotationG.getAttribute("data-annotation-index");
|
|
3278
4248
|
if (indexStr === null) continue;
|
|
3279
|
-
const
|
|
3280
|
-
const specAnnotation = specAnnotations[
|
|
4249
|
+
const index2 = Number(indexStr);
|
|
4250
|
+
const specAnnotation = specAnnotations[index2];
|
|
3281
4251
|
if (!specAnnotation || specAnnotation.type !== "text") continue;
|
|
3282
4252
|
const textAnnotation = specAnnotation;
|
|
3283
4253
|
const connectorLine = annotationG.querySelector("line.viz-annotation-connector");
|
|
@@ -3412,8 +4382,8 @@ function wireAnnotationLabelDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
|
3412
4382
|
if (!annotationG) continue;
|
|
3413
4383
|
const indexStr = annotationG.getAttribute("data-annotation-index");
|
|
3414
4384
|
if (indexStr === null) continue;
|
|
3415
|
-
const
|
|
3416
|
-
const specAnnotation = specAnnotations[
|
|
4385
|
+
const index2 = Number(indexStr);
|
|
4386
|
+
const specAnnotation = specAnnotations[index2];
|
|
3417
4387
|
if (!specAnnotation) continue;
|
|
3418
4388
|
const labelEl = label;
|
|
3419
4389
|
labelEl.style.cursor = "grab";
|
|
@@ -3618,12 +4588,12 @@ function wireKeyboardNav(svg, container, tooltipDescriptors, tooltipManager, lay
|
|
|
3618
4588
|
}
|
|
3619
4589
|
}
|
|
3620
4590
|
let focusIndex = -1;
|
|
3621
|
-
function highlightMark(
|
|
4591
|
+
function highlightMark(index2) {
|
|
3622
4592
|
if (focusIndex >= 0 && focusIndex < markElements.length) {
|
|
3623
4593
|
markElements[focusIndex].classList.remove("viz-mark-focused");
|
|
3624
4594
|
markElements[focusIndex].removeAttribute("aria-selected");
|
|
3625
4595
|
}
|
|
3626
|
-
focusIndex =
|
|
4596
|
+
focusIndex = index2;
|
|
3627
4597
|
if (focusIndex >= 0 && focusIndex < markElements.length) {
|
|
3628
4598
|
const el = markElements[focusIndex];
|
|
3629
4599
|
el.classList.add("viz-mark-focused");
|
|
@@ -3639,9 +4609,9 @@ function wireKeyboardNav(svg, container, tooltipDescriptors, tooltipManager, lay
|
|
|
3639
4609
|
if (!content) return;
|
|
3640
4610
|
const bbox = el.getBoundingClientRect();
|
|
3641
4611
|
const containerRect = container.getBoundingClientRect();
|
|
3642
|
-
const
|
|
3643
|
-
const
|
|
3644
|
-
tooltipManager.show(content,
|
|
4612
|
+
const x3 = bbox.left + bbox.width / 2 - containerRect.left;
|
|
4613
|
+
const y3 = bbox.top - containerRect.top;
|
|
4614
|
+
tooltipManager.show(content, x3, y3);
|
|
3645
4615
|
}
|
|
3646
4616
|
const handleKeyDown = (e) => {
|
|
3647
4617
|
if (markElements.length === 0) return;
|
|
@@ -3979,7 +4949,7 @@ function applyCellStyle(td, cell) {
|
|
|
3979
4949
|
}
|
|
3980
4950
|
}
|
|
3981
4951
|
function countryToEmoji(code) {
|
|
3982
|
-
return [...code.toUpperCase()].map((
|
|
4952
|
+
return [...code.toUpperCase()].map((c2) => String.fromCodePoint(c2.charCodeAt(0) + 127397)).join("");
|
|
3983
4953
|
}
|
|
3984
4954
|
var COUNTRY_NAMES = {
|
|
3985
4955
|
US: "United States",
|
|
@@ -4178,11 +5148,11 @@ function renderSparklineCell(cell) {
|
|
|
4178
5148
|
const barW = Math.max(1, (innerW - gap * (barCount - 1)) / barCount);
|
|
4179
5149
|
for (let i = 0; i < barCount; i++) {
|
|
4180
5150
|
const barH = Math.max(1, sparklineData.bars[i] * innerH);
|
|
4181
|
-
const
|
|
4182
|
-
const
|
|
5151
|
+
const x3 = padding + i * (barW + gap);
|
|
5152
|
+
const y3 = padding + innerH - barH;
|
|
4183
5153
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4184
|
-
rect.setAttribute("x", String(
|
|
4185
|
-
rect.setAttribute("y", String(
|
|
5154
|
+
rect.setAttribute("x", String(x3));
|
|
5155
|
+
rect.setAttribute("y", String(y3));
|
|
4186
5156
|
rect.setAttribute("width", String(barW));
|
|
4187
5157
|
rect.setAttribute("height", String(barH));
|
|
4188
5158
|
rect.setAttribute("rx", "1.5");
|
|
@@ -4208,11 +5178,11 @@ function renderSparklineCell(cell) {
|
|
|
4208
5178
|
const barH = Math.max(1, (innerH - gap * (barCount - 1)) / barCount);
|
|
4209
5179
|
for (let i = 0; i < barCount; i++) {
|
|
4210
5180
|
const barW = Math.max(1, sparklineData.bars[i] * innerW);
|
|
4211
|
-
const
|
|
4212
|
-
const
|
|
5181
|
+
const x3 = padding;
|
|
5182
|
+
const y3 = padding + i * (barH + gap);
|
|
4213
5183
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4214
|
-
rect.setAttribute("x", String(
|
|
4215
|
-
rect.setAttribute("y", String(
|
|
5184
|
+
rect.setAttribute("x", String(x3));
|
|
5185
|
+
rect.setAttribute("y", String(y3));
|
|
4216
5186
|
rect.setAttribute("width", String(barW));
|
|
4217
5187
|
rect.setAttribute("height", String(barH));
|
|
4218
5188
|
rect.setAttribute("rx", "1.5");
|
|
@@ -4547,12 +5517,12 @@ function renderTbody(rows, columns) {
|
|
|
4547
5517
|
const tr = document.createElement("tr");
|
|
4548
5518
|
tr.setAttribute("role", "row");
|
|
4549
5519
|
tr.setAttribute("data-row-id", row.id);
|
|
4550
|
-
for (let
|
|
4551
|
-
const cell = row.cells[
|
|
5520
|
+
for (let c2 = 0; c2 < columns.length; c2++) {
|
|
5521
|
+
const cell = row.cells[c2];
|
|
4552
5522
|
if (!cell) continue;
|
|
4553
5523
|
const td = renderCell(cell);
|
|
4554
5524
|
td.setAttribute("role", "gridcell");
|
|
4555
|
-
td.style.textAlign = columns[
|
|
5525
|
+
td.style.textAlign = columns[c2].align;
|
|
4556
5526
|
tr.appendChild(td);
|
|
4557
5527
|
}
|
|
4558
5528
|
tbody.appendChild(tr);
|
|
@@ -4990,7 +5960,7 @@ function createTable(container, spec, options) {
|
|
|
4990
5960
|
search: state.search || void 0
|
|
4991
5961
|
// No page/pageSize: get all rows
|
|
4992
5962
|
});
|
|
4993
|
-
const headers = fullLayout.columns.map((
|
|
5963
|
+
const headers = fullLayout.columns.map((c2) => c2.label);
|
|
4994
5964
|
const csvRows = [headers.map(csvEscape2).join(",")];
|
|
4995
5965
|
for (const row of fullLayout.rows) {
|
|
4996
5966
|
const values = row.cells.map((cell) => csvEscape2(cell.formattedValue));
|