簡體   English   中英

一段時間后添加新節點時出現d3 / svg分層問題

[英]d3 / svg layering issue when adding new nodes after a time

我正在構建一個惱人的問題,我正在構建我正在構建的地方,我最初使用我需要的節點和鏈接呈現頁面,然后通過ajax定期檢查新信息。 當我需要一個新節點和鏈接時,我繪制它們,這很好

但是由於SVG圖層元素的方式,新鏈接在舊節點上繪制,因此我將節點作為圓形並在它們之間繪制線條,添加的任何新節點都會在舊節點上的圓頂上繪制。 見下圖:

分層問題

http://i40.tinypic.com/4fx25j.gif

我知道這在技術上不是d3問題,但必須有辦法解決這個問題。 我確實嘗試刪除所有的圓圈並重新繪制它們,但問題是它附加的svg:g節點在圖層中太低,所以它仍然被繪制。

在jsfiddle演示 - 請看下面的部分

draw() {
   ...
}

因為這就是魔術發生的地方。 http://jsfiddle.net/zuzzy/uwAhy/

我用5秒計時器模擬了ajax,這對於演示更容易。

有任何想法嗎?

據我所知,你只能通過它在DOM中的位置來控制SVG元素的深度。

那么對你有用的是創建兩組<g id='lines'><g id='circles'>

append元素時,應將所有行添加到第一組,將所有圓添加到第二組。

您可能必須改變添加元素的方式,但只要您確保lines組出現在circles組之前,那么您應該是金色的。

如果這完全不適合您的實施,我道歉。 我遇到了一個非常類似的問題,發現對我來說唯一的解決方案是首先繪制'下'元素。

第一次工作! 我已將所有元素分組在一個下面,所以我只是替換了:

var vis = d3.select("body")    
.append("svg:svg")  
.attr("pointer-events", "all");  
.append('svg:g')

我使用vis.xxxx來渲染鏈接和圓圈

var vis = d3.select("body") 
.append("svg:svg")   
.attr("pointer-events", "all");  

var linkvis = vis.append('svg:g')  
.attr("id","link_elements");   

vis = vis.append('svg:g')   
.attr("id","node_elements");   

並在繪制鏈接時參考linkvis並繪制圓圈。

(注意我知道這應該是一個評論,但我不能適應它,我認為它可能對某人有幫助。@保羅的回答已被標記為答案)

解決此問題的另一種方法是使用insert方法,如下面的代碼所示。

 link.enter().insert("line",".node"); //Inserts link element before the first DOM element with class node.

