【问题标题】:d3 force layout nodes always start at top-left of screend3 强制布局节点总是从屏幕的左上角开始
【发布时间】:2015-11-10 22:22:33
【问题描述】:

我有一个力布局,其节点定义如下...

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。感谢您的任何想法!

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    我会检查 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;
    }
    

    【讨论】:

    • 感谢 Lars - 这完全解决了问题 - 只需要确保在我在页面上绘制任何圆圈、图像等之前发生 1 个刻度。
    • 在这种情况下,您甚至可以在启动之后和添加处理程序之前调用force.tick()
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-02-01
      • 1970-01-01
      • 2014-01-02
      • 2014-10-18
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多