问题描述
我有一个带有节点和链接的力有向图,我想在点击重置后将图重置到其原始位置。我设法通过创建另一个图形来实现重置结果,该图形具有力有向图的坐标:https://jsfiddle.net/Lf0jcnt1/1/
对于reset方法,我使用了这个函数:
function reset(source) {
source.selectAll("circle")
.transition()
.duration(750)
.style("fill","red")
.attr("cx",function(d) {
console.log("Initial X position from RESET is " + d.c);
return (d.c)
})
.attr("cy",function(d) {
return (d.z)
})
}
像这样附加数据的地方:
var circle_data = d3.range(nodes_len).map(function(i) {
return {
c: x_nodes[i],z:y_nodes[i]
};
});
问题是当单击重置按钮时,力有向图不会将节点位置重置为原始位置,节点将被平移到与原始位置不同的位置。
下面是强制图的代码:
constructor(nodes: Node[],links: Link[],options: { width: number,height: number }) {
this.nodes = nodes;
this.links = links;
this.options = options;
this.simulation = forceSimulation<Node,Link>()
.force('links',forceLink(this.links).distance(FORCES.DISTANCE).strength(FORCES.LINKS))
.force('collide',forceCollide((node: Node) => node.radius * 2 + 30))
.force('center',forceCenter(this.options.width / 2,this.options.height / 2))
.force('cluster',forceCluster((node: Node,index: number,data: Node[]) => {
const numberOfGroups = this.nodes.map(n => n.group).filter((value,i,array) => array.indexOf(value) === i).length;
for (let i = 0; i < numberOfGroups; i++) {
if (node.group === i + 1) {
const max = data.filter(n => n.group === i + 1).map(n => n.instancesCount).sort((n1,n2) => n1 - n2).pop();
return data.filter(n => n.group === i + 1).filter(n => n.instancesCount === max).pop();
}
}
}).strength(FORCES.CLUSTER))
.nodes(this.nodes)
;
this.simulation.on('tick',() => {
this.ticker.next();
});
this.simulation.on('end',() => {
console.log("end of simulation values);
this.xNodeValues = this.nodes.map( (node)=> node.x);
this.yNodeValues = this.nodes.map( (node)=> node.y);
});
}
对于力有向图,我尝试使用和之前一样的reset方法,只是用x和y代替了c和z,但是产生了平移效果,而不是复位到原来的位置。知道如何解决这个问题吗?
解决方法
您可以在初始位置 JSON.stringify
处创建节点的“快照”
this.savedNodes = JSON.stringify(nodes)
当点击重置按钮时,您可以将其加载回类和模拟:
this.nodes = JSON.parse(this.savedNodes)
this.simulation.nodes(this.nodes).restart()