目的
现在有一个需求,是要实现如下图所示的一个职位地铁图,用来表示公司所有的职位情况,其中黄色表示经历过的职位,绿色表示当前的职位,实现的方法可能包括canvas绘制甚至是一个个div拼凑而成,本篇文章介绍一种比较简单的方法——基于ECharts来实现。
1、熟悉ECharts实例
因为是基于ECharts来实现的,所以我们先来熟悉一下ECharts官方所提供的一个Graph实例,地址:https://echarts.apache.org/examples/zh/editor.html?c=graph-simple,他的例子实现如下图所示。
可以看出和我们的需求有些类似,但又有些差别,所以我们来看一下他的option,主要就是分析一下series里边的数据。
series: [
{
type: 'graph',//类型
layout: 'none',
symbolSize: 50,//节点的大小
roam: true,//是否开启鼠标缩放和平移漫游
label: {//节点样式
show: true
},
edgeSymbol: ['circle', 'arrow'],//连线样式,第一个表示首部为圆,第二个表示以箭头结尾,我们这边不需要
edgeSymbolSize: [4, 10],//首尾样式的大小
edgeLabel: {//连线描述字体的大小
fontSize: 20
},
data: [{//数据,这里指节点,包括节点的名称,根据x、y布局
name: '节点1',
x: 300,
y: 300
}, {
name: '节点2',
x: 800,
y: 300
}, {
name: '节点3',
x: 550,
y: 100
}, {
name: '节点4',
x: 550,
y: 500
}],
links: [{//连线,source表示连线开始位置,target表示连线结束位置,可以是data里节点对象的下标,也可以是名称;symbolSize表示当前节点首尾样式的大小;label设置字体样式;lineStyle设置连线样式
source: 0,
target: 1,
symbolSize: [5, 20],
label: {
show: true
},
lineStyle: {
width: 5,
curveness: 0.2
}
}, {
source: '节点2',
target: '节点1',
label: {
show: true
},
lineStyle: {
curveness: 0.2
}
}, {
source: '节点1',
target: '节点3'
}, {
source: '节点2',
target: '节点3'
}, {
source: '节点2',
target: '节点4'
}, {
source: '节点1',
target: '节点4'
}],
lineStyle: {//这个lineStyle表示为所有连线设置样式
opacity: 0.9,
width: 2,
curveness: 0
}
}
]
2、修改Graph实例
OK,熟悉了ECharts官方所提供的Graph实例之后,相信心里都有了一些想法,接下来就根据我们自己的需求,尝试着修改一下这里实例,把它做成我们所需要的一个效果。
series: [
{
type: 'graph',
layout: 'none',
symbolSize: 17,//节点大小为17
roam: true,
itemStyle: {//给所有节点的类型一个默认样式,特殊的可在其节点下单独修改样式
normal: {
color: "#FFFFFF",//颜色默认白色
borderColor: "#009900"//边框默认绿色
}
},
label: {//给所有的节点字体一个默认样式
normal: {
show: true,//显示
position: "bottom",//下方显示
color: "#C9C9C9",//默认颜色灰色
fontSize: 12//字体样式
}
},
lineStyle: {//给所有连线一个默认样式
normal: {
width: 3,
color: "#009900"
}
},
data: [{//节点,name不可重复
name: '助理研究员',
x: 0,
y: 0,
itemStyle: {//给特殊的节点设置不同的样式
normal: {
color: "#F0C209",
}
},
label: {
normal: {
color:"#000000"
}
}
}, {
name: '2019-07',//由于一个节点只能设置一个label,所以有时间的节点需要同时设置一个时间节点,位置一致,label显示在上方
x: 0,
y: 0,
itemStyle: {
normal: {
color: "#F0C209",
}
},
label: {
normal: {
position:"top",
color:"#000000"
}
}
}, {
name: '研究员',
x: 50,
y: 0,
itemStyle: {
normal: {
color: "#07F236",
}
},
label: {
normal: {
color:"#000000"
}
}
}, {
name: '2020-06',
x: 50,
y: 0,
itemStyle: {
normal: {
color: "#07F236",
}
},
label: {
normal: {
position:"top",
color:"#000000"
}
}
}, {
name: '高级研究员',
x: 100,
y: 0
}, {
name: '资深研究员',
x: 150,
y: 0
}, {
name: '专家',
x: 200,
y: 0
}, {
name: '主管',
x: 150,
y: 50,
itemStyle: {
normal: {
color: "#FFFFFF",
borderColor: "#FF0000"
}
}
}, {
name: '经理',
x: 200,
y: 50,
itemStyle: {
normal: {
color: "#FFFFFF",
borderColor: "#FF0000"
}
}
}],
links: [{//连线的source和target可以选择index,也可选择name,这里方便查看理解我用了name
source: '助理研究员',
target: '研究员',
}, {
source: '研究员',
target: '高级研究员',
}, {
source: '高级研究员',
target: '资深研究员'
}, {
source: '资深研究员',
target: '专家'
}, {
source: '高级研究员',
target: '主管',
lineStyle: {//特色的连线设置特殊的样式
normal: {
color: "#FF0000"
}
}
}, {
source: '主管',
target: '经理',
lineStyle: {
normal: {
color: "#FF0000"
}
}
}],
}
]
最终得到的结果如下图所示,已经满足了我们的需求,在实际项目中使用的时候节点(date)和连线(links)的数据由后端提供,前端做个渲染即可,相对来说还是比较简单的。
3、项目中使用
<v-chart :options="gradeLine" autoresize></v-chart>
gradeLine就是刚刚所提到的的option,需要注意的一点是date节点中name属性必须是唯一的,不可重复,否则会渲染失败。