financial-bigscreen/public/static/3d-force-graph/index1.html

96 lines
3.1 KiB
HTML

<head>
<style> body { margin: 0; } </style>
<script src="3d-force-graph.min.js"></script>
<!--<script src="../../dist/3d-force-graph.js"></script>-->
</head>
<body>
<div id="3d-graph"></div>
<div style="position: absolute; top: 5px; right: 5px;">
<button id="rotationToggle" style="margin: 8px; height: 25px; width: 150px;">
暂停旋转
</button>
</div>
<script type="importmap">{ "imports": { "three": "//unpkg.com/three/build/three.module.js" }}</script>
<script type="module">
import SpriteText from "//unpkg.com/three-spritetext/dist/three-spritetext.mjs";
const distance = 2000;
let isRotationActive = true;
// Random tree
const N = 1200;
const gData = {
nodes: [...Array(N).keys()].map(i => ({ id: i,group:Math.floor(i/150) })),
links: [...Array(N).keys()]
.filter(id => id)
.map(id => ({
source: id,
target: Math.round(Math.random() * (id-1))
}))
};
const Graph = ForceGraph3D()
(document.getElementById('3d-graph'))
.graphData(gData)
// .jsonUrl('./miserables.json')
.nodeAutoColorBy('group')
.nodeLabel('id')
.linkDirectionalParticles(4)
.linkDirectionalParticleWidth(4)
.linkDirectionalParticleSpeed(d => 4 * 0.001)// d.value
.linkWidth(4)
.nodeRelSize(6)
// .nodeThreeObject(node => {// 借助三方库 实现文字几何的展示
// const sprite = new SpriteText(node.id);
// sprite.material.depthWrite = false; // make sprite background transparent
// sprite.color = node.color;// node.color
// sprite.textHeight = 8;
// return sprite;
// })
// .linkDirectionalArrowLength(3)// 让边带上箭头
// .linkDirectionalArrowRelPos(1)// 设置箭头位置
.onNodeClick(node => {
// Aim at node from outside it
const distance = 1800;
const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z);
const newPos = node.x || node.y || node.z
? { x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }
: { x: 0, y: 0, z: distance }; // special case if node is in (0,0,0)
Graph.cameraPosition(
newPos, // new position
node, // lookAt ({ x, y, z })
3000 // ms transition duration
)
})
.cameraPosition({ z: distance })
// Spread nodes a little wider
// Graph.d3Force('charge').strength(-120);
// camera orbit
let angle = 0;
let time = setInterval(() => {
if (isRotationActive) {
Graph.cameraPosition({
x: distance * Math.sin(angle),
y: 0,
z: distance * Math.cos(angle),
});
angle += Math.PI / 500;
}
}, 10);
document.getElementById('rotationToggle').addEventListener('click', event => {
if(isRotationActive){
isRotationActive = !isRotationActive
}else{
isRotationActive = !isRotationActive
}
event.target.innerHTML = `${(isRotationActive ? '暂停' : '重置')} 旋转`;
});
</script>
</body>