1. 程式人生 > >Echarts實現點選節點顯示 隱藏子節點

Echarts實現點選節點顯示 隱藏子節點

問題背景

     專案中一個根節點,根節點有七八個子節點,子節點有較多的孫子節點。不美觀,因此需要將孫子節點隱藏,當點選子節點時再去顯示此子節點對應的孫子節點,再次點選則隱藏孫子節點。

問題解決

     Echarts的links的source target可以為邊的源節點名稱的字串,也支援使用數字表示源節點的索引,所以建立links連結資料節點時source target使用字串就是使用data節點的id屬性指定的值,使用int就是使用data資料的在陣列中的索引位置,而不是id值。

    實現節點的顯示隱藏,只要將需要顯示的節點賦值給series的data屬性,而links屬性不需要做任何改變,某天連線只要兩端的某一個節點不存在data屬性中,就不會顯示這條邊。因此,節點顯示隱藏只需要控制賦值給data的陣列節點即可。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script type="text/javascript" src="/cityGuardServer/js/echarts.js"></script>
<script type="text/javascript" src="/cityGuardServer/js/jquery-3.3.1.js"></script>
<style type="text/css">
html, body {
	height: 100%;
	overflow: hidden;
}

html {
	background-image: url('/cityGuardServer/assets/image-analysis-body.png');
}

