javascript 为什么我们需要 force.on('tick'.. in d3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28745398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:29:23  来源:igfitidea点击:

Why do we need force.on('tick'.. in d3

javascriptd3.js

提问by timebandit

I am learning d3 by coding a force directed graph from basics. My code is below.What I don't understand is the purpose of force.on('tick'...

我正在通过从基础编码一个力有向图来学习 d3。我的代码如下。我不明白的是force.on('tick'...

Surely if we are using a in-built class for the layout I would have thought that it is enough to give d3.layout.force() your nodes and links and it should be able to draw the graph in a balanced layout.

当然,如果我们为布局使用内置类,我会认为给 d3.layout.force() 你的节点和链接就足够了,它应该能够以平衡的布局绘制图形。

If I comment out the section force.on('tick'... then all my circles and lines end up in the top left hand corner. Is there are difference between what is happening internally and what is happening in the svg container hence we need the force.on('tick'to redraw the layout to match the current set of internal values each time?

如果我注释掉force.on('tick'... 部分,那么我所有的圆圈和线条都会在左上角结束。内部发生的事情与 svg 容器中发生的事情之间是否存在差异,因此我们每次都需要force.on('tick'重新绘制布局以匹配当前的一组内部值吗?

var nodes = [
      {},
      {},
      {}
];

var links = [
      {'source': 0, 'target': 1}
];

// append svg element to container
var mychart = d3.select('#chart')
      .append('svg')
      .attr('width', w)
      .attr('height', h);

// create force layout in memory
var force = d3.layout.force()
      .nodes(nodes)
      .links(links)
      .size([w, h]);

// append a group for each data element
var node = mychart.selectAll('circle')
      .data(nodes).enter()
      .append('g')
      .call(force.drag);

// append circle onto each 'g' node
node.append('circle')
      .attr('fill', palette.green)
      .attr('r', circleWidth);


/*force.on('tick', function(e) {
      node.attr('transform', function(d, i) {
            return 'translate('+ d.x +', '+ d.y +')';
      })

      link
            .attr('x1', function(d) { return d.source.x })
            .attr('y1', function(d) { return d.source.y })
            .attr('x2', function(d) { return d.target.x })
            .attr('y2', function(d) { return d.target.y })
});*/


var link = mychart.selectAll('line')
      .data(links).enter()
      .append('line')
      .attr('stroke', palette.gray)

force.start();

回答by Lars Kotthoff

The force layout runs asynchronously. That is, when you call force.start()it starts doing its computations that determine the position of the nodes in parallel in the background. These computations are not a single step, but a simulation running over a long time (several seconds).

力布局异步运行。也就是说,当您调用force.start()它时,它开始进行计算,以确定后台并行节点的位置。这些计算不是单一步骤,而是长时间(几秒钟)运行的模拟。

The tickhandler is the function that enables you to get the state of the layout when it has changed (the simulation has advanced by a tick) and act on it -- in particular, redraw the nodes and links where they currently are in the simulation.

tick处理器是使当它改变你得到布局的状态(模拟已经蜱高级),并作用于它的作用-尤其是重绘,他们目前都在模拟的节点和链接。

You don't have to handle the tickevent though, you could simply run the layout for a certain number of steps and then draw without handling the tickevent at all, as in this example. Doing it dynamically in the tickhandler function has the advantage that you can see how the layout progresses. However, technically it is not needed if you're just interested in the result.

tick不过,您不必处理事件,您可以简单地将布局运行一定数量的步骤,然后tick在完全不处理事件的情况下进行绘制,如本例所示。在tick处理程序函数中动态执行它的优点是您可以看到布局的进展情况。但是,从技术上讲,如果您只是对结果感兴趣,则不需要它。