gpt4 book ai didi

javascript - D3JS强制布局新节点断开现有节点

转载 作者:行者123 更新时间:2023-11-28 10:53:59 25 4
gpt4 key购买 nike

当我将新节点添加到 D3 的强制布局时,新节点在定位自身时会忽略先前的节点,并且先前的节点变得不可拖动。我觉得我遵循的逻辑是:

  1. 向数组节点和链接添加元素
  2. 更新了force.nodes(节点)和force.links(链接)
  3. 使用新数据运行 .data().enter()
  4. 调用了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();

最佳答案

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

试试这个:

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();
}

已更新example .

关于javascript - D3JS强制布局新节点断开现有节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27930803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com