1.子组件html
<template>
<div :id="id" ref="chartRef" :style="{ height: '100%', width: '100%', }"></div>
</template>
2.子组件js
<script setup lang="ts">
/**
* id
* xAxisList,x轴数据
* seriesDataList,y轴数据
* legend,图例数据
* dateList,标签数据
* 这几个参数必须传
*
*/
import * as echarts from 'echarts';
import { onMounted, defineProps, ref, watch, nextTick } from 'vue'
const props = defineProps({
id: {
type: String,
default: 'barChart'
},
xAxisList: {
type: Object,
default: ['浙江1', '北京1', '上海1', '广东1', '深圳1'],
},
seriesDataList: {
type: Object,
default: [
[2000, 7100, 6200, 7300, 7400],
[8000, 8200, 8400, 8600, 8800],
[6000, 6500, 7000, 7500, 8000],
[7011, 7500, 8000, 8500, 9000],
]
},
legend: {
type: Object,
default: ['收入', '毛利润', '收入增长率', '利润增长率']
},
dateList: {
type: Object,
default: ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05']
},
units: {
type: String,
default: ''
},
charttype: {
type: String,
default: 'bar'
},
lastcharttype: {
type: String,
default: 'bar'
},
stack: {
type: Boolean,
default: false
},
dataZoom: {
type: Boolean,
default: false
},
max: {
type: [Number, String],
default: undefined,
},
// chartsData:{
// type:Object,
// default:{
// dateList:['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'],
// legend:['收入', '毛利润', '收入增长率', '利润增长率'],
// seriesDataList:[
// [2000, 7100, 6200, 7300, 7400],
// [8000, 8200, 8400, 8600, 8800],
// [6000, 6500, 7000, 7500, 8000],
// [7011, 7500, 8000, 8500, 9000],
// ],
// xAxisList:['浙江1', '北京1', '上海1', '广东1', '深圳1']
// },
// }
});
const chartRef = ref<any>('')
let echart = echarts
watch(
() => [props.seriesDataList, props.xAxisList, props.units + props.legend],
() => {
//解决警告 There is a chart instance already initialized on the dom.
// nextTick()
echart.dispose(document.getElementById(props.id) as HTMLDivElement)
initChart()
},
{ deep: true }
)
const colorArr = ['#02c7af', '#62D256', '#FFC550', '#FF8853', '#FF6B8E', '#BF7E7E', '#D177CB', '#9E86DF', '#6881FF', '#91A1B1', '#5EB2E9']
// let idElem:any=''
onMounted(() => {
initChart()
});
let Echarts: any = null
let initChart = () => {
// nextTick()
if (Echarts) {
Echarts.dispose()
}
Echarts = null
// if(!chartRef.vlaue) return false
Echarts = echarts.init(document.getElementById(props.id) as HTMLDivElement)
let options: any = {
title: {
show: props.seriesDataList.length > 0 ? false : true,
text: '暂无数据',
textStyle: {
color: '#888888'
},
// subtext: 'Fake Data',
left: 'center',
top: '50%'
},
grid: {
left: '2%',
right: '5%',
bottom: '4%',
containLabel: true,
},
tooltip: {
trigger: 'axis',
backgroundColor: "rgba(255,255,255, 0)",
padding: 0,
formatter: (param: any) => {
let tmp = ''
param.map((item: any) => {//
tmp += `
<span style="display: flex; align-items: center; margin: 0 0 0 0;">
${item.marker}
<span style="color: #333; margin: 0 30px 0 0;">${item.seriesName}</span>
<span style="color: #777777; font-weight: bold;">${item.value}</span>
</span>
`
})
return `
<div style="min-width: 167px; font-size: 14px; border-radius: 4px; box-shadow: 0 1px 5px #00000029; background-color: white; padding: 15px; font-size: 14px; display: flex; flex-direction: column; justify-content: space-between;">
<span style="color: #999999;">${props.dateList[param[0].dataIndex]}</span>`
+ tmp +
`</div>
`;
},
},
legend: {
x: 'center',
// y: 'top',
top: 10,
padding: [5, 5, 5, 40],
data: props.legend,
textStyle: {
color: '#999'
}
},
xAxis: [
{
type: 'category',
boundaryGap: props.charttype == 'line' ? false : true,
data: props.xAxisList,
splitLine: {
show: false,
lineStyle: {
color: "#dcdcdc",
width: 1,
type: "solid",
},
},
}
],
yAxis: [{
type: 'value',
name: props.units,
min: 0,
/* max:(value:any)=>{
return (props.max=='undefined'|| props.max==undefined)?undefined:props.max
}, */
splitLine: {
lineStyle: {
color: "#dcdcdc",
type: "solid",
},
},
}, {
show: false,
type: 'value',
name: props.units,
min: 0,
/* max:(value:any)=>{
return (props.max=='undefined'|| props.max==undefined)?undefined:props.max
}, */
splitLine: {
show: false,
lineStyle: {
color: "#dcdcdc",
type: "solid",
},
},
}],
dataZoom: props.dataZoom == true ? [
{
type: 'inside',
start: 0,
end: 10
},
{
start: 0,
end: 10
}
] : [],
series: props.seriesDataList.map((item: any, index: any) => {
return {
data: item,
type: (props.seriesDataList.length == index + 1) ? props.lastcharttype : props.charttype,
stack: props.stack ? 'die' : 'die' + index,//判断堆叠图lastcharttype
smooth: true,
yAxisIndex: (props.seriesDataList.length == index + 1 && props.lastcharttype == 'line' && props.seriesDataList.length > 1) ? 1 : 0,
name: props.legend[index],
color: colorArr[index],
}
})
};
Echarts.setOption(options)
const resizeObserver = new ResizeObserver((entries) => {
let elwidth = entries[0].contentRect.width
setTimeout(() => {
Echarts.resize({ width: elwidth, height: "auto" })
}, 300);
})
let idElem = document.getElementById(props.id) as HTMLDivElement
resizeObserver.observe(idElem);
}
</script>
3.引用
import BarChart from '@/components/barChart.vue'
<BarChart
v-if="xAxisList.length > 0"
id="barChartClass"
:xAxisList="xAxisList"
:seriesDataList="seriesDataListTemp"
:legend="legendTemp"
:dateList="dateList"
:stack="typeDataList != null ? true : false"
:charttype="'bar'"
:lastcharttype="'bar'"
:units="'元'"
>
</BarChart>