好久没用D3库作可视化了,现在主要是用百度的echarts库,在项目中做简单的图表太方便了。但像是做关系图其实用echarts也很方便,这次用D3实现主要是复习一下以前做的东西,顺便记录一下。
以下是我参考到的实例代码:
官方下载链接:https://neo4j.com/download/
注意下载后会跳转到Activation Key页面,这时已经自动生成好密钥,复制后,粘贴到 Neo4j Desktop
的 Software Keys
输入框内即可完成激活:
我们先通过Cypher查询将数据从Neo4j中查询出来,Neo4j构建和查询可以参考我上篇博客 基于Neo4j的外贸企业关系图谱做企业相似度查询
由于原Cypher语句比较长,通过下面的查询导出的格式也是一样的,根据自己的关系查询进行修改即可:
MATCH p=(n:Enterprise)-[]->() RETURN p limit 20
查询后的结果如下,点击右上角下载图标,导出为JSON格式:
新建好一个Web项目后,先把D3的JS库导入进来,再通过d3.json()来读取我们的json文件。
可以通过本地方式导入
<!-- 增加D3元素库 -->
<script src="js/d3.v4.min.js"></script>
如果不想下到本地,也可以通过CDN方式直接导入
<!-- 增加D3元素库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/d3/4.9.1/d3.min.js"></script>
导入D3后,就可以通过d3.json
方法读取本地的json文件:
var graph;
//d3.json获取数据
d3.json("data/records.json", function(error, data) {
if(error) throw error;
graph = data;
console.log(graph[0].p);
}
还是先去D3官方图实例参考分析一下标准数据格式,从下图可以看到 data 分为 nodes 和 links 两部分,因为在D3中节点和关系是分开渲染的,渲染过后会自动在各个部分内生成位置坐标的属性。
此时我们需要将neo4j导出的数据做标准化,使数据格式符合D3标准。
(需要注意一个坑:要对json数据做去重处理,不然D3在渲染时无法将节点关系弄出来,原理其实就是节点的唯一标识产生了冲突,我们要保证节点的唯一性)
以下是标准化的代码,将json数据分离到 nodes 和 links 两部分,为数据绑定打好基础:(2021.04更新,解决长路径报错问题)
// 图数据
var graph;
let nodes =[];
let links = []; // 存放节点和关系
let nodeSet = []; // 存放去重后nodes的id
//d3.json获取数据
d3.json(url, function(error, data) {
if (error) throw error
graph = data
console.log(graph[0].p)
for (let item of graph) {
for (let segment of item.p.segments) {
// 重新更改data格式
if (nodeSet.indexOf(segment.start.identity) == -1) {
nodeSet.push(segment.start.identity)
nodes.push({
id: segment.start.identity,
label: segment.start.labels[0],
properties: segment.start.properties
})
}
if (nodeSet.indexOf(segment.end.identity) == -1) {
nodeSet.push(segment.end.identity)
nodes.push({
id: segment.end.identity,
label: segment.end.labels[0],
properties: segment.end.properties
})
}
links.push({
source: segment.relationship.start,
target: segment.relationship.end,
type: segment.relationship.type,
properties: segment.relationship.properties
})
}
}
// 省略D3初始化代码...
}
数据处理好之后,只需要把数据绑定到D3上即可,至于展示部分官网参考代码已经有了,在此不再做详细展开,后面也可以参考我的代码注释理解。
最终展示出的效果如下:
从二图中可以看到可视化还做了一些事件处理,目前完成了拖拽事件、鼠标进入、鼠标离开三个事件。当鼠标放到节点上时,在右边会展示节点信息,并隐藏与该节点无关的其他节点。
最后,加了个节点文字切换和搜索功能,之前的节点全挨在一起,于是又加了个碰撞检测模型,最终效果如下:
像这种力导向关系图可以结合多个力学模型自行扩充,其他的效果可以自行拓展:(官方参考的力模型)
个人实现代码(仅供参考):
在 标签中定位,修改如下几行代码即可,不需要在到处去找位置了
// 自定义图标及颜色(数组保证一一对应)
// names 图例名称变量制作图标
// labels 节点的标签名称(与records.json中保证相同)
// colors 图例颜色
// url json文件的路径
var names = ['企业', '贸易类型', '地区', '国家']
var labels = ['Enterprise', 'Type', 'Region', 'Country']
var colors = ['#55ffff', '#aaaaff', '#4e88af', '#ca635f']
var url = 'data/records.json'
之前的代码只支持 距离为1 的关系路径导入。
如果你从Neo4j导出的 records.json
中关系路径长度大于1,比如下面这种情况会导致节点全部移至左上角。
现在已经修改完毕,支持长距离路径的图,只要满足JSON格式要求,即可进行可视化展示。
修复图例颜色问题,之前图例超过4个就无法填充颜色了,现在已更改
多图例情况:(热心网友提供的数据,所以打个码)
这篇博客主要介绍如何处理Neo4j导出的JSON数据,没有展开来介绍图的可视化展示。正好最近试了一下新版的d3(v6版本),用vue对代码功能作进一步完善,更具体的可视化展示代码可以参考下面几篇博客: