可以先看看前一篇隨筆,主要是對后端數據如何轉換成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);
在具體的使用中,如果知道列名稱,最好是按列名重新對數據排序一下,更符合你的使用;如果不知道列名稱,那么可以過濾掉不需要的列,就算設置的列名稱在數據中不存在,它也不會出錯,有則過濾,沒有則原樣輸出了。
使用中的效果圖,只需要在不同的功能下調用同一個方法就行了,配置不同的參數實現不同的效果




