关于数据可视化的开发,在第三方库的帮助下,从来没觉得复杂,但是一直都觉得颇为繁琐。恰好前段时间产品经理那边安排了一个需求,粗略一看很简单,实际上手的时候,有很多卡壳需要研究的地方。目前,需求已开发完毕,特此做个总结。
折线图或者柱状图坐标系中展示固定数量数据
主要设置
option.dataZoom
属性,此属性主要功能是控制区域缩放,要实现上述需求,只需要禁止缩放并且保持可以鼠标或者滚轮拖动即可,所以将minValueSpan
值和maxValueSpan
值设置为一样即可
option.dataZoom = [
{
type: 'slider',
minValueSpan: 9,
maxValueSpan: 9,
zoomLock: true,
bottom: 0
},
{
type: 'inside',
minValueSpan: 9,
maxValueSpan: 9,
}
]
坐标轴刻度标签文字内容全部显示,并且不能重合,文字过多需要折行显示,超过两行使用…替换
通过
option.xAxis.axisLabel.formatter
方法来自定义坐标轴刻度标签的展示形式
const _numSpan = 10 // 折线图显示18条数据,柱状图显示10条数据
const _realSpan = 10 // 图表真实显示的数据数
const _spanWidth = document.querySelector('.chartsWrapper').offsetWidth / _realSpan // 每条数据的真实宽度
const _fontSize = 14 // 设计稿中,坐标轴单个文字的宽度
option.xAxis.axisLabel.formatter = (value, index) => {
const _numLine = parseInt(parseInt(_spanWidth) / _fontSize - 1) // 每行能显示文字的个数
const _value = value.split('')
const _line1 = _value.slice(0, _numLine)
const _line2 = _value.slice(_numLine, _numLine * 2)
_line2[_numLine - 1] = _value.length > 2 * _numLine ? '...' : _line2[_numLine - 1]
return `${_line1.join('')}\n${_line2.join('')}`
}
效果如下(红框即为折行并且超出部分使用...
代替):
tooltip工具添加点击事件
使用
option.tooltip.formatter
方法来自定义点击事件,值得注意的是,我的项目是vue项目,为了使点击事件和项目中的数据可以进行一系列的交互,我使用了EventBus
方法
echarts.tooltip
代码:
option.tooltip.formatter = params => {
const { area, court, dept } = _this.param
const _linkHtml = `<span style="color: #929AA8; cursor: pointer;" onClick="window.eventBus.$emit('handleClickDataLoginToolTip', \'${area}\')">查看法院科室统计 ></span>`
return `<span style="color: #616E81;">${params[0].name}:${params[0].value}</span><br/>${_linkHtml}`
}
上述代码中,点击自定义的span
标签时,会触发handleClickDataLoginToolTip
事件,并携带area
参数。
EventBus
代码:
import Vue from 'vue'
window.eventBus = new Vue()
window.eventBus.$on('handleClickDataLoginToolTip', val => {
// 写自己的逻辑...
})
效果如下(箭头所指即需要执行自定义事件的元素):
柱状图样式的个性化
需求如下图所示:
1:数据排序以及序号样式
2:类目轴刻度标签位置
3:value值显示位置
需求分析:
- 数据排序功能是后端小伙伴的任务,前端不用考虑
- 图表分为两部分,所以需要两个坐标系,通过设置
option.grid
属性来实现 1
和2
部分样式可以通过设置y
轴的axisLabel.formatter
和axisLabel.rich
,而其位置可以通过axisLable.padding
来控制其在柱状条形的正上方显示- 对于
3
部分而言,可以通过设置series
中的bar
的label
来实现 - 两个坐标系之间x轴的刻度值是各自计算的,互不关联,可以通过设置
x
轴的max
来使其关联
代码如下:
// _value是两个坐标系series的data合并成的数组
option.xAxis = [
{
type: 'value',
gridIndex: 1,
show: false,
max: Math.max(..._value)
},
{
type: 'value',
gridIndex: 2,
show: false,
max: Math.max(..._value)
}
]
option.yAxis.axisLabel = {
inside: true,
padding: [-40, 0, 0, 0],
formatter(value, index) {
const _order = index + 1 + 10 * i
if (_order === 1) {
return `{order0|${_order}}{value|${value}}`
}
if (_order === 2) {
return `{order1|${_order}}{value|${value}}`
}
if (_order === 3) {
return `{order2|${_order}}{value|${value}}`
}
return `{order|${_order}}{value|${value}}`
},
verticalAlign: 'middle',
rich: {
order0: {
backgroundColor: '#FFAF6E',
fontFamily: 'LiGothicMed',
borderRadius: 45,
width: 16,
height: 16,
color: '#fff',
fontSize: 12,
align: 'center',
verticalAlign: 'middle'
},
order1: {
backgroundColor: '#ED828F',
fontFamily: 'LiGothicMed',
borderRadius: 45,
width: 16,
height: 16,
color: '#fff',
fontSize: 12,
align: 'center',
verticalAlign: 'middle'
},
order2: {
backgroundColor: '#6A79E6',
fontFamily: 'LiGothicMed',
borderRadius: 45,
width: 16,
height: 16,
color: '#fff',
fontSize: 12,
align: 'center',
verticalAlign: 'middle'
},
order: {
backgroundColor: '#79A5EB',
fontFamily: 'LiGothicMed',
borderRadius: 45,
width: 16,
height: 16,
color: '#fff',
fontSize: 12,
align: 'center',
verticalAlign: 'middle',
lineHeight: 16
},
value: {
color: '#31415B',
fontSize: 14,
padding: [0, 0, 0, 5]
}
}
}