根据需求个人更倾向于Echarts,在细节上有多属性能复用,也相对熟悉一下。如果很熟悉canvas的更倾向于使用d3的自定义;要考虑后端给的数据类型是什么,后端使用了图形化存储,d3就是不二选择了。如果数据是简单的关系层级,其实完全可以使用echarts。从数据json上是可以看到,两者的区别并不大。
D3.js的Neo4j前端展示
data.json
{
"results": [
{
"columns": [
"user",
"entity"
],
"data": [
{
"graph": {
"nodes": [
{
"id": "1",
"labels": [
"User"
],
"properties": {
"userId": "eisman"
}
},
{
"id": "2",
"labels": [
"Phone"
],
"properties": {
"value": "555-555-5555"
}
}
],
"relationships": [
{
"id": "1",
"type": "NUMBER",
"startNode": "1",
"endNode": "2",
"properties": {
"from": 1473581532586
}
}]
}
}
]
}
],
"errors": []
}
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<title>neo4jd3.js</title>
<link rel="stylesheet" href="./neo4jd3.min.css?v=0.0.1">
<style>
body,
html,
.neo4jd3 {
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="neo4jd3"></div>
<script src="./d3.min.js"></script>
<script src="./neo4jd3.min.js?v=0.0.1"></script>
<script type="text/javascript">
function init() {
var neo4jd3 = new Neo4jd3('#neo4jd3', {
// highlight: [
// {
// class: 'Project',
// property: 'name',
// value: 'neo4jd3'
// }, {
// class: 'User',
// property: 'userId',
// value: 'eisman'
// }
// ],
// icons: {
// 'zoomOut': 'search-minus'
// },
// images: {
// 'zoomOut': 'img/twemoji/1f50e.svg'
// },
minCollision: 60,
neo4jDataUrl: './data.json',
nodeRadius: 25,
onNodeDoubleClick: function (node) {
switch (node.id) {
case '25':
// Google
window.open(node.properties.url, '_blank');
break;
default:
var maxNodes = 5,
data = neo4jd3.randomD3Data(node, maxNodes);
neo4jd3.updateWithD3Data(data);
break;
}
},
onRelationshipDoubleClick: function (relationship) {
console.log('double click on relationship: ' + JSON.stringify(relationship));
},
zoomFit: true
});
}
window.onload = init;
</script>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-430863-29', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>
官方GitHub地址
文件地址:
d3.min.js
neo4jd3.min.css
neo4jd3.min.js
Echarts graph的前端展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
</head>
<body>
<div id="main" style="width: 400px; height:500px;"></div>
<script>
let chartDom = document.getElementById('main');
let myChart = echarts.init(chartDom);
// $.getJSON('./data.json').then(res => {
// const oldNodes = res.results[0].data[0].graph.nodes;
// const oldRelationships = res.results[0].data[0].graph.relationships;
// })
const nodes = [
{ name: '舆情大数据' },
{ name: '用户' },
{ name: '话题' },
]
const links = [
{
source: '舆情大数据',
target: '用户',
name: "分析"
},
{
source: '舆情大数据',
target: '话题',
name: "分析"
},
]
RenderEcharts(nodes, links)
function RenderEcharts(data, links) {
let option = {
tooltip: {},
animationDurationUpdate: 1000,
animationEasingUpdate: 'quinticInOut',
grid: {
top: 0,
left: 0
},
tooltip: {},
series: [
{
type: 'graph',
layout: 'force', // circular
symbolSize: 100,
roam: true, // 是否开启鼠标缩放和平移漫游
draggable: false, // 节点是否可拖拽
focusNodeAdjacency: true, // 是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。
autoCurveness: 0.01,
radius: ['100%', '100%'],
zoom: 1,
symbol: 'circle',
label: {
show: true,
fontSize: 14,
color: '#333',
},
// edgeSymbol: ['circle', 'arrow'],
edgeSymbol: 'none',
edgeSymbolSize: [0, 4],
edgeLabel: {
show: true,
fontSize: 10,
padding: [8, 0, 0, 0],
verticalAlign: 'middle',
opacity: 1,
formatter: x => `{a|${x.data.name}}`,
rich: {
a: {
padding: [2, 10, 2, 10],
backgroundColor: 'rgba(255, 164, 0, 1)',
align: 'center',
color: '#fff',
verticalAlign: 'middle',
borderRadius: 10,
}
}
},
data,
links,
lineStyle: {
width: 1,
color: 'rgba(0,0,0,1)',
// curveness: 0.02 // 弯曲程度
},
itemStyle: {
color: '#2ad5aa'
},
force: {
repulsion: 600, // 值越大则斥力越大
// gravity: 0.01, // 该值越大节点越往中心点靠拢
edgeLength: 300, // 边的两个节点之间的距离
layoutAnimation: true // 在浏览器端节点数据较多(>100)的时候不建议关闭,布局过程会造成浏览器假死。
}
}
]
}
option && myChart.setOption(option);
myChart.on('click', (param) => {
if (param.dataType == 'node') {
console.log('点击了节点')
} else {
console.log('点击了边', param.data)
}
})
}
</script>
</body>
</html>