一:三级关系图知识图谱
最近写了个demo,主要功能是搜索实体,搜索结果显示与该实体相关的公司、子公司、设备、位置、状态、危害这六类,数据是通过我司的数据标注系统提供的。后端用到的技术栈是python3、java1.8、neo4j3.5和Django。前端通过Django获取数据,做数据处理,搭配好echarts配置参数,比如data、links、categories、symbolSize。
二:先上效果图:
三:data、links、category、symbolSize数据配置
3.1 data配置:想要展示三个层级,定义了三个node 每个node里都配置了name、draggable、category、id、symbolSize
3.2 links配置:数据指向
3.3 category:功能是每个状态对应一个颜色
3.4 symbolSize:data节点的大小,一级的大小是全部二级的总和,二级是三级的总和(原始节点的大小是后台返回来的,做的求和)
//echarts 数据
var data = [];
var links = [];
var n2 = []
//构造展示的数据
var maxDisPlayNode = 50;
var id = 0;
var num = {}
var num2 = ''
var temp = [];
for (var i = 0; id < maxDisPlayNode && i < searchResult.length; i++) {
var newset1 = searchResult[i]['n1']['label']
var newset2 = searchResult[i]['n2']['label']
var newset3 = searchResult[i]['n3']['label']
n2.push(newset1, newset2, newset3)
for (var i = 0; i < n2.length; i++) {
if (temp.indexOf(n2[i]) == -1) {
temp.push(n2[i]);
}
}
//获取node1
node1 = {};
node1['name'] = searchResult[i]['n1']['title'];
node1['draggable'] = true;
var n2Category = searchResult[i]['n1']['label']
if (n2Category == 'company') {
node1['category'] = 0;
} else if (n2Category == 'subsidiary') {
node1['category'] = 1;
} else if (n2Category == 'device') {
node1['category'] = 2;
} else if (n2Category == 'location') {
node1['category'] = 3;
} else if (n2Category == 'status') {
node1['category'] = 4;
} else if (n2Category == 'danger') {
node1['category'] = 5;
}
var flag = 1;
relationTarget = id.toString();
for (var j = 0; j < data.length; j++) {
if (data[j]['name'] === node1['name']) {
flag = 0;
relationTarget = data[j]['id'];
break;
}
}
node1['id'] = relationTarget;
// num2 = parseInt(searchResult[i]['rel']['entity2_count'])
// if (!num[node1['id']]) {
// num[node1['id']] = num2 + 20
// } else {
// num[node1['id']] += num2
// }
node1['symbolSize'] = 1
if (flag === 1) {
id++;
data.push(node1);
}
//获取node2
node2 = {};
node2['name'] = searchResult[i]['n2']['title'];
node2['draggable'] = true;
var n2Category = searchResult[i]['n2']['label']
if (n2Category == 'company') {
node2['category'] = 0;
} else if (n2Category == 'subsidiary') {
node2['category'] = 1;
} else if (n2Category == 'device') {
node2['category'] = 2;
} else if (n2Category == 'location') {
node2['category'] = 3;
} else if (n2Category == 'status') {
node2['category'] = 4;
} else if (n2Category == 'danger') {
node2['category'] = 5;
}
flag = 1;
relationTarget = id.toString();
for (var j = 0; j < data.length; j++) {
if (data[j]['name'] === node2['name']) {
flag = 0;
relationTarget = data[j]['id'];
break;
}
}
node2['id'] = relationTarget;
num2 = parseInt(searchResult[i]['rel2']['entity2_count'])
if(!num[node2['id']]){
num[node2['id']] = num2 + 20
} else {
num[node2['id']] += num2
}
if (flag === 1) {
id++;
data.push(node2);
}
// 判断有没有node3 有的话push到data和links
if (searchResult[i]['n3']) {
node3 = {};
node3['name'] = searchResult[i]['n3']['title'];
node3['draggable'] = true;
var n2Category = searchResult[i]['n3']['label']
if (n2Category == 'company') {
node3['category'] = 0;
} else if (n2Category == 'subsidiary') {
node3['category'] = 1;
} else if (n2Category == 'device') {
node3['category'] = 2;
} else if (n2Category == 'location') {
node3['category'] = 3;
} else if (n2Category == 'status') {
node3['category'] = 4;
} else if (n2Category == 'danger') {
node3['category'] = 5;
}
flag = 1;
// node3['level'] = 3;
relationTarget = id.toString();
for (var j = 0; j < data.length; j++) {
if (data[j]['name'] === node3['name']) {
flag = 0;
relationTarget = data[j]['id'];
break;
}
}
node3['id'] = relationTarget;
num2 = parseInt(searchResult[i]['rel2']['entity2_count'])
if (!num[node3['id']]) {
num[node3['id']] = num2 + 20
} else {
num[node3['id']] += num2
}
if (flag === 1) {
id++;
data.push(node3);
}
//获取relation2
relation2 = {}
relation2['source'] = node2['id'];
relation2['target'] = node3['id'];
relation2['category'] = 0;
flag = 1;
for (var j = 0; j < links.length; j++) {
if (links[j]['source'] == relation2['source'] && links[j]['target'] == relation2['target']) {
links[j]['value'] = searchResult[i]['rel2']['type'];
links[j]['entity2_count'] = searchResult[i]['rel2']['entity2_count']
flag = 0;
break;
}
}
if (flag === 1) {
relation2['value'] = searchResult[i]['rel2']['type'];
relation2['symbolSize'] = 10;
links.push(relation2);
}
}
//获取relation1
relation = {}
relation['source'] = node1['id'];
relation['target'] = node2['id'];
relation['category'] = 0;
flag = 1;
for (var j = 0; j < links.length; j++) {
if (links[j]['source'] == relation['source'] && links[j]['target'] == relation['target']) {
links[j]['value'] = searchResult[i]['rel']['type'];
links[j]['entity2_count'] = searchResult[i]['rel']['entity2_count'];
flag = 0;
break;
}
}
if (flag === 1) {
relation['value'] = searchResult[i]['rel']['type'];
relation['symbolSize'] = 10;
links.push(relation);
}
}
// 计算symbolSize大小
for (var i = 0; i < data.length; i++){
data[i]['symbolSize'] = num[data[i]['id']]
}
复制代码
四:option配置参数
option = {
title: {
text: ''
},
tooltip: {},
animationDurationUpdate: 1500,
animationEasingUpdate: 'quinticInOut',
label: {
normal: {
show: true,
textStyle: {
fontSize: 12
},
}
},
legend: {
x: "center",
data: [{
name: '公司',
icon: 'rect' //'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
},{
name: '子公司',
icon: 'triangle'
}, {
name: '设备',
icon: 'circle'
}, {
name: '位置',
icon: 'roundRect'
}, {
name: '状态',
icon: 'pin'
}, {
name: '危害',
icon: 'diamond'
}]
},
series: [
{
type: 'graph',
layout: 'force',
symbolSize: 45,
focusNodeAdjacency: true,
roam: true,
edgeSymbol: ['none', 'arrow'],
categories: [{
name: '公司',
icon: 'rect' //'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
}, {
name: '子公司',
icon: 'triangle'
}, {
name: '设备',
icon: 'circle'
}, {
name: '位置',
icon: 'roundRect'
}, {
name: '状态',
icon: 'pin'
}, {
name: '危害',
icon: 'diamond'
}],
label: {
normal: {
show: true,
textStyle: {
fontSize: 12,
},
}
},
force: {
repulsion: 1000
},
edgeSymbolSize: [4, 50],
edgeLabel: {
normal: {
show: true,
textStyle: {
fontSize: 10
},
formatter: "{c}"
}
},
data: data, // data数据
links: links, // links 主要是做数据箭头连接
lineStyle: {
normal: {
opacity: 1,
width: 3,
curveness: 0,
color: 'source',
}
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
复制代码
至此 完结!best regards!