D3JS Force Layout新节点断开现有节点(D3JS Force Layout new nodes disconnects existing nodes)

编程入门 行业动态 更新时间:2024-10-20 20:37:14
D3JS Force Layout新节点断开现有节点(D3JS Force Layout new nodes disconnects existing nodes)

当我向D3的Force Layout添加新节点时,新节点在定位自身时忽略先前的节点,并且先前的节点变得不可拖动。 我觉得我遵循了以下逻辑:

将元素添加到数组节点和链接 更新了force.nodes(nodes)和force.links(链接) 通过.data()。输入()新数据 叫做force.start()

但仍导致先前的节点断开连接。 新节点是可拖动的,并且似乎考虑了添加节点位置的最后一组并且避免了冲突,所有其他先前节点仍然可以点击,但是它们的定位被忽略并且不被更新。

这是PLNKR中的代码: http ://plnkr.co/edit/5fXZf63s73cTO37zLjNQ?p = preview

var width = 1000; var height = 600; var node_w = 30; var node_h = 30; var text_dx = -20; var text_dy = 20; var new_id = 9; var nodes = [], links = [], links_line, node_circles; var svg = d3.select("body").append("svg") .attr("width",width) .attr("height",height); var nodes = [ { "name": "Nucleus" , "size" : 25, "id" : 0 , "color":"#ac0000"}, { "name": "one" , "size" : 5 , "id": 1 , "color": "#ac0"}, { "name": "two" , "size" : 15 , "id": 2 , "color": "#ac0"}, { "name": "three" , "size" : 25 , "id": 3 , "color": "#ac0"}, { "name": "four" , "size" : 9 , "id": 4 , "color": "#ac0"}, { "name": "five" , "size" : 12 , "id": 5 , "color": "#ac0"}, { "name": "six" , "size" : 15 , "id": 6 , "color": "#ac0"}, { "name": "seven" , "size" : 41 , "id": 7 , "color": "#ac0"}, { "name": "eight" , "size" : 5 , "id": 8 , "color": "#ac0"} ]; var links = [ { "source": 0 , "target": 1 , "link_info":"r01" }, { "source": 1 , "target": 2 , "link_info":"r31" }, { "source": 1 , "target": 3 , "link_info":"r02" }, { "source": 1 , "target": 4 , "link_info":"r04" }, { "source": 0 , "target": 5 , "link_info":"r05" }, { "source": 0 , "target": 6 , "link_info":"r06" }, { "source": 0 , "target": 7 , "link_info":"r87" }, { "source": 0 , "target": 8 , "link_info":"r87" } ]; var force = d3.layout.force() .nodes(nodes) .links(links) .size([width, height]) .linkDistance(150) .charge(-1400); var drag = force.drag(); init(); function init() { force.start(); links_line = svg.selectAll("line") .data(links) .enter() .append("line") .style("stroke", "#ac0") .style("stroke-width", 1); node_circles = svg.selectAll("circle") .data(nodes) .enter() .append("circle") .style("fill", function(d) {return d.color;}) .on("dblclick", function(d, i) { addNodes(i); }) .call(drag); draw(); } function addNodes(i) { for (c=0; c < Math.floor(Math.random() * 20) + 4; c++) { nodes.push({"name": "new " + new_id,"size": (Math.floor(Math.random() * 20) + 10),"id": new_id,"color": "#333"}) links.push({"source": i,"target": new_id,"link_info": "r"+i+new_id}); new_id++; } // Update force.nodes force.nodes(nodes); // Update force.links force.links(links); // exec init() init(); } function draw() { var ticksPerRender = 1; requestAnimationFrame(function render() { force.tick(); //Update nodes node_circles.attr("cx", function(d) {return d.x - d.size / 6;}); node_circles.attr("cy", function(d) {return d.y - d.size / 6;}); node_circles.attr("r", function(d) {return d.size}); //Update Location line links_line.attr("x1", function(d) {return d.source.x;}); links_line.attr("y1", function(d) {return d.source.y;}); links_line.attr("x2", function(d) {return d.target.x;}); links_line.attr("y2", function(d) {return d.target.y;}); requestAnimationFrame(render) }); } // draw();

When I add new nodes to D3's Force Layout, the new nodes ignore the previous nodes when positioning itself and the previous nodes becomes un-draggable. I feel I've followed the logic of:

Add elements to arrays nodes and links Updated force.nodes(nodes) and force.links(links) Ran through .data().enter() with new data Called force.start()

But still results in previous nodes disconnects. The new nodes are draggable and appears to take into consideration the LAST SET of added nodes position and avoids collision, all other previous nodes are clickable still, but their positioning are ignored and not updated.

Here is a the code in PLNKR: http://plnkr.co/edit/5fXZf63s73cTO37zLjNQ?p=preview

var width = 1000; var height = 600; var node_w = 30; var node_h = 30; var text_dx = -20; var text_dy = 20; var new_id = 9; var nodes = [], links = [], links_line, node_circles; var svg = d3.select("body").append("svg") .attr("width",width) .attr("height",height); var nodes = [ { "name": "Nucleus" , "size" : 25, "id" : 0 , "color":"#ac0000"}, { "name": "one" , "size" : 5 , "id": 1 , "color": "#ac0"}, { "name": "two" , "size" : 15 , "id": 2 , "color": "#ac0"}, { "name": "three" , "size" : 25 , "id": 3 , "color": "#ac0"}, { "name": "four" , "size" : 9 , "id": 4 , "color": "#ac0"}, { "name": "five" , "size" : 12 , "id": 5 , "color": "#ac0"}, { "name": "six" , "size" : 15 , "id": 6 , "color": "#ac0"}, { "name": "seven" , "size" : 41 , "id": 7 , "color": "#ac0"}, { "name": "eight" , "size" : 5 , "id": 8 , "color": "#ac0"} ]; var links = [ { "source": 0 , "target": 1 , "link_info":"r01" }, { "source": 1 , "target": 2 , "link_info":"r31" }, { "source": 1 , "target": 3 , "link_info":"r02" }, { "source": 1 , "target": 4 , "link_info":"r04" }, { "source": 0 , "target": 5 , "link_info":"r05" }, { "source": 0 , "target": 6 , "link_info":"r06" }, { "source": 0 , "target": 7 , "link_info":"r87" }, { "source": 0 , "target": 8 , "link_info":"r87" } ]; var force = d3.layout.force() .nodes(nodes) .links(links) .size([width, height]) .linkDistance(150) .charge(-1400); var drag = force.drag(); init(); function init() { force.start(); links_line = svg.selectAll("line") .data(links) .enter() .append("line") .style("stroke", "#ac0") .style("stroke-width", 1); node_circles = svg.selectAll("circle") .data(nodes) .enter() .append("circle") .style("fill", function(d) {return d.color;}) .on("dblclick", function(d, i) { addNodes(i); }) .call(drag); draw(); } function addNodes(i) { for (c=0; c < Math.floor(Math.random() * 20) + 4; c++) { nodes.push({"name": "new " + new_id,"size": (Math.floor(Math.random() * 20) + 10),"id": new_id,"color": "#333"}) links.push({"source": i,"target": new_id,"link_info": "r"+i+new_id}); new_id++; } // Update force.nodes force.nodes(nodes); // Update force.links force.links(links); // exec init() init(); } function draw() { var ticksPerRender = 1; requestAnimationFrame(function render() { force.tick(); //Update nodes node_circles.attr("cx", function(d) {return d.x - d.size / 6;}); node_circles.attr("cy", function(d) {return d.y - d.size / 6;}); node_circles.attr("r", function(d) {return d.size}); //Update Location line links_line.attr("x1", function(d) {return d.source.x;}); links_line.attr("y1", function(d) {return d.source.y;}); links_line.attr("x2", function(d) {return d.target.x;}); links_line.attr("y2", function(d) {return d.target.y;}); requestAnimationFrame(render) }); } // draw();

最满意答案

更新d3可视化遵循输入,更新和退出工作流程( 在此处和此处开始阅读)。

试试这个:

function init() { force.start(); links_line = svg.selectAll("line") .data(links); links_line .enter() .append("line") .style("stroke", "#ac0") .style("stroke-width", 1); links_line.exit().remove(); node_circles = svg.selectAll("circle") .data(nodes); node_circles .enter() .append("circle") .style("fill", function(d) {return d.color;}) .on("dblclick", function(d, i) { addNodes(i); }) .call(drag); draw(); }

更新的例子 。

Updating a d3 visualization follows an enter, update, and exit workflow (start your reading here and here).

Try this instead:

function init() { force.start(); links_line = svg.selectAll("line") .data(links); links_line .enter() .append("line") .style("stroke", "#ac0") .style("stroke-width", 1); links_line.exit().remove(); node_circles = svg.selectAll("circle") .data(nodes); node_circles .enter() .append("circle") .style("fill", function(d) {return d.color;}) .on("dblclick", function(d, i) { addNodes(i); }) .call(drag); draw(); }

Updated example.

更多推荐

本文发布于:2023-07-31 01:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1340496.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:节点   Layout   Force   D3JS   disconnects

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!