D3力导向图添加新节点会导致x& y为NaN [英] D3 force-directed graph adding new nodes causes x & y to be NaN
问题描述
当我单击一个节点时,我希望向其添加一个新节点.它们都应该有标签(我正在尝试建立同义词库可视化文件.)
When I click on a node, I want a new node to be added to it. They should both have labels (I'm trying to build a thesaurus visualization).
我是D3的新手,如果您需要更详细地说明事情,我深表歉意.
I'm very new to D3, so I apologize if you have to explain things in a bit more detail.
到目前为止,这是我的代码:
This is my code so far:
var width = 960;
var height = 500;
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([width, height])
.nodes([{ "name": "One", "group": 1 }])
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var nodes = force.nodes();
var links = force.links();
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 10)
.on("mousedown", onClick);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.name);
force.on("tick", function() {
link.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node.attr("transform", d => {
// d.x & d.y are NaN for new nodes
return "translate(" + d.x + "," + d.y + ")";
});
});
restart();
function restart() {
node = node.data(nodes);
node.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 10)
.on("mousedown", onClick);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.name);
node.exit().remove();
link = link.data(links);
}
function onClick(clicked_node) {
console.log("click!");
console.log(clicked_node);
var new_node = { name: "Test", group: 2 };
nodes.push(new_node);
// Has x & y set to NaN after adding
links.push({ source: clicked_node, target: new_node });
restart();
}
当我单击第一个节点时,导致该节点
As soon as I click on the first node, causing the node
{ name: "Test", group: 2 };
要添加的内容,D3会引发错误
to be added, D3 throws errors within
node.attr("transform", d => {
// d.x & d.y are NaN for new nodes
return "translate(" + d.x + "," + d.y + ")";
});
因为此新节点的d.x
和d.y
是NaN
.
我尝试明确设置它们:
{ name: "Test", group: 2, x: clicked_node.y, y: clicked_node.y };
但是我得到了同样的错误.在检查器中,将此节点添加到屏幕后,x
和y
值将改为px
和py
值!
But I get the same error. In the inspector, when this node is added to the screen, the x
and y
values becomes the px
and py
values instead!
我不明白为什么会这样.
I don't understand why this happens.
推荐答案
您缺少一行代码.添加新节点后,需要重新启动d3
的仿真以计算其位置:
You are missing one line of code. After you add your new node you need to restart the simulation for d3
to calculate it's position:
function restart() {
node = node.data(nodes);
node.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 10)
.on("mousedown", onClick);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.name);
node.exit().remove();
link = link.data(links);
force.start(); //<-- start simulation
}
运行代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@3.5.17" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>
<body>
<script>
var width = 960;
var height = 500;
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([width, height])
.nodes([{ "name": "One", "group": 1 }])
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var nodes = force.nodes();
var links = force.links();
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 10)
.on("mousedown", onClick);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.name);
force.on("tick", function() {
link.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node.attr("transform", d => {
// d.x & d.y are NaN for new nodes
return "translate(" + d.x + "," + d.y + ")";
});
});
restart();
function restart() {
node = node.data(nodes);
node.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 10)
.on("mousedown", onClick);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.name);
node.exit().remove();
link = link.data(links);
force.start();
}
function onClick(clicked_node) {
console.log("click!");
console.log(clicked_node);
var new_node = { name: "Test", group: 2 };
nodes.push(new_node);
// Has x & y set to NaN after adding
links.push({ source: clicked_node, target: new_node });
restart();
}
</script>
</body>
</html>
这篇关于D3力导向图添加新节点会导致x& y为NaN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!