@lv-x-software-house/x_view 1.3.9 → 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/dist/index.js +182 -4
- package/dist/index.mjs +182 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6232,7 +6232,8 @@ function XViewSidebar({
|
|
|
6232
6232
|
options: [
|
|
6233
6233
|
{ value: "Star", label: "Star" },
|
|
6234
6234
|
{ value: "Circle", label: "Circle" },
|
|
6235
|
-
{ value: "Column", label: "Column" }
|
|
6235
|
+
{ value: "Column", label: "Column" },
|
|
6236
|
+
{ value: "Network", label: "Network" }
|
|
6236
6237
|
],
|
|
6237
6238
|
placeholder: "Selecione um Formato"
|
|
6238
6239
|
}
|
|
@@ -20807,12 +20808,20 @@ function XViewScene({
|
|
|
20807
20808
|
);
|
|
20808
20809
|
const handleActivateReshapeLens = (0, import_react38.useCallback)(
|
|
20809
20810
|
({ type, columns, centerNodeId }) => {
|
|
20810
|
-
const {
|
|
20811
|
+
const {
|
|
20812
|
+
nodeObjects,
|
|
20813
|
+
allLinks = [],
|
|
20814
|
+
ancestryLinks = [],
|
|
20815
|
+
tweenGroup,
|
|
20816
|
+
camera,
|
|
20817
|
+
controls
|
|
20818
|
+
} = stateRef.current;
|
|
20811
20819
|
if (!nodeObjects || !tweenGroup || !camera || !controls) return;
|
|
20812
20820
|
const activeNodeIds = Object.keys(nodeObjects);
|
|
20813
20821
|
if (activeNodeIds.length === 0) return;
|
|
20814
20822
|
let sumX = 0;
|
|
20815
20823
|
let sumY = 0;
|
|
20824
|
+
let sumZ = 0;
|
|
20816
20825
|
let nodeCount = 0;
|
|
20817
20826
|
activeNodeIds.forEach((id) => {
|
|
20818
20827
|
const mesh = nodeObjects[id];
|
|
@@ -20916,23 +20925,192 @@ function XViewScene({
|
|
|
20916
20925
|
sumY += targetY;
|
|
20917
20926
|
nodeCount++;
|
|
20918
20927
|
});
|
|
20928
|
+
} else if (type === "Network") {
|
|
20929
|
+
const N = activeNodeIds.length;
|
|
20930
|
+
const activeSet = new Set(activeNodeIds.map(String));
|
|
20931
|
+
const edges = [];
|
|
20932
|
+
const degreeMap = new Map(activeNodeIds.map((id) => [String(id), 0]));
|
|
20933
|
+
const seenPairs = /* @__PURE__ */ new Set();
|
|
20934
|
+
[...allLinks, ...ancestryLinks].forEach((line) => {
|
|
20935
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
|
|
20936
|
+
const u = String(
|
|
20937
|
+
((_c2 = (_b2 = (_a2 = line.userData) == null ? void 0 : _a2.sourceNode) == null ? void 0 : _b2.userData) == null ? void 0 : _c2.id) ?? ((_d2 = line.userData) == null ? void 0 : _d2.source) ?? ""
|
|
20938
|
+
);
|
|
20939
|
+
const v = String(
|
|
20940
|
+
((_g2 = (_f2 = (_e2 = line.userData) == null ? void 0 : _e2.targetNode) == null ? void 0 : _f2.userData) == null ? void 0 : _g2.id) ?? ((_h2 = line.userData) == null ? void 0 : _h2.target) ?? ""
|
|
20941
|
+
);
|
|
20942
|
+
if (u && v && u !== v && activeSet.has(u) && activeSet.has(v)) {
|
|
20943
|
+
const pairKey = u < v ? `${u}_${v}` : `${v}_${u}`;
|
|
20944
|
+
if (!seenPairs.has(pairKey)) {
|
|
20945
|
+
seenPairs.add(pairKey);
|
|
20946
|
+
edges.push([u, v]);
|
|
20947
|
+
degreeMap.set(u, (degreeMap.get(u) || 0) + 1);
|
|
20948
|
+
degreeMap.set(v, (degreeMap.get(v) || 0) + 1);
|
|
20949
|
+
}
|
|
20950
|
+
}
|
|
20951
|
+
});
|
|
20952
|
+
const baseSpread = Math.max(45, Math.sqrt(N) * 19);
|
|
20953
|
+
const boundX = baseSpread * 1.75;
|
|
20954
|
+
const boundY = baseSpread * 1;
|
|
20955
|
+
const boundZ = Math.min(85, Math.max(25, baseSpread * 0.45));
|
|
20956
|
+
const sortedIds = [...activeNodeIds].sort(
|
|
20957
|
+
(a, b) => (degreeMap.get(String(b)) || 0) - (degreeMap.get(String(a)) || 0)
|
|
20958
|
+
);
|
|
20959
|
+
const posMap = /* @__PURE__ */ new Map();
|
|
20960
|
+
const velMap = /* @__PURE__ */ new Map();
|
|
20961
|
+
const goldenAngle = Math.PI * (3 - Math.sqrt(5));
|
|
20962
|
+
sortedIds.forEach((id, idx) => {
|
|
20963
|
+
const t = N > 1 ? idx / (N - 1) : 0.5;
|
|
20964
|
+
const r = Math.sqrt(0.12 + 0.88 * t);
|
|
20965
|
+
const theta = idx * goldenAngle * 7;
|
|
20966
|
+
const zLayer = Math.sin(idx * 2.39996) * boundZ * (0.4 + 0.6 * r);
|
|
20967
|
+
posMap.set(String(id), {
|
|
20968
|
+
x: Math.cos(theta) * r * boundX,
|
|
20969
|
+
y: Math.sin(theta) * r * boundY,
|
|
20970
|
+
z: zLayer
|
|
20971
|
+
});
|
|
20972
|
+
velMap.set(String(id), { x: 0, y: 0, z: 0 });
|
|
20973
|
+
});
|
|
20974
|
+
const iterations = 120;
|
|
20975
|
+
const minNodeDist = 24;
|
|
20976
|
+
const idealEdgeDist = 28;
|
|
20977
|
+
const repulsionRadius = 65;
|
|
20978
|
+
for (let iter = 0; iter < iterations; iter++) {
|
|
20979
|
+
const cooling = 1 - iter / iterations * 0.75;
|
|
20980
|
+
for (let i = 0; i < N; i++) {
|
|
20981
|
+
const idA = String(sortedIds[i]);
|
|
20982
|
+
const pA = posMap.get(idA);
|
|
20983
|
+
const vA = velMap.get(idA);
|
|
20984
|
+
for (let j = i + 1; j < N; j++) {
|
|
20985
|
+
const idB = String(sortedIds[j]);
|
|
20986
|
+
const pB = posMap.get(idB);
|
|
20987
|
+
const vB = velMap.get(idB);
|
|
20988
|
+
const dx = pA.x - pB.x;
|
|
20989
|
+
const dy = pA.y - pB.y;
|
|
20990
|
+
const dz = (pA.z - pB.z) * 0.6;
|
|
20991
|
+
const distSq = dx * dx + dy * dy + dz * dz + 0.1;
|
|
20992
|
+
const dist = Math.sqrt(distSq);
|
|
20993
|
+
if (dist < repulsionRadius) {
|
|
20994
|
+
const force = dist < minNodeDist ? (minNodeDist - dist) / dist * 1.8 : (repulsionRadius - dist) / repulsionRadius * 0.35 / dist;
|
|
20995
|
+
const fx = dx * force;
|
|
20996
|
+
const fy = dy * force;
|
|
20997
|
+
const fz = (pA.z - pB.z) * force * 0.5;
|
|
20998
|
+
vA.x += fx;
|
|
20999
|
+
vA.y += fy;
|
|
21000
|
+
vA.z += fz;
|
|
21001
|
+
vB.x -= fx;
|
|
21002
|
+
vB.y -= fy;
|
|
21003
|
+
vB.z -= fz;
|
|
21004
|
+
}
|
|
21005
|
+
}
|
|
21006
|
+
}
|
|
21007
|
+
for (let e = 0; e < edges.length; e++) {
|
|
21008
|
+
const [u, v] = edges[e];
|
|
21009
|
+
const pU = posMap.get(u);
|
|
21010
|
+
const pV = posMap.get(v);
|
|
21011
|
+
const vU = velMap.get(u);
|
|
21012
|
+
const vV = velMap.get(v);
|
|
21013
|
+
const dx = pV.x - pU.x;
|
|
21014
|
+
const dy = pV.y - pU.y;
|
|
21015
|
+
const dz = pV.z - pU.z;
|
|
21016
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz) || 1;
|
|
21017
|
+
const delta = dist - idealEdgeDist;
|
|
21018
|
+
const springStrength = 0.085;
|
|
21019
|
+
const fx = dx / dist * delta * springStrength;
|
|
21020
|
+
const fy = dy / dist * delta * springStrength;
|
|
21021
|
+
const fz = dz / dist * delta * springStrength;
|
|
21022
|
+
vU.x += fx;
|
|
21023
|
+
vU.y += fy;
|
|
21024
|
+
vU.z += fz;
|
|
21025
|
+
vV.x -= fx;
|
|
21026
|
+
vV.y -= fy;
|
|
21027
|
+
vV.z -= fz;
|
|
21028
|
+
}
|
|
21029
|
+
for (let i = 0; i < N; i++) {
|
|
21030
|
+
const id = String(sortedIds[i]);
|
|
21031
|
+
const p = posMap.get(id);
|
|
21032
|
+
const v = velMap.get(id);
|
|
21033
|
+
const nx = p.x / boundX;
|
|
21034
|
+
const ny = p.y / boundY;
|
|
21035
|
+
const nz = p.z / boundZ;
|
|
21036
|
+
const radialNorm = Math.sqrt(nx * nx + ny * ny);
|
|
21037
|
+
if (radialNorm > 0.95) {
|
|
21038
|
+
const pull = (radialNorm - 0.95) * 2.2;
|
|
21039
|
+
v.x -= nx * pull * 8;
|
|
21040
|
+
v.y -= ny * pull * 8;
|
|
21041
|
+
} else if (radialNorm < 0.2 && N > 12 && (degreeMap.get(id) || 0) === 0) {
|
|
21042
|
+
v.x += (nx || 0.1) * 1.5;
|
|
21043
|
+
v.y += (ny || 0.1) * 1.5;
|
|
21044
|
+
}
|
|
21045
|
+
if (Math.abs(nz) > 0.95) {
|
|
21046
|
+
v.z -= nz * (Math.abs(nz) - 0.95) * 10;
|
|
21047
|
+
}
|
|
21048
|
+
const maxStep = 6 * cooling;
|
|
21049
|
+
const speed = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) || 1;
|
|
21050
|
+
const scale = speed > maxStep ? maxStep / speed : cooling;
|
|
21051
|
+
p.x += v.x * scale;
|
|
21052
|
+
p.y += v.y * scale;
|
|
21053
|
+
p.z += v.z * scale;
|
|
21054
|
+
v.x *= 0.4;
|
|
21055
|
+
v.y *= 0.4;
|
|
21056
|
+
v.z *= 0.4;
|
|
21057
|
+
}
|
|
21058
|
+
}
|
|
21059
|
+
activeNodeIds.forEach((id) => {
|
|
21060
|
+
const mesh = nodeObjects[id];
|
|
21061
|
+
const target = posMap.get(String(id)) || { x: 0, y: 0, z: 0 };
|
|
21062
|
+
const posTween = new import_tween2.Tween(mesh.position).to({ x: target.x, y: target.y, z: target.z }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
21063
|
+
tweenGroup.add(posTween);
|
|
21064
|
+
posTween.start();
|
|
21065
|
+
if (mesh.userData.labelObject) {
|
|
21066
|
+
const labelTarget = new THREE3.Vector3(
|
|
21067
|
+
target.x,
|
|
21068
|
+
target.y,
|
|
21069
|
+
target.z
|
|
21070
|
+
).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
21071
|
+
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
21072
|
+
tweenGroup.add(lblTween);
|
|
21073
|
+
lblTween.start();
|
|
21074
|
+
}
|
|
21075
|
+
sumX += target.x;
|
|
21076
|
+
sumY += target.y;
|
|
21077
|
+
sumZ += target.z;
|
|
21078
|
+
nodeCount++;
|
|
21079
|
+
});
|
|
20919
21080
|
}
|
|
20920
21081
|
if (nodeCount > 0) {
|
|
20921
21082
|
const centerX = sumX / nodeCount;
|
|
20922
21083
|
const centerY = sumY / nodeCount;
|
|
20923
|
-
const
|
|
21084
|
+
const centerZ = type === "Network" ? sumZ / nodeCount : 0;
|
|
21085
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, centerZ);
|
|
20924
21086
|
const targetTween = new import_tween2.Tween(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
20925
21087
|
tweenGroup.add(targetTween);
|
|
20926
21088
|
targetTween.start();
|
|
20927
21089
|
let zoomZ = 140;
|
|
21090
|
+
let camOffsetY = 0;
|
|
20928
21091
|
if (type === "Column") {
|
|
20929
21092
|
const numRows = Math.ceil(nodeCount / (columns || 4));
|
|
20930
21093
|
zoomZ = Math.max(140, numRows * 50);
|
|
20931
21094
|
} else if (type === "Circle" || type === "Star") {
|
|
20932
21095
|
const radius = Math.max(80, nodeCount * 8);
|
|
20933
21096
|
zoomZ = radius * 2.5;
|
|
21097
|
+
} else if (type === "Network") {
|
|
21098
|
+
const baseSpread = Math.max(45, Math.sqrt(nodeCount) * 19);
|
|
21099
|
+
const immersionFactor = Math.max(
|
|
21100
|
+
0.52,
|
|
21101
|
+
1.15 - Math.min(nodeCount, 120) * 52e-4
|
|
21102
|
+
);
|
|
21103
|
+
zoomZ = targetFocus.z + Math.max(55, baseSpread * immersionFactor);
|
|
21104
|
+
camOffsetY = -baseSpread * 0.08;
|
|
20934
21105
|
}
|
|
20935
|
-
const camTween = new import_tween2.Tween(camera.position).to(
|
|
21106
|
+
const camTween = new import_tween2.Tween(camera.position).to(
|
|
21107
|
+
{
|
|
21108
|
+
x: targetFocus.x,
|
|
21109
|
+
y: targetFocus.y + camOffsetY,
|
|
21110
|
+
z: zoomZ
|
|
21111
|
+
},
|
|
21112
|
+
1500
|
|
21113
|
+
).easing(import_tween2.Easing.Cubic.InOut);
|
|
20936
21114
|
tweenGroup.add(camTween);
|
|
20937
21115
|
camTween.start();
|
|
20938
21116
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -6193,7 +6193,8 @@ function XViewSidebar({
|
|
|
6193
6193
|
options: [
|
|
6194
6194
|
{ value: "Star", label: "Star" },
|
|
6195
6195
|
{ value: "Circle", label: "Circle" },
|
|
6196
|
-
{ value: "Column", label: "Column" }
|
|
6196
|
+
{ value: "Column", label: "Column" },
|
|
6197
|
+
{ value: "Network", label: "Network" }
|
|
6197
6198
|
],
|
|
6198
6199
|
placeholder: "Selecione um Formato"
|
|
6199
6200
|
}
|
|
@@ -20909,12 +20910,20 @@ function XViewScene({
|
|
|
20909
20910
|
);
|
|
20910
20911
|
const handleActivateReshapeLens = useCallback8(
|
|
20911
20912
|
({ type, columns, centerNodeId }) => {
|
|
20912
|
-
const {
|
|
20913
|
+
const {
|
|
20914
|
+
nodeObjects,
|
|
20915
|
+
allLinks = [],
|
|
20916
|
+
ancestryLinks = [],
|
|
20917
|
+
tweenGroup,
|
|
20918
|
+
camera,
|
|
20919
|
+
controls
|
|
20920
|
+
} = stateRef.current;
|
|
20913
20921
|
if (!nodeObjects || !tweenGroup || !camera || !controls) return;
|
|
20914
20922
|
const activeNodeIds = Object.keys(nodeObjects);
|
|
20915
20923
|
if (activeNodeIds.length === 0) return;
|
|
20916
20924
|
let sumX = 0;
|
|
20917
20925
|
let sumY = 0;
|
|
20926
|
+
let sumZ = 0;
|
|
20918
20927
|
let nodeCount = 0;
|
|
20919
20928
|
activeNodeIds.forEach((id) => {
|
|
20920
20929
|
const mesh = nodeObjects[id];
|
|
@@ -21018,23 +21027,192 @@ function XViewScene({
|
|
|
21018
21027
|
sumY += targetY;
|
|
21019
21028
|
nodeCount++;
|
|
21020
21029
|
});
|
|
21030
|
+
} else if (type === "Network") {
|
|
21031
|
+
const N = activeNodeIds.length;
|
|
21032
|
+
const activeSet = new Set(activeNodeIds.map(String));
|
|
21033
|
+
const edges = [];
|
|
21034
|
+
const degreeMap = new Map(activeNodeIds.map((id) => [String(id), 0]));
|
|
21035
|
+
const seenPairs = /* @__PURE__ */ new Set();
|
|
21036
|
+
[...allLinks, ...ancestryLinks].forEach((line) => {
|
|
21037
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
|
|
21038
|
+
const u = String(
|
|
21039
|
+
((_c2 = (_b2 = (_a2 = line.userData) == null ? void 0 : _a2.sourceNode) == null ? void 0 : _b2.userData) == null ? void 0 : _c2.id) ?? ((_d2 = line.userData) == null ? void 0 : _d2.source) ?? ""
|
|
21040
|
+
);
|
|
21041
|
+
const v = String(
|
|
21042
|
+
((_g2 = (_f2 = (_e2 = line.userData) == null ? void 0 : _e2.targetNode) == null ? void 0 : _f2.userData) == null ? void 0 : _g2.id) ?? ((_h2 = line.userData) == null ? void 0 : _h2.target) ?? ""
|
|
21043
|
+
);
|
|
21044
|
+
if (u && v && u !== v && activeSet.has(u) && activeSet.has(v)) {
|
|
21045
|
+
const pairKey = u < v ? `${u}_${v}` : `${v}_${u}`;
|
|
21046
|
+
if (!seenPairs.has(pairKey)) {
|
|
21047
|
+
seenPairs.add(pairKey);
|
|
21048
|
+
edges.push([u, v]);
|
|
21049
|
+
degreeMap.set(u, (degreeMap.get(u) || 0) + 1);
|
|
21050
|
+
degreeMap.set(v, (degreeMap.get(v) || 0) + 1);
|
|
21051
|
+
}
|
|
21052
|
+
}
|
|
21053
|
+
});
|
|
21054
|
+
const baseSpread = Math.max(45, Math.sqrt(N) * 19);
|
|
21055
|
+
const boundX = baseSpread * 1.75;
|
|
21056
|
+
const boundY = baseSpread * 1;
|
|
21057
|
+
const boundZ = Math.min(85, Math.max(25, baseSpread * 0.45));
|
|
21058
|
+
const sortedIds = [...activeNodeIds].sort(
|
|
21059
|
+
(a, b) => (degreeMap.get(String(b)) || 0) - (degreeMap.get(String(a)) || 0)
|
|
21060
|
+
);
|
|
21061
|
+
const posMap = /* @__PURE__ */ new Map();
|
|
21062
|
+
const velMap = /* @__PURE__ */ new Map();
|
|
21063
|
+
const goldenAngle = Math.PI * (3 - Math.sqrt(5));
|
|
21064
|
+
sortedIds.forEach((id, idx) => {
|
|
21065
|
+
const t = N > 1 ? idx / (N - 1) : 0.5;
|
|
21066
|
+
const r = Math.sqrt(0.12 + 0.88 * t);
|
|
21067
|
+
const theta = idx * goldenAngle * 7;
|
|
21068
|
+
const zLayer = Math.sin(idx * 2.39996) * boundZ * (0.4 + 0.6 * r);
|
|
21069
|
+
posMap.set(String(id), {
|
|
21070
|
+
x: Math.cos(theta) * r * boundX,
|
|
21071
|
+
y: Math.sin(theta) * r * boundY,
|
|
21072
|
+
z: zLayer
|
|
21073
|
+
});
|
|
21074
|
+
velMap.set(String(id), { x: 0, y: 0, z: 0 });
|
|
21075
|
+
});
|
|
21076
|
+
const iterations = 120;
|
|
21077
|
+
const minNodeDist = 24;
|
|
21078
|
+
const idealEdgeDist = 28;
|
|
21079
|
+
const repulsionRadius = 65;
|
|
21080
|
+
for (let iter = 0; iter < iterations; iter++) {
|
|
21081
|
+
const cooling = 1 - iter / iterations * 0.75;
|
|
21082
|
+
for (let i = 0; i < N; i++) {
|
|
21083
|
+
const idA = String(sortedIds[i]);
|
|
21084
|
+
const pA = posMap.get(idA);
|
|
21085
|
+
const vA = velMap.get(idA);
|
|
21086
|
+
for (let j = i + 1; j < N; j++) {
|
|
21087
|
+
const idB = String(sortedIds[j]);
|
|
21088
|
+
const pB = posMap.get(idB);
|
|
21089
|
+
const vB = velMap.get(idB);
|
|
21090
|
+
const dx = pA.x - pB.x;
|
|
21091
|
+
const dy = pA.y - pB.y;
|
|
21092
|
+
const dz = (pA.z - pB.z) * 0.6;
|
|
21093
|
+
const distSq = dx * dx + dy * dy + dz * dz + 0.1;
|
|
21094
|
+
const dist = Math.sqrt(distSq);
|
|
21095
|
+
if (dist < repulsionRadius) {
|
|
21096
|
+
const force = dist < minNodeDist ? (minNodeDist - dist) / dist * 1.8 : (repulsionRadius - dist) / repulsionRadius * 0.35 / dist;
|
|
21097
|
+
const fx = dx * force;
|
|
21098
|
+
const fy = dy * force;
|
|
21099
|
+
const fz = (pA.z - pB.z) * force * 0.5;
|
|
21100
|
+
vA.x += fx;
|
|
21101
|
+
vA.y += fy;
|
|
21102
|
+
vA.z += fz;
|
|
21103
|
+
vB.x -= fx;
|
|
21104
|
+
vB.y -= fy;
|
|
21105
|
+
vB.z -= fz;
|
|
21106
|
+
}
|
|
21107
|
+
}
|
|
21108
|
+
}
|
|
21109
|
+
for (let e = 0; e < edges.length; e++) {
|
|
21110
|
+
const [u, v] = edges[e];
|
|
21111
|
+
const pU = posMap.get(u);
|
|
21112
|
+
const pV = posMap.get(v);
|
|
21113
|
+
const vU = velMap.get(u);
|
|
21114
|
+
const vV = velMap.get(v);
|
|
21115
|
+
const dx = pV.x - pU.x;
|
|
21116
|
+
const dy = pV.y - pU.y;
|
|
21117
|
+
const dz = pV.z - pU.z;
|
|
21118
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz) || 1;
|
|
21119
|
+
const delta = dist - idealEdgeDist;
|
|
21120
|
+
const springStrength = 0.085;
|
|
21121
|
+
const fx = dx / dist * delta * springStrength;
|
|
21122
|
+
const fy = dy / dist * delta * springStrength;
|
|
21123
|
+
const fz = dz / dist * delta * springStrength;
|
|
21124
|
+
vU.x += fx;
|
|
21125
|
+
vU.y += fy;
|
|
21126
|
+
vU.z += fz;
|
|
21127
|
+
vV.x -= fx;
|
|
21128
|
+
vV.y -= fy;
|
|
21129
|
+
vV.z -= fz;
|
|
21130
|
+
}
|
|
21131
|
+
for (let i = 0; i < N; i++) {
|
|
21132
|
+
const id = String(sortedIds[i]);
|
|
21133
|
+
const p = posMap.get(id);
|
|
21134
|
+
const v = velMap.get(id);
|
|
21135
|
+
const nx = p.x / boundX;
|
|
21136
|
+
const ny = p.y / boundY;
|
|
21137
|
+
const nz = p.z / boundZ;
|
|
21138
|
+
const radialNorm = Math.sqrt(nx * nx + ny * ny);
|
|
21139
|
+
if (radialNorm > 0.95) {
|
|
21140
|
+
const pull = (radialNorm - 0.95) * 2.2;
|
|
21141
|
+
v.x -= nx * pull * 8;
|
|
21142
|
+
v.y -= ny * pull * 8;
|
|
21143
|
+
} else if (radialNorm < 0.2 && N > 12 && (degreeMap.get(id) || 0) === 0) {
|
|
21144
|
+
v.x += (nx || 0.1) * 1.5;
|
|
21145
|
+
v.y += (ny || 0.1) * 1.5;
|
|
21146
|
+
}
|
|
21147
|
+
if (Math.abs(nz) > 0.95) {
|
|
21148
|
+
v.z -= nz * (Math.abs(nz) - 0.95) * 10;
|
|
21149
|
+
}
|
|
21150
|
+
const maxStep = 6 * cooling;
|
|
21151
|
+
const speed = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) || 1;
|
|
21152
|
+
const scale = speed > maxStep ? maxStep / speed : cooling;
|
|
21153
|
+
p.x += v.x * scale;
|
|
21154
|
+
p.y += v.y * scale;
|
|
21155
|
+
p.z += v.z * scale;
|
|
21156
|
+
v.x *= 0.4;
|
|
21157
|
+
v.y *= 0.4;
|
|
21158
|
+
v.z *= 0.4;
|
|
21159
|
+
}
|
|
21160
|
+
}
|
|
21161
|
+
activeNodeIds.forEach((id) => {
|
|
21162
|
+
const mesh = nodeObjects[id];
|
|
21163
|
+
const target = posMap.get(String(id)) || { x: 0, y: 0, z: 0 };
|
|
21164
|
+
const posTween = new Tween2(mesh.position).to({ x: target.x, y: target.y, z: target.z }, 1500).easing(Easing2.Cubic.InOut);
|
|
21165
|
+
tweenGroup.add(posTween);
|
|
21166
|
+
posTween.start();
|
|
21167
|
+
if (mesh.userData.labelObject) {
|
|
21168
|
+
const labelTarget = new THREE3.Vector3(
|
|
21169
|
+
target.x,
|
|
21170
|
+
target.y,
|
|
21171
|
+
target.z
|
|
21172
|
+
).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
21173
|
+
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
21174
|
+
tweenGroup.add(lblTween);
|
|
21175
|
+
lblTween.start();
|
|
21176
|
+
}
|
|
21177
|
+
sumX += target.x;
|
|
21178
|
+
sumY += target.y;
|
|
21179
|
+
sumZ += target.z;
|
|
21180
|
+
nodeCount++;
|
|
21181
|
+
});
|
|
21021
21182
|
}
|
|
21022
21183
|
if (nodeCount > 0) {
|
|
21023
21184
|
const centerX = sumX / nodeCount;
|
|
21024
21185
|
const centerY = sumY / nodeCount;
|
|
21025
|
-
const
|
|
21186
|
+
const centerZ = type === "Network" ? sumZ / nodeCount : 0;
|
|
21187
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, centerZ);
|
|
21026
21188
|
const targetTween = new Tween2(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(Easing2.Cubic.InOut);
|
|
21027
21189
|
tweenGroup.add(targetTween);
|
|
21028
21190
|
targetTween.start();
|
|
21029
21191
|
let zoomZ = 140;
|
|
21192
|
+
let camOffsetY = 0;
|
|
21030
21193
|
if (type === "Column") {
|
|
21031
21194
|
const numRows = Math.ceil(nodeCount / (columns || 4));
|
|
21032
21195
|
zoomZ = Math.max(140, numRows * 50);
|
|
21033
21196
|
} else if (type === "Circle" || type === "Star") {
|
|
21034
21197
|
const radius = Math.max(80, nodeCount * 8);
|
|
21035
21198
|
zoomZ = radius * 2.5;
|
|
21199
|
+
} else if (type === "Network") {
|
|
21200
|
+
const baseSpread = Math.max(45, Math.sqrt(nodeCount) * 19);
|
|
21201
|
+
const immersionFactor = Math.max(
|
|
21202
|
+
0.52,
|
|
21203
|
+
1.15 - Math.min(nodeCount, 120) * 52e-4
|
|
21204
|
+
);
|
|
21205
|
+
zoomZ = targetFocus.z + Math.max(55, baseSpread * immersionFactor);
|
|
21206
|
+
camOffsetY = -baseSpread * 0.08;
|
|
21036
21207
|
}
|
|
21037
|
-
const camTween = new Tween2(camera.position).to(
|
|
21208
|
+
const camTween = new Tween2(camera.position).to(
|
|
21209
|
+
{
|
|
21210
|
+
x: targetFocus.x,
|
|
21211
|
+
y: targetFocus.y + camOffsetY,
|
|
21212
|
+
z: zoomZ
|
|
21213
|
+
},
|
|
21214
|
+
1500
|
|
21215
|
+
).easing(Easing2.Cubic.InOut);
|
|
21038
21216
|
tweenGroup.add(camTween);
|
|
21039
21217
|
camTween.start();
|
|
21040
21218
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
|
|
5
5
|
"author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
|
|
6
6
|
"license": "UNLICENSED",
|