<template>
|
<div>
|
<div :id="id" ref="chartEl" class="echart_size" :style="`height:${config.height};width:${config.width}`"></div>
|
</div>
|
</template>
|
<script>
|
import * as echarts from 'echarts'
|
import { iuCharts } from '@/utils/echarts'
|
import defaultSettings from '@/settings'
|
|
export default {
|
props: {
|
id: {
|
type: String,
|
default: ''
|
},
|
config: {
|
type: Object,
|
default: () => ({})
|
},
|
datas: {
|
type: Object,
|
default: () => ({})
|
}
|
},
|
data() {
|
return {
|
chart: null
|
}
|
},
|
watch: {
|
/* 如果图表数据是后台获取的,监听父组件中的数据变化,重新触发Echarts */
|
datas: {
|
deep: true,
|
handler() {
|
this.$nextTick(() => {
|
this.init()
|
})
|
}
|
}
|
},
|
mounted() {
|
this.init()
|
window.addEventListener('resize', this.windowResizeListener)
|
this.chartEleResizeListener()
|
},
|
beforeUnmount() {
|
window.removeEventListener('resize', this.windowResizeListener)
|
if (this.resizeObserver) {
|
this.resizeObserver.disconnect()
|
this.resizeObserver = null
|
}
|
if (!this.chart) {
|
return
|
}
|
this.chart.dispose()
|
this.chart = null
|
},
|
methods: {
|
init() {
|
// 原实现用 document.getElementById(this.id) 取容器,而调用方写的是 id="'page-left'"
|
// (静态属性,值里连引号一起带上了),查不到节点,echarts.init(null) 直接抛错,
|
// 图表其实从未渲染过。这里改用组件自身的 ref,与 id 传什么无关;
|
// :id 仍然保留,供外部样式选择。
|
if (!this.$refs.chartEl) return
|
this.chart = echarts.init(this.$refs.chartEl)
|
this.chart.showLoading({
|
text: 'loading',
|
// ECharts 画在 canvas 上,解析不了 CSS 变量,只能取配置里的主色字面量
|
color: defaultSettings.theme,
|
textColor: '#000',
|
maskColor: 'rgba(255, 255, 255, 0.2)',
|
zlevel: 0
|
})
|
if (this.config.isLoading) {
|
this.chart.hideLoading()
|
switch (this.config.type) {
|
case 'bar':
|
iuCharts.drawBar(this.chart, this.datas)
|
break
|
case 'line':
|
iuCharts.drawLine(this.chart, this.datas)
|
break
|
case 'pie':
|
iuCharts.drawPie(this.chart, this.datas)
|
break
|
case 'gauge':
|
iuCharts.drawGauge(this.chart, this.datas)
|
break
|
case 'pie0':
|
iuCharts.drawPie0(this.chart, this.datas)
|
break
|
default:
|
break
|
}
|
setTimeout(() => {
|
this.chart?.resize()
|
}, 200)
|
}
|
},
|
/* 对chart元素尺寸进行监听,当发生变化时同步更新echart视图 */
|
chartEleResizeListener() {
|
// element-resize-detector 不再依赖,改用浏览器原生 ResizeObserver
|
if (typeof ResizeObserver === 'undefined') return
|
this.resizeObserver = new ResizeObserver(() => {
|
if (!this.chart) return
|
this.chart.resize()
|
})
|
this.resizeObserver.observe(this.$el)
|
},
|
/* 当窗口缩放时,echart动态调整自身大小 */
|
windowResizeListener() {
|
if (!this.chart) return
|
this.chart.resize()
|
}
|
}
|
}
|
</script>
|
<style scoped>
|
.echart_size {
|
width: 100%;
|
height: 100%;
|
}
|
</style>
|