@cocorof/graphier 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/index.cjs +527 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +98 -0
- package/dist/index.js +527 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -26,7 +26,10 @@ const DEFAULT_LAYOUT = {
|
|
|
26
26
|
alphaDecay: "auto",
|
|
27
27
|
velocityDecay: 0.4,
|
|
28
28
|
settledThreshold: 5e-3,
|
|
29
|
-
spreadFactor: "auto"
|
|
29
|
+
spreadFactor: "auto",
|
|
30
|
+
dimensions: 3,
|
|
31
|
+
clusterBy: null,
|
|
32
|
+
clusterStrength: 0.05
|
|
30
33
|
};
|
|
31
34
|
function hexToRgb(hex) {
|
|
32
35
|
const c2 = hex.replace("#", "");
|
|
@@ -38,6 +41,14 @@ function rgbToHex(r, g, b) {
|
|
|
38
41
|
const hex = clamp(r) << 16 | clamp(g) << 8 | clamp(b);
|
|
39
42
|
return "#" + hex.toString(16).padStart(6, "0");
|
|
40
43
|
}
|
|
44
|
+
function luminance(hex) {
|
|
45
|
+
const [r, g, b] = hexToRgb(hex);
|
|
46
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
47
|
+
}
|
|
48
|
+
function darken(hex, factor) {
|
|
49
|
+
const [r, g, b] = hexToRgb(hex);
|
|
50
|
+
return rgbToHex(r * factor, g * factor, b * factor);
|
|
51
|
+
}
|
|
41
52
|
function brighten(hex, factor) {
|
|
42
53
|
const [r, g, b] = hexToRgb(hex);
|
|
43
54
|
const t = 1 - 1 / factor;
|
|
@@ -119,10 +130,40 @@ const minimal = {
|
|
|
119
130
|
defaultLinkColor: "#444444",
|
|
120
131
|
backgroundColor: "#1a1a2e"
|
|
121
132
|
};
|
|
133
|
+
const paper = {
|
|
134
|
+
nodeColors: {},
|
|
135
|
+
// Bright (label / highlight) colors are auto-derived: on a light
|
|
136
|
+
// background resolveTheme darkens instead of whitening.
|
|
137
|
+
nodeColorsBright: {},
|
|
138
|
+
linkColors: {},
|
|
139
|
+
defaultNodeColor: "#64748b",
|
|
140
|
+
defaultLinkColor: "#b3bdcc",
|
|
141
|
+
backgroundColor: "#f6f7f9",
|
|
142
|
+
blending: "normal",
|
|
143
|
+
palette: [
|
|
144
|
+
"#2563eb",
|
|
145
|
+
// blue
|
|
146
|
+
"#d97706",
|
|
147
|
+
// amber
|
|
148
|
+
"#7c3aed",
|
|
149
|
+
// violet
|
|
150
|
+
"#db2777",
|
|
151
|
+
// pink
|
|
152
|
+
"#0891b2",
|
|
153
|
+
// cyan
|
|
154
|
+
"#16a34a",
|
|
155
|
+
// green
|
|
156
|
+
"#dc2626",
|
|
157
|
+
// red
|
|
158
|
+
"#475569"
|
|
159
|
+
// slate
|
|
160
|
+
]
|
|
161
|
+
};
|
|
122
162
|
const PRESETS = {
|
|
123
163
|
celestial,
|
|
124
164
|
neon,
|
|
125
|
-
minimal
|
|
165
|
+
minimal,
|
|
166
|
+
paper
|
|
126
167
|
};
|
|
127
168
|
const DEFAULT_THEME = {
|
|
128
169
|
nodeColors: celestial.nodeColors ?? {},
|
|
@@ -150,6 +191,8 @@ function resolveTheme(theme) {
|
|
|
150
191
|
const defaultLinkColor = config.defaultLinkColor ?? DEFAULT_THEME.defaultLinkColor;
|
|
151
192
|
const backgroundColor = config.backgroundColor ?? DEFAULT_THEME.backgroundColor;
|
|
152
193
|
const palette = config.palette ?? DEFAULT_THEME.palette;
|
|
194
|
+
const isLight = luminance(backgroundColor) > 0.5;
|
|
195
|
+
const additiveEdges = config.blending ? config.blending === "additive" : !isLight;
|
|
153
196
|
const autoAssigned = /* @__PURE__ */ new Map();
|
|
154
197
|
let nextPaletteIdx = 0;
|
|
155
198
|
function nodeColor(type) {
|
|
@@ -161,16 +204,24 @@ function resolveTheme(theme) {
|
|
|
161
204
|
}
|
|
162
205
|
return palette[autoAssigned.get(type)];
|
|
163
206
|
}
|
|
207
|
+
const emphasize = (c2) => isLight ? darken(c2, 0.72) : brighten(c2, 1.5);
|
|
164
208
|
function nodeColorBright(type) {
|
|
165
|
-
if (!type) return
|
|
209
|
+
if (!type) return emphasize(defaultNodeColor);
|
|
166
210
|
if (nodeColorsBright[type]) return nodeColorsBright[type];
|
|
167
|
-
return
|
|
211
|
+
return emphasize(nodeColor(type));
|
|
168
212
|
}
|
|
169
213
|
function linkColor(type) {
|
|
170
214
|
if (!type) return defaultLinkColor;
|
|
171
215
|
return linkColors[type] ?? defaultLinkColor;
|
|
172
216
|
}
|
|
173
|
-
return {
|
|
217
|
+
return {
|
|
218
|
+
nodeColor,
|
|
219
|
+
nodeColorBright,
|
|
220
|
+
linkColor,
|
|
221
|
+
backgroundColor,
|
|
222
|
+
isLight,
|
|
223
|
+
additiveEdges
|
|
224
|
+
};
|
|
174
225
|
}
|
|
175
226
|
function autoSpreadFactor(n) {
|
|
176
227
|
if (n <= 500) return 1;
|
|
@@ -193,6 +244,8 @@ function resolveLayoutParams(nodeCount, config) {
|
|
|
193
244
|
const postEvery = n > 5e4 ? 5 : n > 1e4 ? 3 : 2;
|
|
194
245
|
const initialRadius2 = (500 + Math.min(n, 1e4) * 0.1) * spread;
|
|
195
246
|
return {
|
|
247
|
+
dimensions: (config == null ? void 0 : config.dimensions) === 2 ? 2 : 3,
|
|
248
|
+
clusterStrength: (config == null ? void 0 : config.clusterStrength) ?? 0.05,
|
|
196
249
|
charge,
|
|
197
250
|
distanceMax,
|
|
198
251
|
theta,
|
|
@@ -204,7 +257,7 @@ function resolveLayoutParams(nodeCount, config) {
|
|
|
204
257
|
initialRadius: initialRadius2
|
|
205
258
|
};
|
|
206
259
|
}
|
|
207
|
-
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';
|
|
260
|
+
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';
|
|
208
261
|
function createLayoutWorker() {
|
|
209
262
|
const blob = new Blob([WORKER_SOURCE], { type: "application/javascript" });
|
|
210
263
|
const url = URL.createObjectURL(blob);
|
|
@@ -1705,6 +1758,7 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1705
1758
|
const nc = nodes.length;
|
|
1706
1759
|
const tmpColor = new THREE.Color();
|
|
1707
1760
|
const brightTmp = new THREE.Color();
|
|
1761
|
+
const bgColor = new THREE.Color(theme.backgroundColor);
|
|
1708
1762
|
for (let i = 0; i < nc; i++) {
|
|
1709
1763
|
const node = nodes[i];
|
|
1710
1764
|
const baseColor = theme.nodeColor(node.type);
|
|
@@ -1712,13 +1766,17 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1712
1766
|
if (!highlightSet) {
|
|
1713
1767
|
tmpColor.set(baseColor);
|
|
1714
1768
|
} else if (node.id === selectedNodeId) {
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1769
|
+
if (theme.isLight) {
|
|
1770
|
+
tmpColor.set(brightColor);
|
|
1771
|
+
} else {
|
|
1772
|
+
tmpColor.set(brightColor);
|
|
1773
|
+
brightTmp.setRGB(1, 1, 1);
|
|
1774
|
+
tmpColor.lerp(brightTmp, 0.65);
|
|
1775
|
+
tmpColor.multiplyScalar(1.4);
|
|
1776
|
+
tmpColor.r = Math.min(tmpColor.r, 2);
|
|
1777
|
+
tmpColor.g = Math.min(tmpColor.g, 2);
|
|
1778
|
+
tmpColor.b = Math.min(tmpColor.b, 2);
|
|
1779
|
+
}
|
|
1722
1780
|
} else if (highlightSet.has(node.id)) {
|
|
1723
1781
|
const hop = highlightSet.get(node.id);
|
|
1724
1782
|
if (hop === 1) {
|
|
@@ -1730,6 +1788,8 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
|
|
|
1730
1788
|
} else {
|
|
1731
1789
|
tmpColor.set(baseColor).multiplyScalar(0.6);
|
|
1732
1790
|
}
|
|
1791
|
+
} else if (theme.isLight) {
|
|
1792
|
+
tmpColor.set(baseColor).lerp(bgColor, 0.88);
|
|
1733
1793
|
} else {
|
|
1734
1794
|
tmpColor.set(baseColor).multiplyScalar(0.04);
|
|
1735
1795
|
}
|
|
@@ -1747,6 +1807,7 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
|
|
|
1747
1807
|
const colorArr = colorAttr.array;
|
|
1748
1808
|
const validCount = edgeNodeIndices.length;
|
|
1749
1809
|
const tmpColor = new THREE.Color();
|
|
1810
|
+
const bgColor = new THREE.Color(theme.backgroundColor);
|
|
1750
1811
|
for (let i = 0; i < validCount; i++) {
|
|
1751
1812
|
const origIdx = edgeLinkIndices[i];
|
|
1752
1813
|
const link = links[origIdx];
|
|
@@ -1758,13 +1819,19 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
|
|
|
1758
1819
|
const maxHopVal = Math.max(highlightSet.get(sId), highlightSet.get(tId));
|
|
1759
1820
|
tmpColor.set(theme.linkColor(link == null ? void 0 : link.type));
|
|
1760
1821
|
if (maxHopVal <= 1) {
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1822
|
+
if (theme.isLight) {
|
|
1823
|
+
tmpColor.multiplyScalar(0.55);
|
|
1824
|
+
} else {
|
|
1825
|
+
tmpColor.multiplyScalar(1.8);
|
|
1826
|
+
tmpColor.r = Math.min(tmpColor.r, 1);
|
|
1827
|
+
tmpColor.g = Math.min(tmpColor.g, 1);
|
|
1828
|
+
tmpColor.b = Math.min(tmpColor.b, 1);
|
|
1829
|
+
}
|
|
1765
1830
|
} else if (maxHopVal === 2) {
|
|
1766
|
-
tmpColor.multiplyScalar(1.2);
|
|
1831
|
+
tmpColor.multiplyScalar(theme.isLight ? 0.8 : 1.2);
|
|
1767
1832
|
}
|
|
1833
|
+
} else if (theme.isLight) {
|
|
1834
|
+
tmpColor.set(theme.linkColor(link == null ? void 0 : link.type)).lerp(bgColor, 0.85);
|
|
1768
1835
|
} else {
|
|
1769
1836
|
tmpColor.setRGB(0.01, 0.01, 0.02);
|
|
1770
1837
|
}
|
|
@@ -1894,7 +1961,7 @@ function getOrCreateTexture(cache, nodeId, text, color) {
|
|
|
1894
1961
|
}
|
|
1895
1962
|
return entry;
|
|
1896
1963
|
}
|
|
1897
|
-
function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet) {
|
|
1964
|
+
function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet, hidden) {
|
|
1898
1965
|
if (!positions || nodes.length === 0 || !showLabels) {
|
|
1899
1966
|
for (const sp of state.sprites) sp.visible = false;
|
|
1900
1967
|
return;
|
|
@@ -1908,6 +1975,7 @@ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels
|
|
|
1908
1975
|
const maxDistSq = maxDist * maxDist;
|
|
1909
1976
|
const candidates = [];
|
|
1910
1977
|
for (let i = 0; i < nc; i++) {
|
|
1978
|
+
if (hidden && hidden[i]) continue;
|
|
1911
1979
|
if (highlightSet && !highlightSet.has(nodes[i].id)) continue;
|
|
1912
1980
|
const dx = positions[i * 3] - camPos.x;
|
|
1913
1981
|
const dy = positions[i * 3 + 1] - camPos.y;
|
|
@@ -2061,7 +2129,9 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
|
|
|
2061
2129
|
container.addEventListener("keydown", onKeyDown2);
|
|
2062
2130
|
container.addEventListener("keyup", onKeyUp);
|
|
2063
2131
|
container.addEventListener("blur", onBlur);
|
|
2064
|
-
|
|
2132
|
+
let enabled = true;
|
|
2133
|
+
const innerUpdate = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
|
|
2134
|
+
const updateFn = () => enabled ? innerUpdate() : false;
|
|
2065
2135
|
function cleanup() {
|
|
2066
2136
|
container.removeEventListener("keydown", onKeyDown2);
|
|
2067
2137
|
container.removeEventListener("keyup", onKeyUp);
|
|
@@ -2070,7 +2140,11 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
|
|
|
2070
2140
|
function setFlySpeed(speed) {
|
|
2071
2141
|
state.flySpeed = speed;
|
|
2072
2142
|
}
|
|
2073
|
-
|
|
2143
|
+
function setEnabled(on) {
|
|
2144
|
+
enabled = on;
|
|
2145
|
+
if (!on) for (const k of Object.keys(keys)) keys[k] = false;
|
|
2146
|
+
}
|
|
2147
|
+
return { update: updateFn, cleanup, setFlySpeed, setEnabled };
|
|
2074
2148
|
}
|
|
2075
2149
|
function createScene(container, backgroundColor, style, rendererConfig) {
|
|
2076
2150
|
const scene = new THREE.Scene();
|
|
@@ -2110,8 +2184,10 @@ function createScene(container, backgroundColor, style, rendererConfig) {
|
|
|
2110
2184
|
const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
|
|
2111
2185
|
const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
|
|
2112
2186
|
controls.enableZoom = false;
|
|
2187
|
+
const flags = { is2D: false };
|
|
2113
2188
|
const _wheelDir = new THREE.Vector3();
|
|
2114
2189
|
const onWheel = (e) => {
|
|
2190
|
+
if (flags.is2D) return;
|
|
2115
2191
|
e.preventDefault();
|
|
2116
2192
|
let delta = -e.deltaY;
|
|
2117
2193
|
if (e.deltaMode === 1) delta *= 40;
|
|
@@ -2135,9 +2211,40 @@ function createScene(container, backgroundColor, style, rendererConfig) {
|
|
|
2135
2211
|
composer: null,
|
|
2136
2212
|
bloomPass: null,
|
|
2137
2213
|
keyboard,
|
|
2138
|
-
scrollCleanup
|
|
2214
|
+
scrollCleanup,
|
|
2215
|
+
flags
|
|
2139
2216
|
};
|
|
2140
2217
|
}
|
|
2218
|
+
function applyCameraMode2D(state, is2D) {
|
|
2219
|
+
const { controls, camera, keyboard } = state;
|
|
2220
|
+
state.flags.is2D = is2D;
|
|
2221
|
+
controls.enableRotate = !is2D;
|
|
2222
|
+
controls.enableZoom = is2D;
|
|
2223
|
+
controls.screenSpacePanning = is2D;
|
|
2224
|
+
keyboard.setEnabled(!is2D);
|
|
2225
|
+
if (is2D) {
|
|
2226
|
+
controls.mouseButtons = {
|
|
2227
|
+
LEFT: THREE.MOUSE.PAN,
|
|
2228
|
+
MIDDLE: THREE.MOUSE.DOLLY,
|
|
2229
|
+
RIGHT: THREE.MOUSE.PAN
|
|
2230
|
+
};
|
|
2231
|
+
controls.touches = { ONE: THREE.TOUCH.PAN, TWO: THREE.TOUCH.DOLLY_PAN };
|
|
2232
|
+
const t = controls.target;
|
|
2233
|
+
const dist = Math.max(camera.position.distanceTo(t), 50);
|
|
2234
|
+
t.z = 0;
|
|
2235
|
+
camera.up.set(0, 1, 0);
|
|
2236
|
+
camera.position.set(t.x, t.y, dist);
|
|
2237
|
+
camera.lookAt(t);
|
|
2238
|
+
} else {
|
|
2239
|
+
controls.mouseButtons = {
|
|
2240
|
+
LEFT: THREE.MOUSE.ROTATE,
|
|
2241
|
+
MIDDLE: THREE.MOUSE.DOLLY,
|
|
2242
|
+
RIGHT: THREE.MOUSE.PAN
|
|
2243
|
+
};
|
|
2244
|
+
controls.touches = { ONE: THREE.TOUCH.ROTATE, TWO: THREE.TOUCH.DOLLY_PAN };
|
|
2245
|
+
}
|
|
2246
|
+
controls.update();
|
|
2247
|
+
}
|
|
2141
2248
|
function initBloom(state, nodeCount, style) {
|
|
2142
2249
|
if (state.composer) return;
|
|
2143
2250
|
try {
|
|
@@ -2334,14 +2441,14 @@ function createNodeMesh(nodes, scales, theme) {
|
|
|
2334
2441
|
mesh.computeBoundingSphere();
|
|
2335
2442
|
return { mesh, material, scales };
|
|
2336
2443
|
}
|
|
2337
|
-
function updateNodePositions(mesh, positions, scales, nodeCount) {
|
|
2444
|
+
function updateNodePositions(mesh, positions, scales, nodeCount, hidden) {
|
|
2338
2445
|
const pos = new THREE.Vector3();
|
|
2339
2446
|
const scale = new THREE.Vector3();
|
|
2340
2447
|
const quat = new THREE.Quaternion();
|
|
2341
2448
|
const mat = new THREE.Matrix4();
|
|
2342
2449
|
for (let i = 0; i < nodeCount; i++) {
|
|
2343
2450
|
pos.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
|
|
2344
|
-
const sc = scales[i];
|
|
2451
|
+
const sc = hidden && hidden[i] ? 1e-4 : scales[i];
|
|
2345
2452
|
scale.set(sc, sc, sc);
|
|
2346
2453
|
mat.compose(pos, quat, scale);
|
|
2347
2454
|
mesh.setMatrixAt(i, mat);
|
|
@@ -2398,7 +2505,7 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
|
|
|
2398
2505
|
transparent: true,
|
|
2399
2506
|
opacity: adaptiveOpacity,
|
|
2400
2507
|
depthWrite: false,
|
|
2401
|
-
blending: THREE.AdditiveBlending
|
|
2508
|
+
blending: theme.additiveEdges ? THREE.AdditiveBlending : THREE.NormalBlending
|
|
2402
2509
|
});
|
|
2403
2510
|
const mesh = new THREE.LineSegments(geometry, material);
|
|
2404
2511
|
return {
|
|
@@ -2410,10 +2517,19 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
|
|
|
2410
2517
|
edgeLinkIndices
|
|
2411
2518
|
};
|
|
2412
2519
|
}
|
|
2413
|
-
function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry) {
|
|
2520
|
+
function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry, hiddenEdges) {
|
|
2414
2521
|
const count = edgeNodeIndices.length;
|
|
2415
2522
|
for (let i = 0; i < count; i++) {
|
|
2416
2523
|
const [si, ti] = edgeNodeIndices[i];
|
|
2524
|
+
if (hiddenEdges && hiddenEdges[i]) {
|
|
2525
|
+
positionArray[i * 6 + 0] = nodePositions[si * 3];
|
|
2526
|
+
positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
|
|
2527
|
+
positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
|
|
2528
|
+
positionArray[i * 6 + 3] = nodePositions[si * 3];
|
|
2529
|
+
positionArray[i * 6 + 4] = nodePositions[si * 3 + 1];
|
|
2530
|
+
positionArray[i * 6 + 5] = nodePositions[si * 3 + 2];
|
|
2531
|
+
continue;
|
|
2532
|
+
}
|
|
2417
2533
|
positionArray[i * 6 + 0] = nodePositions[si * 3];
|
|
2418
2534
|
positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
|
|
2419
2535
|
positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
|
|
@@ -2476,7 +2592,7 @@ function zoomToFitPositions(camera, controls, positions, duration, padding) {
|
|
|
2476
2592
|
);
|
|
2477
2593
|
}
|
|
2478
2594
|
const EDGE_HIT_THRESHOLD = 5;
|
|
2479
|
-
function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData) {
|
|
2595
|
+
function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData, options) {
|
|
2480
2596
|
const raycaster = new THREE.Raycaster();
|
|
2481
2597
|
const mouse = new THREE.Vector2();
|
|
2482
2598
|
let mouseDownPos = null;
|
|
@@ -2634,20 +2750,34 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
|
|
|
2634
2750
|
lastClickTime = now2;
|
|
2635
2751
|
lastClickNodeId = node.id;
|
|
2636
2752
|
singleClickTimer = setTimeout(() => {
|
|
2753
|
+
var _a2, _b;
|
|
2637
2754
|
singleClickTimer = null;
|
|
2638
|
-
const
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2755
|
+
const clickToFocus = ((_a2 = options == null ? void 0 : options.getClickToFocus) == null ? void 0 : _a2.call(options)) ?? true;
|
|
2756
|
+
if (clickToFocus) {
|
|
2757
|
+
const nx = node.x ?? 0;
|
|
2758
|
+
const ny = node.y ?? 0;
|
|
2759
|
+
const nz = node.z ?? 0;
|
|
2760
|
+
if ((_b = options == null ? void 0 : options.getIs2D) == null ? void 0 : _b.call(options)) {
|
|
2761
|
+
animateCamera(
|
|
2762
|
+
camera,
|
|
2763
|
+
controls,
|
|
2764
|
+
{ x: nx, y: ny, z: camera.position.z },
|
|
2765
|
+
{ x: nx, y: ny, z: 0 },
|
|
2766
|
+
800
|
|
2767
|
+
);
|
|
2768
|
+
} else {
|
|
2769
|
+
const dist = Math.hypot(nx, ny, nz);
|
|
2770
|
+
if (dist > 1) {
|
|
2771
|
+
const ratio = 1 + 120 / dist;
|
|
2772
|
+
animateCamera(
|
|
2773
|
+
camera,
|
|
2774
|
+
controls,
|
|
2775
|
+
{ x: nx * ratio, y: ny * ratio, z: nz * ratio },
|
|
2776
|
+
{ x: nx, y: ny, z: nz },
|
|
2777
|
+
1200
|
|
2778
|
+
);
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2651
2781
|
}
|
|
2652
2782
|
callbacks.onNodeClick(node);
|
|
2653
2783
|
}, 250);
|
|
@@ -2787,7 +2917,12 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2787
2917
|
layout: layoutProp,
|
|
2788
2918
|
renderer: rendererProp,
|
|
2789
2919
|
labelFormatter,
|
|
2790
|
-
nodeValueAccessor
|
|
2920
|
+
nodeValueAccessor,
|
|
2921
|
+
visibleNodeIds,
|
|
2922
|
+
linkVisibility,
|
|
2923
|
+
clickToFocus = true,
|
|
2924
|
+
hoverHighlight = false,
|
|
2925
|
+
hoverHighlightHops = 1
|
|
2791
2926
|
} = props;
|
|
2792
2927
|
const containerRef = useRef(null);
|
|
2793
2928
|
const resolvedStyle = useMemo(
|
|
@@ -2824,6 +2959,13 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2824
2959
|
const selectedNodeIdRef = useRef(selectedNodeId);
|
|
2825
2960
|
const labelFormatterRef = useRef(labelFormatter);
|
|
2826
2961
|
const highlightSetRef = useRef(null);
|
|
2962
|
+
const clickToFocusRef = useRef(clickToFocus);
|
|
2963
|
+
const hoverHighlightRef = useRef(hoverHighlight);
|
|
2964
|
+
const hoverHighlightHopsRef = useRef(hoverHighlightHops);
|
|
2965
|
+
const adjacencyMapRef = useRef(/* @__PURE__ */ new Map());
|
|
2966
|
+
const is2DRef = useRef(false);
|
|
2967
|
+
const hiddenNodesRef = useRef(null);
|
|
2968
|
+
const hiddenEdgesRef = useRef(null);
|
|
2827
2969
|
onNodeClickRef.current = onNodeClick;
|
|
2828
2970
|
onNodeDoubleClickRef.current = onNodeDoubleClick;
|
|
2829
2971
|
onNodeHoverRef.current = onNodeHover;
|
|
@@ -2838,6 +2980,14 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2838
2980
|
themeRef.current = resolvedTheme;
|
|
2839
2981
|
selectedNodeIdRef.current = selectedNodeId;
|
|
2840
2982
|
labelFormatterRef.current = labelFormatter;
|
|
2983
|
+
clickToFocusRef.current = clickToFocus;
|
|
2984
|
+
hoverHighlightRef.current = hoverHighlight;
|
|
2985
|
+
hoverHighlightHopsRef.current = hoverHighlightHops;
|
|
2986
|
+
const is2D = (layoutProp == null ? void 0 : layoutProp.dimensions) === 2;
|
|
2987
|
+
is2DRef.current = is2D;
|
|
2988
|
+
const layoutKey = JSON.stringify(layoutProp ?? null);
|
|
2989
|
+
const layoutRef = useRef(layoutProp);
|
|
2990
|
+
layoutRef.current = layoutProp;
|
|
2841
2991
|
const mergedData = useMemo(() => {
|
|
2842
2992
|
if (!appendedData) return data;
|
|
2843
2993
|
const existingIds = new Set(data.nodes.map((n) => n.id));
|
|
@@ -2864,6 +3014,11 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2864
3014
|
() => buildAdjacencyMapFromLinks(mergedData.links),
|
|
2865
3015
|
[mergedData.links]
|
|
2866
3016
|
);
|
|
3017
|
+
adjacencyMapRef.current = adjacencyMap;
|
|
3018
|
+
const visibleSet = useMemo(() => {
|
|
3019
|
+
if (visibleNodeIds == null) return null;
|
|
3020
|
+
return visibleNodeIds instanceof Set ? visibleNodeIds : new Set(visibleNodeIds);
|
|
3021
|
+
}, [visibleNodeIds]);
|
|
2867
3022
|
const highlightSet = useMemo(() => {
|
|
2868
3023
|
if (!selectedNodeId) return null;
|
|
2869
3024
|
return computeHighlightSet(selectedNodeId, adjacencyMap, highlightHops);
|
|
@@ -2877,6 +3032,32 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2877
3032
|
}
|
|
2878
3033
|
return { min: isFinite(min) ? min : 1, max: isFinite(max) ? max : 1 };
|
|
2879
3034
|
}, [mergedData.nodes, nodeValueAccessor]);
|
|
3035
|
+
const applyHoverHighlight = (node) => {
|
|
3036
|
+
if (!hoverHighlightRef.current) return;
|
|
3037
|
+
if (selectedNodeIdRef.current) return;
|
|
3038
|
+
const gObj = graphObjRef.current;
|
|
3039
|
+
if (!gObj) return;
|
|
3040
|
+
const d = dataRef.current;
|
|
3041
|
+
const set2 = node ? computeHighlightSet(
|
|
3042
|
+
node.id,
|
|
3043
|
+
adjacencyMapRef.current,
|
|
3044
|
+
hoverHighlightHopsRef.current
|
|
3045
|
+
) : null;
|
|
3046
|
+
highlightSetRef.current = set2;
|
|
3047
|
+
applyNodeHighlight(gObj.nodesMesh, d.nodes, (node == null ? void 0 : node.id) ?? null, set2, themeRef.current);
|
|
3048
|
+
applyEdgeHighlight(
|
|
3049
|
+
gObj.edgesMesh,
|
|
3050
|
+
d.links,
|
|
3051
|
+
d.edgeNodeIndices,
|
|
3052
|
+
d.edgeLinkIndices,
|
|
3053
|
+
set2,
|
|
3054
|
+
styleRef.current.edgeOpacity,
|
|
3055
|
+
d.nodes.length,
|
|
3056
|
+
themeRef.current
|
|
3057
|
+
);
|
|
3058
|
+
};
|
|
3059
|
+
const applyHoverHighlightRef = useRef(applyHoverHighlight);
|
|
3060
|
+
applyHoverHighlightRef.current = applyHoverHighlight;
|
|
2880
3061
|
useEffect(() => {
|
|
2881
3062
|
const container = containerRef.current;
|
|
2882
3063
|
if (!container) return;
|
|
@@ -2900,7 +3081,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2900
3081
|
styleRef.current.labelThreshold,
|
|
2901
3082
|
styleRef.current.maxLabels,
|
|
2902
3083
|
labelFormatterRef.current,
|
|
2903
|
-
highlightSetRef.current
|
|
3084
|
+
highlightSetRef.current,
|
|
3085
|
+
hiddenNodesRef.current
|
|
2904
3086
|
);
|
|
2905
3087
|
});
|
|
2906
3088
|
const resizeObserver = setupResize(container, state);
|
|
@@ -2924,7 +3106,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2924
3106
|
},
|
|
2925
3107
|
onNodeHover: (node) => {
|
|
2926
3108
|
var _a;
|
|
2927
|
-
|
|
3109
|
+
(_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
|
|
3110
|
+
applyHoverHighlightRef.current(node);
|
|
2928
3111
|
},
|
|
2929
3112
|
onContextMenu: (node, pos) => {
|
|
2930
3113
|
var _a;
|
|
@@ -2940,6 +3123,7 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2940
3123
|
},
|
|
2941
3124
|
onNodeDrag: (node, pos) => {
|
|
2942
3125
|
var _a;
|
|
3126
|
+
if (is2DRef.current) pos = { ...pos, z: 0 };
|
|
2943
3127
|
(_a = onNodeDragRef.current) == null ? void 0 : _a.call(onNodeDragRef, node, pos);
|
|
2944
3128
|
const d = dataRef.current;
|
|
2945
3129
|
const idx = d.nodeIdToIndex.get(node.id);
|
|
@@ -2952,7 +3136,13 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2952
3136
|
node.z = pos.z;
|
|
2953
3137
|
const gObj = graphObjRef.current;
|
|
2954
3138
|
if (gObj && d.scales) {
|
|
2955
|
-
updateNodePositions(
|
|
3139
|
+
updateNodePositions(
|
|
3140
|
+
gObj.nodesMesh,
|
|
3141
|
+
d.positions,
|
|
3142
|
+
d.scales,
|
|
3143
|
+
d.nodes.length,
|
|
3144
|
+
hiddenNodesRef.current
|
|
3145
|
+
);
|
|
2956
3146
|
}
|
|
2957
3147
|
}
|
|
2958
3148
|
},
|
|
@@ -2970,6 +3160,10 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
2970
3160
|
edgeLinkIndices: d.edgeLinkIndices,
|
|
2971
3161
|
positions: d.positions
|
|
2972
3162
|
};
|
|
3163
|
+
},
|
|
3164
|
+
{
|
|
3165
|
+
getClickToFocus: () => clickToFocusRef.current,
|
|
3166
|
+
getIs2D: () => is2DRef.current
|
|
2973
3167
|
}
|
|
2974
3168
|
);
|
|
2975
3169
|
return () => {
|
|
@@ -3116,17 +3310,26 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3116
3310
|
if (msg.type === "positions") {
|
|
3117
3311
|
const positions = new Float32Array(msg.positions);
|
|
3118
3312
|
dataRef.current.positions = positions;
|
|
3119
|
-
|
|
3313
|
+
const hn = hiddenNodesRef.current;
|
|
3314
|
+
updateNodePositions(
|
|
3315
|
+
nodesMesh,
|
|
3316
|
+
positions,
|
|
3317
|
+
scales,
|
|
3318
|
+
nc,
|
|
3319
|
+
hn && hn.length === nc ? hn : null
|
|
3320
|
+
);
|
|
3120
3321
|
for (let i = 0; i < nc; i++) {
|
|
3121
3322
|
nodes[i].x = positions[i * 3];
|
|
3122
3323
|
nodes[i].y = positions[i * 3 + 1];
|
|
3123
3324
|
nodes[i].z = positions[i * 3 + 2];
|
|
3124
3325
|
}
|
|
3326
|
+
const he = hiddenEdgesRef.current;
|
|
3125
3327
|
updateEdgePositions(
|
|
3126
3328
|
edgeResult.positionArray,
|
|
3127
3329
|
positions,
|
|
3128
3330
|
edgeNodeIndices,
|
|
3129
|
-
edgeResult.geometry
|
|
3331
|
+
edgeResult.geometry,
|
|
3332
|
+
he && he.length === edgeNodeIndices.length ? he : null
|
|
3130
3333
|
);
|
|
3131
3334
|
const selId = selectedNodeIdRef.current;
|
|
3132
3335
|
if (selId && sceneState.selectionRing.visible) {
|
|
@@ -3146,7 +3349,20 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3146
3349
|
(_b = onLayoutSettledRef.current) == null ? void 0 : _b.call(onLayoutSettledRef);
|
|
3147
3350
|
}
|
|
3148
3351
|
};
|
|
3149
|
-
const
|
|
3352
|
+
const layoutConfig = layoutRef.current;
|
|
3353
|
+
const layoutParams = resolveLayoutParams(nc, layoutConfig);
|
|
3354
|
+
let groups;
|
|
3355
|
+
if (layoutConfig == null ? void 0 : layoutConfig.clusterBy) {
|
|
3356
|
+
const keyOf = (n) => layoutConfig.clusterBy === "type" ? n.type : n.group;
|
|
3357
|
+
const keyToIdx = /* @__PURE__ */ new Map();
|
|
3358
|
+
groups = nodes.map((n) => {
|
|
3359
|
+
const k = keyOf(n);
|
|
3360
|
+
if (k == null) return -1;
|
|
3361
|
+
const ks = String(k);
|
|
3362
|
+
if (!keyToIdx.has(ks)) keyToIdx.set(ks, keyToIdx.size);
|
|
3363
|
+
return keyToIdx.get(ks);
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3150
3366
|
worker.postMessage({
|
|
3151
3367
|
type: "init",
|
|
3152
3368
|
nodes: nodes.map((n) => ({ id: n.id })),
|
|
@@ -3155,7 +3371,8 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3155
3371
|
target: typeof l.target === "object" ? l.target.id : l.target
|
|
3156
3372
|
})),
|
|
3157
3373
|
params: layoutParams,
|
|
3158
|
-
initialPositions: preservedPositionsRef.current
|
|
3374
|
+
initialPositions: preservedPositionsRef.current,
|
|
3375
|
+
groups
|
|
3159
3376
|
});
|
|
3160
3377
|
return () => {
|
|
3161
3378
|
const d = dataRef.current;
|
|
@@ -3180,7 +3397,56 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3180
3397
|
disposeObject(edgeResult.mesh);
|
|
3181
3398
|
graphObjRef.current = null;
|
|
3182
3399
|
};
|
|
3183
|
-
}, [mergedData, valRange, nodeValueAccessor,
|
|
3400
|
+
}, [mergedData, valRange, nodeValueAccessor, layoutKey]);
|
|
3401
|
+
useEffect(() => {
|
|
3402
|
+
const d = dataRef.current;
|
|
3403
|
+
const gObj = graphObjRef.current;
|
|
3404
|
+
if (!visibleSet && !linkVisibility) {
|
|
3405
|
+
hiddenNodesRef.current = null;
|
|
3406
|
+
hiddenEdgesRef.current = null;
|
|
3407
|
+
} else {
|
|
3408
|
+
const nc = d.nodes.length;
|
|
3409
|
+
const hn = new Uint8Array(nc);
|
|
3410
|
+
if (visibleSet) {
|
|
3411
|
+
for (let i = 0; i < nc; i++) {
|
|
3412
|
+
if (!visibleSet.has(d.nodes[i].id)) hn[i] = 1;
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
const ec = d.edgeNodeIndices.length;
|
|
3416
|
+
const he = new Uint8Array(ec);
|
|
3417
|
+
for (let i = 0; i < ec; i++) {
|
|
3418
|
+
const [si, ti] = d.edgeNodeIndices[i];
|
|
3419
|
+
if (hn[si] || hn[ti]) {
|
|
3420
|
+
he[i] = 1;
|
|
3421
|
+
} else if (linkVisibility) {
|
|
3422
|
+
const link = d.links[d.edgeLinkIndices[i]];
|
|
3423
|
+
if (link && !linkVisibility(link)) he[i] = 1;
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
hiddenNodesRef.current = visibleSet ? hn : null;
|
|
3427
|
+
hiddenEdgesRef.current = he;
|
|
3428
|
+
}
|
|
3429
|
+
if (gObj && d.positions && d.scales) {
|
|
3430
|
+
updateNodePositions(
|
|
3431
|
+
gObj.nodesMesh,
|
|
3432
|
+
d.positions,
|
|
3433
|
+
d.scales,
|
|
3434
|
+
d.nodes.length,
|
|
3435
|
+
hiddenNodesRef.current
|
|
3436
|
+
);
|
|
3437
|
+
updateEdgePositions(
|
|
3438
|
+
gObj.edgePositionArray,
|
|
3439
|
+
d.positions,
|
|
3440
|
+
d.edgeNodeIndices,
|
|
3441
|
+
gObj.edgeGeometry,
|
|
3442
|
+
hiddenEdgesRef.current
|
|
3443
|
+
);
|
|
3444
|
+
}
|
|
3445
|
+
}, [visibleSet, linkVisibility, mergedData]);
|
|
3446
|
+
useEffect(() => {
|
|
3447
|
+
const s = sceneRef.current;
|
|
3448
|
+
if (s) applyCameraMode2D(s, is2D);
|
|
3449
|
+
}, [is2D]);
|
|
3184
3450
|
useEffect(() => {
|
|
3185
3451
|
const gObj = graphObjRef.current;
|
|
3186
3452
|
const sceneState = sceneRef.current;
|
|
@@ -3248,7 +3514,7 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3248
3514
|
resolvedStyle.nodeMaxSize
|
|
3249
3515
|
);
|
|
3250
3516
|
dataRef.current.scales = newScales;
|
|
3251
|
-
updateNodePositions(gObj.nodesMesh, positions, newScales, nc);
|
|
3517
|
+
updateNodePositions(gObj.nodesMesh, positions, newScales, nc, hiddenNodesRef.current);
|
|
3252
3518
|
}, [resolvedStyle.nodeMinSize, resolvedStyle.nodeMaxSize, valRange]);
|
|
3253
3519
|
useEffect(() => {
|
|
3254
3520
|
const gObj = graphObjRef.current;
|
|
@@ -3337,6 +3603,17 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3337
3603
|
const nx = d.positions[idx * 3];
|
|
3338
3604
|
const ny = d.positions[idx * 3 + 1];
|
|
3339
3605
|
const nz = d.positions[idx * 3 + 2];
|
|
3606
|
+
if (is2DRef.current) {
|
|
3607
|
+
const z2 = Math.max(120, Math.min(Math.abs(s.camera.position.z), 500));
|
|
3608
|
+
animateCamera(
|
|
3609
|
+
s.camera,
|
|
3610
|
+
s.controls,
|
|
3611
|
+
{ x: nx, y: ny, z: z2 },
|
|
3612
|
+
{ x: nx, y: ny, z: 0 },
|
|
3613
|
+
duration
|
|
3614
|
+
);
|
|
3615
|
+
return;
|
|
3616
|
+
}
|
|
3340
3617
|
const dist = Math.hypot(nx, ny, nz);
|
|
3341
3618
|
if (dist < 1) return;
|
|
3342
3619
|
const ratio = 1 + 120 / dist;
|
|
@@ -3348,6 +3625,34 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3348
3625
|
duration
|
|
3349
3626
|
);
|
|
3350
3627
|
},
|
|
3628
|
+
panTo(x2, y2, duration = 600) {
|
|
3629
|
+
const s = sceneRef.current;
|
|
3630
|
+
if (!s) return;
|
|
3631
|
+
const t = s.controls.target;
|
|
3632
|
+
if (is2DRef.current) {
|
|
3633
|
+
animateCamera(
|
|
3634
|
+
s.camera,
|
|
3635
|
+
s.controls,
|
|
3636
|
+
{ x: x2, y: y2, z: s.camera.position.z },
|
|
3637
|
+
{ x: x2, y: y2, z: 0 },
|
|
3638
|
+
duration
|
|
3639
|
+
);
|
|
3640
|
+
} else {
|
|
3641
|
+
const dx = x2 - t.x;
|
|
3642
|
+
const dy = y2 - t.y;
|
|
3643
|
+
animateCamera(
|
|
3644
|
+
s.camera,
|
|
3645
|
+
s.controls,
|
|
3646
|
+
{
|
|
3647
|
+
x: s.camera.position.x + dx,
|
|
3648
|
+
y: s.camera.position.y + dy,
|
|
3649
|
+
z: s.camera.position.z
|
|
3650
|
+
},
|
|
3651
|
+
{ x: x2, y: y2, z: t.z },
|
|
3652
|
+
duration
|
|
3653
|
+
);
|
|
3654
|
+
}
|
|
3655
|
+
},
|
|
3351
3656
|
appendData(newNodes, newLinks) {
|
|
3352
3657
|
if (newNodes.length === 0 && newLinks.length === 0) return 0;
|
|
3353
3658
|
const existingIds = new Set(dataRef.current.nodes.map((n) => n.id));
|
|
@@ -3376,6 +3681,32 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3376
3681
|
s.renderer.render(s.scene, s.camera);
|
|
3377
3682
|
return s.renderer.domElement.toDataURL("image/png");
|
|
3378
3683
|
},
|
|
3684
|
+
getGraphSnapshot() {
|
|
3685
|
+
var _a;
|
|
3686
|
+
const gObj = graphObjRef.current;
|
|
3687
|
+
const d = dataRef.current;
|
|
3688
|
+
if (!gObj || !d.positions) return null;
|
|
3689
|
+
return {
|
|
3690
|
+
positions: d.positions,
|
|
3691
|
+
count: d.nodes.length,
|
|
3692
|
+
colors: ((_a = gObj.nodesMesh.instanceColor) == null ? void 0 : _a.array) ?? null,
|
|
3693
|
+
hidden: hiddenNodesRef.current,
|
|
3694
|
+
selectedIndex: selectedNodeIdRef.current ? d.nodeIdToIndex.get(selectedNodeIdRef.current) ?? -1 : -1
|
|
3695
|
+
};
|
|
3696
|
+
},
|
|
3697
|
+
getViewportRect() {
|
|
3698
|
+
const s = sceneRef.current;
|
|
3699
|
+
if (!s) return null;
|
|
3700
|
+
const cam = s.camera;
|
|
3701
|
+
const dist = Math.abs(cam.position.z);
|
|
3702
|
+
const halfH = Math.tan(cam.fov * Math.PI / 360) * dist;
|
|
3703
|
+
return {
|
|
3704
|
+
cx: cam.position.x,
|
|
3705
|
+
cy: cam.position.y,
|
|
3706
|
+
halfW: halfH * cam.aspect,
|
|
3707
|
+
halfH
|
|
3708
|
+
};
|
|
3709
|
+
},
|
|
3379
3710
|
reheatLayout() {
|
|
3380
3711
|
const gObj = graphObjRef.current;
|
|
3381
3712
|
if (gObj == null ? void 0 : gObj.worker) {
|
|
@@ -3397,6 +3728,150 @@ function NetworkGraph3DInner(props, ref) {
|
|
|
3397
3728
|
);
|
|
3398
3729
|
}
|
|
3399
3730
|
const NetworkGraph3D = forwardRef(NetworkGraph3DInner);
|
|
3731
|
+
function GraphMinimap({
|
|
3732
|
+
graphRef,
|
|
3733
|
+
width = 200,
|
|
3734
|
+
height = 140,
|
|
3735
|
+
backgroundColor,
|
|
3736
|
+
viewportColor = "#94a3b8",
|
|
3737
|
+
dotRadius = 1.5,
|
|
3738
|
+
fps = 15,
|
|
3739
|
+
padding = 0.08,
|
|
3740
|
+
className,
|
|
3741
|
+
style
|
|
3742
|
+
}) {
|
|
3743
|
+
const canvasRef = useRef(null);
|
|
3744
|
+
const fitRef = useRef(null);
|
|
3745
|
+
const draggingRef = useRef(false);
|
|
3746
|
+
useEffect(() => {
|
|
3747
|
+
const canvas = canvasRef.current;
|
|
3748
|
+
if (!canvas) return;
|
|
3749
|
+
const ctx = canvas.getContext("2d");
|
|
3750
|
+
if (!ctx) return;
|
|
3751
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
3752
|
+
canvas.width = width * dpr;
|
|
3753
|
+
canvas.height = height * dpr;
|
|
3754
|
+
let raf = 0;
|
|
3755
|
+
let last = 0;
|
|
3756
|
+
const interval2 = 1e3 / fps;
|
|
3757
|
+
const draw = (now2) => {
|
|
3758
|
+
var _a, _b;
|
|
3759
|
+
raf = requestAnimationFrame(draw);
|
|
3760
|
+
if (now2 - last < interval2) return;
|
|
3761
|
+
last = now2;
|
|
3762
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
3763
|
+
ctx.clearRect(0, 0, width, height);
|
|
3764
|
+
if (backgroundColor) {
|
|
3765
|
+
ctx.fillStyle = backgroundColor;
|
|
3766
|
+
ctx.fillRect(0, 0, width, height);
|
|
3767
|
+
}
|
|
3768
|
+
const snap = (_a = graphRef.current) == null ? void 0 : _a.getGraphSnapshot();
|
|
3769
|
+
if (!snap || snap.count === 0) {
|
|
3770
|
+
fitRef.current = null;
|
|
3771
|
+
return;
|
|
3772
|
+
}
|
|
3773
|
+
const { positions, count, colors, hidden, selectedIndex } = snap;
|
|
3774
|
+
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
3775
|
+
for (let i = 0; i < count; i++) {
|
|
3776
|
+
if (hidden && hidden[i]) continue;
|
|
3777
|
+
const x2 = positions[i * 3];
|
|
3778
|
+
const y2 = positions[i * 3 + 1];
|
|
3779
|
+
if (x2 < minX) minX = x2;
|
|
3780
|
+
if (x2 > maxX) maxX = x2;
|
|
3781
|
+
if (y2 < minY) minY = y2;
|
|
3782
|
+
if (y2 > maxY) maxY = y2;
|
|
3783
|
+
}
|
|
3784
|
+
if (!isFinite(minX)) {
|
|
3785
|
+
fitRef.current = null;
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
const spanX = Math.max(maxX - minX, 1);
|
|
3789
|
+
const spanY = Math.max(maxY - minY, 1);
|
|
3790
|
+
const pad = Math.min(width, height) * padding;
|
|
3791
|
+
const scale = Math.min(
|
|
3792
|
+
(width - pad * 2) / spanX,
|
|
3793
|
+
(height - pad * 2) / spanY
|
|
3794
|
+
);
|
|
3795
|
+
const offsetX = width / 2 - (minX + maxX) / 2 * scale;
|
|
3796
|
+
const offsetY = height / 2 + (minY + maxY) / 2 * scale;
|
|
3797
|
+
fitRef.current = { scale, offsetX, offsetY };
|
|
3798
|
+
const r = dotRadius;
|
|
3799
|
+
for (let i = 0; i < count; i++) {
|
|
3800
|
+
if (hidden && hidden[i]) continue;
|
|
3801
|
+
const cx = positions[i * 3] * scale + offsetX;
|
|
3802
|
+
const cy = -positions[i * 3 + 1] * scale + offsetY;
|
|
3803
|
+
if (colors) {
|
|
3804
|
+
const cr = Math.min(255, Math.round(colors[i * 3] * 255));
|
|
3805
|
+
const cg = Math.min(255, Math.round(colors[i * 3 + 1] * 255));
|
|
3806
|
+
const cb = Math.min(255, Math.round(colors[i * 3 + 2] * 255));
|
|
3807
|
+
ctx.fillStyle = `rgb(${cr},${cg},${cb})`;
|
|
3808
|
+
} else {
|
|
3809
|
+
ctx.fillStyle = viewportColor;
|
|
3810
|
+
}
|
|
3811
|
+
const rad = i === selectedIndex ? r * 2 : r;
|
|
3812
|
+
ctx.beginPath();
|
|
3813
|
+
ctx.arc(cx, cy, rad, 0, Math.PI * 2);
|
|
3814
|
+
ctx.fill();
|
|
3815
|
+
}
|
|
3816
|
+
const vp = (_b = graphRef.current) == null ? void 0 : _b.getViewportRect();
|
|
3817
|
+
if (vp) {
|
|
3818
|
+
const x2 = (vp.cx - vp.halfW) * scale + offsetX;
|
|
3819
|
+
const y2 = -(vp.cy + vp.halfH) * scale + offsetY;
|
|
3820
|
+
const w = vp.halfW * 2 * scale;
|
|
3821
|
+
const h = vp.halfH * 2 * scale;
|
|
3822
|
+
ctx.strokeStyle = viewportColor;
|
|
3823
|
+
ctx.lineWidth = 1;
|
|
3824
|
+
ctx.strokeRect(x2, y2, w, h);
|
|
3825
|
+
ctx.fillStyle = viewportColor + "1a";
|
|
3826
|
+
ctx.fillRect(x2, y2, w, h);
|
|
3827
|
+
}
|
|
3828
|
+
};
|
|
3829
|
+
raf = requestAnimationFrame(draw);
|
|
3830
|
+
return () => cancelAnimationFrame(raf);
|
|
3831
|
+
}, [graphRef, width, height, backgroundColor, viewportColor, dotRadius, fps, padding]);
|
|
3832
|
+
const panToPointer = (e) => {
|
|
3833
|
+
var _a;
|
|
3834
|
+
const fit = fitRef.current;
|
|
3835
|
+
const canvas = canvasRef.current;
|
|
3836
|
+
if (!fit || !canvas) return;
|
|
3837
|
+
const rect = canvas.getBoundingClientRect();
|
|
3838
|
+
const px = e.clientX - rect.left;
|
|
3839
|
+
const py = e.clientY - rect.top;
|
|
3840
|
+
const wx = (px - fit.offsetX) / fit.scale;
|
|
3841
|
+
const wy = -(py - fit.offsetY) / fit.scale;
|
|
3842
|
+
(_a = graphRef.current) == null ? void 0 : _a.panTo(wx, wy, draggingRef.current ? 0 : 300);
|
|
3843
|
+
};
|
|
3844
|
+
return /* @__PURE__ */ jsx(
|
|
3845
|
+
"canvas",
|
|
3846
|
+
{
|
|
3847
|
+
ref: canvasRef,
|
|
3848
|
+
className,
|
|
3849
|
+
style: {
|
|
3850
|
+
width,
|
|
3851
|
+
height,
|
|
3852
|
+
cursor: "pointer",
|
|
3853
|
+
touchAction: "none",
|
|
3854
|
+
display: "block",
|
|
3855
|
+
...style
|
|
3856
|
+
},
|
|
3857
|
+
onPointerDown: (e) => {
|
|
3858
|
+
draggingRef.current = true;
|
|
3859
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
3860
|
+
panToPointer(e);
|
|
3861
|
+
},
|
|
3862
|
+
onPointerMove: (e) => {
|
|
3863
|
+
if (draggingRef.current) panToPointer(e);
|
|
3864
|
+
},
|
|
3865
|
+
onPointerUp: (e) => {
|
|
3866
|
+
draggingRef.current = false;
|
|
3867
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
3868
|
+
},
|
|
3869
|
+
onPointerCancel: () => {
|
|
3870
|
+
draggingRef.current = false;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
);
|
|
3874
|
+
}
|
|
3400
3875
|
function forceCenter(x2, y2, z2) {
|
|
3401
3876
|
var nodes, strength = 1;
|
|
3402
3877
|
if (x2 == null) x2 = 0;
|
|
@@ -5465,6 +5940,7 @@ function CtrlBtn({ children, title, onClick }) {
|
|
|
5465
5940
|
export {
|
|
5466
5941
|
DEFAULT_LAYOUT,
|
|
5467
5942
|
DEFAULT_STYLE,
|
|
5943
|
+
GraphMinimap,
|
|
5468
5944
|
NetworkGraph3D,
|
|
5469
5945
|
NodeDetailPanel,
|
|
5470
5946
|
SubgraphView2D,
|
|
@@ -5475,6 +5951,7 @@ export {
|
|
|
5475
5951
|
computeHighlightSet,
|
|
5476
5952
|
minimal,
|
|
5477
5953
|
neon,
|
|
5954
|
+
paper,
|
|
5478
5955
|
resolveTheme,
|
|
5479
5956
|
zoomToFitPositions
|
|
5480
5957
|
};
|