d3.js实现隐藏部分关系
如果用d3畫人物圖的話,這個問題會經常遇到。
例如:人物A和人物B之間的關系有:同學、親戚、同事;人物A和人物C之間的關系有:同學、同事;
需求:不想看到親戚關系。(為什么會有這樣的需求:節點多了后,各種復雜關系都顯示出來了,看著就密密麻麻,隱藏部分關系后,看起來就清爽多了)
原始圖:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?隱藏“親戚”關系后的圖:
要實現這樣的隱藏部分關系效果的解決方案:
(1)修改json文件:方法:把“親戚”所在的關系進行處理,relation.replace("親戚",“”),重新加載一次json文件。
缺點:界面相當于重新繪制了一遍,用戶體驗不太好,尤其是你的人物關系圖是動態的時候。
難易程度:簡單
(2)界面刷新:方法:遍歷每條線上的關系,找到“親戚”所在的關系,標記“親戚”(添加一個類),然后設置該類不可見。
優點:界面沒有進行刷新,用戶體驗比較好
優點:要給一個文字關系添加一個類
難易程度:困難
以上是我的兩個解決問題的思路。
方案一代碼:
<html> <head><meta charset="utf-8"> <title>隱藏部分關系通過切換json文件</title> <style>.nodetext {font-size: 12px ;font-family: SimSun;fill:#000000; }.linetext {font-size: 12px ;font-family: SimSun;fill:#1f77b4; }.circleImg {stroke: #ff7f0e;stroke-width: 1.5px; } </style></head> <body> <div class="lay" style="position: fixed;top: 20px;left: 20px;"><button id="button">隱藏 親戚 關系</button></div><script src="d3.js" type="text/javascript" charset="utf-8"></script><script> var data1 = "data1.json";var data2 = "data2.json";var width = 900;var height = 800;var img_w = 77;var img_h = 80;var radius = 30; var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);function updatesvg(soursefile){d3.select("svg").selectAll("*").remove();d3.json(soursefile,function(error,root){if( error ){return console.log(error);}console.log(root);//D3力導向布局var force = d3.layout.force().nodes(root.nodes).links(root.edges).size([width,height]).linkDistance(200).charge(-1500).start();//邊 var edges_line = svg.selectAll("line").data(root.edges).enter().append("line").style("stroke","#ccc").style("stroke-width",1);//邊上的文字(人物之間的關系) var edges_text = svg.selectAll(".linetext").data(root.edges).enter().append("text").attr("class","linetext").style("display","block").style("color","red").text(function(d){return d.relation;});// 圓形圖片節點(人物頭像)var nodes_img = svg.selectAll("image").data(root.nodes).enter().append("circle").attr("class", "circleImg").attr("r", radius).attr("fill", function(d, i){//創建圓形圖片var defs = svg.append("defs").attr("id", "imgdefs")var catpattern = defs.append("pattern").attr("id", "catpattern" + i).attr("height", 1).attr("width", 1)catpattern.append("image").attr("x", - (img_w / 2 - radius)).attr("y", - (img_h / 2 - radius)).attr("width", img_w).attr("height", img_h).attr("xlink:href", d.image)return "url(#catpattern" + i + ")";}).call(force.drag);var text_dx = -20;var text_dy = 20;var nodes_text = svg.selectAll(".nodetext").data(root.nodes).enter().append("text").attr("class","nodetext").attr("dx",text_dx).attr("dy",text_dy).text(function(d){return d.name;});force.on("tick", function(){//更新連接線的位置edges_line.attr("x1",function(d){ return d.source.x; });edges_line.attr("y1",function(d){ return d.source.y; });edges_line.attr("x2",function(d){ return d.target.x; });edges_line.attr("y2",function(d){ return d.target.y; });//更新連接線上文字的位置edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });//更新結點圖片和文字nodes_img.attr("cx",function(d){ return d.x });nodes_img.attr("cy",function(d){ return d.y });//聯系nodes_text.attr("x",function(d){ return d.x });nodes_text.attr("y",function(d){ return d.y + img_w/2; });});});}updatesvg(data1);var btn = document.getElementById("button");btn.onclick = function(){//這里應該要遍歷json文件,找到"親戚"再刪除后生成新的json,再作為參數傳遞var data3 = "data3.json";updatesvg(data3);}</script> </body> </html>通過改動json文件來實現部分隱藏,此時要復原就基本不可能了。
于是測試第二種方案。目前我把包含“親戚”的關系都隱藏起來了,并未實現部分隱藏,希望大家改進改進,共同學習。如果我解決了,也會及時更新。
以下是代碼:
<html> <head><meta charset="utf-8"> <title>隱藏部分關系</title> <style>.nodetext {font-size: 12px ;font-family: SimSun;fill:#000000; }.linetext {font-size: 12px ;font-family: SimSun;fill:#1f77b4; }.baohan{display: none;opacity: 0; } .circleImg {stroke: #ff7f0e;stroke-width: 1.5px; }</style></head> <body> <div class="lay" style="position: fixed;top: 20px;left: 20px;"><button id="button3">隱藏 親戚 關系</button><button id="button4">顯示 親戚 關系</button></div><script src="d3.js" type="text/javascript" charset="utf-8"></script><script> var data1 = "data1.json";var data2 = "data2.json";var width = 900;var height = 800;var img_w = 77;var img_h = 80;var radius = 30; var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);function updatesvg(soursefile){d3.select("svg").selectAll("*").remove();d3.json(soursefile,function(error,root){if( error ){return console.log(error);}console.log(root);//D3力導向布局var force = d3.layout.force().nodes(root.nodes).links(root.edges).size([width,height]).linkDistance(200).charge(-1500).start();//邊 var edges_line = svg.selectAll("line").data(root.edges).enter().append("line").style("stroke","#ccc").style("stroke-width",1);//邊上的文字(人物之間的關系) var edges_text = svg.selectAll(".linetext").data(root.edges).enter().append("text").attr("class","linetext").style("display","block").style("color","red").text(function(d){return d.relation;});// 圓形圖片節點(人物頭像)var nodes_img = svg.selectAll("image").data(root.nodes).enter().append("circle").attr("class", "circleImg").attr("r", radius).attr("fill", function(d, i){//創建圓形圖片var defs = svg.append("defs").attr("id", "imgdefs")var catpattern = defs.append("pattern").attr("id", "catpattern" + i).attr("height", 1).attr("width", 1)catpattern.append("image").attr("x", - (img_w / 2 - radius)).attr("y", - (img_h / 2 - radius)).attr("width", img_w).attr("height", img_h).attr("xlink:href", d.image)return "url(#catpattern" + i + ")";}).call(force.drag);var text_dx = -20;var text_dy = 20;var nodes_text = svg.selectAll(".nodetext").data(root.nodes).enter().append("text").attr("class","nodetext").attr("dx",text_dx).attr("dy",text_dy).text(function(d){return d.name;});force.on("tick", function(){//更新連接線的位置edges_line.attr("x1",function(d){ return d.source.x; });edges_line.attr("y1",function(d){ return d.source.y; });edges_line.attr("x2",function(d){ return d.target.x; });edges_line.attr("y2",function(d){ return d.target.y; });//更新連接線上文字的位置edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });//更新結點圖片和文字nodes_img.attr("cx",function(d){ return d.x });nodes_img.attr("cy",function(d){ return d.y });//聯系nodes_text.attr("x",function(d){ return d.x });nodes_text.attr("y",function(d){ return d.y + img_w/2; });});document.getElementById("button3").onclick = function(){d3.selectAll(".linetext").each(function(d,i){console.log("關系:"+d.relation);if(d.relation.indexOf("親戚")>-1){console.log("包含:親戚");var result = d.relation.replace("親戚", "");console.log("替換后的結果:"+result);d3.select(this).attr("class","linetext baohan")}})}document.getElementById("button4").onclick = function(){d3.selectAll(".linetext").each(function(d,i){console.log("關系:"+d.relation);if(d.relation.indexOf("親戚")>-1){console.log("包含:親戚");var result = d.relation.replace("親戚", "");console.log("替換后的結果:"+result);d3.select(this).attr("class","linetext")}})}});}updatesvg(data1);</script> </body> </html>附:json文件
data1.json:
{"nodes":[{ "name": "測試1" , "image" : "renwu.jpg" },{ "name": "測試2" , "image" : "renwu.jpg" },{ "name": "測試3" , "image" : "renwu.jpg" }],"edges":[{ "source": 0 , "target": 1 , "relation":"同學 同事 親戚" },{ "source": 0 , "target": 2 , "relation":"同學 同事 " }] }data3.json:
{"nodes":[{ "name": "測試1" , "image" : "renwu.jpg" },{ "name": "測試2" , "image" : "renwu.jpg" },{ "name": "測試3" , "image" : "renwu.jpg" }],"edges":[{ "source": 0 , "target": 1 , "relation":"同學 同事" },{ "source": 0 , "target": 2 , "relation":"同學 同事" }] }以上是我在7月25做的,但是并沒有實現我想要的結果,今天實在是氣不過,花了時間,效果還沒有出來。于是我又做了調整,終于實現了預想的設計圖:
代碼附上:
<html> <head><meta charset="utf-8"> <title>隱藏部分關系</title> <style>.nodetext {font-size: 12px ;font-family: SimSun;fill:#000000; }.linetext {font-size: 12px ;font-family: SimSun;fill:#1f77b4; }.circleImg {stroke: #ff7f0e;stroke-width: 1.5px; }.btn{position: fixed;top: 50px;left: 20px; } .btn2{position: fixed;top: 100px;left: 20px; } .btn3{position: fixed;top: 150px;left: 20px; } .btn4{position: fixed;top: 200px;left: 20px; } .baohan{display: none;opacity: 0; } .unbaohan{display: block;opacity: 1; } </style></head> <body> <p>我想點擊按鈕,把“摯友”關系刪掉</p><hr /><button id="btn" class="btn">隱藏 摯友 關系</button><button id="btn2" class="btn2">顯示 摯友 關系</button><button id="btn3" class="btn3">隱藏 同學 關系</button><button id="btn4" class="btn4">顯示 同學 關系</button><script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script><script> var width = 900;var height = 800;var img_w = 77;var img_h = 80;var radius = 30; var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);d3.json("json/relation.json",function(error,root){if( error ){return console.log(error);}console.log(root);createD3(root);});function createD3(root){//D3力導向布局var force = d3.layout.force().nodes(root.nodes).links(root.edges).size([width,height]).linkDistance(200).charge(-1500).start();//邊 var edges_line = svg.selectAll("line").data(root.edges).enter().append("line").style("stroke","#ccc").style("stroke-width",1);//邊上的文字(人物之間的關系) var edges_text = svg.selectAll(".linetext").data(root.edges).enter().append("text").attr("class","linetext").style("display","block").style("color","red").text(function(d){return d.relation;});// 圓形圖片節點(人物頭像)var nodes_img = svg.selectAll("image").data(root.nodes).enter().append("circle").attr("class", "circleImg").attr("r", radius).attr("fill", function(d, i){//創建圓形圖片var defs = svg.append("defs").attr("id", "imgdefs")var catpattern = defs.append("pattern").attr("id", "catpattern" + i).attr("height", 1).attr("width", 1)catpattern.append("image").attr("x", - (img_w / 2 - radius)).attr("y", - (img_h / 2 - radius)).attr("width", img_w).attr("height", img_h).attr("xlink:href", d.image)return "url(#catpattern" + i + ")";}).call(force.drag);var text_dx = -20;var text_dy = 20;var nodes_text = svg.selectAll(".nodetext").data(root.nodes).enter().append("text").attr("class","nodetext").attr("dx",text_dx).attr("dy",text_dy).text(function(d){return d.name;});force.on("tick", function(){//更新連接線的位置edges_line.attr("x1",function(d){ return d.source.x; });edges_line.attr("y1",function(d){ return d.source.y; });edges_line.attr("x2",function(d){ return d.target.x; });edges_line.attr("y2",function(d){ return d.target.y; });//更新連接線上文字的位置edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });//更新結點圖片和文字nodes_img.attr("cx",function(d){ return d.x });nodes_img.attr("cy",function(d){ return d.y });//聯系nodes_text.attr("x",function(d){ return d.x });nodes_text.attr("y",function(d){ return d.y + img_w/2; });});}document.getElementById("btn").onclick = function(){xx("摯友",true)}document.getElementById("btn2").onclick = function(){xx("摯友",false)}document.getElementById("btn3").onclick = function(){xx("同學",true)}document.getElementById("btn4").onclick = function(){xx("同學",false)}function xx(info,flag){d3.selectAll(".linetext").each(function(d,i){var old = d3.select(this).text();if(flag){if(d.relation.indexOf(info)>-1){var result = old.replace(info,"");d3.select(this).text(result);}}else{if(d.relation.indexOf(info)>-1){if(old.indexOf(info)>-1){d3.select(this).text(old);}else{d3.select(this).text(old+" "+info);}}}})}</script> </body> </html>其中xx函數是實現的核心函數。效果非常好,高興之余,也分享給大家!
總結
以上是生活随笔為你收集整理的d3.js实现隐藏部分关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC实现简单登录
- 下一篇: 点击按钮显示div并向div中传递参数