使用echart图表时,偶尔会遇到使用和弦关系图的问题,这里举例和弦关系图的配置
<template>
<div>
<div>和弦关系图(echart官网也称:悲惨世界人物关系图)</div>
<div ref="myChordEchart"></div>
</div>
</template>
<script>
export default {
data () {
return {
myChordEchart: null
}
},
mounted () {
this.initEcharts()
},
methods: {
averageSize (res, max, commSize = 16) { // 平均分为16等份,等份可自定义
const step = max / commSize
const level = Math.ceil(res / step)
return level * 2 + 6
},
initEcharts () {
if (this.myChordEchart) { // 首先清理原来的和弦图(echart官网也称:悲惨世界人物关系图)
this.myChordEchart.clear()
this.myChordEchart.dispose()
this.myChordEchart = null
}
const testEchartArr = [
{
'end_node': '20238',
'cross_times': 92,
'start_node': '20231',
'end_node_name': '北二路出口',
'id': '20231-20238',
'start_node_name': '第八大道入口'
},
{
'end_node': '20238',
'cross_times': 71,
'start_node': '20232',
'end_node_name': '北二路出口',
'id': '20232-20238',
'start_node_name': '第六大道入口'
},
{
'end_node': '20238',
'cross_times': 49,
'start_node': '20233',
'end_node_name': '北二路出口',
'id': '20233-20238',
'start_node_name': '第五大道入口'
},
{
'end_node': '20238',
'cross_times': 52,
'start_node': '20234',
'end_node_name': '北二路出口',
'id': '20234-20238',
'start_node_name': '第三大道入口'
}
]
let linksArr = []
let nodesArr = []
let max = 0
if (testEchartArr?.length > 0) {
testEchartArr.forEach(v => {
linksArr.push({
source: v.start_node,
target: v.end_node,
sourceName: v.start_node_name,
targetName: v.end_node_name,
value: v.cross_times
})
if (nodesArr.length === 0) {
nodesArr = [
{
id: v.start_node,
name: v.start_node_name,
value: v.cross_times
},
{
id: v.end_node,
name: v.end_node_name,
value: v.cross_times
}
]
max = Math.max(max, v.cross_times)
} else {
const sourceItem = nodesArr.findIndex(j => j.id === v.start_node)
if (sourceItem < 0) { // 找不到相同的起始路段的id
nodesArr.push({
id: v.start_node,
name: v.start_node_name,
value: v.cross_times
})
max = Math.max(max, v.cross_times)
} else { // 累加value的值
nodesArr[sourceItem].value += v.cross_times
max = Math.max(max, nodesArr[sourceItem].value)
}
const targetItem = nodesArr.findIndex(j => j.id === v.end_node)
if (targetItem < 0) { // 找不到相同的结束路段的id
nodesArr.push({
id: v.end_node,
name: v.end_node_name,
value: v.cross_times
})
max = Math.max(max, v.cross_times)
} else { // 累加value的值
nodesArr[targetItem].value += v.cross_times
max = Math.max(max, nodesArr[targetItem].value)
}
}
})
nodesArr.forEach(v => { // 按照最大值平均分16等份,并设置nodes的symbolSize
v.symbolSize = this.averageSize(v.value, max)
v.category = v.name
v.label = {
normal: {
show: true
}
}
})
let sliNumer = 0
try {
sliNumer = Math.ceil(nodesArr.length / 4)
} catch (error) {
sliNumer = 0
}
if (sliNumer > 0) { // 因和弦图设置为环形状态时,默认会从90度位置顺时针旋转显示,所以把最初始的四分之一数据,添加到最后,即可实现从0度开始顺时针旋转的效果,可根据业务自定义更改数据的位置
let nodeCopyArr = nodesArr
nodesArr = (nodeCopyArr.slice(sliNumer, nodeCopyArr.length)).concat(nodeCopyArr.slice(0, sliNumer))
}
}
let categoriesArr = nodesArr?.length > 0 ? nodesArr.map(v => {
return { name: v.name }
}) : [] // 筛选出所有路段的名称
const option = {
// color: ['#ff0000', '#f00000'], // 可自定义多种颜色
tooltip: {},
animationDurationUpdate: 1500,
animationEasingUpdate: 'quinticInOut',
series: [
{
type: 'graph',
layout: 'circular',
circular: {
rotateLabel: true
},
data: nodesArr, // 所有路段的数据
links: linksArr, // 路段连接的数据
categories: categoriesArr, // 所有路段的名称数据
roam: true,
label: {
position: 'right',
formatter: '{b}'
},
lineStyle: {
color: 'source',
curveness: 0.3
}
}
]
}
this.$nextTick(() => {
this.myChordEchart = this.$echarts.init(this.$refs.myChordEchart)
this.myChordEchart.setOption(option, true)
})
},
close () {
this.$emit('close')
}
}
}
</script>
<style lang='less' scoped></style>
写好配置项后即可看到效果,因数据量大仅提供部分测试数据演示,最终的效果和echart官网类似。
最后,原创不易,如本文对您有所帮助,麻烦点赞收藏一下谢谢!