d3强制布局节点始终从屏幕的左上角开始

时间:2015-10-20 16:07:52

标签: d3.js

我有一个强制布局,节点定义如下......

nodes = someData.map(function (d) {
        return {
            image_location: d.image_location, 
            image_width: d.image_width, 
            image_height: d.image_height, 
            aspect_ratio: d.aspect_ratio,
            radius: circleRadiusScale(d.someCount),
            x: width/2,
            y: height / 2,
            px: width/2,
            py: height/2,
            cx: width/2,
            cy: height / 2
        };
    });     

然后在代码中稍后使用...

创建强制布局
force = d3.layout.force()
    .gravity(.05)
    .alpha(0.1) 
    .size([width, height])
    .on("tick", tick); 

force.nodes(nodes)
      .start();

我强制x / y,px / py,cx / cy值的原因是我只是想确保节点不总是开始在浏览器的左上角投影(在力模拟生效之前只有一瞬间,但特别是在Firefox或移动设备上非常明显。)

对我来说奇怪的是,我正在使用我的x / y,cx / cy,px / py值开始强制布局,然后在我编写的代码中加入浏览器应该显示的圆圈,图像等 - 在其他单词,此代码在定义/启动力布局之后出现......

node = svg.selectAll(".node")
              .data(force.nodes(), function(d) { return d.id; })
              .enter()           
              .append("g")
              .attr("class", "node") etc to append circles, images...

所以我想知道如何阻止浏览器对节点的投影,直到我知道力布局的初始位置不是0,0。谢谢你的任何想法!

2 个答案:

答案 0 :(得分:4)

我会检查tick处理函数内的位置,并在条件满足后初始化:

var initialized = false;
force.on("tick", function() {
  if(!initialized) {
    // can also check multiple nodes here...
    if(nodes[0].x != width/2 && nodes[0].y != height/2) initialize();
  } else {
    // update node positions
  }
});

function initialize() {
  node = svg.selectAll(".node")
          .data(force.nodes(), function(d) { return d.id; })
          .enter()           
          .append("g")
          .attr("class", "node") // etc
  initialized = true;
}

答案 1 :(得分:1)

在我的情况下,节点在调用tick()之前进入并显示。因此,它们将首先显示在屏幕的左上角,然后调用tick()以转换为图形中的实际位置。 添加图形时只隐藏节点:

nodeEnter.style("visibility", "hidden")

并且,在tick()函数中可见:

nodeEnter.style("visibility", "visible")