Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 重新启动模拟以添加或删除节点时,D3.js节点会跳转_Javascript_D3.js_Force Layout - Fatal编程技术网

Javascript 重新启动模拟以添加或删除节点时,D3.js节点会跳转

Javascript 重新启动模拟以添加或删除节点时,D3.js节点会跳转,javascript,d3.js,force-layout,Javascript,D3.js,Force Layout,我使用d3.JSV6和force布局来表示网络图。 我正在添加和删除节点,但当我重新启动模拟时,所有节点都跳转到左上角位置,然后返回到原始位置 下面的代码片段正好说明了我的意思,我在网上看到了其他的例子,它们工作得很好,但没有找到我做错了什么,非常感谢您的帮助 var数据集={ 节点:[ { 身份证号码:1 }, { 身份证号码:2 } ], 链接:[{ id:1, 资料来源:1, 目标:2 }] }; 设switchBool=false; 让svg=d3。选择('svg') .attr('

我使用d3.JSV6和force布局来表示网络图。 我正在添加和删除节点,但当我重新启动模拟时,所有节点都跳转到左上角位置,然后返回到原始位置

下面的代码片段正好说明了我的意思,我在网上看到了其他的例子,它们工作得很好,但没有找到我做错了什么,非常感谢您的帮助

var数据集={
节点:[
{
身份证号码:1
}, 
{
身份证号码:2
}
],
链接:[{
id:1,
资料来源:1,
目标:2
}]
};
设switchBool=false;
让svg=d3。选择('svg')
.attr('width','100%”)
.attr(‘高度’、‘100%’);
const width=svg.node()
.getBoundingClientRect().width;
const height=svg.node()
.getBoundingClientRect()高度;
log(`${width},${height}`);
svg=svg.append('g');
append('g')
.attr('class','links');
append('g')
.attr('class','nodes');
常量模拟=d3.forceSimulation();
initSimulation();
让link=svg.select(“.links”)
.selectAll(“行”);
loadLinks();
让node=svg.select(“.nodes”)
.selectAll('.node');
loadNodes();
重启模拟();
函数initSimulation(){
模拟
.force('link',d3.forceLink())
.force('charge',d3.forceManyBody())
.force('collide',d3.forceCollide())
.force('center',d3.forceCenter())
.force('forceX',d3.forceX())
.force('forceY',d3.forceY());
模拟力(“中心”)
.x(宽度*0.5)
.y(高度*0.5);
simulation.force('link'))
.id((d)=>d.id)
.距离(100)
.迭代次数(1);
模拟力(“碰撞”)
.半径(10);
模拟力(“电荷”)
.兵力(-100);
}
函数loadLinks(){
link=svg。选择(“.links”)
.selectAll('行')
.数据(dataset.links,(d)=>d.id)
.加入(
enter=>enter.append('line').attr('stroke','#000000'),
);
}
函数loadNodes(){
node=svg.select(“.nodes”)
.selectAll(“.node”)
.data(dataset.nodes,(d)=>d.id)
.加入(
输入=>{
const nodes=enter.append('g')
.attr('类','节点')
nodes.append('circle').attr('r',10);
返回节点;
},
);
}
函数restartSimulation(){
模拟节点(dataset.nodes);
simulation.force('link').links(dataset.links);
simulation.alpha(1.restart();
模拟。on('tick',ticked);
}
函数勾选(){
链接
.attr('x1',(d)=>d.source.x)
.attr('y1',(d)=>d.source.y)
.attr('x2',(d)=>d.target.x)
.attr('y2',(d)=>d.target.y);
attr('transform',(d)=>`translate(${d.x},${d.y})`);
}
函数updateData(){
switchBool=!switchBool;
if(switchBool){
dataset.nodes.push({id:3});
push({id:2,源:1,目标:3});
}否则{
dataset.nodes.pop();
dataset.links.pop();
}
loadLinks();
loadNodes();
重启模拟();
}

添加/删除

事实上,我刚刚找到了问题的解决方案

我有两个带有默认参数的
forceX
forceY
,这意味着有一个力将节点推向(0,0),更改此代码位后,我能够修复它:

.force('x', d3.forceX().x(width * 0.5))
.force('y', d3.forceY().y(height * 0.5));

这是因为您使用的
d3.forceCenter()
不会将节点强制到中心点:

定心力均匀地平移节点,以便 所有节点的位置(如果所有节点具有相等的 重量)在给定位置⟨x、 y⟩. ()

因此,如果两个节点位于d3.forceCenter的中心点正下方或正上方,则质量是平衡的。引入一个新节点,整个力必须进行转换,以使质心为中心。这个翻译就是你看到的跳跃

删除forceCenter并使用d3.forceX和d3.forceY指定中心值,它们会将节点推向指定的x和y值:

var数据集={
节点:[
{
身份证号码:1
}, 
{
身份证号码:2
}
],
链接:[{
id:1,
资料来源:1,
目标:2
}]
};
设switchBool=false;
让svg=d3。选择('svg')
.attr('width','100%”)
.attr(‘高度’、‘100%’);
const width=svg.node()
.getBoundingClientRect().width;
const height=svg.node()
.getBoundingClientRect()高度;
log(`${width},${height}`);
svg=svg.append('g');
append('g')
.attr('class','links');
append('g')
.attr('class','nodes');
常量模拟=d3.forceSimulation();
initSimulation();
让link=svg.select(“.links”)
.selectAll(“行”);
loadLinks();
让node=svg.select(“.nodes”)
.selectAll('.node');
loadNodes();
重启模拟();
函数initSimulation(){
模拟
.force('link',d3.forceLink())
.force('charge',d3.forceManyBody())
.force('collide',d3.forceCollide())
.力('forceX',d3.forceX().x(宽度/2))
.力('forceY',d3.forceY().y(高度/2));
simulation.force('link'))
.id((d)=>d.id)
.距离(100)
.迭代次数(1);
模拟力(“碰撞”)
.半径(10);
模拟力(“电荷”)
.兵力(-100);
}
函数loadLinks(){
link=svg。选择(“.links”)
.selectAll('行')
.数据(dataset.links,(d)=>d.id)
.加入(
enter=>enter.append('line').attr('stroke','#000000'),
);
}
函数loadNodes(){
node=svg.select(“.nodes”)
.selectAll(“.node”)
.data(dataset.nodes,(d)=>d.id)
.加入(
输入=>{
const nodes=enter.append('g')
.attr('类','节点')
nodes.append('circle').attr('r',10);
返回节点;
},
);
}
函数restartSimulation(){
模拟节点(dataset.nodes);
simulation.force('link').links(dataset.links);
simulation.alpha(1.restart();
模拟。on('tick',ticked);
}
函数勾选(){
链接
.attr('x1',(d)=>d.source.x)
.attr('y1',(d)=>d.source.y)
.attr('x2',(d)=>d。