div {
	
}
</style>
</head>
<body style="background-color: rgba(ffffaa)">
	<!-- 為ECharts準備一個具備大小(寬高)的Dom -->
	<div id="main" style="width: 100%; height: 100%; margin: 0 auto;"></div>
	<script type="text/javascript">
	<!-- ?car_number= & region = -->
		var url = document.location.toString();
		console.log(url);
		var arrUrl = url.split("?");
		var carParam = arrUrl[1].split("&");
		var carParamArr = carParam[0].split("=");
		var regionParamArr = carParam[1].split("=");
		var car_number = decodeURI(carParamArr[1]).toString();
		var region = decodeURI(regionParamArr[1]).toString();
		//console.log(car_number +" " + region);
		//var param = "{\"args\":'{\"region\":\"1\",\"car_number\":"+car_number+"}'}";
		var param = "{\"region\":" + region + ",\"car_number\":\"" + car_number
				+ "\"}";

		var mapObj = new Map();

		//var param = "{args:'{\"region\":\"1\",\"car_number\":\"雲aaa\"}'}";
		var myChart = echarts.init(document.getElementById('main'));
		var master;
		//節點的分類資料以及圖例顯示資料
		var categories = [ {
			name : '車',
			itemStyle : {
				color : '#fc0800'
			}
		}, {
			name : '人',
			itemStyle : {
				color : '#E29E00'
			}
		}, {
			name : '人繫結其他車',
			itemStyle : {
				color : '#0be200'
			}
		} ];
		var option = {
			//圖例顯示 每個圖例樣式需要在一個物件裡寫出來
			legend : [ {
				data : categories.map(function(a) {
					return a.name;
				}),
				textStyle : {
					color : "#ffffff"
				}
			} ],
			//連線和節點 提示框內容
			tooltip : {
				//回撥函式顯示
				formatter : function(params) {
					str = params.data.name;
					return str;
				},
				backgroundColor : '#8CC7B5',
				padding : [ 5, 10, 5, 10 ],
				textStyle : {
					fontFamily : 'Courier New'
				}
			},
			animationDuration : 1500,
			animationEasingUpdate : 'quinticInOut',
			//各個系列顯示的資料格式
			series : [ {
				//節點、連線樣式
				itemStyle : {
					normal : {
						//新增陰影 
						borderColor : '#fff',
						borderWidth : 1,
						shadowBlur : 10,
						ShadowColor : 'rgab(0,0,0,0.3)',

						lineStyle : {
							color : '#ffffff',
							curveness : 0.3,
							width : 3,
							opacity : 0.7
						},
					},

				},

				//節點顯示的標籤內容
				label : {
					position : 'right',
					formatter : '{b}',
					//回撥函式顯示
					/* formatter : function(params) {
						str = params.data.id;
						return str;
					}, */
					show : true,
					textStyle : {
						color : '#ffffff'
					},
				},
				categories : categories,
				force : {
					initLayout : 'circular',//初始佈局
					repulsion : [ 60, 120 ],//斥力大小
					edgeLength : [ 30, 100 ],
					layoutAnimation : true,
				},

				animation : false,
				name : "",
				type : 'graph',//關係圖型別
				layout : 'force',//引力佈局
				roam : true,//可以拖動
				focusNodeAdjacency : true,
				emphasis : {
					lineStyle : {
						width : 8
					}
				},
				//節點和關聯資料置空,下面Ajax獲取資料填充即可
				nodes : [],
				links : []
			} ]
		}
		myChart.setOption(option);
        //記錄所有節點
		var allArr = [];
        //記錄需要顯示的節點
		var display = [];
        //記錄連線資訊,通過這個陣列得到節點 子節點關係
		var linkArr = [];
		//非同步獲取資料
		$.ajax({
			type : "POST",
			url : "/projectname/analysis_car/car_graph_history?args="
					+ param,
			dataType : "json",
			data : {},
			success : function(data) {
				console.log(data.nodes);
				console.log(data.links);
				linkArr = data.links;
				allArr = data.nodes;
				display = allArr.filter(function(x, index) {
					return x.category != 2;
				});
				console.log(display);
				myChart.setOption({
					series : [ {
						nodes : display,
						links : data.links
					/* nodes : [{symbol: "circle", symbolSize: 27, name: "n0", id: "雲A2RG210", category: 0},
					         {symbol: "circle", symbolSize: 27, name: "n1", id: "雲A2RG20", category: 0}],
					links : [{source:"雲A2RG210",target:"雲A2RG20"}] */
					} ]
				});//將option新增到mychart中
			},
			error : function(err) {
				console.log(param);
			}
		});
		//下面為點選某個節點之後進行的操作,其實就是像display加入要顯示的子節點.節點的顯示和隱藏只是改變節點data陣列即可,link始終不需要改變。
		myChart.on('click', function(params) {
            //本次點選需要新增或刪除的節點
			var addArr = [];
            //記錄本次點選需要新增的元素是否已經在display陣列中,如果在,說明本次點選需要從    
            //display中刪除掉addArr中節點;不在,需要新增到待顯示陣列display中
			var exist = false;
			if (params.data.category == '1') {
				var temp = linkArr.filter(function(x, index) {
					if (x.source == params.data.id) {
						return x;
					}
				});
				console.log(temp);
				//判斷display裡面是否有本次新增的元素,如果有,說明節點已經顯示,就去刪除
				for (var k = 0; k < display.length; k++) {
					for (var i = 0; i < temp.length; i++) {
						if (display[k].id == temp[i].target) {
							exist = true;
							break;
							console.log(x.id);
						}
					}
					if (exist) {
						break;
					}
				}
				console.log(exist);
				//得到需要新增或刪除的節點元素
				allArr.forEach(function(x, index, a) {
					temp.forEach(function(y, indey, b) {
						if (x.id == y.target) {
							addArr.push(x);
						}
					});
				});
			} else {
				return;
			}
			if (!exist) {
				display = display.concat(addArr);
			} else {
				var disTemp = [];
				for (var i = 0; i < display.length; i++) {
					var del = false;
					for (var j = 0; j < addArr.length; j++) {

						if (display[i].id == addArr[j].id) {
							del = true;
							break;
						}
					}
					if (!del) {
						disTemp.push(display[i]);
					}
				}
				display = disTemp;
			}
			myChart.setOption({
				series : [ {
					nodes : display,
				} ]
			});
		});
	</script>
</body>
</html>