@cocorof/graphier 1.3.3 → 1.4.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/README.md +26 -0
- package/dist/index.cjs +585 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +104 -0
- package/dist/index.js +585 -51
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -44,7 +44,10 @@ const DEFAULT_LAYOUT = {
|
|
|
44
44
|
alphaDecay: "auto",
|
|
45
45
|
velocityDecay: 0.4,
|
|
46
46
|
settledThreshold: 5e-3,
|
|
47
|
-
spreadFactor: "auto"
|
|
47
|
+
spreadFactor: "auto",
|
|
48
|
+
dimensions: 3,
|
|
49
|
+
clusterBy: null,
|
|
50
|
+
clusterStrength: 0.05
|
|
48
51
|
};
|
|
49
52
|
function hexToRgb(hex) {
|
|
50
53
|
const c2 = hex.replace("#", "");
|
|
@@ -56,6 +59,14 @@ function rgbToHex(r, g, b) {
|
|
|
56
59
|
const hex = clamp(r) << 16 | clamp(g) << 8 | clamp(b);
|
|
57
60
|
return "#" + hex.toString(16).padStart(6, "0");
|
|
58
61
|
}
|
|
62
|
+
function luminance(hex) {
|
|
63
|
+
const [r, g, b] = hexToRgb(hex);
|
|
64
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
65
|
+
}
|
|
66
|
+
function darken(hex, factor) {
|
|
67
|
+
const [r, g, b] = hexToRgb(hex);
|
|
68
|
+
return rgbToHex(r * factor, g * factor, b * factor);
|
|
69
|
+
}
|
|
59
70
|
function brighten(hex, factor) {
|
|
60
71
|
const [r, g, b] = hexToRgb(hex);
|
|
61
72
|
const t = 1 - 1 / factor;
|
|
@@ -137,10 +148,40 @@ const minimal = {
|
|
|
137
148
|
defaultLinkColor: "#444444",
|
|
138
149
|
backgroundColor: "#1a1a2e"
|
|
139
150
|
};
|
|
151
|
+
const paper = {
|
|
152
|
+
nodeColors: {},
|
|
153
|
+
// Bright (label / highlight) colors are auto-derived: on a light
|
|
154
|
+
// background resolveTheme darkens instead of whitening.
|
|
155
|
+
nodeColorsBright: {},
|
|
156
|
+
linkColors: {},
|
|
157
|
+
defaultNodeColor: "#64748b",
|
|
158
|
+
defaultLinkColor: "#b3bdcc",
|
|
159
|
+
backgroundColor: "#f6f7f9",
|
|
160
|
+
blending: "normal",
|
|
161
|
+
palette: [
|
|
162
|
+
"#2563eb",
|
|
163
|
+
// blue
|
|
164
|
+
"#d97706",
|
|
165
|
+
// amber
|
|
166
|
+
"#7c3aed",
|
|
167
|
+
// violet
|
|
168
|
+
"#db2777",
|
|
169
|
+
// pink
|
|
170
|
+
"#0891b2",
|
|
171
|
+
// cyan
|
|
172
|
+
"#16a34a",
|
|
173
|
+
// green
|
|
174
|
+
"#dc2626",
|
|
175
|
+
// red
|
|
176
|
+
"#475569"
|
|
177
|
+
// slate
|
|
178
|
+
]
|
|
179
|
+
};
|
|
140
180
|
const PRESETS = {
|
|
141
181
|
celestial,
|
|
142
182
|
neon,
|
|
143
|
-
minimal
|
|
183
|
+
minimal,
|
|
184
|
+
paper
|
|
144
185
|
};
|
|
145
186
|
const DEFAULT_THEME = {
|
|
146
187
|
nodeColors: celestial.nodeColors ?? {},
|
|
@@ -168,6 +209,8 @@ function resolveTheme(theme) {
|
|
|
168
209
|
const defaultLinkColor = config.defaultLinkColor ?? DEFAULT_THEME.defaultLinkColor;
|
|
169
210
|
const backgroundColor = config.backgroundColor ?? DEFAULT_THEME.backgroundColor;
|
|
170
211
|
const palette = config.palette ?? DEFAULT_THEME.palette;
|
|
212
|
+
const isLight = luminance(backgroundColor) > 0.5;
|
|
213
|
+
const additiveEdges = config.blending ? config.blending === "additive" : !isLight;
|
|
171
214
|
const autoAssigned = /* @__PURE__ */ new Map();
|
|
172
215
|
let nextPaletteIdx = 0;
|
|
173
216
|
function nodeColor(type) {
|
|
@@ -179,16 +222,24 @@ function resolveTheme(theme) {
|
|
|
179
222
|
}
|
|
180
223
|
return palette[autoAssigned.get(type)];
|
|
181
224
|
}
|
|
225
|
+
const emphasize = (c2) => isLight ? darken(c2, 0.72) : brighten(c2, 1.5);
|
|
182
226
|
function nodeColorBright(type) {
|
|
183
|
-
if (!type) return
|
|
227
|
+
if (!type) return emphasize(defaultNodeColor);
|
|
184
228
|
if (nodeColorsBright[type]) return nodeColorsBright[type];
|
|
185
|
-
return
|
|
229
|
+
return emphasize(nodeColor(type));
|
|
186
230
|
}
|
|
187
231
|
function linkColor(type) {
|
|
188
232
|
if (!type) return defaultLinkColor;
|
|
189
233
|
return linkColors[type] ?? defaultLinkColor;
|
|
190
234
|
}
|
|
191
|
-
return {
|
|
235
|
+
return {
|
|
236
|
+
nodeColor,
|
|
237
|
+
nodeColorBright,
|
|
238
|
+
linkColor,
|
|
239
|
+
backgroundColor,
|
|
240
|
+
isLight,
|
|
241
|
+
additiveEdges
|
|
242
|
+
};
|
|
192
243
|
}
|
|
193
244
|
function autoSpreadFactor(n) {
|
|
194
245
|
if (n <= 500) return 1;
|
|
@@ -211,6 +262,8 @@ function resolveLayoutParams(nodeCount, config) {
|
|
|
211
262
|
const postEvery = n > 5e4 ? 5 : n > 1e4 ? 3 : 2;
|
|
212
263
|
const initialRadius2 = (500 + Math.min(n, 1e4) * 0.1) * spread;
|
|
213
264
|
return {
|
|
265
|
+
dimensions: (config == null ? void 0 : config.dimensions) === 2 ? 2 : 3,
|
|
266
|
+
clusterStrength: (config == null ? void 0 : config.clusterStrength) ?? 0.05,
|
|
214
267
|
charge,
|
|
215
268
|
distanceMax,
|
|
216
269
|
theta,
|
|
@@ -222,7 +275,7 @@ function resolveLayoutParams(nodeCount, config) {
|
|
|
222
275
|
initialRadius: initialRadius2
|
|
223
276
|
};
|
|
224
277
|
}
|
|
225
|
-
const WORKER_SOURCE = '(function(){"use strict";function At(t,n,i){var e,r=1;t==null&&(t=0),n==null&&(n=0),i==null&&(i=0);function s(){var a,o=e.length,h,u=0,c=0,l=0;for(a=0;a<o;++a)h=e[a],u+=h.x||0,c+=h.y||0,l+=h.z||0;for(u=(u/o-t)*r,c=(c/o-n)*r,l=(l/o-i)*r,a=0;a<o;++a)h=e[a],u&&(h.x-=u),c&&(h.y-=c),l&&(h.z-=l)}return s.initialize=function(a){e=a},s.x=function(a){return arguments.length?(t=+a,s):t},s.y=function(a){return arguments.length?(n=+a,s):n},s.z=function(a){return arguments.length?(i=+a,s):i},s.strength=function(a){return arguments.length?(r=+a,s):r},s}function $t(t){const n=+this._x.call(null,t);return et(this.cover(n),n,t)}function et(t,n,i){if(isNaN(n))return t;var e,r=t._root,s={data:i},a=t._x0,o=t._x1,h,u,c,l,v;if(!r)return t._root=s,t;for(;r.length;)if((c=n>=(h=(a+o)/2))?a=h:o=h,e=r,!(r=r[l=+c]))return e[l]=s,t;if(u=+t._x.call(null,r.data),n===u)return s.next=r,e?e[l]=s:t._root=s,t;do e=e?e[l]=new Array(2):t._root=new Array(2),(c=n>=(h=(a+o)/2))?a=h:o=h;while((l=+c)==(v=+(u>=h)));return e[v]=r,e[l]=s,t}function mt(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n);let e=1/0,r=-1/0;for(let s=0,a;s<n;++s)isNaN(a=+this._x.call(null,t[s]))||(i[s]=a,a<e&&(e=a),a>r&&(r=a));if(e>r)return this;this.cover(e).cover(r);for(let s=0;s<n;++s)et(this,i[s],t[s]);return this}function qt(t){if(isNaN(t=+t))return this;var n=this._x0,i=this._x1;if(isNaN(n))i=(n=Math.floor(t))+1;else{for(var e=i-n||1,r=this._root,s,a;n>t||t>=i;)switch(a=+(t<n),s=new Array(2),s[a]=r,r=s,e*=2,a){case 0:i=n+e;break;case 1:n=i-e;break}this._root&&this._root.length&&(this._root=r)}return this._x0=n,this._x1=i,this}function It(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function bt(t){return arguments.length?this.cover(+t[0][0]).cover(+t[1][0]):isNaN(this._x0)?void 0:[[this._x0],[this._x1]]}function j(t,n,i){this.node=t,this.x0=n,this.x1=i}function kt(t,n){var i,e=this._x0,r,s,a=this._x1,o=[],h=this._root,u,c;for(h&&o.push(new j(h,e,a)),n==null?n=1/0:(e=t-n,a=t+n);u=o.pop();)if(!(!(h=u.node)||(r=u.x0)>a||(s=u.x1)<e))if(h.length){var l=(r+s)/2;o.push(new j(h[1],l,s),new j(h[0],r,l)),(c=+(t>=l))&&(u=o[o.length-1],o[o.length-1]=o[o.length-1-c],o[o.length-1-c]=u)}else{var v=Math.abs(t-+this._x.call(null,h.data));v<n&&(n=v,e=t-v,a=t+v,i=h.data)}return i}function Dt(t){if(isNaN(h=+this._x.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._x1,h,u,c,l,v;if(!i)return this;if(i.length)for(;;){if((c=h>=(u=(a+o)/2))?a=u:o=u,n=i,!(i=i[l=+c]))return this;if(!i.length)break;n[l+1&1]&&(e=n,v=l)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[l]=s:delete n[l],(i=n[0]||n[1])&&i===(n[1]||n[0])&&!i.length&&(e?e[v]=i:this._root=i),this):(this._root=s,this)}function Et(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Tt(){return this._root}function jt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Pt(t){var n=[],i,e=this._root,r,s,a;for(e&&n.push(new j(e,this._x0,this._x1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.x1)&&e.length){var o=(s+a)/2;(r=e[1])&&n.push(new j(r,o,a)),(r=e[0])&&n.push(new j(r,s,o))}return this}function Ft(t){var n=[],i=[],e;for(this._root&&n.push(new j(this._root,this._x0,this._x1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.x1,h=(a+o)/2;(s=r[0])&&n.push(new j(s,a,h)),(s=r[1])&&n.push(new j(s,h,o))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.x1);return this}function Ot(t){return t[0]}function St(t){return arguments.length?(this._x=t,this):this._x}function rt(t,n){var i=new G(n??Ot,NaN,NaN);return t==null?i:i.addAll(t)}function G(t,n,i){this._x=t,this._x0=n,this._x1=i,this._root=void 0}function st(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var k=rt.prototype=G.prototype;k.copy=function(){var t=new G(this._x,this._x0,this._x1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=st(n),t;for(i=[{source:n,target:t._root=new Array(2)}];n=i.pop();)for(var r=0;r<2;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(2)}):n.target[r]=st(e));return t},k.add=$t,k.addAll=mt,k.cover=qt,k.data=It,k.extent=bt,k.find=kt,k.remove=Dt,k.removeAll=Et,k.root=Tt,k.size=jt,k.visit=Pt,k.visitAfter=Ft,k.x=St;function Rt(t){const n=+this._x.call(null,t),i=+this._y.call(null,t);return at(this.cover(n,i),n,i,t)}function at(t,n,i,e){if(isNaN(n)||isNaN(i))return t;var r,s=t._root,a={data:e},o=t._x0,h=t._y0,u=t._x1,c=t._y1,l,v,y,_,N,p,f,d;if(!s)return t._root=a,t;for(;s.length;)if((N=n>=(l=(o+u)/2))?o=l:u=l,(p=i>=(v=(h+c)/2))?h=v:c=v,r=s,!(s=s[f=p<<1|N]))return r[f]=a,t;if(y=+t._x.call(null,s.data),_=+t._y.call(null,s.data),n===y&&i===_)return a.next=s,r?r[f]=a:t._root=a,t;do r=r?r[f]=new Array(4):t._root=new Array(4),(N=n>=(l=(o+u)/2))?o=l:u=l,(p=i>=(v=(h+c)/2))?h=v:c=v;while((f=p<<1|N)===(d=(_>=v)<<1|y>=l));return r[d]=s,r[f]=a,t}function Xt(t){var n,i,e=t.length,r,s,a=new Array(e),o=new Array(e),h=1/0,u=1/0,c=-1/0,l=-1/0;for(i=0;i<e;++i)isNaN(r=+this._x.call(null,n=t[i]))||isNaN(s=+this._y.call(null,n))||(a[i]=r,o[i]=s,r<h&&(h=r),r>c&&(c=r),s<u&&(u=s),s>l&&(l=s));if(h>c||u>l)return this;for(this.cover(h,u).cover(c,l),i=0;i<e;++i)at(this,a[i],o[i],t[i]);return this}function Bt(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var i=this._x0,e=this._y0,r=this._x1,s=this._y1;if(isNaN(i))r=(i=Math.floor(t))+1,s=(e=Math.floor(n))+1;else{for(var a=r-i||1,o=this._root,h,u;i>t||t>=r||e>n||n>=s;)switch(u=(n<e)<<1|t<i,h=new Array(4),h[u]=o,o=h,a*=2,u){case 0:r=i+a,s=e+a;break;case 1:i=r-a,s=e+a;break;case 2:r=i+a,e=s-a;break;case 3:i=r-a,e=s-a;break}this._root&&this._root.length&&(this._root=o)}return this._x0=i,this._y0=e,this._x1=r,this._y1=s,this}function Ct(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function Lt(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function I(t,n,i,e,r){this.node=t,this.x0=n,this.y0=i,this.x1=e,this.y1=r}function Yt(t,n,i){var e,r=this._x0,s=this._y0,a,o,h,u,c=this._x1,l=this._y1,v=[],y=this._root,_,N;for(y&&v.push(new I(y,r,s,c,l)),i==null?i=1/0:(r=t-i,s=n-i,c=t+i,l=n+i,i*=i);_=v.pop();)if(!(!(y=_.node)||(a=_.x0)>c||(o=_.y0)>l||(h=_.x1)<r||(u=_.y1)<s))if(y.length){var p=(a+h)/2,f=(o+u)/2;v.push(new I(y[3],p,f,h,u),new I(y[2],a,f,p,u),new I(y[1],p,o,h,f),new I(y[0],a,o,p,f)),(N=(n>=f)<<1|t>=p)&&(_=v[v.length-1],v[v.length-1]=v[v.length-1-N],v[v.length-1-N]=_)}else{var d=t-+this._x.call(null,y.data),w=n-+this._y.call(null,y.data),g=d*d+w*w;if(g<i){var x=Math.sqrt(i=g);r=t-x,s=n-x,c=t+x,l=n+x,e=y.data}}return e}function Ht(t){if(isNaN(c=+this._x.call(null,t))||isNaN(l=+this._y.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._y0,h=this._x1,u=this._y1,c,l,v,y,_,N,p,f;if(!i)return this;if(i.length)for(;;){if((_=c>=(v=(a+h)/2))?a=v:h=v,(N=l>=(y=(o+u)/2))?o=y:u=y,n=i,!(i=i[p=N<<1|_]))return this;if(!i.length)break;(n[p+1&3]||n[p+2&3]||n[p+3&3])&&(e=n,f=p)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[p]=s:delete n[p],(i=n[0]||n[1]||n[2]||n[3])&&i===(n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[f]=i:this._root=i),this):(this._root=s,this)}function Qt(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Wt(){return this._root}function Zt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Gt(t){var n=[],i,e=this._root,r,s,a,o,h;for(e&&n.push(new I(e,this._x0,this._y0,this._x1,this._y1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.y0,o=i.x1,h=i.y1)&&e.length){var u=(s+o)/2,c=(a+h)/2;(r=e[3])&&n.push(new I(r,u,c,o,h)),(r=e[2])&&n.push(new I(r,s,c,u,h)),(r=e[1])&&n.push(new I(r,u,a,o,c)),(r=e[0])&&n.push(new I(r,s,a,u,c))}return this}function Jt(t){var n=[],i=[],e;for(this._root&&n.push(new I(this._root,this._x0,this._y0,this._x1,this._y1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.y0,h=e.x1,u=e.y1,c=(a+h)/2,l=(o+u)/2;(s=r[0])&&n.push(new I(s,a,o,c,l)),(s=r[1])&&n.push(new I(s,c,o,h,l)),(s=r[2])&&n.push(new I(s,a,l,c,u)),(s=r[3])&&n.push(new I(s,c,l,h,u))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.x1,e.y1);return this}function Kt(t){return t[0]}function Ut(t){return arguments.length?(this._x=t,this):this._x}function Vt(t){return t[1]}function tn(t){return arguments.length?(this._y=t,this):this._y}function ht(t,n,i){var e=new J(n??Kt,i??Vt,NaN,NaN,NaN,NaN);return t==null?e:e.addAll(t)}function J(t,n,i,e,r,s){this._x=t,this._y=n,this._x0=i,this._y0=e,this._x1=r,this._y1=s,this._root=void 0}function ot(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var b=ht.prototype=J.prototype;b.copy=function(){var t=new J(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=ot(n),t;for(i=[{source:n,target:t._root=new Array(4)}];n=i.pop();)for(var r=0;r<4;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(4)}):n.target[r]=ot(e));return t},b.add=Rt,b.addAll=Xt,b.cover=Bt,b.data=Ct,b.extent=Lt,b.find=Yt,b.remove=Ht,b.removeAll=Qt,b.root=Wt,b.size=Zt,b.visit=Gt,b.visitAfter=Jt,b.x=Ut,b.y=tn;function nn(t){const n=+this._x.call(null,t),i=+this._y.call(null,t),e=+this._z.call(null,t);return ft(this.cover(n,i,e),n,i,e,t)}function ft(t,n,i,e,r){if(isNaN(n)||isNaN(i)||isNaN(e))return t;var s,a=t._root,o={data:r},h=t._x0,u=t._y0,c=t._z0,l=t._x1,v=t._y1,y=t._z1,_,N,p,f,d,w,g,x,M,z,A;if(!a)return t._root=o,t;for(;a.length;)if((g=n>=(_=(h+l)/2))?h=_:l=_,(x=i>=(N=(u+v)/2))?u=N:v=N,(M=e>=(p=(c+y)/2))?c=p:y=p,s=a,!(a=a[z=M<<2|x<<1|g]))return s[z]=o,t;if(f=+t._x.call(null,a.data),d=+t._y.call(null,a.data),w=+t._z.call(null,a.data),n===f&&i===d&&e===w)return o.next=a,s?s[z]=o:t._root=o,t;do s=s?s[z]=new Array(8):t._root=new Array(8),(g=n>=(_=(h+l)/2))?h=_:l=_,(x=i>=(N=(u+v)/2))?u=N:v=N,(M=e>=(p=(c+y)/2))?c=p:y=p;while((z=M<<2|x<<1|g)===(A=(w>=p)<<2|(d>=N)<<1|f>=_));return s[A]=a,s[z]=o,t}function en(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n),e=new Float64Array(n),r=new Float64Array(n);let s=1/0,a=1/0,o=1/0,h=-1/0,u=-1/0,c=-1/0;for(let l=0,v,y,_,N;l<n;++l)isNaN(y=+this._x.call(null,v=t[l]))||isNaN(_=+this._y.call(null,v))||isNaN(N=+this._z.call(null,v))||(i[l]=y,e[l]=_,r[l]=N,y<s&&(s=y),y>h&&(h=y),_<a&&(a=_),_>u&&(u=_),N<o&&(o=N),N>c&&(c=N));if(s>h||a>u||o>c)return this;this.cover(s,a,o).cover(h,u,c);for(let l=0;l<n;++l)ft(this,i[l],e[l],r[l],t[l]);return this}function rn(t,n,i){if(isNaN(t=+t)||isNaN(n=+n)||isNaN(i=+i))return this;var e=this._x0,r=this._y0,s=this._z0,a=this._x1,o=this._y1,h=this._z1;if(isNaN(e))a=(e=Math.floor(t))+1,o=(r=Math.floor(n))+1,h=(s=Math.floor(i))+1;else{for(var u=a-e||1,c=this._root,l,v;e>t||t>=a||r>n||n>=o||s>i||i>=h;)switch(v=(i<s)<<2|(n<r)<<1|t<e,l=new Array(8),l[v]=c,c=l,u*=2,v){case 0:a=e+u,o=r+u,h=s+u;break;case 1:e=a-u,o=r+u,h=s+u;break;case 2:a=e+u,r=o-u,h=s+u;break;case 3:e=a-u,r=o-u,h=s+u;break;case 4:a=e+u,o=r+u,s=h-u;break;case 5:e=a-u,o=r+u,s=h-u;break;case 6:a=e+u,r=o-u,s=h-u;break;case 7:e=a-u,r=o-u,s=h-u;break}this._root&&this._root.length&&(this._root=c)}return this._x0=e,this._y0=r,this._z0=s,this._x1=a,this._y1=o,this._z1=h,this}function sn(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function an(t){return arguments.length?this.cover(+t[0][0],+t[0][1],+t[0][2]).cover(+t[1][0],+t[1][1],+t[1][2]):isNaN(this._x0)?void 0:[[this._x0,this._y0,this._z0],[this._x1,this._y1,this._z1]]}function $(t,n,i,e,r,s,a){this.node=t,this.x0=n,this.y0=i,this.z0=e,this.x1=r,this.y1=s,this.z1=a}function hn(t,n,i,e){var r,s=this._x0,a=this._y0,o=this._z0,h,u,c,l,v,y,_=this._x1,N=this._y1,p=this._z1,f=[],d=this._root,w,g;for(d&&f.push(new $(d,s,a,o,_,N,p)),e==null?e=1/0:(s=t-e,a=n-e,o=i-e,_=t+e,N=n+e,p=i+e,e*=e);w=f.pop();)if(!(!(d=w.node)||(h=w.x0)>_||(u=w.y0)>N||(c=w.z0)>p||(l=w.x1)<s||(v=w.y1)<a||(y=w.z1)<o))if(d.length){var x=(h+l)/2,M=(u+v)/2,z=(c+y)/2;f.push(new $(d[7],x,M,z,l,v,y),new $(d[6],h,M,z,x,v,y),new $(d[5],x,u,z,l,M,y),new $(d[4],h,u,z,x,M,y),new $(d[3],x,M,c,l,v,z),new $(d[2],h,M,c,x,v,z),new $(d[1],x,u,c,l,M,z),new $(d[0],h,u,c,x,M,z)),(g=(i>=z)<<2|(n>=M)<<1|t>=x)&&(w=f[f.length-1],f[f.length-1]=f[f.length-1-g],f[f.length-1-g]=w)}else{var A=t-+this._x.call(null,d.data),E=n-+this._y.call(null,d.data),T=i-+this._z.call(null,d.data),D=A*A+E*E+T*T;if(D<e){var m=Math.sqrt(e=D);s=t-m,a=n-m,o=i-m,_=t+m,N=n+m,p=i+m,r=d.data}}return r}const on=(t,n,i,e,r,s)=>Math.sqrt((t-e)**2+(n-r)**2+(i-s)**2);function fn(t,n,i,e){const r=[],s=t-e,a=n-e,o=i-e,h=t+e,u=n+e,c=i+e;return this.visit((l,v,y,_,N,p,f)=>{if(!l.length)do{const d=l.data;on(t,n,i,this._x(d),this._y(d),this._z(d))<=e&&r.push(d)}while(l=l.next);return v>h||y>u||_>c||N<s||p<a||f<o}),r}function un(t){if(isNaN(v=+this._x.call(null,t))||isNaN(y=+this._y.call(null,t))||isNaN(_=+this._z.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._y0,h=this._z0,u=this._x1,c=this._y1,l=this._z1,v,y,_,N,p,f,d,w,g,x,M;if(!i)return this;if(i.length)for(;;){if((d=v>=(N=(a+u)/2))?a=N:u=N,(w=y>=(p=(o+c)/2))?o=p:c=p,(g=_>=(f=(h+l)/2))?h=f:l=f,n=i,!(i=i[x=g<<2|w<<1|d]))return this;if(!i.length)break;(n[x+1&7]||n[x+2&7]||n[x+3&7]||n[x+4&7]||n[x+5&7]||n[x+6&7]||n[x+7&7])&&(e=n,M=x)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[x]=s:delete n[x],(i=n[0]||n[1]||n[2]||n[3]||n[4]||n[5]||n[6]||n[7])&&i===(n[7]||n[6]||n[5]||n[4]||n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[M]=i:this._root=i),this):(this._root=s,this)}function ln(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function cn(){return this._root}function _n(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function vn(t){var n=[],i,e=this._root,r,s,a,o,h,u,c;for(e&&n.push(new $(e,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.y0,o=i.z0,h=i.x1,u=i.y1,c=i.z1)&&e.length){var l=(s+h)/2,v=(a+u)/2,y=(o+c)/2;(r=e[7])&&n.push(new $(r,l,v,y,h,u,c)),(r=e[6])&&n.push(new $(r,s,v,y,l,u,c)),(r=e[5])&&n.push(new $(r,l,a,y,h,v,c)),(r=e[4])&&n.push(new $(r,s,a,y,l,v,c)),(r=e[3])&&n.push(new $(r,l,v,o,h,u,y)),(r=e[2])&&n.push(new $(r,s,v,o,l,u,y)),(r=e[1])&&n.push(new $(r,l,a,o,h,v,y)),(r=e[0])&&n.push(new $(r,s,a,o,l,v,y))}return this}function xn(t){var n=[],i=[],e;for(this._root&&n.push(new $(this._root,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.y0,h=e.z0,u=e.x1,c=e.y1,l=e.z1,v=(a+u)/2,y=(o+c)/2,_=(h+l)/2;(s=r[0])&&n.push(new $(s,a,o,h,v,y,_)),(s=r[1])&&n.push(new $(s,v,o,h,u,y,_)),(s=r[2])&&n.push(new $(s,a,y,h,v,c,_)),(s=r[3])&&n.push(new $(s,v,y,h,u,c,_)),(s=r[4])&&n.push(new $(s,a,o,_,v,y,l)),(s=r[5])&&n.push(new $(s,v,o,_,u,y,l)),(s=r[6])&&n.push(new $(s,a,y,_,v,c,l)),(s=r[7])&&n.push(new $(s,v,y,_,u,c,l))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.z0,e.x1,e.y1,e.z1);return this}function yn(t){return t[0]}function pn(t){return arguments.length?(this._x=t,this):this._x}function gn(t){return t[1]}function wn(t){return arguments.length?(this._y=t,this):this._y}function dn(t){return t[2]}function Nn(t){return arguments.length?(this._z=t,this):this._z}function ut(t,n,i,e){var r=new K(n??yn,i??gn,e??dn,NaN,NaN,NaN,NaN,NaN,NaN);return t==null?r:r.addAll(t)}function K(t,n,i,e,r,s,a,o,h){this._x=t,this._y=n,this._z=i,this._x0=e,this._y0=r,this._z0=s,this._x1=a,this._y1=o,this._z1=h,this._root=void 0}function lt(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var q=ut.prototype=K.prototype;q.copy=function(){var t=new K(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=lt(n),t;for(i=[{source:n,target:t._root=new Array(8)}];n=i.pop();)for(var r=0;r<8;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(8)}):n.target[r]=lt(e));return t},q.add=nn,q.addAll=en,q.cover=rn,q.data=sn,q.extent=an,q.find=hn,q.findAllWithinRadius=fn,q.remove=un,q.removeAll=ln,q.root=cn,q.size=_n,q.visit=vn,q.visitAfter=xn,q.x=pn,q.y=wn,q.z=Nn;function R(t){return function(){return t}}function P(t){return(t()-.5)*1e-6}function Mn(t){return t.index}function ct(t,n){var i=t.get(n);if(!i)throw new Error("node not found: "+n);return i}function zn(t){var n=Mn,i=v,e,r=R(30),s,a,o,h,u,c,l=1;t==null&&(t=[]);function v(f){return 1/Math.min(h[f.source.index],h[f.target.index])}function y(f){for(var d=0,w=t.length;d<l;++d)for(var g=0,x,M,z,A=0,E=0,T=0,D,m;g<w;++g)x=t[g],M=x.source,z=x.target,A=z.x+z.vx-M.x-M.vx||P(c),o>1&&(E=z.y+z.vy-M.y-M.vy||P(c)),o>2&&(T=z.z+z.vz-M.z-M.vz||P(c)),D=Math.sqrt(A*A+E*E+T*T),D=(D-s[g])/D*f*e[g],A*=D,E*=D,T*=D,z.vx-=A*(m=u[g]),o>1&&(z.vy-=E*m),o>2&&(z.vz-=T*m),M.vx+=A*(m=1-m),o>1&&(M.vy+=E*m),o>2&&(M.vz+=T*m)}function _(){if(a){var f,d=a.length,w=t.length,g=new Map(a.map((M,z)=>[n(M,z,a),M])),x;for(f=0,h=new Array(d);f<w;++f)x=t[f],x.index=f,typeof x.source!="object"&&(x.source=ct(g,x.source)),typeof x.target!="object"&&(x.target=ct(g,x.target)),h[x.source.index]=(h[x.source.index]||0)+1,h[x.target.index]=(h[x.target.index]||0)+1;for(f=0,u=new Array(w);f<w;++f)x=t[f],u[f]=h[x.source.index]/(h[x.source.index]+h[x.target.index]);e=new Array(w),N(),s=new Array(w),p()}}function N(){if(a)for(var f=0,d=t.length;f<d;++f)e[f]=+i(t[f],f,t)}function p(){if(a)for(var f=0,d=t.length;f<d;++f)s[f]=+r(t[f],f,t)}return y.initialize=function(f,...d){a=f,c=d.find(w=>typeof w=="function")||Math.random,o=d.find(w=>[1,2,3].includes(w))||2,_()},y.links=function(f){return arguments.length?(t=f,_(),y):t},y.id=function(f){return arguments.length?(n=f,y):n},y.iterations=function(f){return arguments.length?(l=+f,y):l},y.strength=function(f){return arguments.length?(i=typeof f=="function"?f:R(+f),N(),y):i},y.distance=function(f){return arguments.length?(r=typeof f=="function"?f:R(+f),p(),y):r},y}var An={value:()=>{}};function _t(){for(var t=0,n=arguments.length,i={},e;t<n;++t){if(!(e=arguments[t]+"")||e in i||/[\\s.]/.test(e))throw new Error("illegal type: "+e);i[e]=[]}return new H(i)}function H(t){this._=t}function $n(t,n){return t.trim().split(/^|\\s+/).map(function(i){var e="",r=i.indexOf(".");if(r>=0&&(e=i.slice(r+1),i=i.slice(0,r)),i&&!n.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:e}})}H.prototype=_t.prototype={constructor:H,on:function(t,n){var i=this._,e=$n(t+"",i),r,s=-1,a=e.length;if(arguments.length<2){for(;++s<a;)if((r=(t=e[s]).type)&&(r=mn(i[r],t.name)))return r;return}if(n!=null&&typeof n!="function")throw new Error("invalid callback: "+n);for(;++s<a;)if(r=(t=e[s]).type)i[r]=vt(i[r],t.name,n);else if(n==null)for(r in i)i[r]=vt(i[r],t.name,null);return this},copy:function(){var t={},n=this._;for(var i in n)t[i]=n[i].slice();return new H(t)},call:function(t,n){if((r=arguments.length-2)>0)for(var i=new Array(r),e=0,r,s;e<r;++e)i[e]=arguments[e+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(s=this._[t],e=0,r=s.length;e<r;++e)s[e].value.apply(n,i)},apply:function(t,n,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var e=this._[t],r=0,s=e.length;r<s;++r)e[r].value.apply(n,i)}};function mn(t,n){for(var i=0,e=t.length,r;i<e;++i)if((r=t[i]).name===n)return r.value}function vt(t,n,i){for(var e=0,r=t.length;e<r;++e)if(t[e].name===n){t[e]=An,t=t.slice(0,e).concat(t.slice(e+1));break}return i!=null&&t.push({name:n,value:i}),t}var S=0,X=0,B=0,xt=1e3,Q,C,W=0,O=0,Z=0,L=typeof performance=="object"&&performance.now?performance:Date,yt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function pt(){return O||(yt(qn),O=L.now()+Z)}function qn(){O=0}function U(){this._call=this._time=this._next=null}U.prototype=gt.prototype={constructor:U,restart:function(t,n,i){if(typeof t!="function")throw new TypeError("callback is not a function");i=(i==null?pt():+i)+(n==null?0:+n),!this._next&&C!==this&&(C?C._next=this:Q=this,C=this),this._call=t,this._time=i,V()},stop:function(){this._call&&(this._call=null,this._time=1/0,V())}};function gt(t,n,i){var e=new U;return e.restart(t,n,i),e}function In(){pt(),++S;for(var t=Q,n;t;)(n=O-t._time)>=0&&t._call.call(void 0,n),t=t._next;--S}function wt(){O=(W=L.now())+Z,S=X=0;try{In()}finally{S=0,kn(),O=0}}function bn(){var t=L.now(),n=t-W;n>xt&&(Z-=n,W=t)}function kn(){for(var t,n=Q,i,e=1/0;n;)n._call?(e>n._time&&(e=n._time),t=n,n=n._next):(i=n._next,n._next=null,n=t?t._next=i:Q=i);C=t,V(e)}function V(t){if(!S){X&&(X=clearTimeout(X));var n=t-O;n>24?(t<1/0&&(X=setTimeout(wt,t-L.now()-Z)),B&&(B=clearInterval(B))):(B||(W=L.now(),B=setInterval(bn,xt)),S=1,yt(wt))}}const Dn=1664525,En=1013904223,dt=4294967296;function Tn(){let t=1;return()=>(t=(Dn*t+En)%dt)/dt}var Nt=3;function tt(t){return t.x}function Mt(t){return t.y}function jn(t){return t.z}var Pn=10,Fn=Math.PI*(3-Math.sqrt(5)),On=Math.PI*20/(9+Math.sqrt(221));function Sn(t,n){n=n||2;var i=Math.min(Nt,Math.max(1,Math.round(n))),e,r=1,s=.001,a=1-Math.pow(s,1/300),o=0,h=.6,u=new Map,c=gt(y),l=_t("tick","end"),v=Tn();t==null&&(t=[]);function y(){_(),l.call("tick",e),r<s&&(c.stop(),l.call("end",e))}function _(f){var d,w=t.length,g;f===void 0&&(f=1);for(var x=0;x<f;++x)for(r+=(o-r)*a,u.forEach(function(M){M(r)}),d=0;d<w;++d)g=t[d],g.fx==null?g.x+=g.vx*=h:(g.x=g.fx,g.vx=0),i>1&&(g.fy==null?g.y+=g.vy*=h:(g.y=g.fy,g.vy=0)),i>2&&(g.fz==null?g.z+=g.vz*=h:(g.z=g.fz,g.vz=0));return e}function N(){for(var f=0,d=t.length,w;f<d;++f){if(w=t[f],w.index=f,w.fx!=null&&(w.x=w.fx),w.fy!=null&&(w.y=w.fy),w.fz!=null&&(w.z=w.fz),isNaN(w.x)||i>1&&isNaN(w.y)||i>2&&isNaN(w.z)){var g=Pn*(i>2?Math.cbrt(.5+f):i>1?Math.sqrt(.5+f):f),x=f*Fn,M=f*On;i===1?w.x=g:i===2?(w.x=g*Math.cos(x),w.y=g*Math.sin(x)):(w.x=g*Math.sin(x)*Math.cos(M),w.y=g*Math.cos(x),w.z=g*Math.sin(x)*Math.sin(M))}(isNaN(w.vx)||i>1&&isNaN(w.vy)||i>2&&isNaN(w.vz))&&(w.vx=0,i>1&&(w.vy=0),i>2&&(w.vz=0))}}function p(f){return f.initialize&&f.initialize(t,v,i),f}return N(),e={tick:_,restart:function(){return c.restart(y),e},stop:function(){return c.stop(),e},numDimensions:function(f){return arguments.length?(i=Math.min(Nt,Math.max(1,Math.round(f))),u.forEach(p),e):i},nodes:function(f){return arguments.length?(t=f,N(),u.forEach(p),e):t},alpha:function(f){return arguments.length?(r=+f,e):r},alphaMin:function(f){return arguments.length?(s=+f,e):s},alphaDecay:function(f){return arguments.length?(a=+f,e):+a},alphaTarget:function(f){return arguments.length?(o=+f,e):o},velocityDecay:function(f){return arguments.length?(h=1-f,e):1-h},randomSource:function(f){return arguments.length?(v=f,u.forEach(p),e):v},force:function(f,d){return arguments.length>1?(d==null?u.delete(f):u.set(f,p(d)),e):u.get(f)},find:function(){var f=Array.prototype.slice.call(arguments),d=f.shift()||0,w=(i>1?f.shift():null)||0,g=(i>2?f.shift():null)||0,x=f.shift()||1/0,M=0,z=t.length,A,E,T,D,m,zt;for(x*=x,M=0;M<z;++M)m=t[M],A=d-m.x,E=w-(m.y||0),T=g-(m.z||0),D=A*A+E*E+T*T,D<x&&(zt=m,x=D);return zt},on:function(f,d){return arguments.length>1?(l.on(f,d),e):l.on(f)}}}function Rn(){var t,n,i,e,r,s=R(-30),a,o=1,h=1/0,u=.81;function c(_){var N,p=t.length,f=(n===1?rt(t,tt):n===2?ht(t,tt,Mt):n===3?ut(t,tt,Mt,jn):null).visitAfter(v);for(r=_,N=0;N<p;++N)i=t[N],f.visit(y)}function l(){if(t){var _,N=t.length,p;for(a=new Array(N),_=0;_<N;++_)p=t[_],a[p.index]=+s(p,_,t)}}function v(_){var N=0,p,f,d=0,w,g,x,M,z=_.length;if(z){for(w=g=x=M=0;M<z;++M)(p=_[M])&&(f=Math.abs(p.value))&&(N+=p.value,d+=f,w+=f*(p.x||0),g+=f*(p.y||0),x+=f*(p.z||0));N*=Math.sqrt(4/z),_.x=w/d,n>1&&(_.y=g/d),n>2&&(_.z=x/d)}else{p=_,p.x=p.data.x,n>1&&(p.y=p.data.y),n>2&&(p.z=p.data.z);do N+=a[p.data.index];while(p=p.next)}_.value=N}function y(_,N,p,f,d){if(!_.value)return!0;var w=[p,f,d][n-1],g=_.x-i.x,x=n>1?_.y-i.y:0,M=n>2?_.z-i.z:0,z=w-N,A=g*g+x*x+M*M;if(z*z/u<A)return A<h&&(g===0&&(g=P(e),A+=g*g),n>1&&x===0&&(x=P(e),A+=x*x),n>2&&M===0&&(M=P(e),A+=M*M),A<o&&(A=Math.sqrt(o*A)),i.vx+=g*_.value*r/A,n>1&&(i.vy+=x*_.value*r/A),n>2&&(i.vz+=M*_.value*r/A)),!0;if(_.length||A>=h)return;(_.data!==i||_.next)&&(g===0&&(g=P(e),A+=g*g),n>1&&x===0&&(x=P(e),A+=x*x),n>2&&M===0&&(M=P(e),A+=M*M),A<o&&(A=Math.sqrt(o*A)));do _.data!==i&&(z=a[_.data.index]*r/A,i.vx+=g*z,n>1&&(i.vy+=x*z),n>2&&(i.vz+=M*z));while(_=_.next)}return c.initialize=function(_,...N){t=_,e=N.find(p=>typeof p=="function")||Math.random,n=N.find(p=>[1,2,3].includes(p))||2,l()},c.strength=function(_){return arguments.length?(s=typeof _=="function"?_:R(+_),l(),c):s},c.distanceMin=function(_){return arguments.length?(o=_*_,c):Math.sqrt(o)},c.distanceMax=function(_){return arguments.length?(h=_*_,c):Math.sqrt(h)},c.theta=function(_){return arguments.length?(u=_*_,c):Math.sqrt(u)},c}let F=null,Y=[],nt=0,it=!1;self.onmessage=t=>{const n=t.data;if(n.type==="init"){F&&F.stop(),it=!1,nt=0;const i=n.nodes.length,e=n.params,r=n.initialPositions??{};Y=n.nodes.map((a,o)=>{const h=r[a.id];if(h)return{id:a.id,index:o,x:h.x,y:h.y,z:h.z};const u=Math.random()*Math.PI*2,c=Math.acos(2*Math.random()-1),l=e.initialRadius*(.5+Math.random()*.5);return{id:a.id,index:o,x:l*Math.sin(c)*Math.cos(u),y:l*Math.sin(c)*Math.sin(u),z:l*Math.cos(c)}});const s=n.links.map(a=>({source:a.source,target:a.target}));F=Sn(Y,3).force("charge",Rn().strength(e.charge).distanceMax(e.distanceMax).theta(e.theta)).force("link",zn(s).id(a=>a.id).distance(e.linkDistance).strength(.2)).force("center",At()).alphaDecay(e.alphaDecay).velocityDecay(e.velocityDecay),F.on("tick",()=>{nt++;const a=F.alpha();if(nt%e.postEvery!==0&&a>e.settledThreshold)return;const o=new Float32Array(i*3);for(let h=0;h<i;h++)o[h*3]=Y[h].x||0,o[h*3+1]=Y[h].y||0,o[h*3+2]=Y[h].z||0;self.postMessage({type:"positions",positions:o.buffer,alpha:a},[o.buffer]),!it&&a<e.settledThreshold&&(it=!0,self.postMessage({type:"settled"}))})}n.type==="stop"&&F&&(F.stop(),F=null)}})();\n';
|
|
278
|
+
const WORKER_SOURCE = '(function(){"use strict";function At(t,n,i){var e,r=1;t==null&&(t=0),n==null&&(n=0),i==null&&(i=0);function s(){var o,u=e.length,h,f=0,l=0,c=0;for(o=0;o<u;++o)h=e[o],f+=h.x||0,l+=h.y||0,c+=h.z||0;for(f=(f/u-t)*r,l=(l/u-n)*r,c=(c/u-i)*r,o=0;o<u;++o)h=e[o],f&&(h.x-=f),l&&(h.y-=l),c&&(h.z-=c)}return s.initialize=function(o){e=o},s.x=function(o){return arguments.length?(t=+o,s):t},s.y=function(o){return arguments.length?(n=+o,s):n},s.z=function(o){return arguments.length?(i=+o,s):i},s.strength=function(o){return arguments.length?(r=+o,s):r},s}function $t(t){const n=+this._x.call(null,t);return et(this.cover(n),n,t)}function et(t,n,i){if(isNaN(n))return t;var e,r=t._root,s={data:i},o=t._x0,u=t._x1,h,f,l,c,v;if(!r)return t._root=s,t;for(;r.length;)if((l=n>=(h=(o+u)/2))?o=h:u=h,e=r,!(r=r[c=+l]))return e[c]=s,t;if(f=+t._x.call(null,r.data),n===f)return s.next=r,e?e[c]=s:t._root=s,t;do e=e?e[c]=new Array(2):t._root=new Array(2),(l=n>=(h=(o+u)/2))?o=h:u=h;while((c=+l)==(v=+(f>=h)));return e[v]=r,e[c]=s,t}function mt(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n);let e=1/0,r=-1/0;for(let s=0,o;s<n;++s)isNaN(o=+this._x.call(null,t[s]))||(i[s]=o,o<e&&(e=o),o>r&&(r=o));if(e>r)return this;this.cover(e).cover(r);for(let s=0;s<n;++s)et(this,i[s],t[s]);return this}function qt(t){if(isNaN(t=+t))return this;var n=this._x0,i=this._x1;if(isNaN(n))i=(n=Math.floor(t))+1;else{for(var e=i-n||1,r=this._root,s,o;n>t||t>=i;)switch(o=+(t<n),s=new Array(2),s[o]=r,r=s,e*=2,o){case 0:i=n+e;break;case 1:n=i-e;break}this._root&&this._root.length&&(this._root=r)}return this._x0=n,this._x1=i,this}function It(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function bt(t){return arguments.length?this.cover(+t[0][0]).cover(+t[1][0]):isNaN(this._x0)?void 0:[[this._x0],[this._x1]]}function P(t,n,i){this.node=t,this.x0=n,this.x1=i}function kt(t,n){var i,e=this._x0,r,s,o=this._x1,u=[],h=this._root,f,l;for(h&&u.push(new P(h,e,o)),n==null?n=1/0:(e=t-n,o=t+n);f=u.pop();)if(!(!(h=f.node)||(r=f.x0)>o||(s=f.x1)<e))if(h.length){var c=(r+s)/2;u.push(new P(h[1],c,s),new P(h[0],r,c)),(l=+(t>=c))&&(f=u[u.length-1],u[u.length-1]=u[u.length-1-l],u[u.length-1-l]=f)}else{var v=Math.abs(t-+this._x.call(null,h.data));v<n&&(n=v,e=t-v,o=t+v,i=h.data)}return i}function Dt(t){if(isNaN(h=+this._x.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._x1,h,f,l,c,v;if(!i)return this;if(i.length)for(;;){if((l=h>=(f=(o+u)/2))?o=f:u=f,n=i,!(i=i[c=+l]))return this;if(!i.length)break;n[c+1&1]&&(e=n,v=c)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[c]=s:delete n[c],(i=n[0]||n[1])&&i===(n[1]||n[0])&&!i.length&&(e?e[v]=i:this._root=i),this):(this._root=s,this)}function Et(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Tt(){return this._root}function jt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Pt(t){var n=[],i,e=this._root,r,s,o;for(e&&n.push(new P(e,this._x0,this._x1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.x1)&&e.length){var u=(s+o)/2;(r=e[1])&&n.push(new P(r,u,o)),(r=e[0])&&n.push(new P(r,s,u))}return this}function Ft(t){var n=[],i=[],e;for(this._root&&n.push(new P(this._root,this._x0,this._x1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.x1,h=(o+u)/2;(s=r[0])&&n.push(new P(s,o,h)),(s=r[1])&&n.push(new P(s,h,u))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.x1);return this}function St(t){return t[0]}function Ot(t){return arguments.length?(this._x=t,this):this._x}function rt(t,n){var i=new G(n??St,NaN,NaN);return t==null?i:i.addAll(t)}function G(t,n,i){this._x=t,this._x0=n,this._x1=i,this._root=void 0}function st(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var k=rt.prototype=G.prototype;k.copy=function(){var t=new G(this._x,this._x0,this._x1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=st(n),t;for(i=[{source:n,target:t._root=new Array(2)}];n=i.pop();)for(var r=0;r<2;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(2)}):n.target[r]=st(e));return t},k.add=$t,k.addAll=mt,k.cover=qt,k.data=It,k.extent=bt,k.find=kt,k.remove=Dt,k.removeAll=Et,k.root=Tt,k.size=jt,k.visit=Pt,k.visitAfter=Ft,k.x=Ot;function Rt(t){const n=+this._x.call(null,t),i=+this._y.call(null,t);return ot(this.cover(n,i),n,i,t)}function ot(t,n,i,e){if(isNaN(n)||isNaN(i))return t;var r,s=t._root,o={data:e},u=t._x0,h=t._y0,f=t._x1,l=t._y1,c,v,y,_,g,x,a,N;if(!s)return t._root=o,t;for(;s.length;)if((g=n>=(c=(u+f)/2))?u=c:f=c,(x=i>=(v=(h+l)/2))?h=v:l=v,r=s,!(s=s[a=x<<1|g]))return r[a]=o,t;if(y=+t._x.call(null,s.data),_=+t._y.call(null,s.data),n===y&&i===_)return o.next=s,r?r[a]=o:t._root=o,t;do r=r?r[a]=new Array(4):t._root=new Array(4),(g=n>=(c=(u+f)/2))?u=c:f=c,(x=i>=(v=(h+l)/2))?h=v:l=v;while((a=x<<1|g)===(N=(_>=v)<<1|y>=c));return r[N]=s,r[a]=o,t}function Xt(t){var n,i,e=t.length,r,s,o=new Array(e),u=new Array(e),h=1/0,f=1/0,l=-1/0,c=-1/0;for(i=0;i<e;++i)isNaN(r=+this._x.call(null,n=t[i]))||isNaN(s=+this._y.call(null,n))||(o[i]=r,u[i]=s,r<h&&(h=r),r>l&&(l=r),s<f&&(f=s),s>c&&(c=s));if(h>l||f>c)return this;for(this.cover(h,f).cover(l,c),i=0;i<e;++i)ot(this,o[i],u[i],t[i]);return this}function Bt(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var i=this._x0,e=this._y0,r=this._x1,s=this._y1;if(isNaN(i))r=(i=Math.floor(t))+1,s=(e=Math.floor(n))+1;else{for(var o=r-i||1,u=this._root,h,f;i>t||t>=r||e>n||n>=s;)switch(f=(n<e)<<1|t<i,h=new Array(4),h[f]=u,u=h,o*=2,f){case 0:r=i+o,s=e+o;break;case 1:i=r-o,s=e+o;break;case 2:r=i+o,e=s-o;break;case 3:i=r-o,e=s-o;break}this._root&&this._root.length&&(this._root=u)}return this._x0=i,this._y0=e,this._x1=r,this._y1=s,this}function Ct(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function Lt(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function I(t,n,i,e,r){this.node=t,this.x0=n,this.y0=i,this.x1=e,this.y1=r}function Yt(t,n,i){var e,r=this._x0,s=this._y0,o,u,h,f,l=this._x1,c=this._y1,v=[],y=this._root,_,g;for(y&&v.push(new I(y,r,s,l,c)),i==null?i=1/0:(r=t-i,s=n-i,l=t+i,c=n+i,i*=i);_=v.pop();)if(!(!(y=_.node)||(o=_.x0)>l||(u=_.y0)>c||(h=_.x1)<r||(f=_.y1)<s))if(y.length){var x=(o+h)/2,a=(u+f)/2;v.push(new I(y[3],x,a,h,f),new I(y[2],o,a,x,f),new I(y[1],x,u,h,a),new I(y[0],o,u,x,a)),(g=(n>=a)<<1|t>=x)&&(_=v[v.length-1],v[v.length-1]=v[v.length-1-g],v[v.length-1-g]=_)}else{var N=t-+this._x.call(null,y.data),d=n-+this._y.call(null,y.data),w=N*N+d*d;if(w<i){var p=Math.sqrt(i=w);r=t-p,s=n-p,l=t+p,c=n+p,e=y.data}}return e}function Ht(t){if(isNaN(l=+this._x.call(null,t))||isNaN(c=+this._y.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._y0,h=this._x1,f=this._y1,l,c,v,y,_,g,x,a;if(!i)return this;if(i.length)for(;;){if((_=l>=(v=(o+h)/2))?o=v:h=v,(g=c>=(y=(u+f)/2))?u=y:f=y,n=i,!(i=i[x=g<<1|_]))return this;if(!i.length)break;(n[x+1&3]||n[x+2&3]||n[x+3&3])&&(e=n,a=x)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[x]=s:delete n[x],(i=n[0]||n[1]||n[2]||n[3])&&i===(n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[a]=i:this._root=i),this):(this._root=s,this)}function Qt(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Wt(){return this._root}function Zt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Gt(t){var n=[],i,e=this._root,r,s,o,u,h;for(e&&n.push(new I(e,this._x0,this._y0,this._x1,this._y1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.y0,u=i.x1,h=i.y1)&&e.length){var f=(s+u)/2,l=(o+h)/2;(r=e[3])&&n.push(new I(r,f,l,u,h)),(r=e[2])&&n.push(new I(r,s,l,f,h)),(r=e[1])&&n.push(new I(r,f,o,u,l)),(r=e[0])&&n.push(new I(r,s,o,f,l))}return this}function Jt(t){var n=[],i=[],e;for(this._root&&n.push(new I(this._root,this._x0,this._y0,this._x1,this._y1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.y0,h=e.x1,f=e.y1,l=(o+h)/2,c=(u+f)/2;(s=r[0])&&n.push(new I(s,o,u,l,c)),(s=r[1])&&n.push(new I(s,l,u,h,c)),(s=r[2])&&n.push(new I(s,o,c,l,f)),(s=r[3])&&n.push(new I(s,l,c,h,f))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.x1,e.y1);return this}function Kt(t){return t[0]}function Ut(t){return arguments.length?(this._x=t,this):this._x}function Vt(t){return t[1]}function tn(t){return arguments.length?(this._y=t,this):this._y}function ht(t,n,i){var e=new J(n??Kt,i??Vt,NaN,NaN,NaN,NaN);return t==null?e:e.addAll(t)}function J(t,n,i,e,r,s){this._x=t,this._y=n,this._x0=i,this._y0=e,this._x1=r,this._y1=s,this._root=void 0}function at(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var b=ht.prototype=J.prototype;b.copy=function(){var t=new J(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=at(n),t;for(i=[{source:n,target:t._root=new Array(4)}];n=i.pop();)for(var r=0;r<4;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(4)}):n.target[r]=at(e));return t},b.add=Rt,b.addAll=Xt,b.cover=Bt,b.data=Ct,b.extent=Lt,b.find=Yt,b.remove=Ht,b.removeAll=Qt,b.root=Wt,b.size=Zt,b.visit=Gt,b.visitAfter=Jt,b.x=Ut,b.y=tn;function nn(t){const n=+this._x.call(null,t),i=+this._y.call(null,t),e=+this._z.call(null,t);return ft(this.cover(n,i,e),n,i,e,t)}function ft(t,n,i,e,r){if(isNaN(n)||isNaN(i)||isNaN(e))return t;var s,o=t._root,u={data:r},h=t._x0,f=t._y0,l=t._z0,c=t._x1,v=t._y1,y=t._z1,_,g,x,a,N,d,w,p,M,z,A;if(!o)return t._root=u,t;for(;o.length;)if((w=n>=(_=(h+c)/2))?h=_:c=_,(p=i>=(g=(f+v)/2))?f=g:v=g,(M=e>=(x=(l+y)/2))?l=x:y=x,s=o,!(o=o[z=M<<2|p<<1|w]))return s[z]=u,t;if(a=+t._x.call(null,o.data),N=+t._y.call(null,o.data),d=+t._z.call(null,o.data),n===a&&i===N&&e===d)return u.next=o,s?s[z]=u:t._root=u,t;do s=s?s[z]=new Array(8):t._root=new Array(8),(w=n>=(_=(h+c)/2))?h=_:c=_,(p=i>=(g=(f+v)/2))?f=g:v=g,(M=e>=(x=(l+y)/2))?l=x:y=x;while((z=M<<2|p<<1|w)===(A=(d>=x)<<2|(N>=g)<<1|a>=_));return s[A]=o,s[z]=u,t}function en(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n),e=new Float64Array(n),r=new Float64Array(n);let s=1/0,o=1/0,u=1/0,h=-1/0,f=-1/0,l=-1/0;for(let c=0,v,y,_,g;c<n;++c)isNaN(y=+this._x.call(null,v=t[c]))||isNaN(_=+this._y.call(null,v))||isNaN(g=+this._z.call(null,v))||(i[c]=y,e[c]=_,r[c]=g,y<s&&(s=y),y>h&&(h=y),_<o&&(o=_),_>f&&(f=_),g<u&&(u=g),g>l&&(l=g));if(s>h||o>f||u>l)return this;this.cover(s,o,u).cover(h,f,l);for(let c=0;c<n;++c)ft(this,i[c],e[c],r[c],t[c]);return this}function rn(t,n,i){if(isNaN(t=+t)||isNaN(n=+n)||isNaN(i=+i))return this;var e=this._x0,r=this._y0,s=this._z0,o=this._x1,u=this._y1,h=this._z1;if(isNaN(e))o=(e=Math.floor(t))+1,u=(r=Math.floor(n))+1,h=(s=Math.floor(i))+1;else{for(var f=o-e||1,l=this._root,c,v;e>t||t>=o||r>n||n>=u||s>i||i>=h;)switch(v=(i<s)<<2|(n<r)<<1|t<e,c=new Array(8),c[v]=l,l=c,f*=2,v){case 0:o=e+f,u=r+f,h=s+f;break;case 1:e=o-f,u=r+f,h=s+f;break;case 2:o=e+f,r=u-f,h=s+f;break;case 3:e=o-f,r=u-f,h=s+f;break;case 4:o=e+f,u=r+f,s=h-f;break;case 5:e=o-f,u=r+f,s=h-f;break;case 6:o=e+f,r=u-f,s=h-f;break;case 7:e=o-f,r=u-f,s=h-f;break}this._root&&this._root.length&&(this._root=l)}return this._x0=e,this._y0=r,this._z0=s,this._x1=o,this._y1=u,this._z1=h,this}function sn(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function on(t){return arguments.length?this.cover(+t[0][0],+t[0][1],+t[0][2]).cover(+t[1][0],+t[1][1],+t[1][2]):isNaN(this._x0)?void 0:[[this._x0,this._y0,this._z0],[this._x1,this._y1,this._z1]]}function $(t,n,i,e,r,s,o){this.node=t,this.x0=n,this.y0=i,this.z0=e,this.x1=r,this.y1=s,this.z1=o}function hn(t,n,i,e){var r,s=this._x0,o=this._y0,u=this._z0,h,f,l,c,v,y,_=this._x1,g=this._y1,x=this._z1,a=[],N=this._root,d,w;for(N&&a.push(new $(N,s,o,u,_,g,x)),e==null?e=1/0:(s=t-e,o=n-e,u=i-e,_=t+e,g=n+e,x=i+e,e*=e);d=a.pop();)if(!(!(N=d.node)||(h=d.x0)>_||(f=d.y0)>g||(l=d.z0)>x||(c=d.x1)<s||(v=d.y1)<o||(y=d.z1)<u))if(N.length){var p=(h+c)/2,M=(f+v)/2,z=(l+y)/2;a.push(new $(N[7],p,M,z,c,v,y),new $(N[6],h,M,z,p,v,y),new $(N[5],p,f,z,c,M,y),new $(N[4],h,f,z,p,M,y),new $(N[3],p,M,l,c,v,z),new $(N[2],h,M,l,p,v,z),new $(N[1],p,f,l,c,M,z),new $(N[0],h,f,l,p,M,z)),(w=(i>=z)<<2|(n>=M)<<1|t>=p)&&(d=a[a.length-1],a[a.length-1]=a[a.length-1-w],a[a.length-1-w]=d)}else{var A=t-+this._x.call(null,N.data),E=n-+this._y.call(null,N.data),T=i-+this._z.call(null,N.data),D=A*A+E*E+T*T;if(D<e){var m=Math.sqrt(e=D);s=t-m,o=n-m,u=i-m,_=t+m,g=n+m,x=i+m,r=N.data}}return r}const an=(t,n,i,e,r,s)=>Math.sqrt((t-e)**2+(n-r)**2+(i-s)**2);function fn(t,n,i,e){const r=[],s=t-e,o=n-e,u=i-e,h=t+e,f=n+e,l=i+e;return this.visit((c,v,y,_,g,x,a)=>{if(!c.length)do{const N=c.data;an(t,n,i,this._x(N),this._y(N),this._z(N))<=e&&r.push(N)}while(c=c.next);return v>h||y>f||_>l||g<s||x<o||a<u}),r}function un(t){if(isNaN(v=+this._x.call(null,t))||isNaN(y=+this._y.call(null,t))||isNaN(_=+this._z.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._y0,h=this._z0,f=this._x1,l=this._y1,c=this._z1,v,y,_,g,x,a,N,d,w,p,M;if(!i)return this;if(i.length)for(;;){if((N=v>=(g=(o+f)/2))?o=g:f=g,(d=y>=(x=(u+l)/2))?u=x:l=x,(w=_>=(a=(h+c)/2))?h=a:c=a,n=i,!(i=i[p=w<<2|d<<1|N]))return this;if(!i.length)break;(n[p+1&7]||n[p+2&7]||n[p+3&7]||n[p+4&7]||n[p+5&7]||n[p+6&7]||n[p+7&7])&&(e=n,M=p)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[p]=s:delete n[p],(i=n[0]||n[1]||n[2]||n[3]||n[4]||n[5]||n[6]||n[7])&&i===(n[7]||n[6]||n[5]||n[4]||n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[M]=i:this._root=i),this):(this._root=s,this)}function ln(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function cn(){return this._root}function _n(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function vn(t){var n=[],i,e=this._root,r,s,o,u,h,f,l;for(e&&n.push(new $(e,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.y0,u=i.z0,h=i.x1,f=i.y1,l=i.z1)&&e.length){var c=(s+h)/2,v=(o+f)/2,y=(u+l)/2;(r=e[7])&&n.push(new $(r,c,v,y,h,f,l)),(r=e[6])&&n.push(new $(r,s,v,y,c,f,l)),(r=e[5])&&n.push(new $(r,c,o,y,h,v,l)),(r=e[4])&&n.push(new $(r,s,o,y,c,v,l)),(r=e[3])&&n.push(new $(r,c,v,u,h,f,y)),(r=e[2])&&n.push(new $(r,s,v,u,c,f,y)),(r=e[1])&&n.push(new $(r,c,o,u,h,v,y)),(r=e[0])&&n.push(new $(r,s,o,u,c,v,y))}return this}function xn(t){var n=[],i=[],e;for(this._root&&n.push(new $(this._root,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.y0,h=e.z0,f=e.x1,l=e.y1,c=e.z1,v=(o+f)/2,y=(u+l)/2,_=(h+c)/2;(s=r[0])&&n.push(new $(s,o,u,h,v,y,_)),(s=r[1])&&n.push(new $(s,v,u,h,f,y,_)),(s=r[2])&&n.push(new $(s,o,y,h,v,l,_)),(s=r[3])&&n.push(new $(s,v,y,h,f,l,_)),(s=r[4])&&n.push(new $(s,o,u,_,v,y,c)),(s=r[5])&&n.push(new $(s,v,u,_,f,y,c)),(s=r[6])&&n.push(new $(s,o,y,_,v,l,c)),(s=r[7])&&n.push(new $(s,v,y,_,f,l,c))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.z0,e.x1,e.y1,e.z1);return this}function yn(t){return t[0]}function pn(t){return arguments.length?(this._x=t,this):this._x}function gn(t){return t[1]}function wn(t){return arguments.length?(this._y=t,this):this._y}function dn(t){return t[2]}function Nn(t){return arguments.length?(this._z=t,this):this._z}function ut(t,n,i,e){var r=new K(n??yn,i??gn,e??dn,NaN,NaN,NaN,NaN,NaN,NaN);return t==null?r:r.addAll(t)}function K(t,n,i,e,r,s,o,u,h){this._x=t,this._y=n,this._z=i,this._x0=e,this._y0=r,this._z0=s,this._x1=o,this._y1=u,this._z1=h,this._root=void 0}function lt(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var q=ut.prototype=K.prototype;q.copy=function(){var t=new K(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=lt(n),t;for(i=[{source:n,target:t._root=new Array(8)}];n=i.pop();)for(var r=0;r<8;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(8)}):n.target[r]=lt(e));return t},q.add=nn,q.addAll=en,q.cover=rn,q.data=sn,q.extent=on,q.find=hn,q.findAllWithinRadius=fn,q.remove=un,q.removeAll=ln,q.root=cn,q.size=_n,q.visit=vn,q.visitAfter=xn,q.x=pn,q.y=wn,q.z=Nn;function X(t){return function(){return t}}function F(t){return(t()-.5)*1e-6}function Mn(t){return t.index}function ct(t,n){var i=t.get(n);if(!i)throw new Error("node not found: "+n);return i}function zn(t){var n=Mn,i=v,e,r=X(30),s,o,u,h,f,l,c=1;t==null&&(t=[]);function v(a){return 1/Math.min(h[a.source.index],h[a.target.index])}function y(a){for(var N=0,d=t.length;N<c;++N)for(var w=0,p,M,z,A=0,E=0,T=0,D,m;w<d;++w)p=t[w],M=p.source,z=p.target,A=z.x+z.vx-M.x-M.vx||F(l),u>1&&(E=z.y+z.vy-M.y-M.vy||F(l)),u>2&&(T=z.z+z.vz-M.z-M.vz||F(l)),D=Math.sqrt(A*A+E*E+T*T),D=(D-s[w])/D*a*e[w],A*=D,E*=D,T*=D,z.vx-=A*(m=f[w]),u>1&&(z.vy-=E*m),u>2&&(z.vz-=T*m),M.vx+=A*(m=1-m),u>1&&(M.vy+=E*m),u>2&&(M.vz+=T*m)}function _(){if(o){var a,N=o.length,d=t.length,w=new Map(o.map((M,z)=>[n(M,z,o),M])),p;for(a=0,h=new Array(N);a<d;++a)p=t[a],p.index=a,typeof p.source!="object"&&(p.source=ct(w,p.source)),typeof p.target!="object"&&(p.target=ct(w,p.target)),h[p.source.index]=(h[p.source.index]||0)+1,h[p.target.index]=(h[p.target.index]||0)+1;for(a=0,f=new Array(d);a<d;++a)p=t[a],f[a]=h[p.source.index]/(h[p.source.index]+h[p.target.index]);e=new Array(d),g(),s=new Array(d),x()}}function g(){if(o)for(var a=0,N=t.length;a<N;++a)e[a]=+i(t[a],a,t)}function x(){if(o)for(var a=0,N=t.length;a<N;++a)s[a]=+r(t[a],a,t)}return y.initialize=function(a,...N){o=a,l=N.find(d=>typeof d=="function")||Math.random,u=N.find(d=>[1,2,3].includes(d))||2,_()},y.links=function(a){return arguments.length?(t=a,_(),y):t},y.id=function(a){return arguments.length?(n=a,y):n},y.iterations=function(a){return arguments.length?(c=+a,y):c},y.strength=function(a){return arguments.length?(i=typeof a=="function"?a:X(+a),g(),y):i},y.distance=function(a){return arguments.length?(r=typeof a=="function"?a:X(+a),x(),y):r},y}var An={value:()=>{}};function _t(){for(var t=0,n=arguments.length,i={},e;t<n;++t){if(!(e=arguments[t]+"")||e in i||/[\\s.]/.test(e))throw new Error("illegal type: "+e);i[e]=[]}return new H(i)}function H(t){this._=t}function $n(t,n){return t.trim().split(/^|\\s+/).map(function(i){var e="",r=i.indexOf(".");if(r>=0&&(e=i.slice(r+1),i=i.slice(0,r)),i&&!n.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:e}})}H.prototype=_t.prototype={constructor:H,on:function(t,n){var i=this._,e=$n(t+"",i),r,s=-1,o=e.length;if(arguments.length<2){for(;++s<o;)if((r=(t=e[s]).type)&&(r=mn(i[r],t.name)))return r;return}if(n!=null&&typeof n!="function")throw new Error("invalid callback: "+n);for(;++s<o;)if(r=(t=e[s]).type)i[r]=vt(i[r],t.name,n);else if(n==null)for(r in i)i[r]=vt(i[r],t.name,null);return this},copy:function(){var t={},n=this._;for(var i in n)t[i]=n[i].slice();return new H(t)},call:function(t,n){if((r=arguments.length-2)>0)for(var i=new Array(r),e=0,r,s;e<r;++e)i[e]=arguments[e+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(s=this._[t],e=0,r=s.length;e<r;++e)s[e].value.apply(n,i)},apply:function(t,n,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var e=this._[t],r=0,s=e.length;r<s;++r)e[r].value.apply(n,i)}};function mn(t,n){for(var i=0,e=t.length,r;i<e;++i)if((r=t[i]).name===n)return r.value}function vt(t,n,i){for(var e=0,r=t.length;e<r;++e)if(t[e].name===n){t[e]=An,t=t.slice(0,e).concat(t.slice(e+1));break}return i!=null&&t.push({name:n,value:i}),t}var R=0,B=0,C=0,xt=1e3,Q,L,W=0,O=0,Z=0,Y=typeof performance=="object"&&performance.now?performance:Date,yt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function pt(){return O||(yt(qn),O=Y.now()+Z)}function qn(){O=0}function U(){this._call=this._time=this._next=null}U.prototype=gt.prototype={constructor:U,restart:function(t,n,i){if(typeof t!="function")throw new TypeError("callback is not a function");i=(i==null?pt():+i)+(n==null?0:+n),!this._next&&L!==this&&(L?L._next=this:Q=this,L=this),this._call=t,this._time=i,V()},stop:function(){this._call&&(this._call=null,this._time=1/0,V())}};function gt(t,n,i){var e=new U;return e.restart(t,n,i),e}function In(){pt(),++R;for(var t=Q,n;t;)(n=O-t._time)>=0&&t._call.call(void 0,n),t=t._next;--R}function wt(){O=(W=Y.now())+Z,R=B=0;try{In()}finally{R=0,kn(),O=0}}function bn(){var t=Y.now(),n=t-W;n>xt&&(Z-=n,W=t)}function kn(){for(var t,n=Q,i,e=1/0;n;)n._call?(e>n._time&&(e=n._time),t=n,n=n._next):(i=n._next,n._next=null,n=t?t._next=i:Q=i);L=t,V(e)}function V(t){if(!R){B&&(B=clearTimeout(B));var n=t-O;n>24?(t<1/0&&(B=setTimeout(wt,t-Y.now()-Z)),C&&(C=clearInterval(C))):(C||(W=Y.now(),C=setInterval(bn,xt)),R=1,yt(wt))}}const Dn=1664525,En=1013904223,dt=4294967296;function Tn(){let t=1;return()=>(t=(Dn*t+En)%dt)/dt}var Nt=3;function tt(t){return t.x}function Mt(t){return t.y}function jn(t){return t.z}var Pn=10,Fn=Math.PI*(3-Math.sqrt(5)),Sn=Math.PI*20/(9+Math.sqrt(221));function On(t,n){n=n||2;var i=Math.min(Nt,Math.max(1,Math.round(n))),e,r=1,s=.001,o=1-Math.pow(s,1/300),u=0,h=.6,f=new Map,l=gt(y),c=_t("tick","end"),v=Tn();t==null&&(t=[]);function y(){_(),c.call("tick",e),r<s&&(l.stop(),c.call("end",e))}function _(a){var N,d=t.length,w;a===void 0&&(a=1);for(var p=0;p<a;++p)for(r+=(u-r)*o,f.forEach(function(M){M(r)}),N=0;N<d;++N)w=t[N],w.fx==null?w.x+=w.vx*=h:(w.x=w.fx,w.vx=0),i>1&&(w.fy==null?w.y+=w.vy*=h:(w.y=w.fy,w.vy=0)),i>2&&(w.fz==null?w.z+=w.vz*=h:(w.z=w.fz,w.vz=0));return e}function g(){for(var a=0,N=t.length,d;a<N;++a){if(d=t[a],d.index=a,d.fx!=null&&(d.x=d.fx),d.fy!=null&&(d.y=d.fy),d.fz!=null&&(d.z=d.fz),isNaN(d.x)||i>1&&isNaN(d.y)||i>2&&isNaN(d.z)){var w=Pn*(i>2?Math.cbrt(.5+a):i>1?Math.sqrt(.5+a):a),p=a*Fn,M=a*Sn;i===1?d.x=w:i===2?(d.x=w*Math.cos(p),d.y=w*Math.sin(p)):(d.x=w*Math.sin(p)*Math.cos(M),d.y=w*Math.cos(p),d.z=w*Math.sin(p)*Math.sin(M))}(isNaN(d.vx)||i>1&&isNaN(d.vy)||i>2&&isNaN(d.vz))&&(d.vx=0,i>1&&(d.vy=0),i>2&&(d.vz=0))}}function x(a){return a.initialize&&a.initialize(t,v,i),a}return g(),e={tick:_,restart:function(){return l.restart(y),e},stop:function(){return l.stop(),e},numDimensions:function(a){return arguments.length?(i=Math.min(Nt,Math.max(1,Math.round(a))),f.forEach(x),e):i},nodes:function(a){return arguments.length?(t=a,g(),f.forEach(x),e):t},alpha:function(a){return arguments.length?(r=+a,e):r},alphaMin:function(a){return arguments.length?(s=+a,e):s},alphaDecay:function(a){return arguments.length?(o=+a,e):+o},alphaTarget:function(a){return arguments.length?(u=+a,e):u},velocityDecay:function(a){return arguments.length?(h=1-a,e):1-h},randomSource:function(a){return arguments.length?(v=a,f.forEach(x),e):v},force:function(a,N){return arguments.length>1?(N==null?f.delete(a):f.set(a,x(N)),e):f.get(a)},find:function(){var a=Array.prototype.slice.call(arguments),N=a.shift()||0,d=(i>1?a.shift():null)||0,w=(i>2?a.shift():null)||0,p=a.shift()||1/0,M=0,z=t.length,A,E,T,D,m,zt;for(p*=p,M=0;M<z;++M)m=t[M],A=N-m.x,E=d-(m.y||0),T=w-(m.z||0),D=A*A+E*E+T*T,D<p&&(zt=m,p=D);return zt},on:function(a,N){return arguments.length>1?(c.on(a,N),e):c.on(a)}}}function Rn(){var t,n,i,e,r,s=X(-30),o,u=1,h=1/0,f=.81;function l(_){var g,x=t.length,a=(n===1?rt(t,tt):n===2?ht(t,tt,Mt):n===3?ut(t,tt,Mt,jn):null).visitAfter(v);for(r=_,g=0;g<x;++g)i=t[g],a.visit(y)}function c(){if(t){var _,g=t.length,x;for(o=new Array(g),_=0;_<g;++_)x=t[_],o[x.index]=+s(x,_,t)}}function v(_){var g=0,x,a,N=0,d,w,p,M,z=_.length;if(z){for(d=w=p=M=0;M<z;++M)(x=_[M])&&(a=Math.abs(x.value))&&(g+=x.value,N+=a,d+=a*(x.x||0),w+=a*(x.y||0),p+=a*(x.z||0));g*=Math.sqrt(4/z),_.x=d/N,n>1&&(_.y=w/N),n>2&&(_.z=p/N)}else{x=_,x.x=x.data.x,n>1&&(x.y=x.data.y),n>2&&(x.z=x.data.z);do g+=o[x.data.index];while(x=x.next)}_.value=g}function y(_,g,x,a,N){if(!_.value)return!0;var d=[x,a,N][n-1],w=_.x-i.x,p=n>1?_.y-i.y:0,M=n>2?_.z-i.z:0,z=d-g,A=w*w+p*p+M*M;if(z*z/f<A)return A<h&&(w===0&&(w=F(e),A+=w*w),n>1&&p===0&&(p=F(e),A+=p*p),n>2&&M===0&&(M=F(e),A+=M*M),A<u&&(A=Math.sqrt(u*A)),i.vx+=w*_.value*r/A,n>1&&(i.vy+=p*_.value*r/A),n>2&&(i.vz+=M*_.value*r/A)),!0;if(_.length||A>=h)return;(_.data!==i||_.next)&&(w===0&&(w=F(e),A+=w*w),n>1&&p===0&&(p=F(e),A+=p*p),n>2&&M===0&&(M=F(e),A+=M*M),A<u&&(A=Math.sqrt(u*A)));do _.data!==i&&(z=o[_.data.index]*r/A,i.vx+=w*z,n>1&&(i.vy+=p*z),n>2&&(i.vz+=M*z));while(_=_.next)}return l.initialize=function(_,...g){t=_,e=g.find(x=>typeof x=="function")||Math.random,n=g.find(x=>[1,2,3].includes(x))||2,c()},l.strength=function(_){return arguments.length?(s=typeof _=="function"?_:X(+_),c(),l):s},l.distanceMin=function(_){return arguments.length?(u=_*_,l):Math.sqrt(u)},l.distanceMax=function(_){return arguments.length?(h=_*_,l):Math.sqrt(h)},l.theta=function(_){return arguments.length?(f=_*_,l):Math.sqrt(f)},l}let S=null,j=[],nt=0,it=!1;self.onmessage=t=>{const n=t.data;if(n.type==="init"){S&&S.stop(),it=!1,nt=0;const i=n.nodes.length,e=n.params,r=n.initialPositions??{},s=e.dimensions===2?2:3;j=n.nodes.map((h,f)=>{const l=r[h.id];if(l)return{id:h.id,index:f,x:l.x,y:l.y,z:s===2?0:l.z};const c=Math.random()*Math.PI*2,v=e.initialRadius*(.5+Math.random()*.5);if(s===2)return{id:h.id,index:f,x:v*Math.cos(c),y:v*Math.sin(c),z:0};const y=Math.acos(2*Math.random()-1);return{id:h.id,index:f,x:v*Math.sin(y)*Math.cos(c),y:v*Math.sin(y)*Math.sin(c),z:v*Math.cos(y)}});const o=n.links.map(h=>({source:h.source,target:h.target}));S=On(j,s).force("charge",Rn().strength(e.charge).distanceMax(e.distanceMax).theta(e.theta)).force("link",zn(o).id(h=>h.id).distance(e.linkDistance).strength(.2)).force("center",At()).alphaDecay(e.alphaDecay).velocityDecay(e.velocityDecay);const u=n.groups;if(u&&u.length===j.length&&e.clusterStrength>0){const h=e.clusterStrength;S.force("cluster",f=>{const l={},c={},v={},y={};for(let g=0;g<j.length;g++){const x=u[g];x<0||(l[x]=(l[x]??0)+j[g].x,c[x]=(c[x]??0)+j[g].y,v[x]=(v[x]??0)+(j[g].z||0),y[x]=(y[x]??0)+1)}const _=h*f;for(let g=0;g<j.length;g++){const x=u[g];if(x<0||!y[x])continue;const a=j[g];a.vx=(a.vx||0)+(l[x]/y[x]-a.x)*_,a.vy=(a.vy||0)+(c[x]/y[x]-a.y)*_,s===3&&(a.vz=(a.vz||0)+(v[x]/y[x]-a.z)*_)}})}S.on("tick",()=>{nt++;const h=S.alpha();if(nt%e.postEvery!==0&&h>e.settledThreshold)return;const f=new Float32Array(i*3);for(let l=0;l<i;l++)f[l*3]=j[l].x||0,f[l*3+1]=j[l].y||0,f[l*3+2]=s===2?0:j[l].z||0;self.postMessage({type:"positions",positions:f.buffer,alpha:h},[f.buffer]),!it&&h<e.settledThreshold&&(it=!0,self.postMessage({type:"settled"}))})}n.type==="stop"&&S&&(S.stop(),S=null)}})();\n';
|
|
226
279
|
function createLayoutWorker() {
|
|
227
280
|
const blob = new Blob([WORKER_SOURCE], { type: "application/javascript" });
|
|
228
281
|
const url = URL.createObjectURL(blob);
|
|
@@ -1723,6 +1776,7 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1723
1776
|
const nc = nodes.length;
|
|
1724
1777
|
const tmpColor = new THREE__namespace.Color();
|
|
1725
1778
|
const brightTmp = new THREE__namespace.Color();
|
|
1779
|
+
const bgColor = new THREE__namespace.Color(theme.backgroundColor);
|
|
1726
1780
|
for (let i = 0; i < nc; i++) {
|
|
1727
1781
|
const node = nodes[i];
|
|
1728
1782
|
const baseColor = theme.nodeColor(node.type);
|
|
@@ -1730,13 +1784,17 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1730
1784
|
if (!highlightSet) {
|
|
1731
1785
|
tmpColor.set(baseColor);
|
|
1732
1786
|
} else if (node.id === selectedNodeId) {
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1787
|
+
if (theme.isLight) {
|
|
1788
|
+
tmpColor.set(brightColor);
|
|
1789
|
+
} else {
|
|
1790
|
+
tmpColor.set(brightColor);
|
|
1791
|
+
brightTmp.setRGB(1, 1, 1);
|
|
1792
|
+
tmpColor.lerp(brightTmp, 0.65);
|
|
1793
|
+
tmpColor.multiplyScalar(1.4);
|
|
1794
|
+
tmpColor.r = Math.min(tmpColor.r, 2);
|
|
1795
|
+
tmpColor.g = Math.min(tmpColor.g, 2);
|
|
1796
|
+
tmpColor.b = Math.min(tmpColor.b, 2);
|
|
1797
|
+
}
|
|
1740
1798
|
} else if (highlightSet.has(node.id)) {
|
|
1741
1799
|
const hop = highlightSet.get(node.id);
|
|
1742
1800
|
if (hop === 1) {
|
|
@@ -1748,6 +1806,8 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1748
1806
|
} else {
|
|
1749
1807
|
tmpColor.set(baseColor).multiplyScalar(0.6);
|
|
1750
1808
|
}
|
|
1809
|
+
} else if (theme.isLight) {
|
|
1810
|
+
tmpColor.set(baseColor).lerp(bgColor, 0.88);
|
|
1751
1811
|
} else {
|
|
1752
1812
|
tmpColor.set(baseColor).multiplyScalar(0.04);
|
|
1753
1813
|
}
|
|
@@ -1765,6 +1825,7 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
|
|
|
1765
1825
|
const colorArr = colorAttr.array;
|
|
1766
1826
|
const validCount = edgeNodeIndices.length;
|
|
1767
1827
|
const tmpColor = new THREE__namespace.Color();
|
|
1828
|
+
const bgColor = new THREE__namespace.Color(theme.backgroundColor);
|
|
1768
1829
|
for (let i = 0; i < validCount; i++) {
|
|
1769
1830
|
const origIdx = edgeLinkIndices[i];
|
|
1770
1831
|
const link = links[origIdx];
|
|
@@ -1776,13 +1837,19 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
|
|
|
1776
1837
|
const maxHopVal = Math.max(highlightSet.get(sId), highlightSet.get(tId));
|
|
1777
1838
|
tmpColor.set(theme.linkColor(link == null ? void 0 : link.type));
|
|
1778
1839
|
if (maxHopVal <= 1) {
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1840
|
+
if (theme.isLight) {
|
|
1841
|
+
tmpColor.multiplyScalar(0.55);
|
|
1842
|
+
} else {
|
|
1843
|
+
tmpColor.multiplyScalar(1.8);
|
|
1844
|
+
tmpColor.r = Math.min(tmpColor.r, 1);
|
|
1845
|
+
tmpColor.g = Math.min(tmpColor.g, 1);
|
|
1846
|
+
tmpColor.b = Math.min(tmpColor.b, 1);
|
|
1847
|
+
}
|
|
1783
1848
|
} else if (maxHopVal === 2) {
|
|
1784
|
-
tmpColor.multiplyScalar(1.2);
|
|
1849
|
+
tmpColor.multiplyScalar(theme.isLight ? 0.8 : 1.2);
|
|
1785
1850
|
}
|
|
1851
|
+
} else if (theme.isLight) {
|
|
1852
|
+
tmpColor.set(theme.linkColor(link == null ? void 0 : link.type)).lerp(bgColor, 0.85);
|
|
1786
1853
|
} else {
|
|
1787
1854
|
tmpColor.setRGB(0.01, 0.01, 0.02);
|
|
1788
1855
|
}
|
|
@@ -1912,7 +1979,7 @@ function getOrCreateTexture(cache, nodeId, text, color) {
|
|
|
1912
1979
|
}
|
|
1913
1980
|
return entry;
|
|
1914
1981
|
}
|
|
1915
|
-
function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet) {
|
|
1982
|
+
function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet, hidden) {
|
|
1916
1983
|
if (!positions || nodes.length === 0 || !showLabels) {
|
|
1917
1984
|
for (const sp of state.sprites) sp.visible = false;
|
|
1918
1985
|
return;
|
|
@@ -1926,6 +1993,7 @@ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels
|
|
|
1926
1993
|
const maxDistSq = maxDist * maxDist;
|
|
1927
1994
|
const candidates = [];
|
|
1928
1995
|
for (let i = 0; i < nc; i++) {
|
|
1996
|
+
if (hidden && hidden[i]) continue;
|
|
1929
1997
|
if (highlightSet && !highlightSet.has(nodes[i].id)) continue;
|
|
1930
1998
|
const dx = positions[i * 3] - camPos.x;
|
|
1931
1999
|
const dy = positions[i * 3 + 1] - camPos.y;
|
|
@@ -1981,6 +2049,45 @@ const _right = new THREE__namespace.Vector3();
|
|
|
1981
2049
|
const _q = new THREE__namespace.Quaternion();
|
|
1982
2050
|
const _dir = new THREE__namespace.Vector3();
|
|
1983
2051
|
const _worldUp = new THREE__namespace.Vector3(0, 1, 0);
|
|
2052
|
+
const PAN_SPEED = 0.02;
|
|
2053
|
+
const PAN_ZOOM_FACTOR = 0.02;
|
|
2054
|
+
function createPanUpdate(camera, controls, keys) {
|
|
2055
|
+
const _panRight = new THREE__namespace.Vector3();
|
|
2056
|
+
const _panUp = new THREE__namespace.Vector3();
|
|
2057
|
+
const _panOffset = new THREE__namespace.Vector3();
|
|
2058
|
+
return function update() {
|
|
2059
|
+
let dx = 0;
|
|
2060
|
+
let dy = 0;
|
|
2061
|
+
if (keys["ArrowLeft"] || keys["a"] || keys["A"]) dx -= 1;
|
|
2062
|
+
if (keys["ArrowRight"] || keys["d"] || keys["D"]) dx += 1;
|
|
2063
|
+
if (keys["ArrowUp"] || keys["w"] || keys["W"]) dy += 1;
|
|
2064
|
+
if (keys["ArrowDown"] || keys["s"] || keys["S"]) dy -= 1;
|
|
2065
|
+
const zoomIn = keys["z"] || keys["Z"] || keys["+"] || keys["="];
|
|
2066
|
+
const zoomOut = keys["x"] || keys["X"] || keys["-"] || keys["_"];
|
|
2067
|
+
if (!dx && !dy && !zoomIn && !zoomOut) return false;
|
|
2068
|
+
const target = controls.target;
|
|
2069
|
+
const dist = camera.position.distanceTo(target);
|
|
2070
|
+
if (dx || dy) {
|
|
2071
|
+
const step = Math.max(dist, 50) * PAN_SPEED;
|
|
2072
|
+
_panRight.setFromMatrixColumn(camera.matrix, 0);
|
|
2073
|
+
_panUp.setFromMatrixColumn(camera.matrix, 1);
|
|
2074
|
+
_panOffset.set(0, 0, 0).addScaledVector(_panRight, dx * step).addScaledVector(_panUp, dy * step);
|
|
2075
|
+
camera.position.add(_panOffset);
|
|
2076
|
+
target.add(_panOffset);
|
|
2077
|
+
}
|
|
2078
|
+
if (zoomIn || zoomOut) {
|
|
2079
|
+
const factor = zoomIn ? -PAN_ZOOM_FACTOR : PAN_ZOOM_FACTOR;
|
|
2080
|
+
_panOffset.copy(camera.position).sub(target);
|
|
2081
|
+
const newLen = Math.max(
|
|
2082
|
+
controls.minDistance,
|
|
2083
|
+
Math.min(controls.maxDistance, _panOffset.length() * (1 + factor))
|
|
2084
|
+
);
|
|
2085
|
+
_panOffset.setLength(newLen);
|
|
2086
|
+
camera.position.copy(target).add(_panOffset);
|
|
2087
|
+
}
|
|
2088
|
+
return true;
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
1984
2091
|
function createOrbitUpdate(camera, controls, keys) {
|
|
1985
2092
|
return function update() {
|
|
1986
2093
|
let zoom = 0;
|
|
@@ -2079,7 +2186,14 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
|
|
|
2079
2186
|
container.addEventListener("keydown", onKeyDown2);
|
|
2080
2187
|
container.addEventListener("keyup", onKeyUp);
|
|
2081
2188
|
container.addEventListener("blur", onBlur);
|
|
2082
|
-
|
|
2189
|
+
let enabled = true;
|
|
2190
|
+
let currentMode = mode;
|
|
2191
|
+
const updaters = {
|
|
2192
|
+
fly: createFlyUpdate(camera, controls, keys, state),
|
|
2193
|
+
orbit: createOrbitUpdate(camera, controls, keys),
|
|
2194
|
+
pan: createPanUpdate(camera, controls, keys)
|
|
2195
|
+
};
|
|
2196
|
+
const updateFn = () => enabled ? updaters[currentMode]() : false;
|
|
2083
2197
|
function cleanup() {
|
|
2084
2198
|
container.removeEventListener("keydown", onKeyDown2);
|
|
2085
2199
|
container.removeEventListener("keyup", onKeyUp);
|
|
@@ -2088,7 +2202,15 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
|
|
|
2088
2202
|
function setFlySpeed(speed) {
|
|
2089
2203
|
state.flySpeed = speed;
|
|
2090
2204
|
}
|
|
2091
|
-
|
|
2205
|
+
function setEnabled(on) {
|
|
2206
|
+
enabled = on;
|
|
2207
|
+
if (!on) for (const k of Object.keys(keys)) keys[k] = false;
|
|
2208
|
+
}
|
|
2209
|
+
function setMode(m2) {
|
|
2210
|
+
currentMode = m2;
|
|
2211
|
+
for (const k of Object.keys(keys)) keys[k] = false;
|
|
2212
|
+
}
|
|
2213
|
+
return { update: updateFn, cleanup, setFlySpeed, setEnabled, setMode };
|
|
2092
2214
|
}
|
|
2093
2215
|
function createScene(container, backgroundColor, style, rendererConfig) {
|
|
2094
2216
|
const scene = new THREE__namespace.Scene();
|
|
@@ -2128,8 +2250,13 @@ function createScene(container, backgroundColor, style, rendererConfig) {
|
|
|
2128
2250
|
const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
|
|
2129
2251
|
const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
|
|
2130
2252
|
controls.enableZoom = false;
|
|
2253
|
+
const flags = {
|
|
2254
|
+
is2D: false,
|
|
2255
|
+
keyboardMode3D: cameraMode
|
|
2256
|
+
};
|
|
2131
2257
|
const _wheelDir = new THREE__namespace.Vector3();
|
|
2132
2258
|
const onWheel = (e) => {
|
|
2259
|
+
if (flags.is2D) return;
|
|
2133
2260
|
e.preventDefault();
|
|
2134
2261
|
let delta = -e.deltaY;
|
|
2135
2262
|
if (e.deltaMode === 1) delta *= 40;
|
|
@@ -2153,9 +2280,41 @@ function createScene(container, backgroundColor, style, rendererConfig) {
|
|
|
2153
2280
|
composer: null,
|
|
2154
2281
|
bloomPass: null,
|
|
2155
2282
|
keyboard,
|
|
2156
|
-
scrollCleanup
|
|
2283
|
+
scrollCleanup,
|
|
2284
|
+
flags
|
|
2157
2285
|
};
|
|
2158
2286
|
}
|
|
2287
|
+
function applyCameraMode2D(state, is2D) {
|
|
2288
|
+
const { controls, camera, keyboard } = state;
|
|
2289
|
+
state.flags.is2D = is2D;
|
|
2290
|
+
controls.enableRotate = true;
|
|
2291
|
+
controls.enableZoom = is2D;
|
|
2292
|
+
controls.screenSpacePanning = is2D;
|
|
2293
|
+
keyboard.setEnabled(true);
|
|
2294
|
+
keyboard.setMode(is2D ? "pan" : state.flags.keyboardMode3D);
|
|
2295
|
+
if (is2D) {
|
|
2296
|
+
controls.mouseButtons = {
|
|
2297
|
+
LEFT: THREE__namespace.MOUSE.PAN,
|
|
2298
|
+
MIDDLE: THREE__namespace.MOUSE.DOLLY,
|
|
2299
|
+
RIGHT: THREE__namespace.MOUSE.ROTATE
|
|
2300
|
+
};
|
|
2301
|
+
controls.touches = { ONE: THREE__namespace.TOUCH.PAN, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
|
|
2302
|
+
const t = controls.target;
|
|
2303
|
+
const dist = Math.max(camera.position.distanceTo(t), 50);
|
|
2304
|
+
t.z = 0;
|
|
2305
|
+
camera.up.set(0, 1, 0);
|
|
2306
|
+
camera.position.set(t.x, t.y, dist);
|
|
2307
|
+
camera.lookAt(t);
|
|
2308
|
+
} else {
|
|
2309
|
+
controls.mouseButtons = {
|
|
2310
|
+
LEFT: THREE__namespace.MOUSE.ROTATE,
|
|
2311
|
+
MIDDLE: THREE__namespace.MOUSE.DOLLY,
|
|
2312
|
+
RIGHT: THREE__namespace.MOUSE.PAN
|
|
2313
|
+
};
|
|
2314
|
+
controls.touches = { ONE: THREE__namespace.TOUCH.ROTATE, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
|
|
2315
|
+
}
|
|
2316
|
+
controls.update();
|
|
2317
|
+
}
|
|
2159
2318
|
function initBloom(state, nodeCount, style) {
|
|
2160
2319
|
if (state.composer) return;
|
|
2161
2320
|
try {
|
|
@@ -2352,14 +2511,14 @@ function createNodeMesh(nodes, scales, theme) {
|
|
|
2352
2511
|
mesh.computeBoundingSphere();
|
|
2353
2512
|
return { mesh, material, scales };
|
|
2354
2513
|
}
|
|
2355
|
-
function updateNodePositions(mesh, positions, scales, nodeCount) {
|
|
2514
|
+
function updateNodePositions(mesh, positions, scales, nodeCount, hidden) {
|
|
2356
2515
|
const pos = new THREE__namespace.Vector3();
|
|
2357
2516
|
const scale = new THREE__namespace.Vector3();
|
|
2358
2517
|
const quat = new THREE__namespace.Quaternion();
|
|
2359
2518
|
const mat = new THREE__namespace.Matrix4();
|
|
2360
2519
|
for (let i = 0; i < nodeCount; i++) {
|
|
2361
2520
|
pos.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
|
|
2362
|
-
const sc = scales[i];
|
|
2521
|
+
const sc = hidden && hidden[i] ? 1e-4 : scales[i];
|
|
2363
2522
|
scale.set(sc, sc, sc);
|
|
2364
2523
|
mat.compose(pos, quat, scale);
|
|
2365
2524
|
mesh.setMatrixAt(i, mat);
|
|
@@ -2416,7 +2575,7 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
|
|
|
2416
2575
|
transparent: true,
|
|
2417
2576
|
opacity: adaptiveOpacity,
|
|
2418
2577
|
depthWrite: false,
|
|
2419
|
-
blending: THREE__namespace.AdditiveBlending
|
|
2578
|
+
blending: theme.additiveEdges ? THREE__namespace.AdditiveBlending : THREE__namespace.NormalBlending
|
|
2420
2579
|
});
|
|
2421
2580
|
const mesh = new THREE__namespace.LineSegments(geometry, material);
|
|
2422
2581
|
return {
|
|
@@ -2428,10 +2587,19 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
|
|
|
2428
2587
|
edgeLinkIndices
|
|
2429
2588
|
};
|
|
2430
2589
|
}
|
|
2431
|
-
function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry) {
|
|
2590
|
+
function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry, hiddenEdges) {
|
|
2432
2591
|
const count = edgeNodeIndices.length;
|
|
2433
2592
|
for (let i = 0; i < count; i++) {
|
|
2434
2593
|
const [si, ti] = edgeNodeIndices[i];
|
|
2594
|
+
if (hiddenEdges && hiddenEdges[i]) {
|
|
2595
|
+
positionArray[i * 6 + 0] = nodePositions[si * 3];
|
|
2596
|
+
positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
|
|
2597
|
+
positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
|
|
2598
|
+
positionArray[i * 6 + 3] = nodePositions[si * 3];
|
|
2599
|
+
positionArray[i * 6 + 4] = nodePositions[si * 3 + 1];
|
|
2600
|
+
positionArray[i * 6 + 5] = nodePositions[si * 3 + 2];
|
|
2601
|
+
continue;
|
|
2602
|
+
}
|
|
2435
2603
|
positionArray[i * 6 + 0] = nodePositions[si * 3];
|
|
2436
2604
|
positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
|
|
2437
2605
|
positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
|
|
@@ -2494,7 +2662,7 @@ function zoomToFitPositions(camera, controls, positions, duration, padding) {
|
|
|
2494
2662
|
);
|
|
2495
2663
|
}
|
|
2496
2664
|
const EDGE_HIT_THRESHOLD = 5;
|
|
2497
|
-
function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData) {
|
|
2665
|
+
function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData, options) {
|
|
2498
2666
|
const raycaster = new THREE__namespace.Raycaster();
|
|
2499
2667
|
const mouse = new THREE__namespace.Vector2();
|
|
2500
2668
|
let mouseDownPos = null;
|
|
@@ -2506,11 +2674,12 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
|
|
|
2506
2674
|
const dragPlane = new THREE__namespace.Plane();
|
|
2507
2675
|
const dragIntersect = new THREE__namespace.Vector3();
|
|
2508
2676
|
function onPointerDown2(e) {
|
|
2677
|
+
var _a;
|
|
2509
2678
|
mouseDownPos = { x: e.clientX, y: e.clientY };
|
|
2510
2679
|
if (container && document.activeElement !== container) {
|
|
2511
2680
|
container.focus({ preventScroll: true });
|
|
2512
2681
|
}
|
|
2513
|
-
if (callbacks.onNodeDrag) {
|
|
2682
|
+
if (callbacks.onNodeDrag && (((_a = options == null ? void 0 : options.getNodeDragEnabled) == null ? void 0 : _a.call(options)) ?? true)) {
|
|
2514
2683
|
const nodesMesh = getNodesMesh();
|
|
2515
2684
|
if (nodesMesh) {
|
|
2516
2685
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -2652,20 +2821,34 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
|
|
|
2652
2821
|
lastClickTime = now2;
|
|
2653
2822
|
lastClickNodeId = node.id;
|
|
2654
2823
|
singleClickTimer = setTimeout(() => {
|
|
2824
|
+
var _a2, _b;
|
|
2655
2825
|
singleClickTimer = null;
|
|
2656
|
-
const
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2826
|
+
const clickToFocus = ((_a2 = options == null ? void 0 : options.getClickToFocus) == null ? void 0 : _a2.call(options)) ?? true;
|
|
2827
|
+
if (clickToFocus) {
|
|
2828
|
+
const nx = node.x ?? 0;
|
|
2829
|
+
const ny = node.y ?? 0;
|
|
2830
|
+
const nz = node.z ?? 0;
|
|
2831
|
+
if ((_b = options == null ? void 0 : options.getIs2D) == null ? void 0 : _b.call(options)) {
|
|
2832
|
+
animateCamera(
|
|
2833
|
+
camera,
|
|
2834
|
+
controls,
|
|
2835
|
+
{ x: nx, y: ny, z: camera.position.z },
|
|
2836
|
+
{ x: nx, y: ny, z: 0 },
|
|
2837
|
+
800
|
|
2838
|
+
);
|
|
2839
|
+
} else {
|
|
2840
|
+
const dist = Math.hypot(nx, ny, nz);
|
|
2841
|
+
if (dist > 1) {
|
|
2842
|
+
const ratio = 1 + 120 / dist;
|
|
2843
|
+
animateCamera(
|
|
2844
|
+
camera,
|
|
2845
|
+
controls,
|
|
2846
|
+
{ x: nx * ratio, y: ny * ratio, z: nz * ratio },
|
|
2847
|
+
{ x: nx, y: ny, z: nz },
|
|
2848
|
+
1200
|
|
2849
|
+
);
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2669
2852
|
}
|
|
2670
2853
|
callbacks.onNodeClick(node);
|
|
2671
2854
|
}, 250);
|
|
@@ -2805,7 +2988,13 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2805
2988
|
layout: layoutProp,
|
|
2806
2989
|
renderer: rendererProp,
|
|
2807
2990
|
labelFormatter,
|
|
2808
|
-
nodeValueAccessor
|
|
2991
|
+
nodeValueAccessor,
|
|
2992
|
+
visibleNodeIds,
|
|
2993
|
+
linkVisibility,
|
|
2994
|
+
enableNodeDrag = true,
|
|
2995
|
+
clickToFocus = true,
|
|
2996
|
+
hoverHighlight = false,
|
|
2997
|
+
hoverHighlightHops = 1
|
|
2809
2998
|
} = props;
|
|
2810
2999
|
const containerRef = react.useRef(null);
|
|
2811
3000
|
const resolvedStyle = react.useMemo(
|
|
@@ -2842,6 +3031,14 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2842
3031
|
const selectedNodeIdRef = react.useRef(selectedNodeId);
|
|
2843
3032
|
const labelFormatterRef = react.useRef(labelFormatter);
|
|
2844
3033
|
const highlightSetRef = react.useRef(null);
|
|
3034
|
+
const clickToFocusRef = react.useRef(clickToFocus);
|
|
3035
|
+
const enableNodeDragRef = react.useRef(enableNodeDrag);
|
|
3036
|
+
const hoverHighlightRef = react.useRef(hoverHighlight);
|
|
3037
|
+
const hoverHighlightHopsRef = react.useRef(hoverHighlightHops);
|
|
3038
|
+
const adjacencyMapRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3039
|
+
const is2DRef = react.useRef(false);
|
|
3040
|
+
const hiddenNodesRef = react.useRef(null);
|
|
3041
|
+
const hiddenEdgesRef = react.useRef(null);
|
|
2845
3042
|
onNodeClickRef.current = onNodeClick;
|
|
2846
3043
|
onNodeDoubleClickRef.current = onNodeDoubleClick;
|
|
2847
3044
|
onNodeHoverRef.current = onNodeHover;
|
|
@@ -2856,6 +3053,15 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2856
3053
|
themeRef.current = resolvedTheme;
|
|
2857
3054
|
selectedNodeIdRef.current = selectedNodeId;
|
|
2858
3055
|
labelFormatterRef.current = labelFormatter;
|
|
3056
|
+
clickToFocusRef.current = clickToFocus;
|
|
3057
|
+
enableNodeDragRef.current = enableNodeDrag;
|
|
3058
|
+
hoverHighlightRef.current = hoverHighlight;
|
|
3059
|
+
hoverHighlightHopsRef.current = hoverHighlightHops;
|
|
3060
|
+
const is2D = (layoutProp == null ? void 0 : layoutProp.dimensions) === 2;
|
|
3061
|
+
is2DRef.current = is2D;
|
|
3062
|
+
const layoutKey = JSON.stringify(layoutProp ?? null);
|
|
3063
|
+
const layoutRef = react.useRef(layoutProp);
|
|
3064
|
+
layoutRef.current = layoutProp;
|
|
2859
3065
|
const mergedData = react.useMemo(() => {
|
|
2860
3066
|
if (!appendedData) return data;
|
|
2861
3067
|
const existingIds = new Set(data.nodes.map((n) => n.id));
|
|
@@ -2882,6 +3088,11 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2882
3088
|
() => buildAdjacencyMapFromLinks(mergedData.links),
|
|
2883
3089
|
[mergedData.links]
|
|
2884
3090
|
);
|
|
3091
|
+
adjacencyMapRef.current = adjacencyMap;
|
|
3092
|
+
const visibleSet = react.useMemo(() => {
|
|
3093
|
+
if (visibleNodeIds == null) return null;
|
|
3094
|
+
return visibleNodeIds instanceof Set ? visibleNodeIds : new Set(visibleNodeIds);
|
|
3095
|
+
}, [visibleNodeIds]);
|
|
2885
3096
|
const highlightSet = react.useMemo(() => {
|
|
2886
3097
|
if (!selectedNodeId) return null;
|
|
2887
3098
|
return computeHighlightSet(selectedNodeId, adjacencyMap, highlightHops);
|
|
@@ -2895,6 +3106,32 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2895
3106
|
}
|
|
2896
3107
|
return { min: isFinite(min) ? min : 1, max: isFinite(max) ? max : 1 };
|
|
2897
3108
|
}, [mergedData.nodes, nodeValueAccessor]);
|
|
3109
|
+
const applyHoverHighlight = (node) => {
|
|
3110
|
+
if (!hoverHighlightRef.current) return;
|
|
3111
|
+
if (selectedNodeIdRef.current) return;
|
|
3112
|
+
const gObj = graphObjRef.current;
|
|
3113
|
+
if (!gObj) return;
|
|
3114
|
+
const d = dataRef.current;
|
|
3115
|
+
const set2 = node ? computeHighlightSet(
|
|
3116
|
+
node.id,
|
|
3117
|
+
adjacencyMapRef.current,
|
|
3118
|
+
hoverHighlightHopsRef.current
|
|
3119
|
+
) : null;
|
|
3120
|
+
highlightSetRef.current = set2;
|
|
3121
|
+
applyNodeHighlight(gObj.nodesMesh, d.nodes, (node == null ? void 0 : node.id) ?? null, set2, themeRef.current);
|
|
3122
|
+
applyEdgeHighlight(
|
|
3123
|
+
gObj.edgesMesh,
|
|
3124
|
+
d.links,
|
|
3125
|
+
d.edgeNodeIndices,
|
|
3126
|
+
d.edgeLinkIndices,
|
|
3127
|
+
set2,
|
|
3128
|
+
styleRef.current.edgeOpacity,
|
|
3129
|
+
d.nodes.length,
|
|
3130
|
+
themeRef.current
|
|
3131
|
+
);
|
|
3132
|
+
};
|
|
3133
|
+
const applyHoverHighlightRef = react.useRef(applyHoverHighlight);
|
|
3134
|
+
applyHoverHighlightRef.current = applyHoverHighlight;
|
|
2898
3135
|
react.useEffect(() => {
|
|
2899
3136
|
const container = containerRef.current;
|
|
2900
3137
|
if (!container) return;
|
|
@@ -2918,7 +3155,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2918
3155
|
styleRef.current.labelThreshold,
|
|
2919
3156
|
styleRef.current.maxLabels,
|
|
2920
3157
|
labelFormatterRef.current,
|
|
2921
|
-
highlightSetRef.current
|
|
3158
|
+
highlightSetRef.current,
|
|
3159
|
+
hiddenNodesRef.current
|
|
2922
3160
|
);
|
|
2923
3161
|
});
|
|
2924
3162
|
const resizeObserver = setupResize(container, state);
|
|
@@ -2942,7 +3180,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2942
3180
|
},
|
|
2943
3181
|
onNodeHover: (node) => {
|
|
2944
3182
|
var _a;
|
|
2945
|
-
|
|
3183
|
+
(_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
|
|
3184
|
+
applyHoverHighlightRef.current(node);
|
|
2946
3185
|
},
|
|
2947
3186
|
onContextMenu: (node, pos) => {
|
|
2948
3187
|
var _a;
|
|
@@ -2958,6 +3197,7 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2958
3197
|
},
|
|
2959
3198
|
onNodeDrag: (node, pos) => {
|
|
2960
3199
|
var _a;
|
|
3200
|
+
if (is2DRef.current) pos = { ...pos, z: 0 };
|
|
2961
3201
|
(_a = onNodeDragRef.current) == null ? void 0 : _a.call(onNodeDragRef, node, pos);
|
|
2962
3202
|
const d = dataRef.current;
|
|
2963
3203
|
const idx = d.nodeIdToIndex.get(node.id);
|
|
@@ -2970,7 +3210,13 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2970
3210
|
node.z = pos.z;
|
|
2971
3211
|
const gObj = graphObjRef.current;
|
|
2972
3212
|
if (gObj && d.scales) {
|
|
2973
|
-
updateNodePositions(
|
|
3213
|
+
updateNodePositions(
|
|
3214
|
+
gObj.nodesMesh,
|
|
3215
|
+
d.positions,
|
|
3216
|
+
d.scales,
|
|
3217
|
+
d.nodes.length,
|
|
3218
|
+
hiddenNodesRef.current
|
|
3219
|
+
);
|
|
2974
3220
|
}
|
|
2975
3221
|
}
|
|
2976
3222
|
},
|
|
@@ -2988,6 +3234,11 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2988
3234
|
edgeLinkIndices: d.edgeLinkIndices,
|
|
2989
3235
|
positions: d.positions
|
|
2990
3236
|
};
|
|
3237
|
+
},
|
|
3238
|
+
{
|
|
3239
|
+
getClickToFocus: () => clickToFocusRef.current,
|
|
3240
|
+
getIs2D: () => is2DRef.current,
|
|
3241
|
+
getNodeDragEnabled: () => enableNodeDragRef.current
|
|
2991
3242
|
}
|
|
2992
3243
|
);
|
|
2993
3244
|
return () => {
|
|
@@ -3134,17 +3385,26 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3134
3385
|
if (msg.type === "positions") {
|
|
3135
3386
|
const positions = new Float32Array(msg.positions);
|
|
3136
3387
|
dataRef.current.positions = positions;
|
|
3137
|
-
|
|
3388
|
+
const hn = hiddenNodesRef.current;
|
|
3389
|
+
updateNodePositions(
|
|
3390
|
+
nodesMesh,
|
|
3391
|
+
positions,
|
|
3392
|
+
scales,
|
|
3393
|
+
nc,
|
|
3394
|
+
hn && hn.length === nc ? hn : null
|
|
3395
|
+
);
|
|
3138
3396
|
for (let i = 0; i < nc; i++) {
|
|
3139
3397
|
nodes[i].x = positions[i * 3];
|
|
3140
3398
|
nodes[i].y = positions[i * 3 + 1];
|
|
3141
3399
|
nodes[i].z = positions[i * 3 + 2];
|
|
3142
3400
|
}
|
|
3401
|
+
const he = hiddenEdgesRef.current;
|
|
3143
3402
|
updateEdgePositions(
|
|
3144
3403
|
edgeResult.positionArray,
|
|
3145
3404
|
positions,
|
|
3146
3405
|
edgeNodeIndices,
|
|
3147
|
-
edgeResult.geometry
|
|
3406
|
+
edgeResult.geometry,
|
|
3407
|
+
he && he.length === edgeNodeIndices.length ? he : null
|
|
3148
3408
|
);
|
|
3149
3409
|
const selId = selectedNodeIdRef.current;
|
|
3150
3410
|
if (selId && sceneState.selectionRing.visible) {
|
|
@@ -3164,7 +3424,20 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3164
3424
|
(_b = onLayoutSettledRef.current) == null ? void 0 : _b.call(onLayoutSettledRef);
|
|
3165
3425
|
}
|
|
3166
3426
|
};
|
|
3167
|
-
const
|
|
3427
|
+
const layoutConfig = layoutRef.current;
|
|
3428
|
+
const layoutParams = resolveLayoutParams(nc, layoutConfig);
|
|
3429
|
+
let groups;
|
|
3430
|
+
if (layoutConfig == null ? void 0 : layoutConfig.clusterBy) {
|
|
3431
|
+
const keyOf = (n) => layoutConfig.clusterBy === "type" ? n.type : n.group;
|
|
3432
|
+
const keyToIdx = /* @__PURE__ */ new Map();
|
|
3433
|
+
groups = nodes.map((n) => {
|
|
3434
|
+
const k = keyOf(n);
|
|
3435
|
+
if (k == null) return -1;
|
|
3436
|
+
const ks = String(k);
|
|
3437
|
+
if (!keyToIdx.has(ks)) keyToIdx.set(ks, keyToIdx.size);
|
|
3438
|
+
return keyToIdx.get(ks);
|
|
3439
|
+
});
|
|
3440
|
+
}
|
|
3168
3441
|
worker.postMessage({
|
|
3169
3442
|
type: "init",
|
|
3170
3443
|
nodes: nodes.map((n) => ({ id: n.id })),
|
|
@@ -3173,7 +3446,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3173
3446
|
target: typeof l.target === "object" ? l.target.id : l.target
|
|
3174
3447
|
})),
|
|
3175
3448
|
params: layoutParams,
|
|
3176
|
-
initialPositions: preservedPositionsRef.current
|
|
3449
|
+
initialPositions: preservedPositionsRef.current,
|
|
3450
|
+
groups
|
|
3177
3451
|
});
|
|
3178
3452
|
return () => {
|
|
3179
3453
|
const d = dataRef.current;
|
|
@@ -3198,7 +3472,56 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3198
3472
|
disposeObject(edgeResult.mesh);
|
|
3199
3473
|
graphObjRef.current = null;
|
|
3200
3474
|
};
|
|
3201
|
-
}, [mergedData, valRange, nodeValueAccessor,
|
|
3475
|
+
}, [mergedData, valRange, nodeValueAccessor, layoutKey]);
|
|
3476
|
+
react.useEffect(() => {
|
|
3477
|
+
const d = dataRef.current;
|
|
3478
|
+
const gObj = graphObjRef.current;
|
|
3479
|
+
if (!visibleSet && !linkVisibility) {
|
|
3480
|
+
hiddenNodesRef.current = null;
|
|
3481
|
+
hiddenEdgesRef.current = null;
|
|
3482
|
+
} else {
|
|
3483
|
+
const nc = d.nodes.length;
|
|
3484
|
+
const hn = new Uint8Array(nc);
|
|
3485
|
+
if (visibleSet) {
|
|
3486
|
+
for (let i = 0; i < nc; i++) {
|
|
3487
|
+
if (!visibleSet.has(d.nodes[i].id)) hn[i] = 1;
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
const ec = d.edgeNodeIndices.length;
|
|
3491
|
+
const he = new Uint8Array(ec);
|
|
3492
|
+
for (let i = 0; i < ec; i++) {
|
|
3493
|
+
const [si, ti] = d.edgeNodeIndices[i];
|
|
3494
|
+
if (hn[si] || hn[ti]) {
|
|
3495
|
+
he[i] = 1;
|
|
3496
|
+
} else if (linkVisibility) {
|
|
3497
|
+
const link = d.links[d.edgeLinkIndices[i]];
|
|
3498
|
+
if (link && !linkVisibility(link)) he[i] = 1;
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
hiddenNodesRef.current = visibleSet ? hn : null;
|
|
3502
|
+
hiddenEdgesRef.current = he;
|
|
3503
|
+
}
|
|
3504
|
+
if (gObj && d.positions && d.scales) {
|
|
3505
|
+
updateNodePositions(
|
|
3506
|
+
gObj.nodesMesh,
|
|
3507
|
+
d.positions,
|
|
3508
|
+
d.scales,
|
|
3509
|
+
d.nodes.length,
|
|
3510
|
+
hiddenNodesRef.current
|
|
3511
|
+
);
|
|
3512
|
+
updateEdgePositions(
|
|
3513
|
+
gObj.edgePositionArray,
|
|
3514
|
+
d.positions,
|
|
3515
|
+
d.edgeNodeIndices,
|
|
3516
|
+
gObj.edgeGeometry,
|
|
3517
|
+
hiddenEdgesRef.current
|
|
3518
|
+
);
|
|
3519
|
+
}
|
|
3520
|
+
}, [visibleSet, linkVisibility, mergedData]);
|
|
3521
|
+
react.useEffect(() => {
|
|
3522
|
+
const s = sceneRef.current;
|
|
3523
|
+
if (s) applyCameraMode2D(s, is2D);
|
|
3524
|
+
}, [is2D]);
|
|
3202
3525
|
react.useEffect(() => {
|
|
3203
3526
|
const gObj = graphObjRef.current;
|
|
3204
3527
|
const sceneState = sceneRef.current;
|
|
@@ -3266,7 +3589,7 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3266
3589
|
resolvedStyle.nodeMaxSize
|
|
3267
3590
|
);
|
|
3268
3591
|
dataRef.current.scales = newScales;
|
|
3269
|
-
updateNodePositions(gObj.nodesMesh, positions, newScales, nc);
|
|
3592
|
+
updateNodePositions(gObj.nodesMesh, positions, newScales, nc, hiddenNodesRef.current);
|
|
3270
3593
|
}, [resolvedStyle.nodeMinSize, resolvedStyle.nodeMaxSize, valRange]);
|
|
3271
3594
|
react.useEffect(() => {
|
|
3272
3595
|
const gObj = graphObjRef.current;
|
|
@@ -3355,6 +3678,17 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3355
3678
|
const nx = d.positions[idx * 3];
|
|
3356
3679
|
const ny = d.positions[idx * 3 + 1];
|
|
3357
3680
|
const nz = d.positions[idx * 3 + 2];
|
|
3681
|
+
if (is2DRef.current) {
|
|
3682
|
+
const z2 = Math.max(120, Math.min(Math.abs(s.camera.position.z), 500));
|
|
3683
|
+
animateCamera(
|
|
3684
|
+
s.camera,
|
|
3685
|
+
s.controls,
|
|
3686
|
+
{ x: nx, y: ny, z: z2 },
|
|
3687
|
+
{ x: nx, y: ny, z: 0 },
|
|
3688
|
+
duration
|
|
3689
|
+
);
|
|
3690
|
+
return;
|
|
3691
|
+
}
|
|
3358
3692
|
const dist = Math.hypot(nx, ny, nz);
|
|
3359
3693
|
if (dist < 1) return;
|
|
3360
3694
|
const ratio = 1 + 120 / dist;
|
|
@@ -3366,6 +3700,34 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3366
3700
|
duration
|
|
3367
3701
|
);
|
|
3368
3702
|
},
|
|
3703
|
+
panTo(x2, y2, duration = 600) {
|
|
3704
|
+
const s = sceneRef.current;
|
|
3705
|
+
if (!s) return;
|
|
3706
|
+
const t = s.controls.target;
|
|
3707
|
+
if (is2DRef.current) {
|
|
3708
|
+
animateCamera(
|
|
3709
|
+
s.camera,
|
|
3710
|
+
s.controls,
|
|
3711
|
+
{ x: x2, y: y2, z: s.camera.position.z },
|
|
3712
|
+
{ x: x2, y: y2, z: 0 },
|
|
3713
|
+
duration
|
|
3714
|
+
);
|
|
3715
|
+
} else {
|
|
3716
|
+
const dx = x2 - t.x;
|
|
3717
|
+
const dy = y2 - t.y;
|
|
3718
|
+
animateCamera(
|
|
3719
|
+
s.camera,
|
|
3720
|
+
s.controls,
|
|
3721
|
+
{
|
|
3722
|
+
x: s.camera.position.x + dx,
|
|
3723
|
+
y: s.camera.position.y + dy,
|
|
3724
|
+
z: s.camera.position.z
|
|
3725
|
+
},
|
|
3726
|
+
{ x: x2, y: y2, z: t.z },
|
|
3727
|
+
duration
|
|
3728
|
+
);
|
|
3729
|
+
}
|
|
3730
|
+
},
|
|
3369
3731
|
appendData(newNodes, newLinks) {
|
|
3370
3732
|
if (newNodes.length === 0 && newLinks.length === 0) return 0;
|
|
3371
3733
|
const existingIds = new Set(dataRef.current.nodes.map((n) => n.id));
|
|
@@ -3394,6 +3756,32 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3394
3756
|
s.renderer.render(s.scene, s.camera);
|
|
3395
3757
|
return s.renderer.domElement.toDataURL("image/png");
|
|
3396
3758
|
},
|
|
3759
|
+
getGraphSnapshot() {
|
|
3760
|
+
var _a;
|
|
3761
|
+
const gObj = graphObjRef.current;
|
|
3762
|
+
const d = dataRef.current;
|
|
3763
|
+
if (!gObj || !d.positions) return null;
|
|
3764
|
+
return {
|
|
3765
|
+
positions: d.positions,
|
|
3766
|
+
count: d.nodes.length,
|
|
3767
|
+
colors: ((_a = gObj.nodesMesh.instanceColor) == null ? void 0 : _a.array) ?? null,
|
|
3768
|
+
hidden: hiddenNodesRef.current,
|
|
3769
|
+
selectedIndex: selectedNodeIdRef.current ? d.nodeIdToIndex.get(selectedNodeIdRef.current) ?? -1 : -1
|
|
3770
|
+
};
|
|
3771
|
+
},
|
|
3772
|
+
getViewportRect() {
|
|
3773
|
+
const s = sceneRef.current;
|
|
3774
|
+
if (!s) return null;
|
|
3775
|
+
const cam = s.camera;
|
|
3776
|
+
const dist = Math.abs(cam.position.z);
|
|
3777
|
+
const halfH = Math.tan(cam.fov * Math.PI / 360) * dist;
|
|
3778
|
+
return {
|
|
3779
|
+
cx: cam.position.x,
|
|
3780
|
+
cy: cam.position.y,
|
|
3781
|
+
halfW: halfH * cam.aspect,
|
|
3782
|
+
halfH
|
|
3783
|
+
};
|
|
3784
|
+
},
|
|
3397
3785
|
reheatLayout() {
|
|
3398
3786
|
const gObj = graphObjRef.current;
|
|
3399
3787
|
if (gObj == null ? void 0 : gObj.worker) {
|
|
@@ -3415,6 +3803,150 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3415
3803
|
);
|
|
3416
3804
|
}
|
|
3417
3805
|
const NetworkGraph3D = react.forwardRef(NetworkGraph3DInner);
|
|
3806
|
+
function GraphMinimap({
|
|
3807
|
+
graphRef,
|
|
3808
|
+
width = 200,
|
|
3809
|
+
height = 140,
|
|
3810
|
+
backgroundColor,
|
|
3811
|
+
viewportColor = "#94a3b8",
|
|
3812
|
+
dotRadius = 1.5,
|
|
3813
|
+
fps = 15,
|
|
3814
|
+
padding = 0.08,
|
|
3815
|
+
className,
|
|
3816
|
+
style
|
|
3817
|
+
}) {
|
|
3818
|
+
const canvasRef = react.useRef(null);
|
|
3819
|
+
const fitRef = react.useRef(null);
|
|
3820
|
+
const draggingRef = react.useRef(false);
|
|
3821
|
+
react.useEffect(() => {
|
|
3822
|
+
const canvas = canvasRef.current;
|
|
3823
|
+
if (!canvas) return;
|
|
3824
|
+
const ctx = canvas.getContext("2d");
|
|
3825
|
+
if (!ctx) return;
|
|
3826
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
3827
|
+
canvas.width = width * dpr;
|
|
3828
|
+
canvas.height = height * dpr;
|
|
3829
|
+
let raf = 0;
|
|
3830
|
+
let last = 0;
|
|
3831
|
+
const interval2 = 1e3 / fps;
|
|
3832
|
+
const draw = (now2) => {
|
|
3833
|
+
var _a, _b;
|
|
3834
|
+
raf = requestAnimationFrame(draw);
|
|
3835
|
+
if (now2 - last < interval2) return;
|
|
3836
|
+
last = now2;
|
|
3837
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
3838
|
+
ctx.clearRect(0, 0, width, height);
|
|
3839
|
+
if (backgroundColor) {
|
|
3840
|
+
ctx.fillStyle = backgroundColor;
|
|
3841
|
+
ctx.fillRect(0, 0, width, height);
|
|
3842
|
+
}
|
|
3843
|
+
const snap = (_a = graphRef.current) == null ? void 0 : _a.getGraphSnapshot();
|
|
3844
|
+
if (!snap || snap.count === 0) {
|
|
3845
|
+
fitRef.current = null;
|
|
3846
|
+
return;
|
|
3847
|
+
}
|
|
3848
|
+
const { positions, count, colors, hidden, selectedIndex } = snap;
|
|
3849
|
+
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3850
|
+
for (let i = 0; i < count; i++) {
|
|
3851
|
+
if (hidden && hidden[i]) continue;
|
|
3852
|
+
const x2 = positions[i * 3];
|
|
3853
|
+
const y2 = positions[i * 3 + 1];
|
|
3854
|
+
if (x2 < minX) minX = x2;
|
|
3855
|
+
if (x2 > maxX) maxX = x2;
|
|
3856
|
+
if (y2 < minY) minY = y2;
|
|
3857
|
+
if (y2 > maxY) maxY = y2;
|
|
3858
|
+
}
|
|
3859
|
+
if (!isFinite(minX)) {
|
|
3860
|
+
fitRef.current = null;
|
|
3861
|
+
return;
|
|
3862
|
+
}
|
|
3863
|
+
const spanX = Math.max(maxX - minX, 1);
|
|
3864
|
+
const spanY = Math.max(maxY - minY, 1);
|
|
3865
|
+
const pad = Math.min(width, height) * padding;
|
|
3866
|
+
const scale = Math.min(
|
|
3867
|
+
(width - pad * 2) / spanX,
|
|
3868
|
+
(height - pad * 2) / spanY
|
|
3869
|
+
);
|
|
3870
|
+
const offsetX = width / 2 - (minX + maxX) / 2 * scale;
|
|
3871
|
+
const offsetY = height / 2 + (minY + maxY) / 2 * scale;
|
|
3872
|
+
fitRef.current = { scale, offsetX, offsetY };
|
|
3873
|
+
const r = dotRadius;
|
|
3874
|
+
for (let i = 0; i < count; i++) {
|
|
3875
|
+
if (hidden && hidden[i]) continue;
|
|
3876
|
+
const cx = positions[i * 3] * scale + offsetX;
|
|
3877
|
+
const cy = -positions[i * 3 + 1] * scale + offsetY;
|
|
3878
|
+
if (colors) {
|
|
3879
|
+
const cr = Math.min(255, Math.round(colors[i * 3] * 255));
|
|
3880
|
+
const cg = Math.min(255, Math.round(colors[i * 3 + 1] * 255));
|
|
3881
|
+
const cb = Math.min(255, Math.round(colors[i * 3 + 2] * 255));
|
|
3882
|
+
ctx.fillStyle = `rgb(${cr},${cg},${cb})`;
|
|
3883
|
+
} else {
|
|
3884
|
+
ctx.fillStyle = viewportColor;
|
|
3885
|
+
}
|
|
3886
|
+
const rad = i === selectedIndex ? r * 2 : r;
|
|
3887
|
+
ctx.beginPath();
|
|
3888
|
+
ctx.arc(cx, cy, rad, 0, Math.PI * 2);
|
|
3889
|
+
ctx.fill();
|
|
3890
|
+
}
|
|
3891
|
+
const vp = (_b = graphRef.current) == null ? void 0 : _b.getViewportRect();
|
|
3892
|
+
if (vp) {
|
|
3893
|
+
const x2 = (vp.cx - vp.halfW) * scale + offsetX;
|
|
3894
|
+
const y2 = -(vp.cy + vp.halfH) * scale + offsetY;
|
|
3895
|
+
const w = vp.halfW * 2 * scale;
|
|
3896
|
+
const h = vp.halfH * 2 * scale;
|
|
3897
|
+
ctx.strokeStyle = viewportColor;
|
|
3898
|
+
ctx.lineWidth = 1;
|
|
3899
|
+
ctx.strokeRect(x2, y2, w, h);
|
|
3900
|
+
ctx.fillStyle = viewportColor + "1a";
|
|
3901
|
+
ctx.fillRect(x2, y2, w, h);
|
|
3902
|
+
}
|
|
3903
|
+
};
|
|
3904
|
+
raf = requestAnimationFrame(draw);
|
|
3905
|
+
return () => cancelAnimationFrame(raf);
|
|
3906
|
+
}, [graphRef, width, height, backgroundColor, viewportColor, dotRadius, fps, padding]);
|
|
3907
|
+
const panToPointer = (e) => {
|
|
3908
|
+
var _a;
|
|
3909
|
+
const fit = fitRef.current;
|
|
3910
|
+
const canvas = canvasRef.current;
|
|
3911
|
+
if (!fit || !canvas) return;
|
|
3912
|
+
const rect = canvas.getBoundingClientRect();
|
|
3913
|
+
const px = e.clientX - rect.left;
|
|
3914
|
+
const py = e.clientY - rect.top;
|
|
3915
|
+
const wx = (px - fit.offsetX) / fit.scale;
|
|
3916
|
+
const wy = -(py - fit.offsetY) / fit.scale;
|
|
3917
|
+
(_a = graphRef.current) == null ? void 0 : _a.panTo(wx, wy, draggingRef.current ? 0 : 300);
|
|
3918
|
+
};
|
|
3919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3920
|
+
"canvas",
|
|
3921
|
+
{
|
|
3922
|
+
ref: canvasRef,
|
|
3923
|
+
className,
|
|
3924
|
+
style: {
|
|
3925
|
+
width,
|
|
3926
|
+
height,
|
|
3927
|
+
cursor: "pointer",
|
|
3928
|
+
touchAction: "none",
|
|
3929
|
+
display: "block",
|
|
3930
|
+
...style
|
|
3931
|
+
},
|
|
3932
|
+
onPointerDown: (e) => {
|
|
3933
|
+
draggingRef.current = true;
|
|
3934
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
3935
|
+
panToPointer(e);
|
|
3936
|
+
},
|
|
3937
|
+
onPointerMove: (e) => {
|
|
3938
|
+
if (draggingRef.current) panToPointer(e);
|
|
3939
|
+
},
|
|
3940
|
+
onPointerUp: (e) => {
|
|
3941
|
+
draggingRef.current = false;
|
|
3942
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
3943
|
+
},
|
|
3944
|
+
onPointerCancel: () => {
|
|
3945
|
+
draggingRef.current = false;
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
);
|
|
3949
|
+
}
|
|
3418
3950
|
function forceCenter(x2, y2, z2) {
|
|
3419
3951
|
var nodes, strength = 1;
|
|
3420
3952
|
if (x2 == null) x2 = 0;
|
|
@@ -5482,6 +6014,7 @@ function CtrlBtn({ children, title, onClick }) {
|
|
|
5482
6014
|
}
|
|
5483
6015
|
exports.DEFAULT_LAYOUT = DEFAULT_LAYOUT;
|
|
5484
6016
|
exports.DEFAULT_STYLE = DEFAULT_STYLE;
|
|
6017
|
+
exports.GraphMinimap = GraphMinimap;
|
|
5485
6018
|
exports.NetworkGraph3D = NetworkGraph3D;
|
|
5486
6019
|
exports.NodeDetailPanel = NodeDetailPanel;
|
|
5487
6020
|
exports.SubgraphView2D = SubgraphView2D;
|
|
@@ -5492,6 +6025,7 @@ exports.celestial = celestial;
|
|
|
5492
6025
|
exports.computeHighlightSet = computeHighlightSet;
|
|
5493
6026
|
exports.minimal = minimal;
|
|
5494
6027
|
exports.neon = neon;
|
|
6028
|
+
exports.paper = paper;
|
|
5495
6029
|
exports.resolveTheme = resolveTheme;
|
|
5496
6030
|
exports.zoomToFitPositions = zoomToFitPositions;
|
|
5497
6031
|
//# sourceMappingURL=index.cjs.map
|