在开发过程中,我发现项目的很多地方会用到echarts图,因为如果每个echarts单独写的话,感觉很麻烦,所以我就直接使用组件的形式,把一个echarts用组件的形式封装起来,然后里面的数据就由父组件传值进去,子组件(即这个echarts组件)接收,但是在开发过程中,我遇到了一个问题,就是多图的时候,我使用遍历数组的形式,然后传id给echarts组件,发现组件里面的resize()其他三个图无效,只有最后一个生效,这个问题困扰了我很久,上网查资料找答案,发现网上的答案,都是使用把多图的每个id拿出来初始化,然后每个id进行resize(),这样确实有效果,但是问题是我是遍历的,而不是每个图都是独立的,都是由id传进来,所以我自己想了一个方法,就是定义一个数组,然后把这个初始化的echarts的实例push进这个数组去,最后要进行resize()的时候,对这个数组进行遍历,然后每个进行resize()即可。
代码如下:
这个是组件的代码,命名为chart.vue
<template> <div :id="id" :style="{ height: height, width: width }" /> </template> <script> import * as echarts from 'echarts'; require('echarts/theme/macarons'); // echarts theme import { debounce } from '@/utils/tools'; let chart = null; export default { // mixins: [resize], props: { width: { type: String, default: '100%', }, height: { type: String, default: '460px', }, // 线性图的id id: { type: String, default: '', }, // 里面内容 dataLegend: { type: Array, default: () => [], }, // 横坐标内容 dataListChart: { type: Array, default: () => [], }, // 线形图里面的数据 seriesDataChart: { type: Array, default: () => [], }, // 悬浮框 tooltip: { type: Object, default: () => {}, }, }, data() { return { // chart: null, $_sidebarElm: null, $_resizeHandler: null, echartsAll: [], }; }, mounted() { this.$_resizeHandler = debounce(() => { if (chart) { // console.log('this.echartsAll',this.echartsAll); // console.log('chart',chart); for (let i = 0; i < this.echartsAll.length; i++) { this.echartsAll[i].resize(); } // chart.resize(); } }, 100); this.$_initResizeEvent(); this.$_initSidebarResizeEvent(); this.$nextTick(() => { setTimeout(this.initChart, 300); }); }, activated() { this.$_initResizeEvent(); this.$_initSidebarResizeEvent(); }, deactivated() { this.$_destroyResizeEvent(); this.$_destroySidebarResizeEvent(); }, beforeUnmount() { this.$_destroyResizeEvent(); this.$_destroySidebarResizeEvent(); if (!chart) { return; } chart.dispose(); chart = null; }, computed: {}, methods: { initChart() { // chart = echarts.init(this.$el, 'macarons'); // if (chart != null && chart != '' && chart != undefined) { // chart.dispose(); //销毁 // } chart = echarts.init(document.getElementById(this.id)); this.echartsAll.push(chart); // this.$store.state.user.echartsAll.push(chart); chart.setOption( { // title: { // text: 'Stacked Area Chart', // }, tooltip: this.tooltip, legend: { data: this.dataLegend, // data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'], }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true, }, xAxis: [ { type: 'category', boundaryGap: false, // 横坐标内容 data: this.dataListChart, }, ], yAxis: [ { type: 'value', }, ], series: this.seriesDataChart, }, true ); }, $_initResizeEvent() { window.addEventListener('resize', this.$_resizeHandler); }, $_destroyResizeEvent() { window.removeEventListener('resize', this.$_resizeHandler); }, $_sidebarResizeHandler(e) { if (e.propertyName === 'width') { this.$_resizeHandler(); } }, $_initSidebarResizeEvent() { this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]; this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler); }, $_destroySidebarResizeEvent() { this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler); }, }, }; </script>
复制
然后是父组件代码,也就是引用以上的组件的代码:
<template> <div class="dashboard"> <el-row :gutter="30"> <el-col :span="12" v-for="(item, index) in testReportList" :key="index"> <div class="item"> <div class="b"> <FootPanelGroupVue :report="item.report"></FootPanelGroupVue> <div v-for="(item2, indey) in item.charts" :key="indey"> <AreaChartVue :id="item.id" :dataLegend="dataLegend" :seriesDataChart="item2.seriesDataChart" :dataListChart="item2.dataListChart" :tooltip="item2.tooltip" ></AreaChartVue> </div> <div class="report-title">{{ item.title }}</div> </div> </div> </el-col> </el-row> </div> </template> <script> import FootPanelGroupVue from '@/views/dashboard/components/FootPanelGroup.vue'; import AreaChartVue from '@/components/AreaChart/chart.vue'; import { getGeneral, getReportChart } from '@/api'; export default { name: 'Dashboard', components: { BasePage, BarChart, CountTo, PanelGroup, TestParamTable, TestReportTable, TestFailTable, TestFailRateTable, FootPanelGroupVue, AreaChartVue, }, data() { return { typeList: [], typeTextList: [], levelList: [], levelTextList: [], statOrg: {}, statStaff: {}, // statOrgCert: { innerLevel1: [], innerLevel2: [], outerLevel1: [], outerLevel2: [] }, innerLevel1: [], innerLevel2: [], outerLevel1: [], outerLevel2: [], statSigner: {}, xText: [], flag: false, dataList: ['岩土工程类', '混凝土工程类', '金属结构类', '机械电气类', '量测类'], dataLegend: ['合格报告数', '不合格报告数', '其他报告数量'], seriesList: [], // 柱状图的数据 // 悬浮窗 tooltip: {}, // 堆叠图的数据 seriesDataConstruction: [], // 施工方 seriesDataParallel: [], // 平行检 seriesDataThird: [], // 第三方检 seriesDataSupervise: [], // 监督检 // 堆叠图的横坐标内容 dataListConstruction: [], // 施工方 dataListParallel: [], // 平行检 dataListThird: [], // 第三方检 dataListSupervise: [], // 监督检 // 堆叠图的纵坐标数据内容 // 施工方 dataConstructionReportYaxis: [], dataConstructionPassYaxis: [], dataConstructionFailYaxis: [], dataConstructionOtherYaxis: [], // 平行检 dataParallelReportYaxis: [], dataParallelPassYaxis: [], dataParallelFailYaxis: [], dataParallelOtherYaxis: [], // 第三方检 dataThirdReportYaxis: [], dataThirdPassYaxis: [], dataThirdFailYaxis: [], dataThirdOtherYaxis: [], // 监督检 dataSuperviseReportYaxis: [], dataSupervisePassYaxis: [], dataSuperviseFailYaxis: [], dataSuperviseOtherYaxis: [], // 概览 headDataList: [], activeName: 'testParam', // 四张堆叠图数据 testReportList: [], // 堆叠图数据 dataResult: [], }; }, methods: { // 获取报告图标数据 async getReportChartData() { const res = await getReportChart.fn({}); // console.log('获取报告图标数据是', res); if (res.code == 0) { this.dataResult = res.data; this.getChartData(); } else { this.$message.warning(res.message); } }, // 获取报告数量 getReportChart() { // 施工方 this.seriesDataConstruction = [ { name: '合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataConstructionPassYaxis, }, { name: '不合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataConstructionFailYaxis, }, { name: '其他报告数量', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataConstructionOtherYaxis, }, ]; // 平行检 this.seriesDataParallel = [ { name: '合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataParallelPassYaxis, }, { name: '不合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataParallelFailYaxis, }, { name: '其他报告数量', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataParallelOtherYaxis, }, ]; // 第三方检 this.seriesDataThird = [ { name: '合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataThirdPassYaxis, }, { name: '不合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataThirdFailYaxis, }, { name: '其他报告数量', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataThirdOtherYaxis, }, ]; // 监督检 this.seriesDataSupervise = [ { name: '合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataSupervisePassYaxis, }, { name: '不合格报告数', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataSuperviseFailYaxis, }, { name: '其他报告数量', type: 'line', stack: 'Total', areaStyle: {}, emphasis: { focus: 'series', }, data: this.dataSuperviseOtherYaxis, }, ]; this.tooltip = { trigger: 'axis', // axisPointer: { // type: 'cross', // label: { // backgroundColor: '#6a7985', // }, // }, formatter: function (params, ticket, callback) { let htmlStr = ''; let counts = 0; let xName = ''; for (let i = 0; i < params.length; i++) { let param = params[i].data; xName = params[i].name; counts = Number(param) + counts; } htmlStr += '<div style="font-size:14px; color: #666; font-weight: 400; line-height: 1; margin:5px 0px;">'; htmlStr += xName; htmlStr += '</div>'; htmlStr += '<div>'; htmlStr += '<span style="margin-right:5px;display:inline-block;width:10px;height:10px;border-radius:10px;background-color:violet;"></span>'; htmlStr += '<span style="font-size:14px; color:#666; font-weight:400; margin-left:2px">报告总数量:</span><span style="float:right; text-align:right; margin-left:20px; font-size: 14px; color: #666; font-weight:900">' + counts + ' 个</span>'; htmlStr += '<div style="clear: both;"></div>'; htmlStr += '</div>'; for (let i = 0; i < params.length; i++) { // console.log('总的数据是', params[i]); let param = params[i].data; let seriesName = params[i].seriesName; let value = param; //y轴值 let color = params[i].color; htmlStr += '<div>'; htmlStr += '<span style="margin-right:5px;display:inline-block;width:10px;height:10px;border-radius:10px;background-color:' + color + ';"></span>'; htmlStr += '<span style="font-size:14px; color:#666; font-weight:400; margin-left:2px">' + seriesName + ':</span>' + '<span style="float:right; margin-left:20px; font-size: 14px; color: #666; font-weight:900">' + value + ' 个</span>'; htmlStr += '<div style="clear: both;"></div>'; htmlStr += '</div>'; } return htmlStr; }, }; }, getChartList() { return [ { report: [ { reportTitle: '报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格率', reportNum: '0', }, ], title: '施工方自检情况', id: 'main', charts: [ { seriesDataChart: this.seriesDataConstruction, dataListChart: this.dataListConstruction, tooltip: this.tooltip, }, ], }, { report: [ { reportTitle: '报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格率', reportNum: '0', }, ], title: '平行检情况', id: 'second', charts: [ { seriesDataChart: this.seriesDataParallel, dataListChart: this.dataListParallel, tooltip: this.tooltip, }, ], }, { report: [ { reportTitle: '报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格率', reportNum: '0', }, ], title: '第三方检情况', id: 'three', charts: [ { seriesDataChart: this.seriesDataThird, dataListChart: this.dataListThird, tooltip: this.tooltip, }, ], }, { report: [ { reportTitle: '报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格报告数量', reportNum: 0, addNum: 0, }, { reportTitle: '不合格率', reportNum: '0', }, ], title: '监督检情况', id: 'four', charts: [ { // dataLegend: ['合格报告数', '不合格报告数', '其他报告数量'], seriesDataChart: this.seriesDataSupervise, dataListChart: this.dataListSupervise, tooltip: this.tooltip, }, ], }, ]; }, // 堆叠图数据整理 getChartData() { this.dataResult.forEach((item) => { // console.log('数据item是', item); if (item.testingType == 0) { let testReportCount = ''; let testReportFailCount = ''; let testReportOtherCount = ''; let testReportPassCount = ''; let failRate = ''; // 遍历返回的数据 item.statistical.chartData.forEach((itemChart) => { testReportCount = Number(itemChart.testReportCount) + Number(testReportCount); testReportFailCount = Number(itemChart.testReportFailCount) + Number(testReportFailCount); testReportPassCount = Number(itemChart.testReportPassCount) + Number(testReportPassCount); testReportOtherCount = Number(itemChart.testReportOtherCount) + Number(testReportOtherCount); itemChart.month = itemChart.month.substring(0, 7); this.dataListConstruction.push(itemChart.month); this.dataConstructionPassYaxis.push(testReportPassCount); this.dataConstructionFailYaxis.push(testReportFailCount); this.dataConstructionOtherYaxis.push(testReportOtherCount); }); // 把服务器组装完之后的数据放到自己的数组中 this.testReportList.forEach((itemList) => { if (itemList.title == '施工方自检情况') { itemList.report.forEach((itemReport) => { if (itemReport.reportTitle == '报告数量') { itemReport.addNum = item.statistical.testReportRecentCount; itemReport.reportNum = testReportCount; } else if (itemReport.reportTitle == '不合格报告数量') { itemReport.addNum = item.statistical.testReportRecentFailCount; itemReport.reportNum = testReportFailCount; } else if (itemReport.reportTitle == '不合格率') { if (testReportCount == 0 || testReportFailCount == 0) { itemReport.reportNum = 0; } else { failRate = ((testReportFailCount / testReportCount) * 100).toFixed(1); itemReport.reportNum = failRate + '%'; } } }); } }); } else if (item.testingType == 1) { let testReportCount = ''; let testReportFailCount = ''; let failRate = ''; let testReportOtherCount = ''; let testReportPassCount = ''; // 遍历返回的数据 item.statistical.chartData.forEach((itemChart) => { testReportCount = Number(itemChart.testReportCount) + Number(testReportCount); testReportFailCount = Number(itemChart.testReportFailCount) + Number(testReportFailCount); testReportPassCount = Number(itemChart.testReportPassCount) + Number(testReportPassCount); testReportOtherCount = Number(itemChart.testReportOtherCount) + Number(testReportOtherCount); itemChart.month = itemChart.month.substring(0, 7); this.dataListParallel.push(itemChart.month); this.dataParallelPassYaxis.push(testReportPassCount); this.dataParallelFailYaxis.push(testReportFailCount); this.dataParallelOtherYaxis.push(testReportOtherCount); }); // 把服务器组装完之后的数据放到自己的数组中 this.testReportList.forEach((itemList) => { if (itemList.title == '平行检情况') { itemList.report.forEach((itemReport) => { if (itemReport.reportTitle == '报告数量') { itemReport.addNum = item.statistical.testReportRecentCount; itemReport.reportNum = testReportCount; } else if (itemReport.reportTitle == '不合格报告数量') { itemReport.addNum = item.statistical.testReportRecentFailCount; itemReport.reportNum = testReportFailCount; } else if (itemReport.reportTitle == '不合格率') { if (testReportCount == 0 || testReportFailCount == 0) { itemReport.reportNum = 0; } else { failRate = ((testReportFailCount / testReportCount) * 100).toFixed(1); itemReport.reportNum = failRate + '%'; } } }); } }); } else if (item.testingType == 3) { let testReportCount = ''; let testReportFailCount = ''; let failRate = ''; let testReportOtherCount = ''; let testReportPassCount = ''; // 遍历返回的数据 item.statistical.chartData.forEach((itemChart) => { testReportCount = Number(itemChart.testReportCount) + Number(testReportCount); testReportFailCount = Number(itemChart.testReportFailCount) + Number(testReportFailCount); testReportPassCount = Number(itemChart.testReportPassCount) + Number(testReportPassCount); testReportOtherCount = Number(itemChart.testReportOtherCount) + Number(testReportOtherCount); itemChart.month = itemChart.month.substring(0, 7); this.dataListThird.push(itemChart.month); this.dataThirdPassYaxis.push(testReportPassCount); this.dataThirdFailYaxis.push(testReportFailCount); this.dataThirdOtherYaxis.push(testReportOtherCount); }); // 把服务器组装完之后的数据放到自己的数组中 this.testReportList.forEach((itemList) => { if (itemList.title == '第三方检情况') { itemList.report.forEach((itemReport) => { if (itemReport.reportTitle == '报告数量') { itemReport.addNum = item.statistical.testReportRecentCount; itemReport.reportNum = testReportCount; } else if (itemReport.reportTitle == '不合格报告数量') { itemReport.addNum = item.statistical.testReportRecentFailCount; itemReport.reportNum = testReportFailCount; } else if (itemReport.reportTitle == '不合格率') { if (testReportCount == 0 || testReportFailCount == 0) { itemReport.reportNum = 0; } else { failRate = ((testReportFailCount / testReportCount) * 100).toFixed(1); itemReport.reportNum = failRate + '%'; } } }); } }); } else if (item.testingType == 4) { let testReportCount = ''; let testReportFailCount = ''; let failRate = ''; let testReportOtherCount = ''; let testReportPassCount = ''; // 遍历返回的数据 item.statistical.chartData.forEach((itemChart) => { testReportCount = Number(itemChart.testReportCount) + Number(testReportCount); testReportFailCount = Number(itemChart.testReportFailCount) + Number(testReportFailCount); testReportPassCount = Number(itemChart.testReportPassCount) + Number(testReportPassCount); testReportOtherCount = Number(itemChart.testReportOtherCount) + Number(testReportOtherCount); itemChart.month = itemChart.month.substring(0, 7); this.dataListSupervise.push(itemChart.month); this.dataSupervisePassYaxis.push(testReportPassCount); this.dataSuperviseFailYaxis.push(testReportFailCount); this.dataSuperviseOtherYaxis.push(testReportOtherCount); }); // 把服务器组装完之后的数据放到自己的数组中 this.testReportList.forEach((itemList) => { if (itemList.title == '监督检情况') { itemList.report.forEach((itemReport) => { if (itemReport.reportTitle == '报告数量') { itemReport.addNum = item.statistical.testReportRecentCount; itemReport.reportNum = testReportCount; } else if (itemReport.reportTitle == '不合格报告数量') { itemReport.addNum = item.statistical.testReportRecentFailCount; itemReport.reportNum = testReportFailCount; } else if (itemReport.reportTitle == '不合格率') { if (testReportCount == 0 || testReportFailCount == 0) { itemReport.reportNum = 0; } else { failRate = ((testReportFailCount / testReportCount) * 100).toFixed(1); itemReport.reportNum = failRate + '%'; } } }); } }); } }); }, }, mounted() { // 父组件自适应 // let echarts = this.$store.state.user.echartsAll; // window.onresize = function () { // for (let i = 0; i < echarts.length; i++) { // echarts[i].resize(); // } // }; // setTimeout(this.fetchData, 3000); // 概览数据 this.headDataList = this.getGeneralListData(); this.getGeneralData(); // 检测机构资质 this.fetchData(); this.getReportChartData(); // 堆叠图数据 this.getReportChart(); this.testReportList = this.getChartList(); }, }; </script>
复制
以上就是差不多的整体代码,有点多,但是其中最重要的还是在组件chart.vue中的几行代码,在data中定义数组echartsAll: [],
data() { return { echartsAll: [], }; },
复制
然后再初始化chart中,
chart = echarts.init(document.getElementById(this.id)); this.echartsAll.push(chart);
复制
最后在mounted中遍历这个数组,然后进行resize()才有效
import { debounce } from '@/utils/tools'; menthods:{ $_initResizeEvent() { window.addEventListener('resize', this.$_resizeHandler); }, }, mounted(){ this.$_resizeHandler = debounce(() => { if (chart) { // console.log('this.echartsAll',this.echartsAll); // console.log('chart',chart); for (let i = 0; i < this.echartsAll.length; i++) { this.echartsAll[i].resize(); } // chart.resize(); } }, 100); }
复制
在其中有两行console.log()代码打印出来,你会发现第一个打印出来的每个chart的id都是不一样的,而第二个打印出来的id都是一样的,而且都是最后一个chart图的id,这也就是为什么是最后一图生效,而其他图不生效的原因所在。
以上就是我关于resize()在遍历中只有最后一张图的自适应生效的理解和解决办法,如果大佬有更好的解决办法,欢迎大佬的建议和评价,谢谢大佬们的阅读。