封装一个echarts子组件,父组件可以多次调用
封装一个柱形图。
柱形图和折线图的区别在于series数据中的type的类型不同,柱形图的type为bar,折线图的type为line,所以封装柱形图的和折线图是一样的,只是两者传入的参数不同
封装一个bar类型的echarts图
子组件:
<template>
<div>
<div
ref='barchart'
class='echartbox'
>
</div>
</div>
</template>
<script>
// 引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入柱状图组件
require('echarts/lib/chart/bar')
// 引入折线图组件
require('echarts/lib/chart/line')
// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
export default {
name: 'Bar',
props: {
textlink: {
type: String,
required: false,
default: ''
},
xname: {
type: String,
required: false,
default: ''
},
yname: {
type: String,
required: false,
default: ''
},
bardata: Object
},
data () {
return {
link: this.textlink,
title: '',
legend_data: [],
axis_data: [],
series_data: [],
x_name: this.xname,
y_name: this.yname
}
},
watch: {
bardata (val) {
this.title = val.title
this.legend_data = val.legend_data
this.axis_data = val.Axis_data
this.series_data = val.series
this.drawBar()
}
},
mounted () {
// this.drawBar()
},
methods: {
drawBar () {
let myCharts = echarts.init(this.$refs.barchart)
myCharts.setOption({
color: ['#83d0d5', '#f1cb48', '#188ae2', '#E8830B', '#7460ae', '#fc4b6c', '#31ce77', '#eae0bc', '#e732cb', '#9dce8a'],
title: {
text: this.title,
left: '35',
top: '20',
link: this.link,
textStyle: {
color: '#B6B6B6'
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '15%',
bottom: '30%'
},
legend: {
data: this.legend_data,
left: 'center',
bottom: '0',
textStyle: {
color: '#B6B6B6'
}
},
xAxis: [
{
type: 'category',
position: 'bottom',
name: this.x_name,
nameLocation: 'center',
nameGap: '50',
data: this.axis_data,
axisTick: {
show: false
},
axisLabel: {
textStyle: {
color: '#BFC2C8'
},
rotate: 30,
interval: 0
},
axisLine: {
lineStyle: {
color: '#BFC2C8'
}
}
}
],
yAxis: [
{
type: 'value',
left: '10',
name: this.y_name,
nameLocation: 'center',
nameGap: '45',
axisLine: {
lineStyle: {
color: '#BFC2C8'
}
},
axisTick: {
show: false
},
splitLine: {
lineStyle: {
color: '#898D95'
}
},
axisLabel: {
textStyle: {
color: '#BFC2C8'
},
interval: 0,
formatter: function (value, index) {
if (value >= 1000 && value < 10000000) {
value = value / 1000 + 'K'
} else if (value >= 1000000 && value < 1000000000) {
value = value / 1000000 + 'M'
} else if (value >= 1000000000) {
value = value / 1000000000 + 'B'
}
return value
}
}
}
],
series: this.series_data
})
window.addEventListener('resize', function () {
myCharts.resize()
})
}
}
}
</script>
父组件:
<bar
:textlink='barlink'
:xname='xname'
:yname='yname'
:bardata='bardata'
></bar>
注意点:
1.后台传过来的参数,柱形图通常包括,series,title,legend_data, axis_data四项数据,这四项数据通常来说不需要单个传给子组件,可以将其作为一个整体传递过来。上例为bardata,里面包含这四项数据,在子组件中解析使用
2.有一些图标可能有横纵坐标的值,或者title点击有跳转的路由,有的没有,这种非强制性的参数我们可以选择在子组件中不强制传参,并设置一个默认值(比如说默认不显示,跳转路由为空),这样的话就是个性化定制了,如果想要显示横纵坐标的名字或者title有跳转,就可以从父组件中传值,不传也不会报错。
3.关于图表的自适应问题,bar图和line图通常来说会数据比较多,所以需要做好自适应的问题,echarts中的resize()方法可以解决这个问题
window.addEventListener('resize', function () {
myCharts.resize()
4.最为重要的一点!父组件向子组件传递参数的时候,会在渲染的时候传参,也就是说此时Ajax的数据还未到,就传送完毕了,Ajax数据到了之后也不会再传递,如何解决这个问题?
有两种比较常用的方法,一是,给子组件设置一个v-if,默认是不显示的,等数据加载完成之后,再给它传值,将其设置为true可见,但是这种方法在数据多变的情况下还是不行,所以一般采用第二种方法。
第二,在子组件中监听我们接收到的来自父组件的参数,如果发生变化,就重新赋值给图表参数,并重新绘制图表
如此,一个柱形图(折线图便封装完成了)
附: 有一种堆叠的柱形图,也是控制于数据series中,我们从后获取了数据,对其添加堆叠柱形图需要有的属性即可
this.stackdata = pipelinehealth
for (let v of this.stackdata.series) {
this.$set(v, 'label', {
normal: {
show: true,
position: 'inside'
}
})
this.$set(v, 'stack', 'all')
}
我们获取数据之后,循环遍历series,往里面添加label对象和stack,要想堆叠,所有要堆叠的数据stack值必须一样,注意修改对象除了直接该引用,还有就是使用vm.$set()方法,这里的vm指向this实例
欧克,各种柱形图折线图,以及衍生搜可以通过这个组件实现了。