Echarts3可伸展力导向图

  最近知识图谱项目的需要,使用Echarts3开发了可伸展力导向图前端代码,现分享如下:
  主要功能:图谱web端可视化;支持用户交互。

<!DOCTYPE html>
<html>

<head>
<meta charset='utf-8'>
<title></title>
<link rel="stylesheet" href="${pageContext.request.contextPath }/css/style.css">
<script src="${pageContext.request.contextPath }/js/echarts.js"></script>
<script src="${pageContext.request.contextPath }/css/iconfont.js"></script>
</head>
<body style="height:500px;">
<div id="container" style="height: 500px"></div>
</body>

<script type="text/javascript">
var entitys = ###见注释###【1】;
var triplet = ###见注释###【2】;
var initentity = ###见注释###【3】;

function selectEle(params) {
clearTimeout(TimeFn)
TimeFn = setTimeout(() => {
let options = myChart.getOption()
let nodesOption = options.series[0].data
let name = params.data.name
options.series[0].itemStyle.opacity = 0.4
options.series[0].lineStyle.opacity = 0.4
for (let m in nodesOption) {
nodesOption[m].itemStyle = {}
if (nodesOption[m].name === name) {
console.log(nodesOption[m])
selectInfo.name = name
selectInfo.index = m
if (name === preName) {
selectInfo.state = false
options.series[0].itemStyle.opacity = 1
options.series[0].lineStyle.opacity = 1
preName = ""
//break
} else {
selectInfo.state = true
nodesOption[m].itemStyle.opacity = 1 //Generally,should break loop once target get ,but for opacity init every time
preName = name //i.e. nodesOption[m].itemStyle = {} enable default opacity=1
//break //could locate by setting preM ,and just recover that node with a large number of nodes
}
}
}
myChart.setOption(options);
}, 300)
}
function preProcess() {
let data = optionFromDB.series[0].data
let links = optionFromDB.series[0].links
data.forEach(function(node) {
node.isSpread = true
})
//other init operation you want
}
function spreadAndcontract(params) {
clearTimeout(TimeFn)
let options = myChart.getOption()
let nodesOption = options.series[0].data
let linksOption = options.series[0].links
let tempLinks = optionFromDB.series[0].links
let tempData = optionFromDB.series[0].data
let name = params.data.name
let count = 0
function hasChild(tempName) {
linksOption.forEach(function(node) {
if (node.source === tempName) {
for (let m in nodesOption) {
if (nodesOption[m].name === node.target) { //hasChild=>contract
count++
nodesOption.splice(m, 1)
hasChild(node.target)

}

}
}
})
if (!count) { // noChild=>spread
let tempTarget = []
tempLinks.forEach(function(node) {
if (node.source === name) {
tempTarget.push(node.target) //no use
for (let m in tempData) {
if (tempData[m].name === node.target) {
let n = 0
for (let m in nodesOption) {
if (nodesOption[m].name === node.target) { //no use
n++
}
}
if (n === 0) {
nodesOption.push(tempData[m])
}
}
}
}
})
}
}
hasChild(name)
myChart.setOption(options)
}
var categories = [{
name: 0,

}, {
name: 1,

}, {
name: 2,

}, {
name: 3,

}]
var graph = {
data: entity,
links: triplet
}
var graph2 = {
data: initentity,
links: triplet
}
var optionFromDB = {
series: [{
color: ['#3385ff', '#ff8c00', '#bda29a', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'],
draggable: true,
label: {
show: true,
position: 'bottom',
formatter: '{b}'
},
edgeSymbol: 'arrow',
force: {
repulsion: 40
},
data: graph.data,
links: graph.links,
categories: categories,
roam: true,
type: 'graph',
// layout: 'force',
// symbolSize: 34,
// animationDurationUpdate: 750

}]
}
var optionFromDB2 = {
series: [{
color: ['#3385ff', '#ff8c00', '#bda29a', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'],
draggable: true,
label: {
show: true,
position: 'bottom',
formatter: '{b}'
},
edgeSymbol: ['none', 'arrow'],
force: {
repulsion: 300
},
data: graph2.data,
links: graph2.links,
categories: categories,
roam: true,
type: 'graph',
// layout: 'force',
// symbolSize: 34,
// animationDurationUpdate: 750

}]
}
var dom = document.getElementById("container");
var myChart = echarts.init(dom)
//preProcess()
option = null
var TimeFn = null //avoid click cover dblclick
var preName=null
var selectInfo={
state:false,
index:null,
name:null
}
// alert(1)
myChart.on('click',selectEle.bind(this))
myChart.on('click',spreadAndcontract) //dbl,not "db"
// alert(2)
myChart.setOption(option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
zoom:2,
type: 'graph',
layout: 'force',
category:categories,
symbolSize: 34,
animationDurationUpdate: 750,


}
]
})
myChart.setOption(optionFromDB2)
</script>

</html>

注释
【1】需要展示的所有实体列表,格式如下:

data = [{
name: 'xxx', #实体名称
category:0, #实体类型(0,1,...)
},...]

【2】需要展示的所有实体的关系边,格式如下:

links: [{
source: 'xxx', #头实体名称
target: 'xxx', #尾实体名称
label: {
normal: {
show: true, #是否显示标签
formatter:'xxx', #边上的文字
color : '#ff0000', #边颜色
}
},
}, ...]

【3】格式与【1】相同,但存储需要首先初始化展示的所有实体

效果图
(1)初始化:


Echarts3可伸展力导向图_ci

(2)点击“文件”结点后:


Echarts3可伸展力导向图_Echarts_02

(3)带有鼠标特效:


Echarts3可伸展力导向图_css_03