如何使用Three.js实现2D关系图绘制及节点间连线
Three.js 2D关系图实现方案
核心实现思路
2D关系图在Three.js生态下完全可以基于正交相机实现,不需要引入额外的DOM渲染层,所有节点、连线都用Three.js原生API渲染即可,性能远高于DOM/SVG实现的关系图,适合节点量级较大的场景。
当前阶段连线功能实现步骤
你已经完成了节点创建、相机和控制器配置,只需要按以下步骤补充连线逻辑即可:
- 首先存储所有节点的引用,方便后续获取节点坐标
你在创建节点时需要将所有节点实例存入数组,避免后续找不到对应节点的位置信息,修改你现有节点创建部分的代码如下:
// 顶部新增节点存储数组 const allNodes = [] // 中心节点加入数组 watch0 = new No(test.nomeCentra, new THREE.Vector3(0.0, 0.0, 0.0), 0.5, 0x999999, 0xffffff, 0x333333, 0xcccccc, 0xffffff, 0xff0000); scene.add(watch0.object); allNodes.push(watch0) var posicaiXInicial = 0.5; var posicaiYInicial = 0.5; for (let i = 0; i < test.ligacoes.length; i++) { const directNodes = new No('New York', new THREE.Vector3(posicaiXInicial, posicaiYInicial, 0.0), 0.25, 0x999999, 0xffffff, 0x333333, 0xcccccc, 0xffffff, 0xff0000); posicaiXInicial += 0.5 posicaiYInicial += 0.5 posicaiXInicial *= -1 scene.add(directNodes.object); // 子节点加入数组 allNodes.push(directNodes) }
- 创建连线材质和连线实例
基于Three.js的LineBasicMaterial和BufferGeometry创建连线,这里以所有子节点都连接中心节点为例,你可以根据你的关系数据调整配对逻辑:
// 初始化连线材质,可自定义颜色、透明度等参数 const lineMaterial = new THREE.LineBasicMaterial({ color: 0x333333, transparent: true, opacity: 0.8 }) // 遍历生成所有连线 for (let i = 1; i < allNodes.length; i++) { // 取两个待连接节点的坐标 const start = allNodes[0].object.position const end = allNodes[i].object.position // 生成线的顶点数据 const points = [ new THREE.Vector3(start.x, start.y, 0), new THREE.Vector3(end.x, end.y, 0) ] const lineGeometry = new THREE.BufferGeometry().setFromPoints(points) const line = new THREE.Line(lineGeometry, lineMaterial) // 设置线的渲染层级低于节点,避免线遮挡节点 line.renderOrder = -1 scene.add(line) }
其他进阶实现建议
- 节点自动排布可以引入力导向计算逻辑,直接用成熟的力导向算法库计算每个节点的坐标后,同步更新Three.js中节点和对应连线的位置即可。
- 如果需要自定义线宽(大于1px),可以使用Three.js的
Line2扩展实现,支持任意像素宽度的线条渲染。 - 节点交互、连线高亮这类功能可以通过
Raycaster射线检测实现,监听到对应的元素后修改对应材质属性即可。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

