@opendata-ai/openchart-vanilla 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1122 -161
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/svg-renderer.test.ts +40 -0
- 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));
|
|
@@ -1873,13 +2785,13 @@ function createGraph(container, spec, options) {
|
|
|
1873
2785
|
},
|
|
1874
2786
|
onNodeDragStart(nodeId) {
|
|
1875
2787
|
const node = positionedNodes.find((n) => n.id === nodeId);
|
|
1876
|
-
const
|
|
1877
|
-
const
|
|
1878
|
-
simulation?.pinNode(nodeId,
|
|
2788
|
+
const x3 = node?.x ?? 0;
|
|
2789
|
+
const y3 = node?.y ?? 0;
|
|
2790
|
+
simulation?.pinNode(nodeId, x3, y3);
|
|
1879
2791
|
canvas?.classList.add("viz-graph-canvas--dragging");
|
|
1880
2792
|
},
|
|
1881
|
-
onNodeDrag(nodeId,
|
|
1882
|
-
simulation?.dragNode(nodeId,
|
|
2793
|
+
onNodeDrag(nodeId, x3, y3) {
|
|
2794
|
+
simulation?.dragNode(nodeId, x3, y3);
|
|
1883
2795
|
},
|
|
1884
2796
|
onNodeDragEnd(nodeId) {
|
|
1885
2797
|
simulation?.unpinNode(nodeId);
|
|
@@ -2158,13 +3070,62 @@ function applyTextStyle(el, style) {
|
|
|
2158
3070
|
el.setAttribute("font-variant", style.fontVariant);
|
|
2159
3071
|
}
|
|
2160
3072
|
}
|
|
3073
|
+
function wrapText(text, fontSize, fontWeight, maxWidth) {
|
|
3074
|
+
if (maxWidth <= 0) return [text];
|
|
3075
|
+
const AVG_CHAR_WIDTH = 0.55;
|
|
3076
|
+
const WEIGHT_FACTORS = {
|
|
3077
|
+
100: 0.9,
|
|
3078
|
+
200: 0.92,
|
|
3079
|
+
300: 0.95,
|
|
3080
|
+
400: 1,
|
|
3081
|
+
500: 1.02,
|
|
3082
|
+
600: 1.05,
|
|
3083
|
+
700: 1.08,
|
|
3084
|
+
800: 1.1,
|
|
3085
|
+
900: 1.12
|
|
3086
|
+
};
|
|
3087
|
+
const weightFactor = WEIGHT_FACTORS[fontWeight] ?? 1;
|
|
3088
|
+
const charWidth = fontSize * AVG_CHAR_WIDTH * weightFactor;
|
|
3089
|
+
const maxChars = Math.floor(maxWidth / charWidth);
|
|
3090
|
+
if (text.length <= maxChars) return [text];
|
|
3091
|
+
const words = text.split(" ");
|
|
3092
|
+
const lines = [];
|
|
3093
|
+
let current = "";
|
|
3094
|
+
for (const word of words) {
|
|
3095
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
3096
|
+
if (candidate.length > maxChars && current) {
|
|
3097
|
+
lines.push(current);
|
|
3098
|
+
current = word;
|
|
3099
|
+
} else {
|
|
3100
|
+
current = candidate;
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
if (current) lines.push(current);
|
|
3104
|
+
return lines;
|
|
3105
|
+
}
|
|
2161
3106
|
function renderChromeElement(parent, element, className, chromeKey) {
|
|
2162
3107
|
const text = createSVGElement("text");
|
|
2163
3108
|
setAttrs(text, { x: element.x, y: element.y });
|
|
2164
3109
|
applyTextStyle(text, element.style);
|
|
2165
3110
|
text.setAttribute("class", className);
|
|
2166
3111
|
text.setAttribute("data-chrome-key", chromeKey);
|
|
2167
|
-
|
|
3112
|
+
const lines = wrapText(
|
|
3113
|
+
element.text,
|
|
3114
|
+
element.style.fontSize,
|
|
3115
|
+
element.style.fontWeight,
|
|
3116
|
+
element.maxWidth
|
|
3117
|
+
);
|
|
3118
|
+
if (lines.length === 1) {
|
|
3119
|
+
text.textContent = element.text;
|
|
3120
|
+
} else {
|
|
3121
|
+
const lineHeight = element.style.fontSize * (element.style.lineHeight ?? 1.3);
|
|
3122
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3123
|
+
const tspan = createSVGElement("tspan");
|
|
3124
|
+
setAttrs(tspan, { x: element.x, dy: i === 0 ? 0 : lineHeight });
|
|
3125
|
+
tspan.textContent = lines[i];
|
|
3126
|
+
text.appendChild(tspan);
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
2168
3129
|
parent.appendChild(text);
|
|
2169
3130
|
}
|
|
2170
3131
|
function renderChrome(parent, layout) {
|
|
@@ -2336,9 +3297,9 @@ var markRenderers = {};
|
|
|
2336
3297
|
function registerMarkRenderer(type, renderer) {
|
|
2337
3298
|
markRenderers[type] = renderer;
|
|
2338
3299
|
}
|
|
2339
|
-
function renderLineMark(mark,
|
|
3300
|
+
function renderLineMark(mark, index2) {
|
|
2340
3301
|
const g = createSVGElement("g");
|
|
2341
|
-
g.setAttribute("data-mark-id", `line-${mark.seriesKey ??
|
|
3302
|
+
g.setAttribute("data-mark-id", `line-${mark.seriesKey ?? index2}`);
|
|
2342
3303
|
g.setAttribute("class", "viz-mark viz-mark-line");
|
|
2343
3304
|
if (mark.points.length > 1) {
|
|
2344
3305
|
const path = createSVGElement("path");
|
|
@@ -2384,9 +3345,9 @@ function renderLineMark(mark, index) {
|
|
|
2384
3345
|
}
|
|
2385
3346
|
return g;
|
|
2386
3347
|
}
|
|
2387
|
-
function renderAreaMark(mark,
|
|
3348
|
+
function renderAreaMark(mark, index2) {
|
|
2388
3349
|
const g = createSVGElement("g");
|
|
2389
|
-
g.setAttribute("data-mark-id", `area-${mark.seriesKey ??
|
|
3350
|
+
g.setAttribute("data-mark-id", `area-${mark.seriesKey ?? index2}`);
|
|
2390
3351
|
g.setAttribute("class", "viz-mark viz-mark-area");
|
|
2391
3352
|
if (mark.path) {
|
|
2392
3353
|
const fill = createSVGElement("path");
|
|
@@ -2410,9 +3371,9 @@ function renderAreaMark(mark, index) {
|
|
|
2410
3371
|
}
|
|
2411
3372
|
return g;
|
|
2412
3373
|
}
|
|
2413
|
-
function renderRectMark(mark,
|
|
3374
|
+
function renderRectMark(mark, index2) {
|
|
2414
3375
|
const g = createSVGElement("g");
|
|
2415
|
-
g.setAttribute("data-mark-id", `rect-${
|
|
3376
|
+
g.setAttribute("data-mark-id", `rect-${index2}`);
|
|
2416
3377
|
g.setAttribute("class", "viz-mark viz-mark-rect");
|
|
2417
3378
|
const rect = createSVGElement("rect");
|
|
2418
3379
|
setAttrs(rect, {
|
|
@@ -2442,9 +3403,9 @@ function renderRectMark(mark, index) {
|
|
|
2442
3403
|
}
|
|
2443
3404
|
return g;
|
|
2444
3405
|
}
|
|
2445
|
-
function renderArcMark(mark,
|
|
3406
|
+
function renderArcMark(mark, index2) {
|
|
2446
3407
|
const g = createSVGElement("g");
|
|
2447
|
-
g.setAttribute("data-mark-id", `arc-${
|
|
3408
|
+
g.setAttribute("data-mark-id", `arc-${index2}`);
|
|
2448
3409
|
g.setAttribute("class", "viz-mark viz-mark-arc");
|
|
2449
3410
|
g.setAttribute("transform", `translate(${mark.center.x},${mark.center.y})`);
|
|
2450
3411
|
const path = createSVGElement("path");
|
|
@@ -2468,9 +3429,9 @@ function renderArcMark(mark, index) {
|
|
|
2468
3429
|
}
|
|
2469
3430
|
return g;
|
|
2470
3431
|
}
|
|
2471
|
-
function renderPointMark(mark,
|
|
3432
|
+
function renderPointMark(mark, index2) {
|
|
2472
3433
|
const circle = createSVGElement("circle");
|
|
2473
|
-
circle.setAttribute("data-mark-id", `point-${
|
|
3434
|
+
circle.setAttribute("data-mark-id", `point-${index2}`);
|
|
2474
3435
|
circle.setAttribute("class", "viz-mark viz-mark-point");
|
|
2475
3436
|
setAttrs(circle, {
|
|
2476
3437
|
cx: mark.cx,
|
|
@@ -2574,10 +3535,10 @@ function renderCurvedArrow(parent, from, to, stroke) {
|
|
|
2574
3535
|
});
|
|
2575
3536
|
parent.appendChild(arrow);
|
|
2576
3537
|
}
|
|
2577
|
-
function renderAnnotation(parent, annotation,
|
|
3538
|
+
function renderAnnotation(parent, annotation, index2) {
|
|
2578
3539
|
const g = createSVGElement("g");
|
|
2579
3540
|
g.setAttribute("class", `viz-annotation viz-annotation-${annotation.type}`);
|
|
2580
|
-
g.setAttribute("data-annotation-index", String(
|
|
3541
|
+
g.setAttribute("data-annotation-index", String(index2));
|
|
2581
3542
|
if (annotation.rect) {
|
|
2582
3543
|
const rect = createSVGElement("rect");
|
|
2583
3544
|
rect.setAttribute("class", "viz-annotation-range");
|
|
@@ -2611,9 +3572,9 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2611
3572
|
}
|
|
2612
3573
|
if (annotation.label?.visible) {
|
|
2613
3574
|
if (annotation.label.connector) {
|
|
2614
|
-
const
|
|
2615
|
-
if (
|
|
2616
|
-
const pointsDown =
|
|
3575
|
+
const c2 = annotation.label.connector;
|
|
3576
|
+
if (c2.style === "caret") {
|
|
3577
|
+
const pointsDown = c2.to.y > c2.from.y;
|
|
2617
3578
|
const caretSize = 4;
|
|
2618
3579
|
const labelLines = annotation.label.text.split("\n");
|
|
2619
3580
|
const labelFontSize = annotation.label.style.fontSize ?? 12;
|
|
@@ -2621,8 +3582,8 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2621
3582
|
const textBottom = annotation.label.y + (labelLines.length - 1) * labelLineHeight + labelFontSize * 0.25;
|
|
2622
3583
|
const textTop = annotation.label.y - labelFontSize;
|
|
2623
3584
|
const gapEdge = pointsDown ? textBottom : textTop;
|
|
2624
|
-
const midY = (gapEdge +
|
|
2625
|
-
const tipX =
|
|
3585
|
+
const midY = (gapEdge + c2.to.y) / 2;
|
|
3586
|
+
const tipX = c2.to.x;
|
|
2626
3587
|
const tipY = pointsDown ? midY + caretSize / 2 : midY - caretSize / 2;
|
|
2627
3588
|
const baseY = pointsDown ? tipY - caretSize : tipY + caretSize;
|
|
2628
3589
|
const path = createSVGElement("path");
|
|
@@ -2630,24 +3591,24 @@ function renderAnnotation(parent, annotation, index) {
|
|
|
2630
3591
|
setAttrs(path, {
|
|
2631
3592
|
d: `M${tipX - caretSize},${baseY} L${tipX},${tipY} L${tipX + caretSize},${baseY}`,
|
|
2632
3593
|
fill: "none",
|
|
2633
|
-
stroke:
|
|
3594
|
+
stroke: c2.stroke,
|
|
2634
3595
|
"stroke-width": 1.5,
|
|
2635
3596
|
"stroke-opacity": 0.4,
|
|
2636
3597
|
"stroke-linecap": "round",
|
|
2637
3598
|
"stroke-linejoin": "round"
|
|
2638
3599
|
});
|
|
2639
3600
|
g.appendChild(path);
|
|
2640
|
-
} else if (
|
|
2641
|
-
renderCurvedArrow(g,
|
|
3601
|
+
} else if (c2.style === "curve") {
|
|
3602
|
+
renderCurvedArrow(g, c2.from, c2.to, c2.stroke);
|
|
2642
3603
|
} else {
|
|
2643
3604
|
const connector = createSVGElement("line");
|
|
2644
3605
|
connector.setAttribute("class", "viz-annotation-connector");
|
|
2645
3606
|
setAttrs(connector, {
|
|
2646
|
-
x1:
|
|
2647
|
-
y1:
|
|
2648
|
-
x2:
|
|
2649
|
-
y2:
|
|
2650
|
-
stroke:
|
|
3607
|
+
x1: c2.from.x,
|
|
3608
|
+
y1: c2.from.y,
|
|
3609
|
+
x2: c2.to.x,
|
|
3610
|
+
y2: c2.to.y,
|
|
3611
|
+
stroke: c2.stroke,
|
|
2651
3612
|
"stroke-width": 1,
|
|
2652
3613
|
"stroke-opacity": 0.5
|
|
2653
3614
|
});
|
|
@@ -2802,12 +3763,12 @@ function renderBrand(parent, layout) {
|
|
|
2802
3763
|
const bottomOffset = layout.area.y + layout.area.height + xAxisExtent;
|
|
2803
3764
|
const firstBottom = chrome.source ?? chrome.byline ?? chrome.footer;
|
|
2804
3765
|
const chromeY = firstBottom ? bottomOffset + firstBottom.y : bottomOffset + layout.theme.spacing.chartToFooter;
|
|
2805
|
-
const
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
3766
|
+
const a2 = createSVGElement("a");
|
|
3767
|
+
a2.setAttribute("href", BRAND_URL);
|
|
3768
|
+
a2.setAttributeNS(XLINK_NS, "xlink:href", BRAND_URL);
|
|
3769
|
+
a2.setAttribute("target", "_blank");
|
|
3770
|
+
a2.setAttribute("rel", "noopener");
|
|
3771
|
+
a2.setAttribute("class", "viz-chrome-ref");
|
|
2811
3772
|
const text = createSVGElement("text");
|
|
2812
3773
|
setAttrs(text, {
|
|
2813
3774
|
x: rightEdge,
|
|
@@ -2827,8 +3788,8 @@ function renderBrand(parent, layout) {
|
|
|
2827
3788
|
dataSpan.setAttribute("font-weight", "600");
|
|
2828
3789
|
dataSpan.textContent = "Data";
|
|
2829
3790
|
text.appendChild(dataSpan);
|
|
2830
|
-
|
|
2831
|
-
parent.appendChild(
|
|
3791
|
+
a2.appendChild(text);
|
|
3792
|
+
parent.appendChild(a2);
|
|
2832
3793
|
}
|
|
2833
3794
|
function renderChartSVG(layout, container) {
|
|
2834
3795
|
const { width, height } = layout.dimensions;
|
|
@@ -2916,16 +3877,16 @@ function wireTooltipEvents(svg, tooltipDescriptors, tooltipManager) {
|
|
|
2916
3877
|
const handleMouseEnter = (e) => {
|
|
2917
3878
|
const mouseEvent = e;
|
|
2918
3879
|
const svgRect = svg.getBoundingClientRect();
|
|
2919
|
-
const
|
|
2920
|
-
const
|
|
2921
|
-
tooltipManager.show(content,
|
|
3880
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
3881
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
3882
|
+
tooltipManager.show(content, x3, y3);
|
|
2922
3883
|
};
|
|
2923
3884
|
const handleMouseMove = (e) => {
|
|
2924
3885
|
const mouseEvent = e;
|
|
2925
3886
|
const svgRect = svg.getBoundingClientRect();
|
|
2926
|
-
const
|
|
2927
|
-
const
|
|
2928
|
-
tooltipManager.show(content,
|
|
3887
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
3888
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
3889
|
+
tooltipManager.show(content, x3, y3);
|
|
2929
3890
|
};
|
|
2930
3891
|
const handleMouseLeave = () => {
|
|
2931
3892
|
tooltipManager.hide();
|
|
@@ -2935,9 +3896,9 @@ function wireTooltipEvents(svg, tooltipDescriptors, tooltipManager) {
|
|
|
2935
3896
|
if (touchEvent.touches.length > 0) {
|
|
2936
3897
|
const touch = touchEvent.touches[0];
|
|
2937
3898
|
const svgRect = svg.getBoundingClientRect();
|
|
2938
|
-
const
|
|
2939
|
-
const
|
|
2940
|
-
tooltipManager.show(content,
|
|
3899
|
+
const x3 = touch.clientX - svgRect.left;
|
|
3900
|
+
const y3 = touch.clientY - svgRect.top;
|
|
3901
|
+
tooltipManager.show(content, x3, y3);
|
|
2941
3902
|
}
|
|
2942
3903
|
};
|
|
2943
3904
|
el.addEventListener("mouseenter", handleMouseEnter);
|
|
@@ -3211,8 +4172,8 @@ function wireAnnotationDrag(svg, specAnnotations, onAnnotationEdit, onEdit, setD
|
|
|
3211
4172
|
for (const el of annotationElements) {
|
|
3212
4173
|
const indexStr = el.getAttribute("data-annotation-index");
|
|
3213
4174
|
if (indexStr === null) continue;
|
|
3214
|
-
const
|
|
3215
|
-
const specAnnotation = specAnnotations[
|
|
4175
|
+
const index2 = Number(indexStr);
|
|
4176
|
+
const specAnnotation = specAnnotations[index2];
|
|
3216
4177
|
if (!specAnnotation || specAnnotation.type !== "text") continue;
|
|
3217
4178
|
const textAnnotation = specAnnotation;
|
|
3218
4179
|
const annotationG = el;
|
|
@@ -3276,8 +4237,8 @@ function wireConnectorEndpointDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
|
3276
4237
|
const annotationG = el;
|
|
3277
4238
|
const indexStr = annotationG.getAttribute("data-annotation-index");
|
|
3278
4239
|
if (indexStr === null) continue;
|
|
3279
|
-
const
|
|
3280
|
-
const specAnnotation = specAnnotations[
|
|
4240
|
+
const index2 = Number(indexStr);
|
|
4241
|
+
const specAnnotation = specAnnotations[index2];
|
|
3281
4242
|
if (!specAnnotation || specAnnotation.type !== "text") continue;
|
|
3282
4243
|
const textAnnotation = specAnnotation;
|
|
3283
4244
|
const connectorLine = annotationG.querySelector("line.viz-annotation-connector");
|
|
@@ -3412,8 +4373,8 @@ function wireAnnotationLabelDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
|
3412
4373
|
if (!annotationG) continue;
|
|
3413
4374
|
const indexStr = annotationG.getAttribute("data-annotation-index");
|
|
3414
4375
|
if (indexStr === null) continue;
|
|
3415
|
-
const
|
|
3416
|
-
const specAnnotation = specAnnotations[
|
|
4376
|
+
const index2 = Number(indexStr);
|
|
4377
|
+
const specAnnotation = specAnnotations[index2];
|
|
3417
4378
|
if (!specAnnotation) continue;
|
|
3418
4379
|
const labelEl = label;
|
|
3419
4380
|
labelEl.style.cursor = "grab";
|
|
@@ -3618,12 +4579,12 @@ function wireKeyboardNav(svg, container, tooltipDescriptors, tooltipManager, lay
|
|
|
3618
4579
|
}
|
|
3619
4580
|
}
|
|
3620
4581
|
let focusIndex = -1;
|
|
3621
|
-
function highlightMark(
|
|
4582
|
+
function highlightMark(index2) {
|
|
3622
4583
|
if (focusIndex >= 0 && focusIndex < markElements.length) {
|
|
3623
4584
|
markElements[focusIndex].classList.remove("viz-mark-focused");
|
|
3624
4585
|
markElements[focusIndex].removeAttribute("aria-selected");
|
|
3625
4586
|
}
|
|
3626
|
-
focusIndex =
|
|
4587
|
+
focusIndex = index2;
|
|
3627
4588
|
if (focusIndex >= 0 && focusIndex < markElements.length) {
|
|
3628
4589
|
const el = markElements[focusIndex];
|
|
3629
4590
|
el.classList.add("viz-mark-focused");
|
|
@@ -3639,9 +4600,9 @@ function wireKeyboardNav(svg, container, tooltipDescriptors, tooltipManager, lay
|
|
|
3639
4600
|
if (!content) return;
|
|
3640
4601
|
const bbox = el.getBoundingClientRect();
|
|
3641
4602
|
const containerRect = container.getBoundingClientRect();
|
|
3642
|
-
const
|
|
3643
|
-
const
|
|
3644
|
-
tooltipManager.show(content,
|
|
4603
|
+
const x3 = bbox.left + bbox.width / 2 - containerRect.left;
|
|
4604
|
+
const y3 = bbox.top - containerRect.top;
|
|
4605
|
+
tooltipManager.show(content, x3, y3);
|
|
3645
4606
|
}
|
|
3646
4607
|
const handleKeyDown = (e) => {
|
|
3647
4608
|
if (markElements.length === 0) return;
|
|
@@ -3979,7 +4940,7 @@ function applyCellStyle(td, cell) {
|
|
|
3979
4940
|
}
|
|
3980
4941
|
}
|
|
3981
4942
|
function countryToEmoji(code) {
|
|
3982
|
-
return [...code.toUpperCase()].map((
|
|
4943
|
+
return [...code.toUpperCase()].map((c2) => String.fromCodePoint(c2.charCodeAt(0) + 127397)).join("");
|
|
3983
4944
|
}
|
|
3984
4945
|
var COUNTRY_NAMES = {
|
|
3985
4946
|
US: "United States",
|
|
@@ -4178,11 +5139,11 @@ function renderSparklineCell(cell) {
|
|
|
4178
5139
|
const barW = Math.max(1, (innerW - gap * (barCount - 1)) / barCount);
|
|
4179
5140
|
for (let i = 0; i < barCount; i++) {
|
|
4180
5141
|
const barH = Math.max(1, sparklineData.bars[i] * innerH);
|
|
4181
|
-
const
|
|
4182
|
-
const
|
|
5142
|
+
const x3 = padding + i * (barW + gap);
|
|
5143
|
+
const y3 = padding + innerH - barH;
|
|
4183
5144
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4184
|
-
rect.setAttribute("x", String(
|
|
4185
|
-
rect.setAttribute("y", String(
|
|
5145
|
+
rect.setAttribute("x", String(x3));
|
|
5146
|
+
rect.setAttribute("y", String(y3));
|
|
4186
5147
|
rect.setAttribute("width", String(barW));
|
|
4187
5148
|
rect.setAttribute("height", String(barH));
|
|
4188
5149
|
rect.setAttribute("rx", "1.5");
|
|
@@ -4208,11 +5169,11 @@ function renderSparklineCell(cell) {
|
|
|
4208
5169
|
const barH = Math.max(1, (innerH - gap * (barCount - 1)) / barCount);
|
|
4209
5170
|
for (let i = 0; i < barCount; i++) {
|
|
4210
5171
|
const barW = Math.max(1, sparklineData.bars[i] * innerW);
|
|
4211
|
-
const
|
|
4212
|
-
const
|
|
5172
|
+
const x3 = padding;
|
|
5173
|
+
const y3 = padding + i * (barH + gap);
|
|
4213
5174
|
const rect = document.createElementNS(svgNS, "rect");
|
|
4214
|
-
rect.setAttribute("x", String(
|
|
4215
|
-
rect.setAttribute("y", String(
|
|
5175
|
+
rect.setAttribute("x", String(x3));
|
|
5176
|
+
rect.setAttribute("y", String(y3));
|
|
4216
5177
|
rect.setAttribute("width", String(barW));
|
|
4217
5178
|
rect.setAttribute("height", String(barH));
|
|
4218
5179
|
rect.setAttribute("rx", "1.5");
|
|
@@ -4547,12 +5508,12 @@ function renderTbody(rows, columns) {
|
|
|
4547
5508
|
const tr = document.createElement("tr");
|
|
4548
5509
|
tr.setAttribute("role", "row");
|
|
4549
5510
|
tr.setAttribute("data-row-id", row.id);
|
|
4550
|
-
for (let
|
|
4551
|
-
const cell = row.cells[
|
|
5511
|
+
for (let c2 = 0; c2 < columns.length; c2++) {
|
|
5512
|
+
const cell = row.cells[c2];
|
|
4552
5513
|
if (!cell) continue;
|
|
4553
5514
|
const td = renderCell(cell);
|
|
4554
5515
|
td.setAttribute("role", "gridcell");
|
|
4555
|
-
td.style.textAlign = columns[
|
|
5516
|
+
td.style.textAlign = columns[c2].align;
|
|
4556
5517
|
tr.appendChild(td);
|
|
4557
5518
|
}
|
|
4558
5519
|
tbody.appendChild(tr);
|
|
@@ -4990,7 +5951,7 @@ function createTable(container, spec, options) {
|
|
|
4990
5951
|
search: state.search || void 0
|
|
4991
5952
|
// No page/pageSize: get all rows
|
|
4992
5953
|
});
|
|
4993
|
-
const headers = fullLayout.columns.map((
|
|
5954
|
+
const headers = fullLayout.columns.map((c2) => c2.label);
|
|
4994
5955
|
const csvRows = [headers.map(csvEscape2).join(",")];
|
|
4995
5956
|
for (const row of fullLayout.rows) {
|
|
4996
5957
|
const values = row.cells.map((cell) => csvEscape2(cell.formattedValue));
|