简体   繁体   English

如何将力有向图重置为其原始 position?

[英]How to reset force directed graph to its original position?

I have a force directed graph with nodes and links and i would like to reset the graph to its original position after hitting reset.我有一个带有节点和链接的力导向图,我想在重置后将图重置为其原始 position。 I managed to achive the reset result by creating another graph, which has the coordinates of the force directed graph: https://jsfiddle.net/Lf0jcnt1/1/我设法通过创建另一个图来实现重置结果,该图具有力导向图的坐标: https://jsfiddle.net/Lf0jcnt1/1/

For the reset method, I used this function:对于重置方法,我使用了这个 function:

  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)
      })
  }

Where data is appended like this:像这样附加数据的地方:

  var circle_data = d3.range(nodes_len).map(function(i) {
    return {
      c: x_nodes[i],
      z:y_nodes[i]
    };
  });

The problem is that the force directed graph won't reset the nodes position to their original ones when clicking the reset button, the nodes will get translated in different positions than the original.问题是,当单击重置按钮时,力有向图不会将节点 position 重置为原始节点,节点将被平移到与原始位置不同的位置。

Below is the code for the forced graph:下面是强制图的代码:

    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);
        });

    }

For the force directed graph, I tried to use the same reset method as before, but replace c and z with x and y, but the translation effect takes place, not the reset to the original place.对于力有向图,我尝试使用与之前相同的重置方法,但将 c 和 z 替换为 x 和 y,但发生平移效果,而不是重置到原始位置。 Any idea on how to solve this?关于如何解决这个问题的任何想法?

You can create a "snapshot" of the nodes at the inital position JSON.stringify您可以在初始 position JSON.stringify创建节点的“快照”

this.savedNodes = JSON.stringify(nodes)

And when the reset button is clicked, you can load it back to the class and to the simulation:单击重置按钮后,您可以将其加载回 class 和仿真:

this.nodes = JSON.parse(this.savedNodes)
this.simulation.nodes(this.nodes).restart()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM