d3 v5强制模拟:如何使用停止和滴答

时间:2019-03-31 20:36:32

标签: javascript d3.js

我试图理解停止d3.force模拟。根据{{​​3}},我应该能够进行simulation.stop(),然后通过它进行restarttick的操作。但是,如果我取消注释simulation.stop()行,下面的代码将停止工作。看来simulation.tick()行被完全忽略了。我在做什么错了?

我需要它来调试节点位置演变。我希望看到位于(50,50)和(51,51)的节点,然后每隔一个刻度便从那里移开。

<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
    var nodes = [{"x": 50, "y": 50}, {"x": 51, "y": 51}];
    var height = 200,
        width = 200;

    var svg = d3
        .select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

    var node = svg.selectAll(".node").data(nodes)
        .enter().append("g").attr("class", "node");

    node.append("circle").attr("r", 5);

    var simulation = d3.forceSimulation()
        .force("collision", d3.forceCollide().radius(30));

    simulation.nodes(nodes).on("tick", ticked);

//    simulation.stop();
    simulation.tick();
    simulation.tick(10);

    function ticked() {
        // console.log("Ticked");
        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    }

</script>

1 个答案:

答案 0 :(得分:1)

答案由@altocumulus在评论中提供。

我的simulation.stop()代码无法正常工作,因为从未调用ticked(),因此节点位置没有更新。如documentation中针对tick()所述:

  

此方法不调度事件。

所以.on("tick", ticked)没有做任何事情。要解决此问题,可以在ticked()之后手动致电tick()

while (simulation.alpha() > simulation.alphaMin()) { simulation.tick(); ticked(); }