2

我创建了一个 D3 力有向图,将反应角作为节点,并在周边末端连接它们。由于我需要根据矩形对齐 div,因此我在 svg1 中创建了两个 svg 和链接,并根据 z-index,在其上方是 div,在 div 上方是第二个包含矩形/节点的 svg(不透明度为 0,因此 div可见的)。我遇到的问题是 IPAD 中的图表速度很慢,并且它的浏览器在打开绘制图表的页面时最小化了大约 80% 的时间。在调试时,我看到问题出在我的tick函数上,它的代码在这里,

force.start();
q = d3.geom.quadtree(nodes),count=0;
// define what to do one each tick of the animation
force.on("tick", function() {
    i = 0;
    //applying collision detection to avoid overlapping by default
    if(!mapCreated){
       while (++i < nodes.length) q.visit(collide(nodes[i]));
    }

    //this checks if node tries to move out (limitToCorners does that)
    node.attr("x", function(d) { return d.x = limitToCorners(d.x,"x"); })
    .attr("y", function(d) { return d.y = limitToCorners(d.y,"y"); });

    //this puts the link attribute to link directly to center of rectangle
    link.attr("x1", function(d) { return d.source.x+nodeModel.width/2; })
    .attr("y1", function(d) { return d.source.y+nodeModel.height/2; })
    .attr("x2", function(d) { return d.target.x+nodeModel.width/2; })
    .attr("y2", function(d) { return d.target.y+nodeModel.height/2; });

    //changing the CSS so that divs are in same place as the nodes
    changeGoalsPosition(refList);

    // changing the attributes of lines on svg so that it comes to the end of rectange (calculateLinkEndPoints does that)
   for(i=0;i<lines.length;i++){
      var obj = {};
      obj.source = {
            x: parseInt(linksRefList[i].attr("x1")),
            y: parseInt(linksRefList[i].attr("y1"))
      };
      obj.target = {
        x: parseInt(linksRefList[i].attr("x2")),
        y: parseInt(linksRefList[i].attr("y2"))
      };
      $(lines[i]).attr("x1", function(d) { return calculateLinkEndPoints(obj,"sx"); })
      .attr("y1", function(d) { return calculateLinkEndPoints(obj,"sy"); })
      .attr("x2", function(d) { return calculateLinkEndPoints(obj,"tx"); })
      .attr("y2", function(d) { return calculateLinkEndPoints(obj,"ty"); });
   }
 });    
4

1 回答 1

4

您在tick函数中进行的处理非常昂贵。你基本上有2个选择。

  • 减少要处理的节点数。
  • 减少tick事件的处理次数。

您是否可以执行前者将取决于您的应用程序。对于后者,您可以执行类似的操作来跳过所有其他事件。

var process = 1;
force.on("tick", function() {
    if(process) {
        // do processing
    }
    process = 1 - process;
});

您当然可以以类似的方式跳过更多事件。在某些时候,您可能会注意到由于跳过的事件,布局变得“跳跃”。您可以通过使用过渡将元素移动到新位置来缓解此问题,而不是简单地设置它们。

于 2013-09-07T11:19:50.910 回答