VUE2中从后端数据到ECharts数据的完美实现小结
可以先看看前一篇随笔,主要是对后端数据如何转换成echarts数据的一些实现。
从后端通过axios返回的数据主要是对像数组。
ECharts中最适合的数据是数据集,也就是dataset
一、但是从后端返回的数据存在如下的问题,需要我们一个个解决:
1、后端返回数据的列过多,Echarts只使用其中的部分列
2、后端返回数据的列顺序与Echarts中用到的列顺序不一致,在转换时需要按指定的列顺序来生成数据
3、后端返回数据的列是动态生成的,也有些是行转列生成的,不能确定列名称,需要按原顺序生成列
4、后端返回数据的列是动态生成的,对于动态生成列的数据,需要过滤掉指定的一列或多列,其他的列保留
二、我们需要做的事情就是通过一个计算属性或方法来解决掉上面的几个问题,实现一个通用的转换功能。
参数一:后端返回的数据,如果绑定到前端,就是对像数组
参数二:按指定的列顺序生成数据,会过滤掉指定列之外的数据,列名之间用|号分隔,如果为空值,则第三个参数生效
参数三:第二个参数为空时生效,需要过滤掉的列,列名之间用|号分隔。
for(var key in item),key是个好东西,读出来就是键名称,正好做比较,不然还不知道怎么搞了。
indexOf(key),用于判断数组中是否包含某个值,不存在的话返回-1
this.mySeries.push({type:'bar'});主要是根据列的数量来动态生成Echarts中Series,第一列不算,所以最后pop出去一个
1 computed:{ 2 //对像转换成数据,供ECharts使用,如果FilterStr有内容,则按指定的顺序生成数据,如果没有,则按原始的顺序生成数据 3 dataText:function(){ 4 return function(obj,filterStr,delCol){ 5 var mainData=[]; 6 var f=[]; //需要保留的列 7 var d=[];//需要删除的列 8 if(filterStr.length>0){ 9 f=filterStr.split('|'); 10 } 11 if(delCol.length>0){ 12 d=delCol.split('|'); 13 } 33 34 //如果filterstr参数有内容,则使用指定的顺序来生成数据 35 this.mySeries=[]; 36 if(filterStr.length>0){ 37 mainData.push(f); //标题列 38 for(var i=0;i<f.length;i++){ 39 this.mySeries.push({type:'bar'}); 40 } 41 for (var i=0;i<obj.length;i++){ 42 var item=obj[i]; 43 var subitem=[]; 44 for(var j=0;j<f.length;j++){ 45 for(var key in item){ 46 if(f[j]==key){ 47 subitem.push(item[key]); 48 } 49 } 50 } 51 mainData.push(subitem) 52 } 53 }else{ 54 //如果参数没有内容,则按原顺序生成数据,并按第三个参数过滤掉不需要的列 55 var titleitem=[]; 56 for(var key in obj[0]){ 57 if(d.indexOf(key)===-1){ 58 titleitem.push(key); 59 this.mySeries.push({type:'bar'}); 60 } 61 62 } 63 mainData.push(titleitem);//标题列 64 65 for(var i=0;i<obj.length;i++){ 66 var item=obj[i]; 67 var subitem=[]; 68 for(var key in item){ 69 if(d.indexOf(key)===-1){ 70 subitem.push(item[key]); 71 } 72 73 } 74 mainData.push(subitem) 75 } 76 77 } 78 this.mySeries.pop(); 79 console.log(mainData); 80 return mainData; 81 } 82 83 }, 91 },
三、Echarts实现的部分
需要特别注意的是setOption的第二个参数,不设置数据不会清缓存,不能实现自动更新图表,你得自己写watch来检测数据更新,如果设置为true,那么Echarts就不保留缓存了,直接实现图表的更新。
1 <el-card shadow="always"> 2 <el-row type="flex" align="center"> 3 <el-col :span="24"> 4 <div id="myEchart" ref="myEchart" style="height:500px;width:100%">无法显示图表</div> 5 </el-col> 6 </el-row> 7 </el-card>
1 FenXiEcharts:function(obj,filter,delCol){ 2 let myChart = this.$echarts.init(this.$refs.myEchart) 3 // 绘制图表 4 myChart.setOption({ 5 legend: {}, 6 tooltip: {}, 7 dataset: { 8 // 提供一份数据。 9 source:this.dataText(obj,filter,delCol) 10 }, 11 xAxis: {type: 'category'}, 12 // 声明一个 Y 轴,数值轴。 13 yAxis: {}, 14 // 声明多个 bar 系列,默认情况下,每个系列会自动对应到 dataset 的每一列。 15 series: this.mySeries, 16 17 },true); 18 19 },
四、具体的使用。
1、生成的数据只包含name、总分、均分三个列,过滤掉了其他无用的列。
1 .then(res=>{ 2 if(res.Code===200){ 3 this.fenxiData=res.Data; 4 var filter='name|总分|均分'; 5 this.FenXiEcharts(res.Data,filter,'');
2、生成的数据中不包含评分人、被评分人列,列是动态生成的,列名是什么不确定
1 this.fenxiToNameData=res.Data; 2 this.FenXiEcharts(res.Data,'','评分人|被评分人'); 3 this.$message.success(res.Msg);
在具体的使用中,如果知道列名称,最好是按列名重新对数据排序一下,更符合你的使用;如果不知道列名称,那么可以过滤掉不需要的列,就算设置的列名称在数据中不存在,它也不会出错,有则过滤,没有则原样输出了。
使用中的效果图,只需要在不同的功能下调用同一个方法就行了,配置不同的参数实现不同的效果