提升D3js力导向图加载速度(转)

D3力导向图

过去一段时间曾两次使用了 D3 力导向图来描绘族群关系。node

http://bl.ocks.org/mbostock/1062288git

第一次用的时候不求甚解,交差了事。当时点也很少,很顺利完成了任务。这一次确不一样,每一个图里要渲染的有成千上万个点,每次渲染都死慢死慢,一大堆点动来动去,动半天才稳定下来,这一晃几分钟过去了。github

阅读了一下官方文档 ,发现问题出来 tick 上。post

force.start() 后,有一个计时器不停地触发 tick 直到全部节点最终受力平衡稳定下来。this

能够理解为,有个计时器不停在打点,每打一次点须要触发一次 tick() 里的动做。而 tick() 的默认动做是重绘全部节点和连线位置。由于图形渲染须要时间长,渲染的次数又多,因此须要等很长时间。spa

function tick() {
  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; });

  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

怎样加快出图的速度呢?或者说,能不能不看中间复杂的变化过程,只看最终稳定的结果?rest

从官方文档里查到 alpha 参数。这个值最开始是 1,随着图形趋于稳定,它也会逐渐趋近 0。code

force.alpha([value])ci

Gets or sets the force layout's cooling parameter, alpha. If value is specified, sets alpha to the specified value and returns the force layout. If value is greater than zero, this method also restarts the force layout if it is not already running, dispatching a "start" event and enabling the tick timer. If value is nonpositive, and the force layout is running, this method stops the force layout on the next tick and dispatches an "end" event. If value is not specified, this
method returns the current alpha value.文档

因而,对原来的代码稍做修改:

force.on("tick", function () {

    if(force.alpha()<=0.05){  // 足够稳定时,才渲染一次

      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; });
      node.attr("cx", function (d) { return d.x; })
          .attr("cy", function (d) { return d.y; });

      force.stop(); // 渲染完成后当即中止刷新
    }
});

这样修改以后,一个上万节点的图,一般在几秒内就能够绘制完成了。好比出这么个图,几秒钟就搞定了。

相关文章
相关标签/搜索