在 d3 canvas 中动态添加节点
Adding a node dynamically in d3 canvas
我是 d3 的新手。我用 JSON 个节点尝试了几个例子,得到了一个很好的工作网络图。
但是,当我尝试动态添加额外的节点时,它并没有出现在屏幕上。
我从Force Dragging III Canvas开始,然后尝试添加以下代码,但它不起作用;我该如何解决这个问题,请帮忙?
graph.addNode("NewNode");
function addNode (id) {
nodes.push({"id":id});
restart();
}
function restart() {
node = node.data(nodes);
node.enter().insert("circle", ".cursor")
.attr("class", "node")
.attr("r", 5);
node.exit()
.remove();
link = link.data(links);
link.enter().insert("line", ".node")
.attr("class", "link");
link.exit()
.remove();
force.start();
}
有几件事与不太明显的力量有关:
- 初始化后,原始数据数组中的节点获得了一堆新属性
- 初始化后,原始数据数组中的link被转换为新形式。
此外,如果您遵循 linked 示例,则不需要 enter/update/exit 样式循环 - 强制使用原始数据数组,而不是任何 DOM元素。
节点数
在您的参考示例中,节点仅以一个 ID 和一个组开头:
{"source": "Montparnasse", "target": "Babet", "value": 2}
然而,在使用 simulation.nodes(nodes)
初始化后,它们会得到一些附加参数:
group: 1
id: "Myriel"
index: 0
vx: 0.0026819653036056477
vy: -0.0005005454729913666
x: 306.003096668046
y: 359.07887474183434
这四个额外的属性跟踪节点。每个 tick 都要求这些属性已经存在,如果它们不存在,我们就会遇到问题。因此,如果我们提供一个新节点,我们可以为它赋予 x,y,vy,vx 属性,以便无缝添加它(example,在所有示例中单击以添加节点)。这给出了一个简单的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id":id, index: id, x: width/2, y: height/2, vx: 0, vy: 0});
}
或者我们可以使用 simulation.nodes()
(example), and the force will place it automatically while giving it the required position. However, this is jumpy unless you specify an x and y coordinate (example).
重新初始化节点
最后一个也给了我们一个非常直接的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id":id, group: 12, x: width/2, y: height/2});
simulation.nodes(graph.nodes)
}
这应该有助于将节点添加到力中。
链接
对于 links,您参考示例中的原始数据在加载时如下所示:
{ source: "Napoleon", target: "Myriel", value: 1 }
但是,在初始化 links 之后,采用以下形式:
index: 0
source: Object { id: "Napoleon", group: 1, index: 1, … }
target: Object { id: "Myriel", group: 1, index: 0, … }
value: 1
源和目标属性被转换为表示每个点的对象。与节点一样,ticked 函数要求节点采用后一种形式。同上,我们可以尝试复制格式,或者强制自己设置格式,我为link选择后者,而为新节点here设置x,y。这是为此的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id": id, x: width/2, y: height/2});
graph.links.push({source: "Javert", target: id });
simulation
.nodes(graph.nodes)
.force("link")
.links(graph.links);
}
作为一个更复杂但理论性较低的示例,例如 might be interesting (and associated block(单击 add/remove 节点,使用左上角的按钮切换操作),其中节点是added/removed 进而影响力和 voronoi
我是 d3 的新手。我用 JSON 个节点尝试了几个例子,得到了一个很好的工作网络图。
但是,当我尝试动态添加额外的节点时,它并没有出现在屏幕上。
我从Force Dragging III Canvas开始,然后尝试添加以下代码,但它不起作用;我该如何解决这个问题,请帮忙?
graph.addNode("NewNode");
function addNode (id) {
nodes.push({"id":id});
restart();
}
function restart() {
node = node.data(nodes);
node.enter().insert("circle", ".cursor")
.attr("class", "node")
.attr("r", 5);
node.exit()
.remove();
link = link.data(links);
link.enter().insert("line", ".node")
.attr("class", "link");
link.exit()
.remove();
force.start();
}
有几件事与不太明显的力量有关:
- 初始化后,原始数据数组中的节点获得了一堆新属性
- 初始化后,原始数据数组中的link被转换为新形式。
此外,如果您遵循 linked 示例,则不需要 enter/update/exit 样式循环 - 强制使用原始数据数组,而不是任何 DOM元素。
节点数
在您的参考示例中,节点仅以一个 ID 和一个组开头:
{"source": "Montparnasse", "target": "Babet", "value": 2}
然而,在使用 simulation.nodes(nodes)
初始化后,它们会得到一些附加参数:
group: 1
id: "Myriel"
index: 0
vx: 0.0026819653036056477
vy: -0.0005005454729913666
x: 306.003096668046
y: 359.07887474183434
这四个额外的属性跟踪节点。每个 tick 都要求这些属性已经存在,如果它们不存在,我们就会遇到问题。因此,如果我们提供一个新节点,我们可以为它赋予 x,y,vy,vx 属性,以便无缝添加它(example,在所有示例中单击以添加节点)。这给出了一个简单的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id":id, index: id, x: width/2, y: height/2, vx: 0, vy: 0});
}
或者我们可以使用 simulation.nodes()
(example), and the force will place it automatically while giving it the required position. However, this is jumpy unless you specify an x and y coordinate (example).
最后一个也给了我们一个非常直接的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id":id, group: 12, x: width/2, y: height/2});
simulation.nodes(graph.nodes)
}
这应该有助于将节点添加到力中。
链接
对于 links,您参考示例中的原始数据在加载时如下所示:
{ source: "Napoleon", target: "Myriel", value: 1 }
但是,在初始化 links 之后,采用以下形式:
index: 0
source: Object { id: "Napoleon", group: 1, index: 1, … }
target: Object { id: "Myriel", group: 1, index: 0, … }
value: 1
源和目标属性被转换为表示每个点的对象。与节点一样,ticked 函数要求节点采用后一种形式。同上,我们可以尝试复制格式,或者强制自己设置格式,我为link选择后者,而为新节点here设置x,y。这是为此的 addNode 函数:
function addNode () {
var id = graph.nodes.length;
graph.nodes.push({"id": id, x: width/2, y: height/2});
graph.links.push({source: "Javert", target: id });
simulation
.nodes(graph.nodes)
.force("link")
.links(graph.links);
}
作为一个更复杂但理论性较低的示例,例如