force-3d-graph 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/force-3d-graph.js +124 -181
- package/dist/force-3d-graph.js.map +1 -1
- package/dist/force-3d-graph.umd.cjs +10 -60
- package/dist/force-3d-graph.umd.cjs.map +1 -1
- package/package.json +1 -1
package/dist/force-3d-graph.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var it = Object.defineProperty;
|
|
2
|
-
var ot = (
|
|
3
|
-
var l = (
|
|
2
|
+
var ot = (d, e, s) => e in d ? it(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;
|
|
3
|
+
var l = (d, e, s) => ot(d, typeof e != "symbol" ? e + "" : e, s);
|
|
4
4
|
import * as x from "three";
|
|
5
5
|
import { EventDispatcher as nt, Vector3 as S, MOUSE as j, TOUCH as $, Spherical as Se, Quaternion as ze, Vector2 as k, Ray as at, Plane as rt, MathUtils as lt } from "three";
|
|
6
6
|
const P = {
|
|
@@ -32,52 +32,52 @@ const P = {
|
|
|
32
32
|
targetFPS: 60,
|
|
33
33
|
maxVisibleNodes: 1e4
|
|
34
34
|
};
|
|
35
|
-
var _ = /* @__PURE__ */ ((
|
|
35
|
+
var _ = /* @__PURE__ */ ((d) => (d[d.HIGH = 0] = "HIGH", d[d.MEDIUM = 1] = "MEDIUM", d[d.LOW = 2] = "LOW", d))(_ || {});
|
|
36
36
|
function ct() {
|
|
37
|
-
const
|
|
38
|
-
return
|
|
37
|
+
const d = document.createElement("div");
|
|
38
|
+
return d.id = "force-graph-3d-container", d.style.cssText = `
|
|
39
39
|
width: 100%;
|
|
40
40
|
height: 100%;
|
|
41
41
|
position: absolute;
|
|
42
42
|
top: 0;
|
|
43
43
|
left: 0;
|
|
44
44
|
overflow: hidden;
|
|
45
|
-
`, document.body.appendChild(
|
|
45
|
+
`, document.body.appendChild(d), d;
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
return
|
|
47
|
+
function ht(d) {
|
|
48
|
+
return d && d instanceof HTMLElement ? d : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), ct());
|
|
49
49
|
}
|
|
50
|
-
function ke(
|
|
51
|
-
const e =
|
|
50
|
+
function ke(d) {
|
|
51
|
+
const e = d.getBoundingClientRect();
|
|
52
52
|
return {
|
|
53
53
|
width: e.width || window.innerWidth,
|
|
54
54
|
height: e.height || window.innerHeight
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
function Fe(
|
|
58
|
-
if (!
|
|
57
|
+
function Fe(d) {
|
|
58
|
+
if (!d || typeof d != "object")
|
|
59
59
|
return console.warn("[ForceGraph3D] Invalid node: must be an object"), !1;
|
|
60
|
-
const e =
|
|
60
|
+
const e = d;
|
|
61
61
|
return typeof e.id != "string" || e.id.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node: id must be a non-empty string"), !1) : typeof e.label != "string" ? (console.warn("[ForceGraph3D] Invalid node: label must be a string"), !1) : e.color !== void 0 && typeof e.color != "number" ? (console.warn("[ForceGraph3D] Invalid node: color must be a number (hex)"), !1) : e.position !== void 0 && !pt(e.position) ? (console.warn("[ForceGraph3D] Invalid node: position must have x, y, z numbers"), !1) : !0;
|
|
62
62
|
}
|
|
63
|
-
function De(
|
|
64
|
-
if (!
|
|
63
|
+
function De(d) {
|
|
64
|
+
if (!d || typeof d != "object")
|
|
65
65
|
return console.warn("[ForceGraph3D] Invalid edge: must be an object"), !1;
|
|
66
|
-
const e =
|
|
66
|
+
const e = d;
|
|
67
67
|
return typeof e.source != "string" || e.source.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: source must be a non-empty string"), !1) : typeof e.target != "string" || e.target.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: target must be a non-empty string"), !1) : !0;
|
|
68
68
|
}
|
|
69
|
-
function
|
|
70
|
-
return typeof
|
|
69
|
+
function dt(d) {
|
|
70
|
+
return typeof d != "string" || d.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node ID: must be a non-empty string"), !1) : !0;
|
|
71
71
|
}
|
|
72
|
-
function pt(
|
|
73
|
-
if (!
|
|
74
|
-
const e =
|
|
72
|
+
function pt(d) {
|
|
73
|
+
if (!d || typeof d != "object") return !1;
|
|
74
|
+
const e = d;
|
|
75
75
|
return typeof e.x == "number" && typeof e.y == "number" && typeof e.z == "number";
|
|
76
76
|
}
|
|
77
|
-
function Dt(
|
|
78
|
-
return
|
|
77
|
+
function Dt(d, e) {
|
|
78
|
+
return d === e ? `${d}-${e}` : d < e ? `${d}-${e}` : `${e}-${d}`;
|
|
79
79
|
}
|
|
80
|
-
const Te = { type: "change" }, le = { type: "start" }, Pe = { type: "end" }, Q = new at(),
|
|
80
|
+
const Te = { type: "change" }, le = { type: "start" }, Pe = { type: "end" }, Q = new at(), Re = new rt(), gt = Math.cos(70 * lt.DEG2RAD);
|
|
81
81
|
class ut extends nt {
|
|
82
82
|
constructor(e, s) {
|
|
83
83
|
super(), this.object = e, this.domElement = s, this.domElement.style.touchAction = "none", this.enabled = !0, this.target = new S(), this.cursor = new S(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: j.ROTATE, MIDDLE: j.DOLLY, RIGHT: j.PAN }, this.touches = { ONE: $.ROTATE, TWO: $.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
|
|
@@ -98,9 +98,9 @@ class ut extends nt {
|
|
|
98
98
|
const a = new S(), g = new ze().setFromUnitVectors(e.up, new S(0, 1, 0)), v = g.clone().invert(), M = new S(), C = new ze(), F = new S(), z = 2 * Math.PI;
|
|
99
99
|
return function(st = null) {
|
|
100
100
|
const Ne = t.object.position;
|
|
101
|
-
a.copy(Ne).sub(t.target), a.applyQuaternion(g), r.setFromVector3(a), t.autoRotate && o === i.NONE && Y(He(st)), t.enableDamping ? (r.theta +=
|
|
102
|
-
let
|
|
103
|
-
isFinite(
|
|
101
|
+
a.copy(Ne).sub(t.target), a.applyQuaternion(g), r.setFromVector3(a), t.autoRotate && o === i.NONE && Y(He(st)), t.enableDamping ? (r.theta += h.theta * t.dampingFactor, r.phi += h.phi * t.dampingFactor) : (r.theta += h.theta, r.phi += h.phi);
|
|
102
|
+
let L = t.minAzimuthAngle, I = t.maxAzimuthAngle;
|
|
103
|
+
isFinite(L) && isFinite(I) && (L < -Math.PI ? L += z : L > Math.PI && (L -= z), I < -Math.PI ? I += z : I > Math.PI && (I -= z), L <= I ? r.theta = Math.max(L, Math.min(I, r.theta)) : r.theta = r.theta > (L + I) / 2 ? Math.max(L, r.theta) : Math.min(I, r.theta)), r.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, r.phi)), r.makeSafe(), t.enableDamping === !0 ? t.target.addScaledVector(p, t.dampingFactor) : t.target.add(p), t.target.sub(t.cursor), t.target.clampLength(t.minTargetRadius, t.maxTargetRadius), t.target.add(t.cursor), t.zoomToCursor && D || t.object.isOrthographicCamera ? r.radius = oe(r.radius) : r.radius = oe(r.radius * c), a.setFromSpherical(r), a.applyQuaternion(v), Ne.copy(t.target).add(a), t.object.lookAt(t.target), t.enableDamping === !0 ? (h.theta *= 1 - t.dampingFactor, h.phi *= 1 - t.dampingFactor, p.multiplyScalar(1 - t.dampingFactor)) : (h.set(0, 0, 0), p.set(0, 0, 0));
|
|
104
104
|
let re = !1;
|
|
105
105
|
if (t.zoomToCursor && D) {
|
|
106
106
|
let K = null;
|
|
@@ -116,7 +116,7 @@ class ut extends nt {
|
|
|
116
116
|
Z.unproject(t.object), t.object.position.sub(Z).add(U), t.object.updateMatrixWorld(), K = a.length();
|
|
117
117
|
} else
|
|
118
118
|
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), t.zoomToCursor = !1;
|
|
119
|
-
K !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(K).add(t.object.position) : (Q.origin.copy(t.object.position), Q.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Q.direction)) < gt ? e.lookAt(t.target) : (
|
|
119
|
+
K !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(K).add(t.object.position) : (Q.origin.copy(t.object.position), Q.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Q.direction)) < gt ? e.lookAt(t.target) : (Re.setFromNormalAndCoplanarPoint(t.object.up, t.target), Q.intersectPlane(Re, t.target))));
|
|
120
120
|
} else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / c)), t.object.updateProjectionMatrix(), re = !0);
|
|
121
121
|
return c = 1, D = !1, re || M.distanceToSquared(t.object.position) > n || 8 * (1 - C.dot(t.object.quaternion)) > n || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(Te), M.copy(t.object.position), C.copy(t.object.quaternion), F.copy(t.target), !0) : !1;
|
|
122
122
|
};
|
|
@@ -134,9 +134,9 @@ class ut extends nt {
|
|
|
134
134
|
TOUCH_DOLLY_ROTATE: 6
|
|
135
135
|
};
|
|
136
136
|
let o = i.NONE;
|
|
137
|
-
const n = 1e-6, r = new Se(),
|
|
137
|
+
const n = 1e-6, r = new Se(), h = new Se();
|
|
138
138
|
let c = 1;
|
|
139
|
-
const p = new S(), f = new k(), m = new k(), u = new k(), y = new k(), b = new k(), w = new k(), N = new k(), O = new k(),
|
|
139
|
+
const p = new S(), f = new k(), m = new k(), u = new k(), y = new k(), b = new k(), w = new k(), N = new k(), O = new k(), R = new k(), G = new S(), T = new k();
|
|
140
140
|
let D = !1;
|
|
141
141
|
const E = [], V = {};
|
|
142
142
|
let te = !1;
|
|
@@ -148,17 +148,17 @@ class ut extends nt {
|
|
|
148
148
|
return Math.pow(0.95, t.zoomSpeed * g);
|
|
149
149
|
}
|
|
150
150
|
function Y(a) {
|
|
151
|
-
|
|
151
|
+
h.theta -= a;
|
|
152
152
|
}
|
|
153
153
|
function W(a) {
|
|
154
|
-
|
|
154
|
+
h.phi -= a;
|
|
155
155
|
}
|
|
156
156
|
const ce = function() {
|
|
157
157
|
const a = new S();
|
|
158
158
|
return function(v, M) {
|
|
159
159
|
a.setFromMatrixColumn(M, 0), a.multiplyScalar(-v), p.add(a);
|
|
160
160
|
};
|
|
161
|
-
}(),
|
|
161
|
+
}(), he = function() {
|
|
162
162
|
const a = new S();
|
|
163
163
|
return function(v, M) {
|
|
164
164
|
t.screenSpacePanning === !0 ? a.setFromMatrixColumn(M, 1) : (a.setFromMatrixColumn(M, 0), a.crossVectors(t.object.up, a)), a.multiplyScalar(v), p.add(a);
|
|
@@ -171,14 +171,14 @@ class ut extends nt {
|
|
|
171
171
|
const F = t.object.position;
|
|
172
172
|
a.copy(F).sub(t.target);
|
|
173
173
|
let z = a.length();
|
|
174
|
-
z *= Math.tan(t.object.fov / 2 * Math.PI / 180), ce(2 * v * z / C.clientHeight, t.object.matrix),
|
|
175
|
-
} else t.object.isOrthographicCamera ? (ce(v * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix),
|
|
174
|
+
z *= Math.tan(t.object.fov / 2 * Math.PI / 180), ce(2 * v * z / C.clientHeight, t.object.matrix), he(2 * M * z / C.clientHeight, t.object.matrix);
|
|
175
|
+
} else t.object.isOrthographicCamera ? (ce(v * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix), he(M * (t.object.top - t.object.bottom) / t.object.zoom / C.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
|
|
176
176
|
};
|
|
177
177
|
}();
|
|
178
178
|
function se(a) {
|
|
179
179
|
t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? c /= a : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
|
|
180
180
|
}
|
|
181
|
-
function
|
|
181
|
+
function de(a) {
|
|
182
182
|
t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? c *= a : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
|
|
183
183
|
}
|
|
184
184
|
function ie(a, g) {
|
|
@@ -206,13 +206,13 @@ class ut extends nt {
|
|
|
206
206
|
Y(2 * Math.PI * u.x / g.clientHeight), W(2 * Math.PI * u.y / g.clientHeight), f.copy(m), t.update();
|
|
207
207
|
}
|
|
208
208
|
function $e(a) {
|
|
209
|
-
O.set(a.clientX, a.clientY),
|
|
209
|
+
O.set(a.clientX, a.clientY), R.subVectors(O, N), R.y > 0 ? se(q(R.y)) : R.y < 0 && de(q(R.y)), N.copy(O), t.update();
|
|
210
210
|
}
|
|
211
211
|
function Ge(a) {
|
|
212
212
|
b.set(a.clientX, a.clientY), w.subVectors(b, y).multiplyScalar(t.panSpeed), H(w.x, w.y), y.copy(b), t.update();
|
|
213
213
|
}
|
|
214
214
|
function Ye(a) {
|
|
215
|
-
ie(a.clientX, a.clientY), a.deltaY < 0 ?
|
|
215
|
+
ie(a.clientX, a.clientY), a.deltaY < 0 ? de(q(a.deltaY)) : a.deltaY > 0 && se(q(a.deltaY)), t.update();
|
|
216
216
|
}
|
|
217
217
|
function Be(a) {
|
|
218
218
|
let g = !1;
|
|
@@ -280,7 +280,7 @@ class ut extends nt {
|
|
|
280
280
|
}
|
|
281
281
|
function be(a) {
|
|
282
282
|
const g = A(a), v = a.pageX - g.x, M = a.pageY - g.y, C = Math.sqrt(v * v + M * M);
|
|
283
|
-
O.set(0, C),
|
|
283
|
+
O.set(0, C), R.set(0, Math.pow(O.y / N.y, t.zoomSpeed)), se(R.y), N.copy(O);
|
|
284
284
|
const F = (a.pageX + g.x) * 0.5, z = (a.pageY + g.y) * 0.5;
|
|
285
285
|
ie(F, z);
|
|
286
286
|
}
|
|
@@ -774,16 +774,16 @@ class mt {
|
|
|
774
774
|
const c = n.findIndex((p) => p.source === e && p.target === s);
|
|
775
775
|
c !== -1 && n.splice(c, 1);
|
|
776
776
|
}
|
|
777
|
-
const
|
|
778
|
-
if (!
|
|
777
|
+
const h = this.edgeObjectMap.get(t);
|
|
778
|
+
if (!h)
|
|
779
779
|
return !0;
|
|
780
780
|
if (n.length === 0) {
|
|
781
|
-
this.sceneManager.remove(
|
|
782
|
-
const c = this.edgeObjects.findIndex((p) => p ===
|
|
781
|
+
this.sceneManager.remove(h.line), this.edgeFactory.disposeEdge(h);
|
|
782
|
+
const c = this.edgeObjects.findIndex((p) => p === h);
|
|
783
783
|
c !== -1 && this.edgeObjects.splice(c, 1), this.edgeGroups.delete(t), this.edgeObjectMap.delete(t), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null);
|
|
784
784
|
} else {
|
|
785
785
|
const c = this.nodeManager.getNode(e), p = this.nodeManager.getNode(s);
|
|
786
|
-
c && p && this.updateEdgeUserData(
|
|
786
|
+
c && p && this.updateEdgeUserData(h, n, c, p);
|
|
787
787
|
}
|
|
788
788
|
return !0;
|
|
789
789
|
}
|
|
@@ -898,7 +898,7 @@ class mt {
|
|
|
898
898
|
this.clear();
|
|
899
899
|
}
|
|
900
900
|
}
|
|
901
|
-
class
|
|
901
|
+
class Le {
|
|
902
902
|
constructor(e, s, t = {}) {
|
|
903
903
|
l(this, "nodes");
|
|
904
904
|
l(this, "edges");
|
|
@@ -972,11 +972,11 @@ class Re {
|
|
|
972
972
|
for (let i = 0; i < s; i++) {
|
|
973
973
|
const o = e[i];
|
|
974
974
|
for (let n = i + 1; n < s; n++) {
|
|
975
|
-
const r = e[n],
|
|
976
|
-
let f =
|
|
975
|
+
const r = e[n], h = r.position.x - o.position.x, c = r.position.y - o.position.y, p = r.position.z - o.position.z;
|
|
976
|
+
let f = h * h + c * c + p * p;
|
|
977
977
|
if (f > this.REPULSION_CUTOFF_SQ) continue;
|
|
978
978
|
f < 0.01 && (f = 0.01);
|
|
979
|
-
const m = Math.sqrt(f), u = t * this.alpha / f, y =
|
|
979
|
+
const m = Math.sqrt(f), u = t * this.alpha / f, y = h / m * u, b = c / m * u, w = p / m * u;
|
|
980
980
|
o.velocity.x -= y / o.mass, o.velocity.y -= b / o.mass, o.velocity.z -= w / o.mass, r.velocity.x += y / r.mass, r.velocity.y += b / r.mass, r.velocity.z += w / r.mass;
|
|
981
981
|
}
|
|
982
982
|
}
|
|
@@ -1000,9 +1000,9 @@ class Re {
|
|
|
1000
1000
|
if (s.mass === 0) return;
|
|
1001
1001
|
const t = s.centerOfMass.x - e.position.x, i = s.centerOfMass.y - e.position.y, o = s.centerOfMass.z - e.position.z, n = t * t + i * i + o * o;
|
|
1002
1002
|
if (n > this.REPULSION_CUTOFF_SQ) return;
|
|
1003
|
-
const r = Math.sqrt(n),
|
|
1003
|
+
const r = Math.sqrt(n), h = this.getEffectiveRepulsion();
|
|
1004
1004
|
if (r > 0 && s.size / r < this.barnesHutTheta) {
|
|
1005
|
-
const c = Math.max(n, 0.01), p =
|
|
1005
|
+
const c = Math.max(n, 0.01), p = h * this.alpha * s.mass / c;
|
|
1006
1006
|
e.velocity.x -= t / r * p / e.mass, e.velocity.y -= i / r * p / e.mass, e.velocity.z -= o / r * p / e.mass;
|
|
1007
1007
|
} else
|
|
1008
1008
|
for (const c of s.children)
|
|
@@ -1027,9 +1027,9 @@ class Re {
|
|
|
1027
1027
|
for (const t of this.edges) {
|
|
1028
1028
|
const i = this.nodes.get(t.source), o = this.nodes.get(t.target);
|
|
1029
1029
|
if (!i || !o) continue;
|
|
1030
|
-
const n = o.position.x - i.position.x, r = o.position.y - i.position.y,
|
|
1030
|
+
const n = o.position.x - i.position.x, r = o.position.y - i.position.y, h = o.position.z - i.position.z, c = Math.sqrt(n * n + r * r + h * h);
|
|
1031
1031
|
if (c < 0.01) continue;
|
|
1032
|
-
const f = (c - 15) * this.attractionStrength * s * this.alpha, m = n / c * f, u = r / c * f, y =
|
|
1032
|
+
const f = (c - 15) * this.attractionStrength * s * this.alpha, m = n / c * f, u = r / c * f, y = h / c * f;
|
|
1033
1033
|
i.velocity.x += m / i.mass, i.velocity.y += u / i.mass, i.velocity.z += y / i.mass, o.velocity.x -= m / o.mass, o.velocity.y -= u / o.mass, o.velocity.z -= y / o.mass;
|
|
1034
1034
|
}
|
|
1035
1035
|
}
|
|
@@ -1136,10 +1136,10 @@ class yt {
|
|
|
1136
1136
|
children: []
|
|
1137
1137
|
};
|
|
1138
1138
|
}
|
|
1139
|
-
const o = (s.min.x + s.max.x) / 2, n = (s.min.y + s.max.y) / 2, r = (s.min.z + s.max.z) / 2,
|
|
1139
|
+
const o = (s.min.x + s.max.x) / 2, n = (s.min.y + s.max.y) / 2, r = (s.min.z + s.max.z) / 2, h = [[], [], [], [], [], [], [], []];
|
|
1140
1140
|
for (const u of e) {
|
|
1141
1141
|
const y = (u.position.x >= o ? 1 : 0) + (u.position.y >= n ? 2 : 0) + (u.position.z >= r ? 4 : 0);
|
|
1142
|
-
|
|
1142
|
+
h[y].push(u);
|
|
1143
1143
|
}
|
|
1144
1144
|
const c = [
|
|
1145
1145
|
{ min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: o, y: n, z: r } },
|
|
@@ -1154,8 +1154,8 @@ class yt {
|
|
|
1154
1154
|
let f = 0;
|
|
1155
1155
|
const m = { x: 0, y: 0, z: 0 };
|
|
1156
1156
|
for (let u = 0; u < 8; u++)
|
|
1157
|
-
if (
|
|
1158
|
-
const y = this.buildTree(
|
|
1157
|
+
if (h[u].length > 0) {
|
|
1158
|
+
const y = this.buildTree(h[u], c[u], t + 1);
|
|
1159
1159
|
p.push(y), f += y.mass, m.x += y.centerOfMass.x * y.mass, m.y += y.centerOfMass.y * y.mass, m.z += y.centerOfMass.z * y.mass;
|
|
1160
1160
|
} else
|
|
1161
1161
|
p.push(null);
|
|
@@ -1285,12 +1285,12 @@ class bt {
|
|
|
1285
1285
|
256 * 0.8
|
|
1286
1286
|
);
|
|
1287
1287
|
r.addColorStop(0, i.colors[0]), r.addColorStop(0.5, i.colors[1]), r.addColorStop(1, i.colors[2]), n.fillStyle = r, n.fillRect(0, 0, 256, 256);
|
|
1288
|
-
const
|
|
1289
|
-
for (let c = 0; c <
|
|
1288
|
+
const h = n.getImageData(0, 0, 256, 256);
|
|
1289
|
+
for (let c = 0; c < h.data.length; c += 4) {
|
|
1290
1290
|
const p = (Math.random() - 0.5) * 5;
|
|
1291
|
-
|
|
1291
|
+
h.data[c] = Math.min(255, Math.max(0, h.data[c] + p)), h.data[c + 1] = Math.min(255, Math.max(0, h.data[c + 1] + p)), h.data[c + 2] = Math.min(255, Math.max(0, h.data[c + 2] + p));
|
|
1292
1292
|
}
|
|
1293
|
-
n.putImageData(
|
|
1293
|
+
n.putImageData(h, 0, 0), s.push(o);
|
|
1294
1294
|
}
|
|
1295
1295
|
this.envMap = new x.CubeTexture(s.map((i) => {
|
|
1296
1296
|
const o = new Image();
|
|
@@ -1477,15 +1477,15 @@ class vt {
|
|
|
1477
1477
|
e.color ?? this.defaultNodeColor
|
|
1478
1478
|
), n = new x.Mesh(i, o);
|
|
1479
1479
|
n.castShadow = !0, n.receiveShadow = !0, t.add(n);
|
|
1480
|
-
const r = this.materialFactory.createLabelMaterial(e.label),
|
|
1481
|
-
return
|
|
1480
|
+
const r = this.materialFactory.createLabelMaterial(e.label), h = new x.Sprite(r);
|
|
1481
|
+
return h.position.y = this.nodeRadius + 1.5, h.scale.set(4, 1, 1), t.add(h), e.position && t.position.set(
|
|
1482
1482
|
e.position.x,
|
|
1483
1483
|
e.position.y,
|
|
1484
1484
|
e.position.z
|
|
1485
1485
|
), {
|
|
1486
1486
|
group: t,
|
|
1487
1487
|
sphere: n,
|
|
1488
|
-
label:
|
|
1488
|
+
label: h,
|
|
1489
1489
|
lodLevel: s
|
|
1490
1490
|
};
|
|
1491
1491
|
}
|
|
@@ -1559,7 +1559,7 @@ class wt {
|
|
|
1559
1559
|
o.z
|
|
1560
1560
|
]);
|
|
1561
1561
|
n.setAttribute("position", new x.BufferAttribute(r, 3));
|
|
1562
|
-
const
|
|
1562
|
+
const h = this.getDefaultMaterial().clone(), c = new x.Line(n, h);
|
|
1563
1563
|
return c.name = `edge-${e.source}-${e.target}`, c.userData = {
|
|
1564
1564
|
source: e.source,
|
|
1565
1565
|
target: e.target,
|
|
@@ -1907,16 +1907,9 @@ class Nt {
|
|
|
1907
1907
|
if (!this.panel) return;
|
|
1908
1908
|
this.currentNodeId = e.id;
|
|
1909
1909
|
let t;
|
|
1910
|
-
this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t;
|
|
1911
|
-
const i = this.panel.querySelector('[data-action="
|
|
1912
|
-
i &&
|
|
1913
|
-
if (this.currentNodeId) {
|
|
1914
|
-
const r = o ? parseInt(o.value, 10) : 1;
|
|
1915
|
-
this.onExpand(this.currentNodeId, r);
|
|
1916
|
-
}
|
|
1917
|
-
});
|
|
1918
|
-
const n = this.panel.querySelector('[data-action="close"]');
|
|
1919
|
-
n && n.addEventListener("click", () => {
|
|
1910
|
+
this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t, this.onExpand;
|
|
1911
|
+
const i = this.panel.querySelector('[data-action="close"]');
|
|
1912
|
+
i && i.addEventListener("click", () => {
|
|
1920
1913
|
this.hide();
|
|
1921
1914
|
}), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
|
|
1922
1915
|
}
|
|
@@ -1995,36 +1988,6 @@ class Nt {
|
|
|
1995
1988
|
border-radius: 12px;
|
|
1996
1989
|
font-size: 12px;
|
|
1997
1990
|
}
|
|
1998
|
-
.force-graph-panel .depth-selector {
|
|
1999
|
-
margin-top: 16px;
|
|
2000
|
-
margin-bottom: 8px;
|
|
2001
|
-
}
|
|
2002
|
-
.force-graph-panel .depth-label {
|
|
2003
|
-
font-size: 12px;
|
|
2004
|
-
color: rgba(255, 255, 255, 0.65);
|
|
2005
|
-
margin-bottom: 6px;
|
|
2006
|
-
text-transform: uppercase;
|
|
2007
|
-
letter-spacing: 0.5px;
|
|
2008
|
-
}
|
|
2009
|
-
.force-graph-panel select {
|
|
2010
|
-
width: 100%;
|
|
2011
|
-
padding: 8px 12px;
|
|
2012
|
-
background: rgba(255, 255, 255, 0.08);
|
|
2013
|
-
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
2014
|
-
border-radius: 8px;
|
|
2015
|
-
color: white;
|
|
2016
|
-
font-size: 13px;
|
|
2017
|
-
cursor: pointer;
|
|
2018
|
-
outline: none;
|
|
2019
|
-
transition: all 0.2s ease;
|
|
2020
|
-
}
|
|
2021
|
-
.force-graph-panel select:hover {
|
|
2022
|
-
background: rgba(255, 255, 255, 0.12);
|
|
2023
|
-
}
|
|
2024
|
-
.force-graph-panel select:focus {
|
|
2025
|
-
border-color: rgba(255, 153, 102, 0.5);
|
|
2026
|
-
box-shadow: 0 0 20px rgba(255, 153, 102, 0.15);
|
|
2027
|
-
}
|
|
2028
1991
|
.force-graph-panel .btn-row {
|
|
2029
1992
|
display: flex;
|
|
2030
1993
|
gap: 8px;
|
|
@@ -2040,15 +2003,6 @@ class Nt {
|
|
|
2040
2003
|
cursor: pointer;
|
|
2041
2004
|
transition: all 0.2s ease;
|
|
2042
2005
|
}
|
|
2043
|
-
.force-graph-panel .btn-expand {
|
|
2044
|
-
background: linear-gradient(135deg, rgba(255, 153, 102, 0.3), rgba(255, 102, 153, 0.2));
|
|
2045
|
-
border-color: rgba(255, 153, 102, 0.35);
|
|
2046
|
-
color: white;
|
|
2047
|
-
}
|
|
2048
|
-
.force-graph-panel .btn-expand:hover {
|
|
2049
|
-
transform: translateY(-1px);
|
|
2050
|
-
box-shadow: 0 0 15px rgba(255, 153, 102, 0.2);
|
|
2051
|
-
}
|
|
2052
2006
|
.force-graph-panel .btn-close {
|
|
2053
2007
|
background: rgba(255, 255, 255, 0.08);
|
|
2054
2008
|
color: rgba(255, 255, 255, 0.8);
|
|
@@ -2087,18 +2041,7 @@ class Nt {
|
|
|
2087
2041
|
</div>
|
|
2088
2042
|
` : ""}
|
|
2089
2043
|
|
|
2090
|
-
<div class="depth-selector">
|
|
2091
|
-
<div class="depth-label">Expansion Depth</div>
|
|
2092
|
-
<select data-depth-select>
|
|
2093
|
-
<option value="1">1 Level</option>
|
|
2094
|
-
<option value="2">2 Levels</option>
|
|
2095
|
-
<option value="3" selected>3 Levels</option>
|
|
2096
|
-
</select>
|
|
2097
|
-
</div>
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
2044
|
<div class="btn-row">
|
|
2101
|
-
<button class="btn-expand" data-action="expand">Expand</button>
|
|
2102
2045
|
<button class="btn-close" data-action="close">Close</button>
|
|
2103
2046
|
</div>
|
|
2104
2047
|
`;
|
|
@@ -2207,8 +2150,8 @@ class St {
|
|
|
2207
2150
|
r && this.onNodeClick && r.addEventListener("click", () => {
|
|
2208
2151
|
this.onNodeClick && this.onNodeClick(e.source);
|
|
2209
2152
|
});
|
|
2210
|
-
const
|
|
2211
|
-
|
|
2153
|
+
const h = this.panel.querySelector('[data-action="goto-target"]');
|
|
2154
|
+
h && this.onNodeClick && h.addEventListener("click", () => {
|
|
2212
2155
|
this.onNodeClick && this.onNodeClick(e.target);
|
|
2213
2156
|
}), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
|
|
2214
2157
|
}
|
|
@@ -2216,7 +2159,7 @@ class St {
|
|
|
2216
2159
|
* Generates default panel content
|
|
2217
2160
|
*/
|
|
2218
2161
|
generateDefaultContent(e, s, t, i = [e]) {
|
|
2219
|
-
const o = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", n = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", r = this.getRelationshipLabel(e),
|
|
2162
|
+
const o = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", n = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", r = this.getRelationshipLabel(e), h = i.length > 0 ? i : [e], c = this.summarizeRelationships(h), p = c.slice(0, 10).map((m) => `
|
|
2220
2163
|
<div class="relationship-item">
|
|
2221
2164
|
<span class="relationship-item-label">${this.escapeHtml(m.label)}</span>
|
|
2222
2165
|
<span class="relationship-item-count">${m.count}</span>
|
|
@@ -2375,7 +2318,7 @@ class St {
|
|
|
2375
2318
|
|
|
2376
2319
|
<div class="relationship-section">
|
|
2377
2320
|
<span class="relationship-label">${this.escapeHtml(r)}</span>
|
|
2378
|
-
<div class="relationship-count">${
|
|
2321
|
+
<div class="relationship-count">${h.length} relationships</div>
|
|
2379
2322
|
</div>
|
|
2380
2323
|
|
|
2381
2324
|
<div class="relationship-list">
|
|
@@ -2504,7 +2447,7 @@ class zt {
|
|
|
2504
2447
|
*/
|
|
2505
2448
|
show(e, s, t, i, o, n = [e]) {
|
|
2506
2449
|
if (!this.tooltip) return;
|
|
2507
|
-
const r = n.length > 0 ? n : [e],
|
|
2450
|
+
const r = n.length > 0 ? n : [e], h = this.summarizeRelationships(r), c = r.length;
|
|
2508
2451
|
if (c <= 1) {
|
|
2509
2452
|
const p = this.getRelationshipLabel(r[0]);
|
|
2510
2453
|
this.tooltip.innerHTML = `
|
|
@@ -2521,7 +2464,7 @@ class zt {
|
|
|
2521
2464
|
</div>
|
|
2522
2465
|
`;
|
|
2523
2466
|
} else {
|
|
2524
|
-
const p =
|
|
2467
|
+
const p = h.slice(0, 4), f = h.length - p.length, m = p.map((u) => `<div style="display:flex; justify-content:space-between; gap:10px; font-size:12px; color: rgba(255,255,255,0.8);">
|
|
2525
2468
|
<span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${this.escapeHtml(u.label)}</span>
|
|
2526
2469
|
<span style="color: rgba(255,153,102,0.9); font-weight:600;">${u.count}</span>
|
|
2527
2470
|
</div>`).join("");
|
|
@@ -2934,7 +2877,7 @@ class Pt {
|
|
|
2934
2877
|
this.legendContainer && this.legendContainer.parentNode && this.legendContainer.parentNode.removeChild(this.legendContainer);
|
|
2935
2878
|
}
|
|
2936
2879
|
}
|
|
2937
|
-
const
|
|
2880
|
+
const Rt = {
|
|
2938
2881
|
backgroundColor: "#0a0a0a",
|
|
2939
2882
|
gridColor: "rgba(255, 255, 255, 0.03)",
|
|
2940
2883
|
nodeRadius: 24,
|
|
@@ -2947,7 +2890,7 @@ const Lt = {
|
|
|
2947
2890
|
damping: 0.85
|
|
2948
2891
|
// Fast energy dissipation
|
|
2949
2892
|
};
|
|
2950
|
-
class
|
|
2893
|
+
class Lt {
|
|
2951
2894
|
constructor(e, s = {}) {
|
|
2952
2895
|
l(this, "container");
|
|
2953
2896
|
l(this, "canvas");
|
|
@@ -2974,7 +2917,7 @@ class Rt {
|
|
|
2974
2917
|
l(this, "isSimulating", !0);
|
|
2975
2918
|
// Resize handler
|
|
2976
2919
|
l(this, "resizeHandler");
|
|
2977
|
-
this.container = e, this.options = { ...
|
|
2920
|
+
this.container = e, this.options = { ...Rt, ...s }, this.canvas = document.createElement("canvas"), this.canvas.style.position = "absolute", this.canvas.style.top = "0", this.canvas.style.left = "0", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.cursor = "grab", e.appendChild(this.canvas);
|
|
2978
2921
|
const t = this.canvas.getContext("2d");
|
|
2979
2922
|
if (!t)
|
|
2980
2923
|
throw new Error("Failed to get 2D context");
|
|
@@ -3037,9 +2980,9 @@ class Rt {
|
|
|
3037
2980
|
for (const i of this.edges) {
|
|
3038
2981
|
const o = this.nodes.get(i.source), n = this.nodes.get(i.target);
|
|
3039
2982
|
if (!o || !n) continue;
|
|
3040
|
-
const r = n.x - o.x,
|
|
2983
|
+
const r = n.x - o.x, h = n.y - o.y, c = r * r + h * h;
|
|
3041
2984
|
if (c === 0) continue;
|
|
3042
|
-
const p = Math.max(0, Math.min(1, ((e - o.x) * r + (s - o.y) *
|
|
2985
|
+
const p = Math.max(0, Math.min(1, ((e - o.x) * r + (s - o.y) * h) / c)), f = o.x + p * r, m = o.y + p * h, u = e - f, y = s - m;
|
|
3043
2986
|
if (Math.sqrt(u * u + y * y) < 12)
|
|
3044
2987
|
return i;
|
|
3045
2988
|
}
|
|
@@ -3057,8 +3000,8 @@ class Rt {
|
|
|
3057
3000
|
const t = 60, i = 5;
|
|
3058
3001
|
let o = 0;
|
|
3059
3002
|
for (let r = 0; r < s; r++)
|
|
3060
|
-
for (let
|
|
3061
|
-
const c = e[r], p = e[
|
|
3003
|
+
for (let h = r + 1; h < s; h++) {
|
|
3004
|
+
const c = e[r], p = e[h];
|
|
3062
3005
|
let f = p.x - c.x, m = p.y - c.y, u = Math.sqrt(f * f + m * m);
|
|
3063
3006
|
if (u < t * 3) {
|
|
3064
3007
|
u < 1 && (u = 1);
|
|
@@ -3068,18 +3011,18 @@ class Rt {
|
|
|
3068
3011
|
}
|
|
3069
3012
|
const n = 80;
|
|
3070
3013
|
for (const r of this.edges) {
|
|
3071
|
-
const
|
|
3072
|
-
if (!
|
|
3073
|
-
let p = c.x -
|
|
3014
|
+
const h = this.nodes.get(r.source), c = this.nodes.get(r.target);
|
|
3015
|
+
if (!h || !c) continue;
|
|
3016
|
+
let p = c.x - h.x, f = c.y - h.y, m = Math.sqrt(p * p + f * f);
|
|
3074
3017
|
m < 1 && (m = 1);
|
|
3075
3018
|
const y = (m - n) * this.options.attractionStrength, b = p / m * y, w = f / m * y;
|
|
3076
|
-
|
|
3019
|
+
h.vx += b, h.vy += w, c.vx -= b, c.vy -= w;
|
|
3077
3020
|
}
|
|
3078
3021
|
for (const r of e) {
|
|
3079
3022
|
if (this.draggedNode === r) continue;
|
|
3080
3023
|
r.vx *= this.options.damping, r.vy *= this.options.damping;
|
|
3081
|
-
const
|
|
3082
|
-
|
|
3024
|
+
const h = Math.sqrt(r.vx * r.vx + r.vy * r.vy);
|
|
3025
|
+
h > i && (r.vx = r.vx / h * i, r.vy = r.vy / h * i), r.x += r.vx, r.y += r.vy, o += r.vx * r.vx + r.vy * r.vy;
|
|
3083
3026
|
}
|
|
3084
3027
|
o < 0.01 && !this.draggedNode && (this.isSimulating = !1);
|
|
3085
3028
|
}
|
|
@@ -3090,9 +3033,9 @@ class Rt {
|
|
|
3090
3033
|
renderGrid(e, s) {
|
|
3091
3034
|
const t = this.ctx, i = 40 * this.transform.scale, o = 1.5, n = this.transform.x % i, r = this.transform.y % i;
|
|
3092
3035
|
t.fillStyle = this.options.gridColor;
|
|
3093
|
-
for (let
|
|
3036
|
+
for (let h = n; h < e; h += i)
|
|
3094
3037
|
for (let c = r; c < s; c += i)
|
|
3095
|
-
t.beginPath(), t.arc(
|
|
3038
|
+
t.beginPath(), t.arc(h, c, o, 0, Math.PI * 2), t.fill();
|
|
3096
3039
|
}
|
|
3097
3040
|
renderEdges() {
|
|
3098
3041
|
const e = this.ctx;
|
|
@@ -3125,8 +3068,8 @@ class Rt {
|
|
|
3125
3068
|
s.x,
|
|
3126
3069
|
s.y,
|
|
3127
3070
|
n
|
|
3128
|
-
),
|
|
3129
|
-
r.addColorStop(0, `rgba(${Math.min(255,
|
|
3071
|
+
), h = s.color >> 16 & 255, c = s.color >> 8 & 255, p = s.color & 255;
|
|
3072
|
+
r.addColorStop(0, `rgba(${Math.min(255, h + 60)}, ${Math.min(255, c + 60)}, ${Math.min(255, p + 60)}, 0.95)`), r.addColorStop(0.7, `rgba(${h}, ${c}, ${p}, 0.9)`), r.addColorStop(1, `rgba(${Math.max(0, h - 40)}, ${Math.max(0, c - 40)}, ${Math.max(0, p - 40)}, 0.85)`), e.beginPath(), e.arc(s.x, s.y, n, 0, Math.PI * 2), e.fillStyle = r, e.fill(), e.strokeStyle = "rgba(255, 255, 255, 0.2)", e.lineWidth = 1, e.stroke(), e.beginPath(), e.arc(s.x - n * 0.25, s.y - n * 0.25, n * 0.3, 0, Math.PI * 2), e.fillStyle = "rgba(255, 255, 255, 0.15)", e.fill(), e.fillStyle = "white", e.font = "600 11px Inter, -apple-system, BlinkMacSystemFont, sans-serif", e.textAlign = "center", e.textBaseline = "middle";
|
|
3130
3073
|
const f = n * 1.6;
|
|
3131
3074
|
let m = s.label, u = e.measureText(m).width;
|
|
3132
3075
|
if (u > f) {
|
|
@@ -3233,8 +3176,8 @@ class Rt {
|
|
|
3233
3176
|
focusOnNode(e) {
|
|
3234
3177
|
const s = this.nodes.get(e);
|
|
3235
3178
|
if (!s) return;
|
|
3236
|
-
const t = this.canvas.width / 2 / (window.devicePixelRatio || 1) - s.x * this.transform.scale, i = this.canvas.height / 2 / (window.devicePixelRatio || 1) - s.y * this.transform.scale, o = this.transform.x, n = this.transform.y, r = 500,
|
|
3237
|
-
const p = performance.now() -
|
|
3179
|
+
const t = this.canvas.width / 2 / (window.devicePixelRatio || 1) - s.x * this.transform.scale, i = this.canvas.height / 2 / (window.devicePixelRatio || 1) - s.y * this.transform.scale, o = this.transform.x, n = this.transform.y, r = 500, h = performance.now(), c = () => {
|
|
3180
|
+
const p = performance.now() - h, f = Math.min(p / r, 1), m = 1 - Math.pow(1 - f, 3);
|
|
3238
3181
|
this.transform.x = o + (t - o) * m, this.transform.y = n + (i - n) * m, f < 1 ? requestAnimationFrame(c) : this.selectedNode = s;
|
|
3239
3182
|
};
|
|
3240
3183
|
c();
|
|
@@ -3315,7 +3258,7 @@ class Ht {
|
|
|
3315
3258
|
l(this, "devControls", null);
|
|
3316
3259
|
l(this, "viewMode", "3d");
|
|
3317
3260
|
l(this, "graphData", null);
|
|
3318
|
-
this.options = { ...P, ...s }, this.container =
|
|
3261
|
+
this.options = { ...P, ...s }, this.container = ht(e), this.materialFactory = new bt(), this.nodeFactory = new vt(
|
|
3319
3262
|
this.materialFactory,
|
|
3320
3263
|
this.options.nodeRadius ?? P.nodeRadius,
|
|
3321
3264
|
this.options.lodSegments ?? P.lodSegments,
|
|
@@ -3331,7 +3274,7 @@ class Ht {
|
|
|
3331
3274
|
), this.frustumCuller = new Et(
|
|
3332
3275
|
this.sceneManager.camera,
|
|
3333
3276
|
this.options.enableEdgeCulling ?? P.enableEdgeCulling
|
|
3334
|
-
), this.nodeManager = new ee(this.sceneManager, this.nodeFactory), this.edgeManager = new mt(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new
|
|
3277
|
+
), this.nodeManager = new ee(this.sceneManager, this.nodeFactory), this.edgeManager = new mt(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Le(
|
|
3335
3278
|
this.nodeManager.getAllNodes(),
|
|
3336
3279
|
this.edgeManager.getAllEdges(),
|
|
3337
3280
|
{
|
|
@@ -3461,7 +3404,7 @@ class Ht {
|
|
|
3461
3404
|
if (o.edges && Array.isArray(o.edges))
|
|
3462
3405
|
for (const r of o.edges)
|
|
3463
3406
|
this.addEdge(r);
|
|
3464
|
-
this.graphEngine = new
|
|
3407
|
+
this.graphEngine = new Le(
|
|
3465
3408
|
this.nodeManager.getAllNodes(),
|
|
3466
3409
|
this.edgeManager.getAllEdges(),
|
|
3467
3410
|
{
|
|
@@ -3488,7 +3431,7 @@ class Ht {
|
|
|
3488
3431
|
* @returns true if removed, false if not found
|
|
3489
3432
|
*/
|
|
3490
3433
|
removeNode(e) {
|
|
3491
|
-
if (!
|
|
3434
|
+
if (!dt(e))
|
|
3492
3435
|
return !1;
|
|
3493
3436
|
this.edgeManager.removeEdgesForNode(e);
|
|
3494
3437
|
const s = this.nodeManager.removeNode(e);
|
|
@@ -3585,13 +3528,13 @@ class Ht {
|
|
|
3585
3528
|
console.warn(`[ForceGraph3D] Node "${e}" not found`);
|
|
3586
3529
|
return;
|
|
3587
3530
|
}
|
|
3588
|
-
const i = t.position, o = this.sceneManager.camera, n = this.sceneManager.controls, r = o.position.clone().sub(n.target).normalize(),
|
|
3531
|
+
const i = t.position, o = this.sceneManager.camera, n = this.sceneManager.controls, r = o.position.clone().sub(n.target).normalize(), h = {
|
|
3589
3532
|
x: i.x + r.x * s,
|
|
3590
3533
|
y: i.y + r.y * s,
|
|
3591
3534
|
z: i.z + r.z * s
|
|
3592
3535
|
}, c = { x: o.position.x, y: o.position.y, z: o.position.z }, p = { x: n.target.x, y: n.target.y, z: n.target.z }, f = 800, m = performance.now(), u = () => {
|
|
3593
3536
|
const y = performance.now() - m, b = Math.min(y / f, 1), w = 1 - Math.pow(1 - b, 3);
|
|
3594
|
-
o.position.x = c.x + (
|
|
3537
|
+
o.position.x = c.x + (h.x - c.x) * w, o.position.y = c.y + (h.y - c.y) * w, o.position.z = c.z + (h.z - c.z) * w, n.target.x = p.x + (i.x - p.x) * w, n.target.y = p.y + (i.y - p.y) * w, n.target.z = p.z + (i.z - p.z) * w, n.update(), b < 1 && requestAnimationFrame(u);
|
|
3595
3538
|
};
|
|
3596
3539
|
u();
|
|
3597
3540
|
}
|
|
@@ -3605,17 +3548,17 @@ class Ht {
|
|
|
3605
3548
|
console.warn(`[ForceGraph3D] Could not find nodes for edge "${e}" -> "${s}"`);
|
|
3606
3549
|
return;
|
|
3607
3550
|
}
|
|
3608
|
-
const n = this.sceneManager.camera, r = this.sceneManager.controls,
|
|
3551
|
+
const n = this.sceneManager.camera, r = this.sceneManager.controls, h = {
|
|
3609
3552
|
x: (i.position.x + o.position.x) / 2,
|
|
3610
3553
|
y: (i.position.y + o.position.y) / 2,
|
|
3611
3554
|
z: (i.position.z + o.position.z) / 2
|
|
3612
3555
|
}, c = o.position.x - i.position.x, p = o.position.y - i.position.y, f = o.position.z - i.position.z, m = Math.sqrt(c * c + p * p + f * f), u = Math.max(m * t, 40), y = n.position.clone().sub(r.target).normalize(), b = {
|
|
3613
|
-
x:
|
|
3614
|
-
y:
|
|
3615
|
-
z:
|
|
3616
|
-
}, w = { x: n.position.x, y: n.position.y, z: n.position.z }, N = { x: r.target.x, y: r.target.y, z: r.target.z }, O = 800,
|
|
3617
|
-
const T = performance.now() -
|
|
3618
|
-
n.position.x = w.x + (b.x - w.x) * E, n.position.y = w.y + (b.y - w.y) * E, n.position.z = w.z + (b.z - w.z) * E, r.target.x = N.x + (
|
|
3556
|
+
x: h.x + y.x * u,
|
|
3557
|
+
y: h.y + y.y * u,
|
|
3558
|
+
z: h.z + y.z * u
|
|
3559
|
+
}, w = { x: n.position.x, y: n.position.y, z: n.position.z }, N = { x: r.target.x, y: r.target.y, z: r.target.z }, O = 800, R = performance.now(), G = () => {
|
|
3560
|
+
const T = performance.now() - R, D = Math.min(T / O, 1), E = 1 - Math.pow(1 - D, 3);
|
|
3561
|
+
n.position.x = w.x + (b.x - w.x) * E, n.position.y = w.y + (b.y - w.y) * E, n.position.z = w.z + (b.z - w.z) * E, r.target.x = N.x + (h.x - N.x) * E, r.target.y = N.y + (h.y - N.y) * E, r.target.z = N.z + (h.z - N.z) * E, r.update(), D < 1 && requestAnimationFrame(G);
|
|
3619
3562
|
};
|
|
3620
3563
|
G();
|
|
3621
3564
|
}
|
|
@@ -3641,8 +3584,8 @@ class Ht {
|
|
|
3641
3584
|
const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), i = [];
|
|
3642
3585
|
return t.forEach((o) => {
|
|
3643
3586
|
var c, p, f;
|
|
3644
|
-
const n = (c = o.label) == null ? void 0 : c.toLowerCase().includes(s), r = (p = o.id) == null ? void 0 : p.toLowerCase().includes(s),
|
|
3645
|
-
(n || r ||
|
|
3587
|
+
const n = (c = o.label) == null ? void 0 : c.toLowerCase().includes(s), r = (p = o.id) == null ? void 0 : p.toLowerCase().includes(s), h = (f = o.type) == null ? void 0 : f.toLowerCase().includes(s);
|
|
3588
|
+
(n || r || h) && i.push(o);
|
|
3646
3589
|
}), i;
|
|
3647
3590
|
}
|
|
3648
3591
|
/**
|
|
@@ -3656,8 +3599,8 @@ class Ht {
|
|
|
3656
3599
|
const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), i = [];
|
|
3657
3600
|
for (const n of t)
|
|
3658
3601
|
if ((o = n.relationship) == null ? void 0 : o.toLowerCase().includes(s)) {
|
|
3659
|
-
const
|
|
3660
|
-
|
|
3602
|
+
const h = this.nodeManager.getNode(n.source), c = this.nodeManager.getNode(n.target);
|
|
3603
|
+
h && c && i.push({ edge: n, sourceNode: h, targetNode: c });
|
|
3661
3604
|
}
|
|
3662
3605
|
return i;
|
|
3663
3606
|
}
|
|
@@ -3690,7 +3633,7 @@ class Ht {
|
|
|
3690
3633
|
* Switches between 2D and 3D view modes
|
|
3691
3634
|
*/
|
|
3692
3635
|
switchView(e) {
|
|
3693
|
-
this.viewMode !== e && (this.viewMode = e, this.panelManager.hide(), this.edgePanelManager.hide(), this.edgeTooltipManager.hide(), e === "2d" ? (this.sceneManager.renderer.domElement.style.display = "none", this.rendererManager.stop(), this.forceGraph2D ? (this.forceGraph2D.show(), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())) : (this.forceGraph2D = new
|
|
3636
|
+
this.viewMode !== e && (this.viewMode = e, this.panelManager.hide(), this.edgePanelManager.hide(), this.edgeTooltipManager.hide(), e === "2d" ? (this.sceneManager.renderer.domElement.style.display = "none", this.rendererManager.stop(), this.forceGraph2D ? (this.forceGraph2D.show(), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())) : (this.forceGraph2D = new Lt(this.container, {
|
|
3694
3637
|
backgroundColor: "#0a0a0a",
|
|
3695
3638
|
nodeRadius: 24,
|
|
3696
3639
|
onNodeClick: (s) => {
|
|
@@ -3892,9 +3835,9 @@ const Ie = [
|
|
|
3892
3835
|
16746564
|
|
3893
3836
|
// Darker tangerine
|
|
3894
3837
|
];
|
|
3895
|
-
function At(
|
|
3838
|
+
function At(d = 30) {
|
|
3896
3839
|
const e = [], s = [];
|
|
3897
|
-
for (let i = 0; i <
|
|
3840
|
+
for (let i = 0; i < d; i++) {
|
|
3898
3841
|
const o = i < Ie.length ? Ie[i] : `Node ${i + 1}`;
|
|
3899
3842
|
e.push({
|
|
3900
3843
|
id: `node-${i}`,
|
|
@@ -3907,7 +3850,7 @@ function At(h = 30) {
|
|
|
3907
3850
|
}
|
|
3908
3851
|
});
|
|
3909
3852
|
}
|
|
3910
|
-
for (let i = 1; i <
|
|
3853
|
+
for (let i = 1; i < d; i++) {
|
|
3911
3854
|
const o = Math.floor(Math.random() * i);
|
|
3912
3855
|
s.push({
|
|
3913
3856
|
source: `node-${i}`,
|
|
@@ -3915,31 +3858,31 @@ function At(h = 30) {
|
|
|
3915
3858
|
relationship: J[Math.floor(Math.random() * J.length)]
|
|
3916
3859
|
});
|
|
3917
3860
|
}
|
|
3918
|
-
const t = Math.floor(
|
|
3861
|
+
const t = Math.floor(d * 0.5);
|
|
3919
3862
|
for (let i = 0; i < t; i++) {
|
|
3920
|
-
const o = Math.floor(Math.random() *
|
|
3921
|
-
let n = Math.floor(Math.random() *
|
|
3922
|
-
o === n && (n = (n + 1) %
|
|
3923
|
-
const r = `node-${o}`,
|
|
3863
|
+
const o = Math.floor(Math.random() * d);
|
|
3864
|
+
let n = Math.floor(Math.random() * d);
|
|
3865
|
+
o === n && (n = (n + 1) % d);
|
|
3866
|
+
const r = `node-${o}`, h = `node-${n}`;
|
|
3924
3867
|
s.some(
|
|
3925
|
-
(p) => p.source === r && p.target ===
|
|
3868
|
+
(p) => p.source === r && p.target === h || p.source === h && p.target === r
|
|
3926
3869
|
) || s.push({
|
|
3927
3870
|
source: r,
|
|
3928
|
-
target:
|
|
3871
|
+
target: h,
|
|
3929
3872
|
relationship: J[Math.floor(Math.random() * J.length)]
|
|
3930
3873
|
});
|
|
3931
3874
|
}
|
|
3932
3875
|
return { nodes: e, edges: s };
|
|
3933
3876
|
}
|
|
3934
|
-
function jt(
|
|
3935
|
-
const e = [], s = [], t = Math.ceil(
|
|
3877
|
+
function jt(d = 1e3) {
|
|
3878
|
+
const e = [], s = [], t = Math.ceil(d / 50), i = [];
|
|
3936
3879
|
for (let o = 0; o < t; o++)
|
|
3937
3880
|
i.push({
|
|
3938
3881
|
x: (Math.random() - 0.5) * 200,
|
|
3939
3882
|
y: (Math.random() - 0.5) * 200,
|
|
3940
3883
|
z: (Math.random() - 0.5) * 200
|
|
3941
3884
|
});
|
|
3942
|
-
for (let o = 0; o <
|
|
3885
|
+
for (let o = 0; o < d; o++) {
|
|
3943
3886
|
const n = i[o % t];
|
|
3944
3887
|
e.push({
|
|
3945
3888
|
id: `node-${o}`,
|
|
@@ -3951,7 +3894,7 @@ function jt(h = 1e3) {
|
|
|
3951
3894
|
}
|
|
3952
3895
|
});
|
|
3953
3896
|
}
|
|
3954
|
-
for (let o = 1; o <
|
|
3897
|
+
for (let o = 1; o < d; o++) {
|
|
3955
3898
|
const n = Math.floor(o / 50) * 50, r = n === 0 ? Math.floor(Math.random() * o) : n + Math.floor(Math.random() * Math.min(o - n, 50));
|
|
3956
3899
|
s.push({
|
|
3957
3900
|
source: `node-${o}`,
|