d3.js實現雙擊刪除節點並刪除節點上的文字
阿新 • • 發佈:2019-01-28
最近專案遇到一個問題:刪除節點,節點上的文字卻無法刪除。
經過F12的除錯,我發現原來自己寫的節點、連線、文字分別包裹在不同的g標籤內。
於是出現了兩種解決方案:
(1)把文字依附在節點上
(2)選中節點的時候遍歷文字確保是哪個文字和該節點是對應的
我個人認為第一種方案是最優化的,我也推薦大家遇到這個問題採用第一種方案。
但是我專案之前寫的結構就這樣了,如果現在改的話,需要改的程式碼太多,於是我採用第二種方案。
廢話之後,乾貨奉上
以下是我寫的一個demo:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>雙擊刪除節點</title> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script> var width = 1366; var height = 768; 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/song.json",function(error,data){ if(error){ return console.log(error); } var dataset = data; console.log(dataset); var force = d3.layout.force() .nodes(dataset.nodes) .links(dataset.links) .size([width,height]) .linkDistance(100) .charge(-1500) .start(); var links = svg.selectAll("line") .data(dataset.links) .enter() .append("line") .attr("class","lines") .attr("style","stroke: #CCCCCC; stroke-width: 2;"); var nodes = svg.selectAll("circle") .data(dataset.nodes) .enter() .append("circle") .attr("r",radius) .attr("class","nodes") .attr("fill","pink") .on("dblclick",function(d){ //雙擊節點刪除,獲取選中節點的在json中的name的值 d3.select(this).remove(); var clickNodeName = d.name;//點選節點的名字 d3.selectAll(".nodetext").each(function(d,i){ var temp = d.name; if(temp==clickNodeName){ // alert("相等"); d3.select(this).remove(); } }); d3.selectAll(".lines").each(function(e){ if(e.source===d||e.target===d){ d3.select(this).remove(); } }) }) .on("mouseout",function(d,i){ nodes.style("stroke",function(edge){ if(edge.source===d){ return "#CCCCCC"; } }); links.style("stroke","#CCCCCC"); }) .call(force.drag); var text_dx = -20; var text_dy = 20; console.log("x:"+text_dx); console.log("y:"+text_dy); var nodes_text = svg.selectAll(".nodetext") .data(dataset.nodes) .enter() .append("text") .attr("class","nodetext") .attr("dy",".35em") .attr("text-anchor","middle") .text(function(d) { return d.name; }); force.on("tick", function() { links.attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); nodes.attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); nodes_text.attr("dx", function(d) { return d.x-img_w/4; }) .attr("dy", function(d) { return d.y+5; }); }); }); </script> </body> </html>
json檔案如下:
{ "nodes":[ {"name":"人物1","group":3,"img":"img/1.jpg"}, {"name":"人物2","group":3,"img":"img/2.jpg"}, {"name":"人物3","group":3,"img":"img/3.jpg"}, {"name":"人物4","group":3,"img":"img/4.jpg"}, {"name":"人物5","group":3,"img":"img/5.jpg"}, {"name":"人物6","group":2,"img":"img/6.jpg"}, {"name":"人物7","group":2,"img":"img/7.jpg"}, {"name":"人物8","group":2,"img":"img/8.jpg"}, {"name":"人物9","group":2,"img":"img/9.jpg"}, {"name":"人物10","group":2,"img":"img/10.jpg"}, {"name":"人物11","group":1,"img":"img/11.jpg"}, {"name":"人物12","group":1,"img":"img/12.jpg"}, {"name":"人物13","group":1,"img":"img/13.jpg"}, {"name":"人物14","group":1,"img":"img/14.jpg"}, {"name":"人物15","group":1,"img":"img/15.jpg"}, {"name":"人物16","group":1,"img":"img/16.jpg"}], "links":[{"source":0,"target":1,"relation":"\ue900 \ue904 \ue908 \ue9a1"}, {"source":0,"target":2,"relation":"關係一"}, {"source":0,"target":3,"relation":"關係二"}, {"source":0,"target":4,"relation":"\ue909"}, {"source":5,"target":6,"relation":"\ue9a1"}, {"source":5,"target":7,"relation":"\ue9a2"}, {"source":5,"target":8,"relation":"\ue9a3"}, {"source":5,"target":9,"relation":"\ue9ad"}, {"source":10,"target":11,"relation":"\ue9c1"}, {"source":10,"target":12,"relation":"\ue9c3"}, {"source":10,"target":13,"relation":"\ue9dd"}, {"source":10,"target":14,"relation":"\ue9fd"}, {"source":10,"target":15,"relation":"\ue9ed"}, {"source":10,"target":11,"relation":"\ue91d"}, {"source":0,"target":5,"relation":"\ue93d"}, {"source":5,"target":10,"relation":"\ue95d"}, {"source":10,"target":0,"relation":"\ue97d"} ] }
測試效果如下: