前言:
我们需要根据后端返回的数据来制作表格,但是往往并不是一组数据对应一个图,很可能需要将某个参数相同的两组或多组数据处理到一个图中,这里就需要处理数据并动态渲染图表。
例如:
后端返回数组包含四组数据,按理来说应该渲染四个图,但是业务要求将unit和type相同的图合为一张图,转成多个图例,我们就需要渲染三张图。
后端返回的数据格式:
data里面定义:
echartsData: [], //请求获取的数据
editableTabs: [], //处理的图表不同的数据
editableTabs1: [], //合并后的数据
options: [], //echarts的option合集
html中根据图表的数量动态渲染echarts图
<div class="echarts">
<a-empty v-if="editableTabs.length === 0" />
<div id="wh" v-for="item in editableTabs1" :key="item.id">
<div :style="{width: '88%', height: '360px', margin: '10px'}" :id="item.id" :ref="item.id">
{{ item.title }}
</div>
</div>
</div>
请求图表数据
getEchartsData() {
// 请求获得图表数据
this.$api
.get('/pointInspectionDetail/statDetail', {
params: {
deviceCode: this.deviceCode,
startTime: this.startDate + this.hourStart,
endTime: this.endDate + this.hourEnd
}
})
.then(res => {
this.echartsData = res.data.data;
})
.then(val => this.drawLine());
},
处理图表数据
drawLine() {
// 遍历整理信息
this.editableTabs = [];
this.echartsData.forEach((item, key) => {
let obj = {
title: this.getName(this.pointMetrologyList, item.type), //图表名字
id: 'chart' + key, //图表id
chart: null, //用来存储图表实例
name: [item.name], //图例
unit: item.unit, //图表单位
type: item.type, //图表类型
value: [item.value] //图表数据
};
this.editableTabs.push(obj);
});
// console.log(this.editableTabs, 'editableTabs');
// type与unit相同的合并,原理同数组去重
function fn1(tempArr) {
for (let i = 0; i < tempArr.length; i++) {
for (let j = i + 1; j < tempArr.length; j++) {
if (tempArr[i].unit === tempArr[j].unit && tempArr[i].type === tempArr[j].type) {
tempArr[i].name.push(tempArr[j].name[0]);
tempArr[i].value.push(tempArr[j].value[0]);
tempArr.splice(j, 1);
j--;
}
}
}
return tempArr;
}
// console.log(fn1(this.editableTabs), 'chuli');
this.editableTabs1 = fn1(this.editableTabs);
this.chartInit();
this.createLineChart(this.editableTabs1);
},
分配初始化表格
chartInit() {
this.$nextTick(() => {
for (let it in this.editableTabs1) {
this.editableTabs1[it].chart = this.$echarts.init(document.getElementById(this.editableTabs1[it].id));
}
});
},
创建图表数据 数据处理完成之后,将携带数据的data传递给渲染图表的方法
createLineChart(data) {
this.options = [];
// 封装处理value数组横轴按时间排序并对应纵轴数据
let dealWith = eachValue => {
let dataDe = []; //键值对一条数据,echarts多条数据的话可以用键值对的方式,他会自动对应x轴的。
let dataSort = [];
for (const key in eachValue) {
dataSort.push({
time: key,
number: eachValue[key]
});
}
dataSort.sort(function (prev, next) {
//处理日期排序
let date1 = new Date(prev.time);
let date2 = new Date(next.time);
return date1 - date2;
});
dataSort.forEach(item => {
dataDe.push([item.time, item.number]);
});
return {
dataDe
};
};
data.forEach(item => {
let dataSeries = [];
item.value.forEach(item1 => {
dataSeries.push(dealWith(item1));
});
// console.log(dataSeries,'dataSeries');
// legend
let legend = [];
item.name.forEach(item1 => {
legend.push(item1);
});
// x轴,取数据中最长的作为X轴
let xAxis = [];
function findLongestArray(obj) {
let longestArray = [];
for (let key in obj) {
if (Array.isArray(obj[key].dataDe)) {
if (obj[key].dataDe.length > longestArray.length) {
longestArray = obj[key].dataDe;
}
}
}
return longestArray;
}
let tempAxis = findLongestArray(dataSeries);
tempAxis.forEach(item1 => {
xAxis.push(item1[0]);
});
// series
let series = [];
item.name.forEach((item1, key) => {
let obj = {
name: item1,
type: 'line',
data: dataSeries[key].dataDe
};
series.push(obj);
});
//设置option
let option = {
title: {
text: item.title
},
tooltip: {
trigger: 'axis'
},
legend: {
data: legend,
top: '36',
left: '220'
},
grid: {
left: '5%',
right: '4%',
bottom: '3%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
axisLabel: {
rotate: 60
},
data: xAxis
},
yAxis: {
type: 'value',
name: '单位 : ' + item.unit,
nameTextStyle: {
fontSize: 14
},
axisLine: {
show: true
}
},
series: series
};
this.options.push(option);
});
this.$nextTick(() => {
this.editableTabs1.forEach((item, key) => {
//对对应标签的echarts实例执行setOption()
item.chart.setOption(this.options[key], true);
});
});
}
这样就可以了。
效果如图:
比较笨的方法,欢迎大家提建议。