第一步:封装e-chart为组建
<template>
<div class="echarts"></div>
</template>
<style>
.echarts {
width: 600px;
height: 400px;
}
</style>
<script>
// copy from vue-echarts 2.4.0
// https://github.com/Justineo/vue-echarts
// 此项目使用图表的地方较多
// vue-echarts 使用比较麻烦,它引入的是未注册 echarts 组件的文件:
// import echarts from 'echarts/lib/echarts'
// 使用时需要单独引入所需 echarts 组件,即没有注册 echarts 组件
//
// copy 源码过来简单做下修改
// 把 echarts 资源引用修改为:
// import echarts from 'echarts'
// 引入的文件会注册 echarts 的所有组件
import Vue from 'vue'
import echarts from 'echarts'
import { debounce } from 'lodash'
// enumerating ECharts events for now
const ACTION_EVENTS = [
'legendselectchanged',
'legendselected',
'legendunselected',
'datazoom',
'datarangeselected',
'timelinechanged',
'timelineplaychanged',
'restore',
'dataviewchanged',
'magictypechanged',
'geoselectchanged',
'geoselected',
'geounselected',
'pieselectchanged',
'pieselected',
'pieunselected',
'mapselectchanged',
'mapselected',
'mapunselected',
'axisareaselected',
'brush',
'brushselected'
]
const MOUSE_EVENTS = [
'click',
'dblclick',
'mouseover',
'mouseout',
'mousedown',
'mouseup',
'globalout'
]
export default {
name: 'ECharts',
props: {
options: Object,
theme: String,
initOptions: Object,
group: String,
autoResize: Boolean,
clickFun: Function
},
data () {
return {
chart: null
}
},
computed: {
// Only recalculated when accessed from JavaScript.
// Won't update DOM on value change because getters
// don't depend on reactive values
width: {
cache: false,
get () {
return this._delegateGet('width', 'getWidth')
}
},
height: {
cache: false,
get () {
return this._delegateGet('height', 'getHeight')
}
},
isDisposed: {
cache: false,
get () {
return !!this._delegateGet('isDisposed', 'isDisposed')
}
},
computedOptions: {
cache: false,
get () {
return this._delegateGet('computedOptions', 'getOption')
}
}
},
watch: {
// use assign statements to tigger "options" and "group" setters
options: {
handler (options) {
if (!this.chart && options) {
this._initChart()
} else {
this.chart.setOption(this.options, true)
}
},
deep: true
},
group: {
handler (group) {
this.chart.group = group
}
}
},
methods: {
// provide a explicit merge option method
mergeOptions (options) {
this._delegateMethod('setOption', options)
},
// just delegates ECharts methods to Vue component
// use explicit params to reduce transpiled size for now
resize (options) {
this._delegateMethod('resize', options)
},
dispatchAction (payload) {
this._delegateMethod('dispatchAction', payload)
},
convertToPixel (finder, value) {
return this._delegateMethod('convertToPixel', finder, value)
},
convertFromPixel (finder, value) {
return this._delegateMethod('convertFromPixel', finder, value)
},
containPixel (finder, value) {
return this._delegateMethod('containPixel', finder, value)
},
showLoading (type, options) {
this._delegateMethod('showLoading', type, options)
},
hideLoading () {
this._delegateMethod('hideLoading')
},
getDataURL (options) {
return this._delegateMethod('getDataURL', options)
},
getConnectedDataURL (options) {
return this._delegateMethod('getConnectedDataURL', options)
},
clear () {
this._delegateMethod('clear')
},
dispose () {
this._delegateMethod('dispose')
},
_delegateMethod (name, ...args) {
if (!this.chart) {
Vue.util.warn(`Cannot call [${name}] before the chart is initialized. Set prop [options] first.`, this)
return
}
return this.chart[name](...args)
},
_delegateGet (name, method) {
if (!this.chart) {
Vue.util.warn(`Cannot get [${name}] before the chart is initialized. Set prop [options] first.`, this)
}
return this.chart[method]()
},
_initChart () {
if (this.chart) {
return
}
let chart = echarts.init(this.$el, this.theme, this.initOptions)
if (this.group) {
chart.group = this.group
}
chart.setOption(this.options, true)
// expose ECharts events as custom events
ACTION_EVENTS.forEach(event => {
chart.on(event, params => {
this.$emit(event, params)
})
})
MOUSE_EVENTS.forEach(event => {
chart.on(event, params => {
this.$emit(event, params)
// for backward compatibility, may remove in the future
this.$emit('chart' + event, params)
})
})
if (this.autoResize) {
this.__resizeHanlder = debounce(() => {
chart.resize()
}, 100, { leading: true })
window.addEventListener('resize', this.__resizeHanlder)
}
this.chart = chart
if(this.clickFun){
this.chart.on('click', this.clickFun);
}
}
},
mounted () {
// auto init if `options` is already provided
if (this.options) {
this._initChart()
}
},
beforeDestroy () {
if (!this.chart) {
return
}
if (this.autoResize) {
window.removeEventListener('resize', this.__resizeHanlder)
}
this.dispose()
},
connect (group) {
if (typeof group !== 'string') {
group = group.map(chart => chart.chart)
}
echarts.connect(group)
},
disconnect (group) {
echarts.disConnect(group)
},
registerMap (...args) {
echarts.registerMap(...args)
},
registerTheme (...args) {
echarts.registerTheme(...args)
}
}
</script>
二、引用组件使用
<template>
<div class="page__monthly-manage">
<header class="section-header">
<h5 class="section-title">计划统计分析</h5>
</header>
<div class="section-content">
<e-charts style="height:570px;width:100%;" :options="chartdata"></e-charts>
<!-- <div :option="myChart" :style="{width: '300px', height: '300px'}" ></div> -->
</div>
</div>
</template>
<script>
import { planChart } from '@/api/course';
import ECharts from '@/components/util/ECharts'
export default {
components:{
ECharts
},
data () {
return {
chartdata:{}
}
},
created () {
},
mounted(){
this.draw_chart()
},
methods: {
draw_chart(){
planChart().then(res =>{
var xAxis_data=[]
var yes_data=[]
var no_data=[]
if(res.success){
xAxis_data = res.data.map(item => item.department)
yes_data = res.data.map(item => item.yes)
no_data = res.data.map(item => item.no)
var chart = {
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
data:['完成','未完成']
},
tooltip: {
trigger: 'item',
formatter: '{b}<br/> {a}{c} (%)'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis : [
{
type : 'category',
data : xAxis_data
}
],
yAxis : [
{
type : 'value'
}
],
series : [
{
name:'未完成',
type:'bar',
data:no_data
},
{
name:'完成',
type:'bar',
// stack: '广告',
data:yes_data
}
]
}
this.chartdata = chart
}
})
}
}
}
</script>
<style scoped>
</style>