一个echarts柱状图实例
这篇文章主要讲了echarts在vue+iview中的一个应用(柱状图)和在实现过程中遇到的问题,如何设置数据以及如何解决参数动态更新效果。
需求
根据所选时间区间和勾选的参数要素生成响应的图表,单参数图表和多参数图表。
分析
- 时间区间格式 传给后台的值 [‘2020-01-15’, ‘2020-02-15’]
- 勾选参数:将参数的中英文字段对应做成字典,使用iview的Checkbox组件,勾选对应的参数直接获取到参数字段组成的数组,便于生成对应的报表
- 两种图表,单一元素的,多元素混合的。需要两个不同的配置项模板
实施
找模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78// 单元素柱状图模板 在A,B,C 处处理数据
optionTpl: {
title: {
text: ''
},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true // grid 区域是否包含坐标轴的刻度标签
},
legend: {
data: [] // A 单元素标题
},
xAxis: {
data: [], // B 时间轴数据 ['202001', '202002']
nameLocation: 'end', //坐标轴名称显示位置。
axisLabel: { //坐标轴刻度标签的相关设置。
interval: 0, // 设置成 0 强制显示所有标签。如果设置为 1,表示『隔一个标签显示一个标签』,如果值为 2,表示隔两个标签显示一个标签,以此类推。
rotate: "30" // x轴文字旋转角度
}
},
yAxis: {},
series: [] // C 参数数据放在这里
// series: [{
// name: '累计融资金额',
// type: 'bar',
// data: [5, 20, 36, 10, 10, 100, 120, 150, 30, 80, 50, 130]
// }]
},
// 多元素柱状图模板 A,B处处理数据
option2Tpl: {
legend: {},
// color: ['#3398DB', '#C0504D', '#9BBB59'],
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: { //直角坐标系内绘图网格
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
dataset: {
source: [] // A 需要展示的数据
// ['product', '已实现收入', '待收入', '还款'],
// ['202001', 43.3, 85.8, 93.7],
// ['202002', 83.1, 73.4, 55.1],
// ['202003', 86.4, 65.2, 82.5],
// ['202004', 72.4, 53.9, 39.1],
// ['202005', 90.4, 30.9, 66.1],
},
xAxis: {
type: 'category',
nameLocation: 'end', //坐标轴名称显示位置。
axisLabel: { //坐标轴刻度标签的相关设置。
interval: 0,
rotate: "0"
}
},
yAxis: {},
series: [] // 有几个图生成 几个type
// series: [
// {type: 'bar'},
// {type: 'bar'},
// {type: 'bar'}
// ]
},html
1
2
3
4
5
6<!-- 动态生成id,为 ECharts 准备一个具备高宽的 DOM 容器 -->
<Row>
<Col span="12" v-for="(k, index) in allSelPam" :key="index">
<div :id="`dom_${k}`" style="height: 320px;width: 100%;"></div>
</Col>
</Row>javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92// 在查询方法中,生成图标dom元素 this.selData是选中的参数组成的数组
// 使用固定的 'allCharts' 作为所用参数综合图表的参数
this.allSelPam = this.selData.length > 0? ['allCharts', ...this.selData]: []
// 多参数图表
setMultipleChart: function (data) {
let vm = this
let selData = ApiUtils.pureData(vm.selData)
let product = ['product']
let source = []
let series = []
let chartData = {allCharts: {}}
data.forEach((item, idx) => {
let yData = [item.loanDate]
selData.forEach(pam => {
yData.push(item[pam])
if (idx === 0) {
let tit = ApiUtils.valueToText(pam, 'dict', 'BUSINESS_SUM_PAM')
product.push(tit)
series.push({type: 'bar'})
}
})
source.push(yData)
})
source.unshift(product)
let option = ApiUtils.pureData(vm.option2Tpl)
option.dataset.source = source
option.series = series
chartData['allCharts'].option = option
return chartData
},
// 单参数图标
setSingleChart: function (data) {
let vm = this
let chartData = {}
this.selData.forEach(pam => {
chartData[pam] = {}
let xData = []
let yData = []
data.forEach(item => {
if (item[pam]) {
yData.push(item[pam])
xData.push(item.loanDate)
}
})
chartData[pam].option = ApiUtils.pureData(vm.optionTpl)
let tit = ApiUtils.valueToText(pam, 'dict', 'BUSINESS_SUM_PAM')
chartData[pam].option.legend.data = [tit]
chartData[pam].option.xAxis.data = xData
chartData[pam].option.series = [{
name: tit,
type: 'bar',
data: yData
}]
})
return chartData
},
// 根据视口大小动态变化图表
resize() {
this.allSelPam.forEach(key => {
this.chartMap.get(key).resize()
})
},
// 初始化echarts
initChart: function (chartData) {
let vm = this
vm.chartMap.clear()
Object.keys(chartData).map((key) => {
let chart = document.getElementById(`dom_${key}`)
let myChart = echarts.init(chart)
vm.chartMap.set(key, myChart)
// 注意 setOption 参数中的 true 保证了图表能及时更新, 如果不使用true还可以使用
// myChart.clear() 每次都重新初始化图表,这和setOption中设置true效果一样,否则
// 数据更新了但是图表没有重绘
myChart.setOption(chartData[key].option, true)
})
tools.on(window, 'resize', vm.resize)
},
// 在ajax获取数据后初始化图表
let option = this.setSingleChart(data)
let option2 = this.setMultipleChart(data)
let chartOptions = Object.assign({}, option, option2)
this.initChart(chartOptions)
// 关闭图表resize
beforeDestroy() {
tools.off(window, 'resize', this.resize)
}工具方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38/**
* tools
* @description 绑定事件 on(element, event, handler)
*/
export const on = (function () {
if (document.addEventListener) {
return function (element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler)
}
}
}
})()
/**
* @description 解绑事件 off(element, event, handler)
*/
export const off = (function () {
if (document.removeEventListener) {
return function (element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler)
}
}
}
})()
备注
echartsInstance.setOption
设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过 setOption
完成,ECharts 会合并新的参数和数据,然后刷新图表。如果开启动画的话,ECharts 找到两组数据之间的差异然后通过合适的动画去表现数据的变化。
注: ECharts 2.x 中的通过 addData
, setSeries
方法设置配置项的方式将不再支持,在 ECharts 3 中统一使用 setOption
,可以参考上面示例。
参数:
option
图表的配置项和数据,具体见配置项手册。
notMerge
可选,是否不跟之前设置的
option
进行合并,默认为false
,即合并。lazyUpdate
可选,在设置完
option
后是否不立即更新图表,默认为false
,即立即更新。silent
可选,阻止调用
setOption
时抛出事件,默认为false
,即抛出事件。