<!-- @/components/MultiYAxisLineChart.vue --> <template> <div ref="chartRef" :style="{ width: width, height: height }"></div> </template> <script setup> import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue' import * as echarts from 'echarts' // Props 定义 const props = defineProps({ // X 轴数据 xAxisData: { type: Array, required: true }, // 系列数据:[{ name, data, type, isTime , lineTyle // line bar}] series: { type: Array, required: true }, // 图表标题 title: { type: String, default: '' }, // 宽度 width: { type: String, default: '100%' }, // 高度 height: { type: String, default: '100%' }, icon: { type: String, default: 'circle' }, smooth: { type: Boolean, default: false }, colorData: { type: Array, default: ['#4895ef', '#eb4d4b', '#f0932b', '#36cbcb', '#9b59b6', '#00b894'] }, optionsObj: { type: Object, default: { interval: 30 } } }) const chartRef = ref(null) let chartInstance = null // 获取最近七天的日期 function getLastSevenDays() { const dates = [] for (let i = 6; i >= 0; i--) { const date = new Date() date.setDate(date.getDate() - i) dates.push(date.toISOString().split('T')[0]) } return dates } const generateOption = () => { const processedSeries = props.series.map((s) => { let displayData = [...s.data] let maxVal = 0 let minVal = 0 const validValues = s.data.filter((val) => val != null && !isNaN(val)) maxVal = Math.max(...validValues) || 100 minVal = Math.min(...validValues) || 0 return { ...s, displayData, maxVal, minVal } }) const getNiceMax = (val, step = 10) => { if (isNaN(val) || !isFinite(val)) return 100 return Math.ceil(val / step) * step } const yAxes = [] const series = [] processedSeries.forEach((s, index) => { const color = props.colorData[index % props.colorData.length] const isLeft = index % 2 === 0 const offset = Math.floor(index / 2) * 30 let yAxisConfig const niceMax = getNiceMax(s.maxVal, 10) yAxisConfig = { type: 'value', position: isLeft ? 'left' : 'right', axisLabel: { formatter: s.labelFunction ? s.labelFunction(s.data) : null, color }, nameTextStyle: { color }, splitLine: { show: false }, min: 0, max: 100 } yAxes.push(yAxisConfig) series.push({ name: s.name, type: s.lineType || 'line', data: s.displayData, yAxisIndex: index, showSymbol: true, symbolSize: 6, lineStyle: { width: 2.5 }, itemStyle: { color }, smooth: props.smooth }) if (yAxes.length === 0) { yAxes.push({ type: 'value', min: 0, max: 100, splitLine: { show: true, lineStyle: { type: 'dashed', opacity: 0.2 } }, axisLabel: { color: '#7a7b7c' } }) } }) return { title: { text: props.title, left: 'center', textStyle: { color: '#0d7ee7' } }, tooltip: { trigger: 'axis', formatter: (params) => { let result = `${params[0].name}<br/>` params.forEach((p) => { let valueDisplay = p.value if (valueDisplay == null) { valueDisplay = '-' } result += `${p.marker}${p.seriesName}: ${valueDisplay}<br/>` }) return result } }, legend: { data: props.series.map((s) => s.name), top: '0%', right: '8%', icon: props.icon, textStyle: { color: '#fff' } }, grid: { left: '8%', right: '8%', top: '20%', bottom: '20%', containLabel: true }, xAxis: { type: 'category', data: props.xAxisData.length > 0 ? props.xAxisData : getLastSevenDays(), axisLine: { lineStyle: { color: '#7a7b7c' } }, axisLabel: { color: '#7a7b7c' } }, yAxis: yAxes, series, alignTicks: true } } // 初始化图表 const initChart = () => { nextTick(() => { if (!chartRef.value) return // 销毁旧实例 if (chartInstance) { chartInstance.dispose() } chartInstance = echarts.init(chartRef.value) const option = generateOption() chartInstance.setOption(option) // 绑定 resize window.addEventListener('resize', handleResize) }) } // resize 处理 const handleResize = () => { chartInstance?.resize() } // 挂载时初始化 onMounted(() => { initChart() }) // 卸载前清理 onBeforeUnmount(() => { if (chartInstance) { chartInstance.dispose() chartInstance = null } window.removeEventListener('resize', handleResize) }) // 数据或属性变化时更新图表 watch( () => [props.xAxisData, props.series, props.title], () => { initChart() }, { deep: true } ) </script> <style scoped></style>
我改成这样了 还是报错