对Neo4j导出数据做知识图谱可视化 D3库实现
- 引言
- Neo4j导出数据
- 前端实现
- d3初始化
- 分离数据
- D3可视化
引言
好久没用D3库作可视化了,现在主要是用百度的echarts库,在项目中做简单的图表太方便了。但像是做关系图其实用echarts也很方便,这次用D3实现主要是复习一下以前做的东西,顺便记录一下。
以下是我参考到的实例代码:
D3官方图实例参考
echarts做关系图实例参考
Neo4j导出数据
我们先通过Cypher查询将数据从Neo4j中查询出来,Neo4j构建和查询可以参考我上篇博客基于Neo4j的外贸企业关系图谱做企业相似度查询
查询后的结果如下,点击右上角下载图标,导出为JSON格式
可以进入JSON在线解析,查看导出的JSON格式:
前端实现
d3初始化
新建好前端项目后,先把D3的js库导入进来,再通过d3.json()来读取我们的json文件。
1 2 | <!-- 增加D3元素库 --> <script src="js/d3.v4.min.js"></script> |
1 2 3 4 5 6 7 | var graph; //d3.json获取数据 d3.json("data/records.json", function(error, data) { if(error) throw error; graph = data; console.log(graph[0].p); } |
先运行结果,查看控制台打印的结果如下:
`
分离数据
还是先去官网分析一下标准数据格式,可以看到下图data分为nodes和links两部分,在D3中节点和关系是分开渲染的,渲染过后会自动在各个部分内生成位置坐标的属性。
此时我们需要将neo4j导出的数据做标准化,使数据格式符合D3标准。
(需要注意一个坑:要对json数据做去重处理,不然D3在渲染时无法将节点关系弄出来,原理其实就是节点的唯一标识产生了冲突,我们要保证节点的唯一性)
以下是标准化的代码,将json数据分离到nodes和links两部分,为数据绑定打好基础:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | // 图数据 var graph; let nodes =[]; let links = []; // 存放节点和关系 let nodeSet = []; // 存放去重后nodes的id //d3.json获取数据 d3.json("data/records.json", function(error, data) { if(error) throw error; graph = data; console.log(graph[0].p); for (let item of graph) { // console.log(item.p.start instanceof Array) // console.log(item.p) // 重新更改data格式 if(nodeSet.indexOf(item.p.start.identity) == -1){ nodeSet.push(item.p.start.identity) nodes.push({ id: item.p.start.identity, label: item.p.start.labels[0], properties: item.p.start.properties }) } if(nodeSet.indexOf(item.p.end.identity) == -1){ nodeSet.push(item.p.end.identity) nodes.push({ id: item.p.end.identity, label: item.p.end.labels[0], properties: item.p.end.properties }) } links.push({ source: item.p.segments[0].relationship.start, target: item.p.segments[0].relationship.end, type: item.p.segments[0].relationship.type, properties: item.p.segments[0].relationship.properties }) } console.log(nodes) console.log(links) } |
D3可视化
数据处理好之后,只需要把数据绑定到d3上即可,官网参考代码已经有了,在此不多做叙述。
最终展示出的效果如下:
从二图中可以看到可视化还做了复杂的事件处理,目前完成了拖拽事件、鼠标进入、鼠标离开三个事件。当鼠标放到节点上时,在右边会展示节点信息,并隐藏与该节点无关的其他节点。
等做完后我再抽时间写到博客上,目前时间太紧张了,要忙各种事情。