创建个echartsComponent文件
<template>
<div :class="['chart', {'img-chart': hasImgBase64}]">
<div :id="uuid1" :class="['chart-show', {'img-chart-show': hasImgBase64}]"></div>
<div v-if="hasImgBase64" :id="uuid2" :style="{ height: imgHeight, width: imgWidth }" class="img-chart-export"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { mapGetters } from 'vuex'
const get_uuid = () => {
var s = [];
var hexDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
export default {
name: "echarts-component",
props: {
option: {
type: Object,
default: null,
},
hasImgBase64: {
type: Boolean,
default: false,
},
imgWidth: {
type: String,
default: '1200px',
},
imgHeight: {
type: String,
default: '900px',
},
},
data() {
return {
uuid1: null,
uuid2: null,
myChart: null,
imagesBase64: null,
};
},
computed: {
...mapGetters(['sidebar']),
},
created() {
this.uuid1 = get_uuid();
this.uuid2 = get_uuid();
},
watch: {
option: {
handler(val, oldVal) {
this.option && this.drawChart()
this.option && this.hasImgBase64 && this.drawChartImg()
},
immediate: true
},
'sidebar.opened': {
handler(newVal) {
this.debounce(this.chartResize, 300)
}
},
},
destroyed() {
window.removeEventListener('resize', this.debounce(this.chartResize, 500))
},
methods: {
chartResize() {
if (this.myChart) {
this.myChart.resize()
}
},
debounce(fn, wait) {
clearTimeout(this.timeout)
this.timeout = setTimeout(fn, wait)
},
drawChart() {
var dom = document.getElementById(this.uuid1)
if(dom) {
dom.removeAttribute('_echarts_instance_');
if (this.myChart != null && this.myChart != "" && this.myChart != undefined) {
this.myChart.dispose();
}
setTimeout(() => {
this.$nextTick(() => {
if(!this.hasImgBase64) {
this.myChart = echarts.init(dom, null, {renderer: 'svg'})
} else {
this.myChart = echarts.init(dom)
}
if(this.myChart) {
this.myChart.setOption(this.option, true)
window.addEventListener('resize', () => {
this.debounce(this.chartResize, 300)
})
}
})
}, 300)
}
},
drawChartImg() {
var dom2 = document.getElementById(this.uuid2)
if(dom2) {
dom2.removeAttribute('_echarts_instance_');
if (this.myImgChart != null && this.myImgChart != "" && this.myImgChart != undefined) {
this.myImgChart.dispose();
}
setTimeout(() => {
this.$nextTick(() => {
this.myImgChart = echarts.init(dom2)
if(this.myImgChart) {
const imgOption = {
...this.option,
animation: false
}
this.myImgChart.setOption(imgOption, true)
this.imagesBase64 = this.myImgChart.getDataURL()
this.$emit('getChartImg', this.imagesBase64)
}
})
}, 300)
}
},
sidebarChange(time) {
this.debounce(this.chartResize, time ?? 300)
},
}
};
</script>
<style scoped lang="scss">
.chart {
width:100%;
height:100%;
position:relative;
&-show {
position: absolute;
width: 100%;
height: 100%;
> div{
width: 100%;
height: 100%;
}
}
}
.img-chart {
overflow: hidden;
&-show {
background-color: #fff;
z-index: 2;
}
&-export {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
> div{
width: 1200px;
height: 800px;
}
}
}
</style>
在其他页面传入data即可调用
<echarts-component ref="homeRevenueCarChart" :option="option"></echarts-component>
{
option = val ? val : [
{ value: 0, name: '0~3公里' },
{ value: 0, name: '3~6公里' },
{ value: 0, name: '6~10公里' },
{ value: 0, name: '10~15公里' },
{ value: 0, name: '15~25公里' },
{ value: 0, name: '25~35公里' },
{ value: 0, name: '大于等于35公里' }
]
return {
tooltip: {
show:true,
trigger: 'item',
confine: true,
borderWidth: 0,
formatter: function(params){
let tip = '';
if(params.seriesIndex === 0){
tip = params.marker + params.name + ":" + params.percent + '%'
}else if(params.seriesIndex === 1){
tip = ''
}
return tip ;
}
},
legend: {
textStyle: {
padding:[fontSize(-8),0,0,0],
height: fontSize(36),
width: fontSize(64),
backgroundColor: 'transparent',
rich: {
name: {
fontSize: fontSize(12),
padding:[fontSize(4),0,0,0],
},
num: {
fontSize: fontSize(16),
fontWeight: 600,
color: '#333',
padding:[fontSize(-4),0,0,fontSize(-20)],
}
},
},
top: '50%',
left: 'center',
icon: 'rect',
itemHeight: fontSize(10),
itemWidth: fontSize(10),
formatter: function (name) {
const item = data.find(item => item.name === name)
const num = item.value
return [
`{num| ${num} %}`,
`{name| ${name}}`,
].join('\n')
}
},
graphic: {
elements: [
{
type: 'image',
style: {
image: require("../images/home_distance.png"),
width: fontSize(38),
height: fontSize(34),
},
left: '44.5%',
top: '24%'
}
]
},
color:['#165DFF', '#57E4F3', '#FF724B','#F6D449', '#FEAA38','#7F76FF','#E784FF'],
series: [
{
type: 'pie',
zlevel: 2,
radius: ['24%', '37%'],
avoidLabelOverlap: false,
center: ['50%', '30%'],
itemStyle: {
borderRadius: fontSize(8),
normal: {
shadowBlur: fontSize(6),
shadowColor: 'rgba(227, 228, 238, 0.1)'
}
},
label: {
show: false,
position: 'center'
},
data: data,
},
{
type: 'pie',
radius: ['21%', '40%'],
center: ['50%', '30%'],
itemStyle: {
normal: {
color: 'rgba(0,0,0,.06)',
label: {
show: false
},
labelLine: {
show: false
}
},
},
hoverAnimation: false,
data: [100],
}
]
}
}