目录
一、参考代码
1. Github参考
- https://github.com/vasturiano/three-forcegraph
- https://github.com/vasturiano/d3-force-3d
- https://github.com/vasturiano/3d-force-graph
2. Demo参考
https://bl.ocks.org/vasturiano/f59675656258d3f490e9faa40828c0e7
二、为什么使用3D做图谱可视化
1. 背景
知识图谱一般包含节点和关系两类数据,之前在做2D可视化展示时:
主要是通过svg完成图形的绘制,而此时每一个节点、关系和文本都会对应一个DOM元素。如果为了做大规模知识图谱展示,当节点个数上千上万时,由于DOM操作的低效性,浏览器在可视化渲染到动态交互上都存在性能问题,此时应该减少DOM操作。
这里简单介绍一下关于操作DOM对性能的影响,它会直接或间接地影响渲染引擎工作,而浏览器分为:渲染引擎 和 JS引擎,再往下又涉及到浏览器渲染页面底层原理及过程,这里不再具体展开。
其中 layout(布局)和paint(绘制)的性能消耗是最大的部分:
- layout 就是布局变动造成重新计算(耗CPU,有时也很耗内存)
- paint 就是调用浏览器UI引擎进行渲染展示页面(耗CPU和内存)
总的来说,为了更好的展示大规模的知识图谱,需要用到3D技术,完成有限的区域容纳更多的节点信息。
2. 使用D3绘制的问题
比如在之前使用 vue+d3v6实现动态知识图谱可视化展示 存在明显的性能问题,该代码需要展示:
- 节点
- 关系
- 节点文字
- 关系文字
- 详情信息
- 动态交互及展示
以本人构建的外贸企业图谱为例,从Neo4j Desktop中导出大小为3.7MB的JSON文件信息如下:
- 节点个数:238
- 关系个数:4908
可以看到有近20万行的JSON数据,如果加载该JSON,就会导致浏览器卡死。
此时有几种优化思路:
- 压缩JSON文件
- 如:去除properties属性
- 缺点:无法展示节点更多的详情信息
- 2D图形使用Canvas代替SVG渲染,减少DOM开销
- 缺点:
- 图形交互上不如SVG
- 图像放大时存在失真(SVG是矢量图)
- 缺点:
- 使用3D渲染
- 缺点同上,因为3D也是Canvas
- 优点:适合大规模的图谱展示场景
2. 2D和3D渲染的对比(D3 vs Three)
通过浏览器调试工具的 performance ,可以看到在分别使用2d和3d初始化页面时,浏览器执行的详细信息对比如下:
首先需要说明,在CPU和GPU的使用和占有率上来说,3d渲染肯定比2d要高。但是,从时间上来看,几百节点就已经看出明显的差距(Rendering/Painting/Idle),如果节点数量上万,可能会更明显。
三、代码实现
1. 安装第三方模块
个人还是推荐使用第三方模块,这个东西的学习成本还是比较高的。。
创建一个vue项目:
vue create 3d-graph-demo
安装3d-force-graph
模块到项目依赖:
npm i -S 3d-force-graph
2. 具体代码
库的导入
在vue中导入3D库
import ForceGraph3D from '3d-force-graph'
// threejs的精灵标签,用于文字的展示
import SpriteText from 'three-spritetext'
初始化
3d渲染的初始化代码,包括数据解析、数据渲染
// 3d初始化,包括数据解析、数据渲染
threeInit (