繁体   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