D3.JS树形图-点击的顺序会弄乱数据

D3.JS树形图-点击的顺序会弄乱数据,d3.js,tree,nodes,interchange,D3.js,Tree,Nodes,Interchange,我有一个D3树图,当单击节点时,它从API加载数据。我注意到节点的点击顺序影响了树中数据的显示。数据是正确的,但节点的顺序会根据单击的顺序发生变化(const nodes=treeData.subjections()) 我的密码 节点\u单击(d){ d、 data.isCollapsed=!d.data.isCollapsed; this.service.linkedConcepts(d.data.id) 。然后(数据=>{ 如果(数据){ const items=任何数据[]; this.

我有一个D3树图,当单击节点时,它从API加载数据。我注意到节点的点击顺序影响了树中数据的显示。数据是正确的,但节点的顺序会根据单击的顺序发生变化(const nodes=treeData.subjections())

我的密码

节点\u单击(d){
d、 data.isCollapsed=!d.data.isCollapsed;
this.service.linkedConcepts(d.data.id)
。然后(数据=>{
如果(数据){
const items=任何数据[];
this.appendData(d.data.id、this.treeData、items);
如果(d.儿童){
d、 _children=d.children;
d、 children=null;
}否则{
d、 儿童=d.\U儿童;
d、 _children=null;
}
this.root=d3.hierarchy(this.treeData,d=>d.children);
本报告更新(d);
}
})
.catch(错误=>{
此.removeFromDataBeingRetrieved(d.data.id);
控制台错误(err);
});
}
appendData(父ID、节点、项){
if(node.id==parentid){
items.forEach(item=>{
node.children.push({
名称:item.Label,
id:item.ConceptID,
是的,
isTopConcept:false,
计数:item.LinkedConceptsCount,
儿童:[]
});
});
node.isCollapsed=false;
}else if(节点子节点){
node.children.forEach(item=>this.appendData(parentid,item,items));
}
}
更新(来源){
const treeData=this.treemap(this.root);
//计算新的树布局。
const nodes=treeData.subjects(),
links=treeData.subjects().slice(1);
//为固定深度进行规格化。
nodes.forEach(d=>d.y=d.depth*180);
//*******************节点部分***************************
设i=0;
//更新节点。。。
const node=this.svg.selectAll('g.node')
.data(节点,函数(d){返回d.id | |(d.id=++i)});
//在父对象的上一个位置输入任何新模式。
const nodenter=node.enter().append('g')
.attr('类','节点')
.attr('transform',d=>'translate('+source.y0+','+source.x0+'))
.on('click',d=>this.node_clicked(d));
//为节点添加圆
nodeEnter.append('circle'))
.attr('类','节点')
.attr('r',1e-6)
.样式(“笔划”,功能(d){
返回d.data.count>0?'#fff':'steelblue';})
.样式(“填充”,功能(d){
返回d.iscollected&&d.data.count>0?'lightsteelblue':'fff';
})
.append('标题')
.text(d=>d.data.count+“链接文章”);
//为节点添加标签
nodeEnter.append('text')
.attr('dy','.35em'))
.attr('x',函数(d){
返回d.children | | d.| U儿童?-13:13;
})
.attr('text-anchor',函数(d){
返回值(d.data.isTopConcept==true)?'end':'start';
})
.text(函数(d){return d.data.name;})
.call(d=>this.wrap(d));
//更新
const nodeUpdate=nodenter.merge(节点);
//转换到节点的正确位置
nodeUpdate.transition()
.duration(此.duration)
.attr('transform',函数(d){
返回“translate”(“+d.y+”,“+d.x+”);
});
//更新节点属性和样式
nodeUpdate.select('circle.node')
.attr('r',10)
.样式(“填充”,功能(d){
如果(d.data.count==0){
返回“#fff”;
}else if(d.data.isCollapsed==true){
返回“lightsteelblue”;
}否则{
返回“#fff”;
}
})
.style('stroke-width','3px')
.样式(“笔划”,功能(d){
返回d._children>0?'#fff':'lightsteelblue';})
.attr(“光标”、“指针”);
//删除任何现有节点
const nodeExit=node.exit().transition()
.duration(此.duration)
.attr('transform',函数(d){
返回“translate('+source.y+','+source.x+');
})
.remove();
//退出时,将节点圆的大小减小为0
nodeExit.select('circle')
.attr('r',1e-6);
//退出时减少文本标签的不透明度
nodeExit.select('text')
.样式(“填充不透明度”,1e-6);
//*******************链接部分***************************
//更新链接。。。
const link=this.svg.selectAll('path.link')
.数据(链接,d=>d['id']);
//在父对象的上一个位置输入任何新链接。
const linkEnter=link.enter().insert('path','g')
.attr('class','link')
.style('填充','无')
.style('stroke','#ccc')
.style('stroke-width','3px')
.attr('d',d=>this.diagonal({x:source.x,y:source.y},
{x:source.x,y:source.y});
//更新
const linkUpdate=linkEnter.merge(link);
//转换回父元素位置
linkUpdate.transition()
.duration(此.duration)
.attr('d',d=>this.diagonal(d,d.parent));
//删除任何现有链接
const linkExit=link.exit().transition()
.duration(此.duration)
.attr('d',d=>this.diagonal({x:source.x,y:source.y},
{x:source.x,y:source.y})
.remove();
//存储旧位置以进行转换。
nodes.forEach(函数(d){
d、 x0=d.x;
d、 y0=d.y;
});

}
这一行代码导致了问题

const node=this.svg.selectAll('g.node'))
.data(节点,函数(d){返回d.id | |(d.id=++i)})