3d-force-graph展示学习记录
此文章仅用来记录3d-force-graph示例学习过程中的问题,以及相关笔记。
1.basic (基本)
const Graph = ForceGraph3D()(document.getElementById('3d-graph')).graphData(gData);
2.async-load (异步加载)
-
// URL scheme "file" is not supported. 未解决
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.jsonUrl('../datasets/miserables.json')
-
.nodeLabel('id')//鼠标悬浮至mesh上显示标签,标签内容未id
-
.nodeAutoColorBy('group');//按照group进行分类
报错:URL scheme "file" is not supported. 未解决,改为:
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData) //直接把json内容粘贴到gData
-
.nodeLabel('id')
-
.nodeAutoColorBy('group');
效果:
3.larger-graph
新知识点:
onNodeClick:监听事件单击,在新页面打开
-
const Graph = ForceGraph3D()(elem)
-
.jsonUrl('../datasets/blocks.json')
-
.nodeAutoColorBy('user')
-
.nodeLabel(node => `${node.user}: ${node.description}`)
-
.onNodeClick(
-
node => window.open(`https://bl.ocks.org/${node.user}/${node.id}`, '_blank') //单击在新页面打开
-
);
4.Directional arrows(带方向的箭头)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeLabel('id')
-
.linkDirectionalArrowLength(3.5) //箭头长度
-
.linkDirectionalArrowRelPos(1) //箭头位置偏移 source指向target
-
.linkCurvature(0.25); //曲度
效果:
5.Directional moving particles Directional moving particles(定向移动例粒子)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeLabel('id')
-
.nodeAutoColorBy('group')
-
.linkDirectionalParticles('value') //粒子个数
-
.linkDirectionalParticleSpeed(d => d.value * 0.001); //粒子运动速度
效果(部分截图):
6.Curved lines and self links(曲线和自链接)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.nodeLabel('id')
-
.linkCurvature('curvature') //曲率 数值越大 弯曲程度越小
-
.linkCurveRotation('rotation') // 链接旋转方向
-
.linkDirectionalParticles(2)
-
.graphData(gData);
7.Auto-colored nodes/links
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.nodeAutoColorBy('group') //节点根据group着色
-
.linkAutoColorBy(d => gData.nodes[d.source].group) //链接根据group着色
-
.linkOpacity(0.5) //链接透明度
-
.graphData(gData);
效果:
8.Text as nodes(文本作为节点)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.jsonUrl('../datasets/miserables.json')
-
.nodeAutoColorBy('group')
-
.nodeThreeObject(node => {
-
const sprite = new SpriteText(node.id);
-
// sprite.material.depthWrite = false; // make sprite background transparent
-
sprite.color = node.color;
-
sprite.textHeight = 8;
-
return sprite;
-
});
-
-
// Spread nodes a little wider
-
Graph.d3Force('charge').strength(-120); //设定引力,是排斥还是吸引
效果:
9.Images as nodes (图像作为节点)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.nodeThreeObject(({ img }) => {
-
const imgTexture = new THREE.TextureLoader().load(`./imgs/${img}`); //创建纹理贴图
-
const material = new THREE.SpriteMaterial({ map: imgTexture });
-
const sprite = new THREE.Sprite(material);
-
sprite.scale.set(12, 12);
-
return sprite;
-
})
-
.graphData(gData);
效果:
10.HTML in nodes
-
const Graph = ForceGraph3D({
-
extraRenderers: [new THREE.CSS2DRenderer()]
-
})(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeAutoColorBy('group')
-
.nodeThreeObject(node => {
-
const nodeEl = document.createElement('div');
-
nodeEl.textContent = node.id;
-
nodeEl.style.color = node.color;
-
nodeEl.className = 'node-label';
-
return new THREE.CSS2DObject(nodeEl);
-
})
-
.nodeThreeObjectExtend(true); //节点对象访问器函数、属性或布尔值,用于确定在使用自定义nodeThreeObject(false)时是替换默认节点还是扩展它(true)
效果:(nodeThreeObjectExtend分别是true false)
11.Custom node geometriesxiao
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.nodeThreeObject(
-
({ id }) =>
-
new THREE.Mesh(
-
[
-
// 方块
-
new THREE.BoxGeometry(
-
Math.random() * 20,
-
Math.random() * 20,
-
Math.random() * 20
-
),
-
// 锥体
-
new THREE.ConeGeometry(Math.random() * 10, Math.random() * 20),
-
// 圆柱
-
new THREE.CylinderGeometry(
-
Math.random() * 10,
-
Math.random() * 10,
-
Math.random() * 20
-
),
-
// 十二面体
-
new THREE.DodecahedronGeometry(Math.random() * 10),
-
// 球体
-
new THREE.SphereGeometry(Math.random() * 10),
-
// 圆环
-
new THREE.TorusGeometry(Math.random() * 10, Math.random() * 2),
-
// 环面扭结
-
new THREE.TorusKnotGeometry(Math.random() * 10, Math.random() * 2)
-
][id % 7],
-
new THREE.MeshLambertMaterial({
-
color: Math.round(Math.random() * Math.pow(2, 24)),
-
transparent: true,
-
opacity: 0.75
-
})
-
)
-
)
-
.graphData(gData);
效果:
12.Gradient Links(渐变链接)
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.nodeColor(node => nodeColorScale(node.id)) //id=0,color=c1;id=1,color=c2....id=4,color=c1...
-
.linkThreeObject(link => {
-
const colors = new Float32Array(
-
[].concat(
-
...[link.source, link.target]
-
.map(nodeColorScale)
-
.map(d3.color)
-
.map(({ r, g, b }) => [r, g, b].map(v => v / 255))
-
)
-
);
-
-
const material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors });
-
const geometry = new THREE.BufferGeometry();
-
geometry.setAttribute(
-
'position',
-
new THREE.BufferAttribute(new Float32Array(2 * 3), 3) //三个为一组 作为坐标
-
);
-
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); //三个为一组 作为颜色
-
-
return new THREE.Line(geometry, material);
-
})
-
.graphData(gData);
效果:
13.Text in Links
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeLabel('id')
-
.nodeAutoColorBy('group')
-
.linkThreeObjectExtend(true)
-
.linkThreeObject(link => {
-
// extend link with text sprite
-
const sprite = new SpriteText(`${link.source} > ${link.target}`);
-
sprite.color = 'lightgrey';
-
sprite.textHeight = 1.5;
-
return sprite;
-
})
-
.linkPositionUpdate((sprite, { start, end }) => {
-
const middlePos = Object.assign(
-
...['x', 'y', 'z'].map(c => ({
-
[c]: start[c] (end[c] - start[c]) / 2 // calc middle point
-
}))
-
);
-
// Position sprite
-
Object.assign(sprite.position, middlePos);
-
});
效果:
14.Orbit controls && Fly controls
-
const Graph = ForceGraph3D({ controlType: 'orbit' })(document.getElementById('3d-graph'))
-
.jsonUrl('../datasets/miserables.json')
-
.nodeLabel('id')
-
.nodeAutoColorBy('group');
-
-
const Graph = ForceGraph3D({ controlType: 'fly' })(document.getElementById('3d-graph'))
-
.jsonUrl('../datasets/miserables.json')
-
.nodeLabel('id')
-
.nodeAutoColorBy('group');
设置threejs控制器的类型,效果相当于:
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls = new TrackballControls(this.camera, this.renderer.domElement);
15.Camera automatic orbitting
-
const distance = 1400;
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.enableNodeDrag(false) //节点拖拽
-
.enableNavigationControls(false) //拖拽
-
.showNavInfo(false)
-
.cameraPosition({ z: distance })
-
.graphData(gData);
-
-
// camera orbit
-
// 每10ms更新一下相机的位置
-
let angle = 0;
-
setInterval(() => {
-
Graph.cameraPosition({
-
x: distance * Math.sin(angle),
-
z: distance * Math.cos(angle)
-
});
-
angle = Math.PI / 300;
-
}, 10);
相当于:camera.position.set(position);
16.Click to focus on node
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeLabel('id')
-
.nodeAutoColorBy('group')
-
//点击事件
-
.onNodeClick(node => {
-
// Aim at node from outside it
-
const distance = 40;
-
const distRatio = 1 distance / Math.hypot(node.x, node.y, node.z);
-
-
Graph.cameraPosition(
-
{ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position
-
node, // lookAt ({ x, y, z })
-
3000 // ms transition duration
-
);
-
});
17.Click to expand/collapse nodes
-
const Graph = ForceGraph3D()(elem)
-
.graphData(getPrunedTree())
-
.linkDirectionalParticles(2)
-
//子节点折叠 red;子节点展开 yellow;无子节点 green;
-
.nodeColor(node =>
-
!node.childLinks.length ? 'green' : node.collapsed ? 'red' : 'yellow'
-
)
-
.onNodeHover(
-
node => (elem.style.cursor = node && node.childLinks.length ? 'pointer' : null)
-
)
-
//点击事件调用getPrunedTree()更新gdata
-
.onNodeClick(node => {
-
if (node.childLinks.length) {
-
node.collapsed = !node.collapsed; // toggle collapse state
-
Graph.graphData(getPrunedTree());
-
}
-
});
18.Fix nodes after dragging
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeLabel('id')
-
.nodeAutoColorBy('group')
-
.onNodeDragEnd(node => {
-
node.fx = node.x;
-
node.fy = node.y;
-
node.fz = node.z;
-
});
拖动节点后,该节点位置不变。
19.Fit graph to canvas
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.cooldownTicks(100) //冷却时间 参数为时间
-
.graphData(gData);
-
-
// fit to canvas when engine stops
-
Graph.onEngineStop(() => Graph.zoomToFit(400));
渲染完成后,会适应画布大小。
20.Highlight nodes/links
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
//node颜色
-
.nodeColor(node =>
-
highlightNodes.has(node)
-
? node === hoverNode
-
? 'rgb(255,0,0,1)'
-
: 'rgba(255,160,0,0.8)'
-
: 'rgba(0,255,255,0.6)'
-
)
-
.linkWidth(link => (highlightLinks.has(link) ? 4 : 1))
-
.linkDirectionalParticles(link => (highlightLinks.has(link) ? 4 : 0))
-
.linkDirectionalParticleWidth(4)
-
.onNodeHover(node => {
-
// no state change
-
if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return;
-
-
highlightNodes.clear();
-
highlightLinks.clear();
-
if (node) {
-
highlightNodes.add(node);
-
node.neighbors.forEach(neighbor => highlightNodes.add(neighbor));
-
node.links.forEach(link => highlightLinks.add(link));
-
}
-
-
hoverNode = node || null;
-
-
updateHighlight();
-
})
-
.onLinkHover(link => {
-
highlightNodes.clear();
-
highlightLinks.clear();
-
-
if (link) {
-
highlightLinks.add(link);
-
highlightNodes.add(link.source);
-
highlightNodes.add(link.target);
-
}
-
updateHighlight();
-
});
效果:
21.Multiple Node Selection
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.graphData(gData)
-
.nodeRelSize(9) //节点大小
-
.nodeColor(node => (selectedNodes.has(node) ? 'yellow' : 'grey'))
-
.onNodeClick((node, event) => {
-
if (event.ctrlKey || event.shiftKey || event.altKey) {
-
// multi-selection
-
selectedNodes.has(node) ? selectedNodes.delete(node) : selectedNodes.add(node);
-
} else {
-
// single-selection
-
const untoggle = selectedNodes.has(node) && selectedNodes.size === 1;
-
selectedNodes.clear();
-
!untoggle && selectedNodes.add(node);
-
}
-
-
Graph.nodeColor(Graph.nodeColor()); // update color of selected nodes
-
})
-
.onNodeDrag((node, translate) => {
-
if (selectedNodes.has(node)) {
-
// moving a selected node
-
[...selectedNodes]
-
.filter(selNode => selNode !== node) // don't touch node being dragged
-
.forEach(node =>
-
['x', 'y', 'z'].forEach(
-
coord => (node[`f${coord}`] = node[coord] translate[coord])
-
)
-
); // translate other nodes by same amount
-
}
-
})
-
.onNodeDragEnd(node => {
-
if (selectedNodes.has(node)) {
-
// finished moving a selected node
-
[...selectedNodes]
-
.filter(selNode => selNode !== node) // don't touch node being dragged
-
.forEach(node =>
-
['x', 'y', 'z'].forEach(coord => (node[`f${coord}`] = undefined))
-
); // unfix controlled nodes
-
}
-
});
效果:按住alt 、 shift、alt均可以进行多选。
22.Dynamic data changes
-
const Graph = ForceGraph3D()(elem)
-
.enableNodeDrag(false)
-
.onNodeClick(removeNode)
-
.graphData(initData);
-
-
//定时添加节点,并连接dst为已有的随机节点
-
setInterval(() => {
-
const { nodes, links } = Graph.graphData();
-
const id = nodes.length;
-
Graph.graphData({
-
nodes: [...nodes, { id }],
-
links: [...links, { source: id, target: Math.round(Math.random() * (id - 1)) }]
-
});
-
}, 1000);
-
-
//
-
function removeNode(node) {
-
let { nodes, links } = Graph.graphData();
-
links = links.filter(l => l.source !== node && l.target !== node); // Remove links attached to node
-
nodes.splice(node.id, 1); // Remove node 从node.id开始删除1个元素
-
//修正其他节点的id
-
nodes.forEach((n, idx) => {
-
n.id = idx;
-
}); // Reset node ids to array index
-
Graph.graphData({ nodes, links });
-
}
23.Node collision detection(节点碰撞检测)
-
const N = 50;
-
const nodes = [...Array(N).keys()].map(() => ({
-
// Initial velocity in random direction
-
// 随机方向上的初始速度
-
vx: Math.random(),
-
vy: Math.random(),
-
vz: Math.random()
-
}));
-
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'));
-
-
Graph.cooldownTime(Infinity)
-
.d3AlphaDecay(0) //alpha 衰减率
-
.d3VelocityDecay(0) //默认为 0.4,较低的衰减系数可以使得迭代次数更多,其布局结果也会更理性,但是可能会引起数值不稳定从而导致震荡。
-
-
// Deactivate existing forces
-
.d3Force('center', null) //centering作用力可以使得节点布局开之后围绕某个中心
-
.d3Force('charge', null) //作用力应用在所用的节点之间
-
-
// Add collision and bounding box forces
-
.d3Force('collide', d3.forceCollide(Graph.nodeRelSize()))
-
.d3Force('box', () => {
-
const CUBE_HALF_SIDE = Graph.nodeRelSize() * N * 0.5;
-
-
nodes.forEach(node => {
-
const x = node.x || 0,
-
y = node.y || 0,
-
z = node.z || 0;
-
-
// bounce on box walls
-
if (Math.abs(x) > CUBE_HALF_SIDE) {
-
node.vx *= -1;
-
}
-
if (Math.abs(y) > CUBE_HALF_SIDE) {
-
node.vy *= -1;
-
}
-
if (Math.abs(z) > CUBE_HALF_SIDE) {
-
node.vz *= -1;
-
}
-
});
-
})
-
-
// Add nodes
-
.graphData({ nodes, links: [] });
24.暂停、恢复动画
-
const distance = 1400;
-
-
let isRotationActive = true;
-
const Graph = ForceGraph3D()(document.getElementById('3d-graph'))
-
.enableNodeDrag(false)
-
.enableNavigationControls(false)
-
.showNavInfo(true)
-
.cameraPosition({ z: distance })
-
.graphData(gData);
-
// camera orbit
-
let angle = 0;
-
-
//使得物体旋转
-
setInterval(() => {
-
if (isRotationActive) {
-
Graph.cameraPosition({
-
x: distance * Math.sin(angle),
-
z: distance * Math.cos(angle)
-
});
-
angle = Math.PI / 300;
-
}
-
}, 10);
-
-
document.getElementById('rotationToggle').addEventListener('click', event => {
-
isRotationActive = !isRotationActive;
-
event.target.innerHTML = `${isRotationActive ? 'Pause' : 'Resume'} Rotation`;
-
});
-
-
let isAnimationActive = true;
-
document.getElementById('animationToggle').addEventListener('click', event => {
-
isAnimationActive ? Graph.pauseAnimation() : Graph.resumeAnimation();
-
-
isAnimationActive = !isAnimationActive;
-
event.target.innerHTML = `${isAnimationActive ? 'Pause' : 'Resume'} Animation`;
-
});
初学结束~~~Fighting!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgafaif
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24