Echarts5.*
中,关系图谱(relation graph
)中的每个节点必须给x
、y
坐标,才会显示在画布上,在前一篇文章里我采用的方法是,随机生成坐标点,可这样会导致节点布局混乱,无法理清各个节点之间的关系。希望能做到如下的优化:
后期的效果如下图所示:
核心代码如下所示:
<template>
<div ref="main" id="graph">div>
template>
<script>
import * as echarts from 'echarts'
export default {
name: "graph",
methods: {
getCenterPos() {
const x = (this.$refs.main.clientWidth - 40) * 0.5
const y = (this.$refs.main.clientHeight - 200) * 0.5
return {
x,
y
}
}
}
}
script>
该方法如下所示:
<template>
<div ref="main" id="graph">div>
template>
<script>
import * as echarts from 'echarts'
export default {
name: "graph",
methods: {
/**
* @param {Object} {x,y} 圆心坐标
* @param {Number} index 索引值,即该子节点在所有同类型子节点中的位置索引(数组索引位置)
* @params {Number} nodesLen 子节点个数
* @params {Number} radius 半径
*/
circledNodesPosition({x,y}, index, nodesLen, radius = 20) {
const avd = 360 / nodesLen;
const ahd = avd * Math.PI / 180
return {
x: Math.sin((ahd*index))*radius + x,
y: Math.cos((ahd*index))*radius + y
}
},
}
script>
360 / nodesLen
,即每个子节点对应的角度
avd * Math.PI / 180
, 即每个子节点对应的弧度
Math.sin((ahd*index))*radius
,得到该子节点与圆中心的x
方向偏移值,若需知道该子节点的x
坐标信息,则需加上圆心的x
值
核心代码如下所示:
initGraph() {
const buildingNode = []
const componentNodes = []
const personNodes = []
let personCenterPos = null
const companyNodes = []
let companyCenterPos = null
const roomNodes = []
let roomCenterPos = null
var center = this.getCenterPos()
graph.nodes.forEach(a => {
const {labels, id, properties} = a
const type = labels[0]
if (type === 'Building') {
buildingNode.push({
...param,
x: center.x,
y: center.y
})
} else if(type === 'Component') {
componentNodes.push({
...param
})
} else if (type === 'Person') {
personNodes.push({
...param
})
} else if (type === 'Company') {
companyNodes.push({
...param
})
} else if (type === 'Room') {
roomNodes.push({
...param
})
}
})
componentNodes.forEach((a,index) => {
var pos = this.circledNodesPosition(center, index, componentNodes.length)
a.x = pos.x
a.y = pos.y
const cType = a.properties.find(a=> a.key === 'component_name').value
if (cType === '人') {
personCenterPos = {
x: a.x,
y: a.y
}
} else if (cType === '企业') {
companyCenterPos = {
x: a.x,
y: a.y
}
} else if (cType === '房间') {
roomCenterPos = {
x: a.x,
y: a.y
}
}
})
const generateNodesPos = (nodes, centerPos, nodesLen) => {
nodes.forEach((a,index) => {
var pos = this.circledNodesPosition(centerPos, index, nodesLen, 5)
a.x = pos.x
a.y = pos.y
})
}
generateNodesPos(personNodes, personCenterPos, personNodes.length)
generateNodesPos(companyNodes, companyCenterPos, companyNodes.length)
generateNodesPos(roomNodes, roomCenterPos, roomNodes.length)
const nodes = [
...buildingNode,
...componentNodes,
...personNodes,
...companyNodes,
...roomNodes
]
var option = {
tooltip: {},
animationDuration: 1500,
animationEasingUpdate: 'quinticInOut',
hoverAnimation:false,
series: [
{
// name: '孪生',
type: 'graph',
layout: 'none',
circular:{rotateLabel:true},
animation: false,
data: nodes
...
}
]
}
myChart.setOption(option);
}
在上面代码中,我先从所有节点中过滤出componentNodes
,因为它是类型聚合点,再根据不同类型,将子节点划分到对应数组中,找出同类型中的圆中心点,遍历同类型子节点,生成各个子节点的x,y
坐标信息即可