發布只是因為這可能對搜索此問題的解決方案的其他用戶有所幫助。

 //Settings: //width, height and the default radius of the circles var w = 1024, h = 768, r = 10; //test data - usually this is recieved via ajax //Initial Data: var hosts = eval({ "ITEM003": { "name": "ITEM003", "parents": [], "status": 0, "hostgroup": "Secure" }, "ITEM004": { "name": "ITEM004", "parents": [], "status": 0, "hostgroup": "Secure" }, "CORE": { "name": "CORE", "parents": ["ITEM004", "ITEM003"], "status": 0, "hostgroup": "DMZ" } }); var mylinks = eval({ "0": ["CORE", "ITEM004"], "1": ["CORE", "ITEM003"] }); //Data after update var updated_hosts = eval({ "ITEM003": { "name": "ITEM003", "parents": [], "status": 0, "hostgroup": "Secure" }, "ITEM004": { "name": "ITEM004", "parents": [], "status": 0, "hostgroup": "Secure" }, "CORE": { "name": "CORE", "parents": ["ITEM004", "ITEM003"], "status": 0, "hostgroup": "DMZ" }, "REMOTE": { "name": "REMOTE", "parents": [], "status": 0, "hostgroup": "" } }); var updated_mylinks = eval({ "0": ["CORE", "ITEM004"], "1": ["CORE", "ITEM003"], "2": ["CORE", "REMOTE"] }); //I define these here so they carry between functions - not really necessary in this jsfiddle probably window.link = undefined; window.node = undefined; //make up my node object window.nodeArray = []; window.node_hash = []; for (var key in hosts) { var a = { id: "node_" + hosts[key].name, labelText: hosts[key].name, status: hosts[key].status, hostgroup: hosts[key].hostgroup, class: "node realnode", iconimage: hosts[key].iconimage, added: true }; nodeArray.push(a); node_hash[key] = a; } //make up my link object window.linkArray = []; for (var key in mylinks) { var linkcolor = "#47CC60"; var a = { source: node_hash[mylinks[key][0]], target: node_hash[mylinks[key][1]], color: linkcolor, class: "link reallink" }; linkArray.push(a); } //make up my node text objects //these are just more nodes with a different class //we will append text to them later //we also add the links to the linkArray now to bind them to their real nodes window.text_hash = []; for (var key in hosts) { var a = { id: "label_" + hosts[key].name, text: hosts[key].name, color: "#ffffff", size: "6", class: "node label", added: true }; nodeArray.push(a); text_hash[key] = a; } //because the text labels are in the same order as the //original nodes we know that node_hash[0] has label text_hash[0] //it doesn't matter which we iterate through here for (var key in text_hash) { var a = { source: node_hash[key], target: text_hash[key], class: "link label" }; linkArray.push(a); } //set up the environment in a div called graph using the settings baove window.vis = d3.select("body") .append("svg:svg") .attr("height", 500) .attr("width", 500) .attr("pointer-events", "all") .append('svg:g') //object to interact with the force libraries in d3 //the settings here set how the nodes interact //seems a bit overcomplicated but it stops the diagram going nuts! window.force = d3.layout.force() .friction("0.7") .gravity(function(d, i) { if (d.class == "link reallink") { return "0.95"; } else { return "0.1"; } }) .charge(function(d, i) { if (d.class == "link reallink") { return "-1500"; } else { return "-300"; } }) .linkDistance(function(d) { if (d.class == "link reallink") { return "120"; } else { return "35"; } }) .linkStrength(function(d) { if (d.class == "link reallink") { return "8"; } else { return "6"; } }) .nodes(nodeArray) .links(linkArray) .on("tick", tick) node = vis.selectAll(".node"); link = vis.selectAll(".link"); //create the objects and run it draw(); for (key in nodeArray) { nodeArray[key].added = false; } //wait 5 seconds then update the diagram TO ADD A NODE setTimeout(function() { //update the objects //vis.selectAll("g.node").data(nodeArray).exit().transition().ease("elastic").remove(); //vis.selectAll("line").data(linkArray).exit().transition().ease("elastic").remove(); var a = { id: "node_REMOTE", labelText: "REMOTE", status: "0", hostgroup: "", class: "node realnode", iconimage: "", added: true }; nodeArray.push(a); node_hash["REMOTE"] = a; var linkcolor = "#47CC60"; var a = { source: node_hash["CORE"], target: node_hash["REMOTE"], color: linkcolor, class: "link reallink" }; linkArray.push(a); //make up my node text objects var a = { id: "label_REMOTE", text: "REMOTE", color: "#000000", size: "6", class: "node label", added: true }; nodeArray.push(a); text_hash["REMOTE"] = a; var a = { source: node_hash["REMOTE"], target: text_hash["REMOTE"], class: "link label" }; linkArray.push(a); //redraw it draw(); }, 5000); //----- functions for drawing and tick below function draw() { link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; }); node = node.data(force.nodes(), function(d) { return d.id; }); //create the link object using the links object in the json //link = vis.selectAll("line").data(linkArray); link.enter().insert("line", ".node") .attr("stroke-width", '0') .transition() .duration(1000) .ease("bounce") .attr("stroke-width", function(d, i) { if (d.class == 'link reallink') { return '3'; } else { return '0'; }; }) .style("stroke", function(d, i) { return d.color; }) .attr("class", function(d, i) { return d.class; }); //node = vis.selectAll("g").data(nodeArray); node.enter().append("svg:g") .attr("class", function(d) { return d.class }) .attr("id", function(d) { return d.id }) .call(force.drag); //append to each node an svg circle element vis.selectAll(".realnode").filter(function(d) { return d.added; }) .append("svg:circle") .attr("r", "0") .transition() .duration(1000) .ease("bounce") .attr("r", "6") .style("fill", "#000000") .style("stroke", function(d) { return d.color; }) .style("stroke-width", "4"); //append to each node the attached text desc vis.selectAll(".label").filter(function(d) { return d.added; }) .append("svg:text") .attr("text-anchor", "middle") .attr("fill", "black") .style("pointer-events", "none") .attr("font-size", "9px") .attr("font-weight", "100") .text(function(d) { return d.text; }) .attr("transform", "rotate(180)") .transition() .duration(1000) .ease("bounce") .attr("transform", "rotate(0)"); node.exit().transition().ease("elastic").remove(); link.exit().transition().ease("elastic").remove(); //activate it all - initiate the nodes and links force.start(); } function tick() { node.attr("cx", function(d) { return dx = Math.max(r + 15, Math.min(w - r - 15, dx)); }) .attr("cy", function(d) { return dy = Math.max(r + 15, Math.min(h - r - 15, dy)); }) .attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); link.data(linkArray).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; }); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM