1. 程式人生 > >如何實現echarts組織結構圖節點的收縮

如何實現echarts組織結構圖節點的收縮

點名 3.0 不讓 信息 修改 conf strong 值引用 option

echarts本身沒有組織結構圖的節點收縮功能,因為項目需求要用到此功能。

引入的echarts必須是2版本的,因為3.0取消了對組織結構圖的支持。下載2版本的源碼,找到關於onclick事件那部分的代碼,修改如下:

_onclick: function (param) {
            callChartListMethodReverse(this, ‘onclick‘, param);
            if (param.target) {
                var ecData = this._eventPackage(param.target);
                
var option = this.getOption(); var myChart = this; if (ecData && ecData.seriesIndex != null) { this._messageCenter.dispatch(ecConfig.EVENT.CLICK, param.event, ecData, this); debugger; //實現tree點擊收縮 a(ecData, option, myChart); } } }

建一個新文件node_contraction.js,添加如下代碼:

/**
 * menglinanke
 * 2017-06-12
 * 註釋只寫了第一層,裏面幾層均相同
 * 此js的前提是數據中name必須唯一,因為是根據name加以判斷的。
 * 目前只實現到第六層(包括root),可擴充
 * 下面所有註釋的代碼供調試使用
 * 未使用遞歸,是因為本人覺得使用遞歸在操作(增刪)data數據的時候,會出現問題(未測)
 * 如有大神有其他簡單辦法,希望告訴我一下。
 * 
 */
var clickMap={};//用來存儲子節點(供收縮,打開節點使用)
//點擊時 調用
function a(ecData, option, myChart){
    
debugger; var _name = ecData.name;//當前點擊節點的名稱 if(_posarr){ var _posarr=null; } var _posarr_=_posarr;//所有老節點的信息{[name,x,y],[name,x,y]..}//貌似沒啥用 // for(var iii= 0 ; iii<_posarr_.length;iii++){ // alert(_posarr_[iii]); // } var isChild=ecData.data.children;//是否存在子節點 //alert(!(!isChild)); var _option=option; var len1=_option.series[0].data.length; var d1=_option.series[0].data;//所有的d*在下面代碼中均為使用到。 var f=false;//是否找到對應節點【循環所有數據,查找到 be clicked node 在option中的位置】//----f=true.跳出所有循環 //循環clickMap中所有的節點信息 //for(var prop in clickMap){ // if(clickMap.hasOwnProperty(prop)){ // alert(prop+‘-‘+clickMap[prop]); // } //} //開始循環_option中的信息,用來查找當前點擊的節點 for(var j=0;j<len1;j++){ //alert(‘d1[j].name=‘+d1[j].name); //第一個節點不讓關閉(收起) if(_option.series[0].data[j].name==_name){ alert(‘can\‘t be closed.‘); break; } //alert(d1[j].children); if(_option.series[0].data[j].children){//若存在子節點 var len2=_option.series[0].data[j].children.length; var d2=_option.series[0].data[j].children; for(var k=0;k<len2;k++){ //alert(‘j:‘+j+‘--k:‘+k+‘-‘+d2[k].name); //根據name判斷節點是否是當前所點擊的節點, if(_option.series[0].data[j].children[k].name==_name){ //判斷該節點是否已關閉,若clickMap中存在k為當前節點名稱的數據,並且不為空。則說明已關閉,要打開。 if(clickMap.hasOwnProperty(_name) && clickMap[_name]!=null){ //alert(_name+‘ has closed . open now.‘); //將clickMap中的該節點的子節點信息重新賦值給當前節點 _option.series[0].data[j].children[k].children=clickMap[_name]; clickMap[_name]=null;//成功打開後,將clickMap中的數據賦null f=true; //跳出所有循環。 break; } //執行到這裏,說明未關閉。執行關閉操作 f=true; //若所點擊的節點存在子節點,則 if(_option.series[0].data[j].children[k].children){ //將子節點信息存入clickMap,形式【當前點擊節點的name為key,子節點數據為value】 clickMap[_option.series[0].data[j].children[k].name]=_option.series[0].data[j].children[k].children; //然後將_option中的當前子節點刪除。 delete _option.series[0].data[j].children[k].children; } //alert(‘find the node.j=‘+j+‘;k=‘+k); //跳出所有循環 break; }//else{alert(‘ not find the node.j=‘+j+‘;k=‘+k);} if(f)break; if(_option.series[0].data[j].children[k].children){ var len3=_option.series[0].data[j].children[k].children.length; var d3=_option.series[0].data[j].children[k].children; for(var l=0;l<len3;l++){ //alert(‘j:‘+j+‘--k:‘+k+‘--l:‘+l+‘-‘+d3[l].name); if(_option.series[0].data[j].children[k].children[l].name==_name){ if(clickMap.hasOwnProperty(_name) && clickMap[_name]!=null){ //alert(_name+‘has closed . open now.‘); _option.series[0].data[j].children[k].children[l].children=clickMap[_name]; clickMap[_name]=null; f=true; break; } f=true; //alert(‘find the node.j=‘+j+‘;k=‘+k+‘;l=‘+l+‘--‘+_option.series[0].data[j].children[k].children[l].name); if(_option.series[0].data[j].children[k].children[l].children){ clickMap[_option.series[0].data[j].children[k].children[l].name]=_option.series[0].data[j].children[k].children[l].children; delete _option.series[0].data[j].children[k].children[l].children; } break; }//else{alert(‘ not find the node.j=‘+j+‘;k=‘+k+‘;l=‘+l+‘--‘+d3[l].name);} if(f)break; if(_option.series[0].data[j].children[k].children[l].children){ var len4=_option.series[0].data[j].children[k].children[l].children.length; var d4=_option.series[0].data[j].children[k].children[l].children; for(var m=0;m<len4;m++){ if(_option.series[0].data[j].children[k].children[l].children[m].name==_name){ if(clickMap.hasOwnProperty(_name) && clickMap[_name]!=null){ //alert(_name+‘has closed . open now.‘); _option.series[0].data[j].children[k].children[l].children[m].children=clickMap[_name]; clickMap[_name]=null; f=true; break; } f=true; //alert(‘find the node.j=‘+j+‘;k=‘+k+‘;l=‘+l+‘;m=‘+m+‘--‘+_option.series[0].data[j].children[k].children[l].children[m].name); if(_option.series[0].data[j].children[k].children[l].children[m].children){ clickMap[_option.series[0].data[j].children[k].children[l].children[m].name]=_option.series[0].data[j].children[k].children[l].children[m].children; delete _option.series[0].data[j].children[k].children[l].children[m].children; } break; }//else{alert(‘ not find the node.j=‘+j+‘;k=‘+k+‘;l=‘+l+‘;m=‘+m+‘--‘+d4[m].name);} if(f)break; if(_option.series[0].data[j].children[k].children[l].children[m].children){ var len5=_option.series[0].data[j].children[k].children[l].children[m].children.length; var d5=_option.series[0].data[j].children[k].children[l].children[m].children; for(var n = 0 ; n<len5;n++){ /** * 最後一層循環 * 若有需要,可擴充 */ if(_option.series[0].data[j].children[k].children[l].children[m].children[n].name==_name){ if(clickMap.hasOwnProperty(_name)&&clickMap[_name]!=null){ //alert(_name+‘has closed . open now.‘); _option.series[0].data[j].children[k].children[l].children[m].children[n].children=clickMap[_name]; clickMap[_name]=null; f=true; break; } f=true; //alert(‘find the final node .‘+_option.series[0].data[j].children[k].children[l].children[m].children[n].name); if(_option.series[0].data[j].children[k].children[l].children[m].children[n].children){ clickMap[_option.series[0].data[j].children[k].children[l].children[m].children[n].name]=_option.series[0].data[j].children[k].children[l].children[m].children[n].children; delete _option.series[0].data[j].children[k].children[l].children[m].children[n].children; } break; }//else{alert(‘ not find the final node .‘+d5[n].name);} if(f)break; } }//else{alert(‘d4[m]:‘+d4[m].name +‘-下沒有子級‘);} if(f)break; } }//else{alert(‘d3[l]:‘+d3[l].name+‘-沒有子級‘);} if(f)break; } }//else{alert(‘d2[k]:‘+d2[k].name+‘沒有子級‘);} if(f)break; } }//else{alert(‘d1[j]:‘+d1[j].name+‘下沒有子級‘);} if(f)break; } //alert(‘over.‘); //清空當前echarts myChart.clear(); //重新賦值,渲染圖表 myChart.setOption(_option); // _posarr_=_posarr;//新的坐標???//待開發功能。 // for(var ii= 0 ; ii<_posarr_.length;ii++){ // alert(_posarr_[ii]); // } //刷新,沒啥用。。 myChart.refresh(); //for(var i=0;i<_posarr_.length;i++){ // if(_name==_posarr_[i][0]){ // alert(‘當前點擊:‘+_posarr_[i]); // break; // } //} }

然後在需要的地方引入這個文件就可以了。

實現原理: 1:定義一個array存放子節點信息。【樣式 [父節點name,子節點]】 2:循環所有data中的數據,找到當前點擊的節點 (if:1)根據父節點name,判斷array中是否存在該節點數據,若存在並且不為空,則將該子節點數據賦值於該節點,然後將array中的該子節點信息賦值為null,跳出所有循環。重新渲染圖表 (if:2)(array中不存在該節點信息的前提下)若該節點存在子節點,則將子節點按照 [父節點 name,子節點] 的樣式,將子節點信息存入map,然後刪除data中的該節點的子節點。跳出所有循環,重新渲染圖表。 難點: 1:循環所有data數據。不能使用值引用,這樣的話在刪除(添加)子節點信息的時候,渲染數據的最終data起不到任何作用。(本人是使用原data,一級一級點下來的) 2:子節點數據的保存及刪除。這裏定義的array實現的功能類似java裏的map,刪除json中的數據使用delete。(delete data[0].children;) 3:重新渲染。setOption之前先clear一下。

如何實現echarts組織結構圖節點的收縮