Javascript D3力布局数据不存在';t更新
我使用D3的强制布局图来绘制数据Javascript D3力布局数据不存在';t更新,javascript,d3.js,d3-force-directed,Javascript,D3.js,D3 Force Directed,我使用D3的强制布局图来绘制数据 使用带有新数据的setInterval调用update函数时,强制布局图节点从随机位置开始。我怎样才能解决这个问题 即使console打印正确的数据,数据也不会得到更新。我怎样才能解决这个问题呢 这里是JSFIDLE:(请避免在同一个问题中询问不同的问题,特别是当它们不相关时。在这里,我将解释您的问题2,它是特定于您的代码的。您的问题1是一个一般性问题,已经在S.O这里的几个问题/答案中解决了。) update函数的问题在于,您将索引用作键。但是,对于这些不同的
setInterval
调用update
函数时,强制布局图节点从随机位置开始。我怎样才能解决这个问题console
打印正确的数据,数据也不会得到更新。我怎样才能解决这个问题呢if (!node.id) node.id = ++i;
。。。用于为节点分配唯一的ID的内容。显而易见的选择是使用他们的名字:
if (!node.id) node.id = node.name;
但是,即使这样也不行,因为有些节点具有相同的名称。。。因此,我们可以混合使用以下方法:
if (!node.id) node.id = node.name + (++i);
请记住,这只是一个例子。最好的解决方案是找到某些属性(或属性的组合),这些属性对于每个节点都是唯一且相同的
以下是仅包含该更改的代码:
var宽度=680,
高度=380,
根;
变量数据1={
“名称”:“根节点”,
“儿童”:[{
“名称”:“B1”,
“儿童”:[{
“名称”:“D1”
}, {
“名称”:“D2”
}, {
“名称”:“D3”
}]
}, {
“名称”:“B2”,
“儿童”:[{
“名称”:“D1”
}, {
“名称”:“D2”
}, {
“名称”:“D3”
}, {
“名称”:“D4”
}]
}, {
“名称”:“B3”,
“儿童”:[{
“名称”:“D1”
}, {
“名称”:“D2”
}, {
“名称”:“D3”
}, {
“名称”:“D4”
}, {
“名称”:“D5”
}]
}, {
“名称”:“B4”,
“儿童”:[{
“名称”:“D1”
}, {
“名称”:“D2”
}, {
“名称”:“D3”
}, {
“名称”:“D4”
}]
}, {
“名称”:“B5”,
“儿童”:[{
“名称”:“D1”
}]
}]
};
变量数据2={
“名称”:“根”,
“儿童”:[{
“名称”:“框1”,
“儿童”:[{
“名称”:“设备1”
}, {
“名称”:“设备2”
}, {
“名称”:“设备3”
}]
}, {
“名称”:“框2”,
“儿童”:[{
“名称”:“设备1”
}, {
“名称”:“设备2”
}, {
“名称”:“设备3”
}, {
“名称”:“设备4”
}]
}, {
“名称”:“框3”,
“儿童”:[{
“名称”:“设备1”
}, {
“名称”:“设备2”
}, {
“名称”:“设备3”
}, {
“名称”:“设备4”
}, {
“名称”:“设备5”
}]
}, {
“名称”:“第4栏”,
“儿童”:[{
“名称”:“设备1”
}, {
“名称”:“设备2”
}, {
“名称”:“设备3”
}, {
“名称”:“设备4”
}]
}, {
“名称”:“第5栏”,
“儿童”:[{
“名称”:“设备1”
}]
}]
};
var-force=d3.layout.force()
.linkDistance(80)
。收费(-120)
.重力(.05)
.尺寸([宽度、高度])
.在(“滴答”,滴答)上;
var svg=d3。选择(“.network graph”)。追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var link=svg.selectAll(“.link”),
node=svg.selectAll(“.node”);
根=数据1;
更新();
setInterval(函数(){
根=数据2;
更新();
}, 5000);
函数更新(){
变量节点=展平(根),
links=d3.layout.tree().links(节点);
//重新启动强制布局。
力
.节点(节点)
.链接(links)
.start();
//更新链接。
link=link.data(链接,函数(d){
返回d.target.id;
});
link.exit().remove();
link.enter().insert(“行”,“节点”)
.attr(“类”、“链接”);
//更新节点。
节点=节点。数据(节点,函数(d){
返回d.id;
});
node.exit().remove();
var nodeEnter=node.enter().append(“g”)
.attr(“类”、“节点”)
.on(“单击”,单击)
.呼叫(强制拖动);
nodeEnter.append(“圆”)
.attr(“r”,函数(d){
返回15 | | 4.5;
});
nodeEnter.append(“文本”)
.attr(“dy”,“.35em”)
.文本(功能(d){
返回d.name;
});
节点。选择(“圆”)
.样式(“填充”,颜色);
}
函数tick(){
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(“转换”,函数(d){
返回“translate”(“+d.x+”,“+d.y+”);
});
}
功能色(d){
退回d.#儿童?#3182bd//折叠包裹
:d.儿童?#c6dbef”//扩展包
:“#fd8d3c”;//叶节点
}
//在单击时切换子项。
功能点击(d){
if(d3.event.defaultPrevented)返回;//忽略拖动
如果(d.儿童){
d、 _children=d.children;
d、 children=null;
}否则{
d、 儿童=d.\U儿童;
d、 _children=null;
}
更新();
}
//返回根目录下所有节点的列表。
函数展平(根){
变量节点=[],
i=0;
函数递归(节点){
if(node.children)node.children.forEach(recurse);
如果(!node.id)node.id=node.name++(++i);
nodes.push(节点);
}
递归(根);
返回节点;
}
。节点圆{
光标:指针;
行程:#3182bd;
笔划宽度:1.5px;
}
.节点文本{
字体:10px无衬线;
指针事件:无;
文本锚定:中间;
}
line.link{
填充:无;
行程:#9ecae1;
笔划宽度:1.5px;
}
感谢@gerardo furtado帮助解决这个问题#2,它现在可以工作了。关于问题#1,我实际上在
start()
之前尝试了alpha(0)
,但没有成功。如果你能告诉我怎么做,或者至少告诉我正确的方向,我会非常感激。再次感谢你的帮助。