D3强制布局将图像作为节点但附加了错误的图像

时间:2015-07-24 22:28:36

标签: javascript image d3.js svg force-layout

我尝试使用图像作为节点创建强制布局,可以根据用户输入(通过几个复选框)进行修改。但是,当用户更改他/她的输入并重新绘制布局时,某些图像会显示在错误的节点之上,我无法理解原因。

我构建代码的方式:

  1. 我从csv
  2. 中提取数据
  3. 我创建了一个"更新"根据用户输入创建/修改数据数组的函数
  4. 我创建了一个" draw"每当用户改变他/她的输入时(即每次调用函数"更新")时绘制力布局的函数
  5. 我的代码的第一部分似乎工作正常。数据数组是从csv创建的,并且可以正确地动态更新。

    但是当重绘图形时,一些图像出现在错误的节点上(即使工具提示中显示的图像是正确的...)。

    以下是我的" draw"功能,我认为这就是问题所在。

    function draw(nodes) {
    
          var force = d3.layout.force()
            .nodes(nodes)
            .size([width, height])
            .on("tick", tick)
            .charge(-0.01)
            .gravity(0)
            .start();
    
        function tick(e) {
    
          // Set initial positions
        nodes.forEach(function(d) {
            d.radius = radius;
          });
    
    
          var node = svg.selectAll(".node")
                        .data(nodes);
    
          var newNode = node.enter().append("g")
                    .attr("class", "node")
                    .on("click", function(d) {
                                       div.transition().duration(300).style("opacity", 1);
                                       div.html("<img src=img_med/" + d.name + ".png >")
                                       .style("left", (d3.event.pageX) + "px")
                                       .style("top", (d3.event.pageY-10) + "px");
                                    })
                    .on("mouseout", function (d) { div.transition().delay(1500).duration(300).style("opacity", 0);});
    
              newNode.append("image")
                 .attr("xlink:href", function(d) { return "img_med/" + d.name + ".png"; })
                 .attr("x", -8)
                 .attr("y", -8)
                 .attr("width", 30)
                 .attr("height", 30)
                 .style("cursor", "pointer")
                 .call(force.drag);
    
          node.exit().remove();
    
          node.each(moveTowardDataPosition(e.alpha));
          node.each(collide(e.alpha));
          node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    
        }
    
        function moveTowardDataPosition(alpha) {
          return function(d) {
            d.x += (x(d[xVar]) - d.x) * 0.1 * alpha;
            d.y += (y(d[yVar]) - d.y) * 0.1 * alpha;
          };
        }
    
        // Resolve collisions between nodes.
        function collide(alpha) {
          var quadtree = d3.geom.quadtree(nodes);
          return function(d) {
            var r = d.radius + radius + padding,
                nx1 = d.x - r,
                nx2 = d.x + r,
                ny1 = d.y - r,
                ny2 = d.y + r;
            quadtree.visit(function(quad, x1, y1, x2, y2) {
              if (quad.point && (quad.point !== d)) {
                var x = d.x - quad.point.x,
                    y = d.y - quad.point.y,
                    l = Math.sqrt(x * x + y * y),
                    r = d.radius + quad.point.radius + padding;
                if (l < r) {
                  l = (l - r) / l * alpha;
                  d.x -= x *= l;
                  d.y -= y *= l;
                  quad.point.x += x;
                  quad.point.y += y;
                }
              }
              return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            });
          };
        }
    }
    

    任何帮助/建议/指示,以帮助我理解为什么错误的图像显示在这些节点之上将是非常感谢!

    如果有什么不清楚,请告诉我。

    非常感谢!

1 个答案:

答案 0 :(得分:0)

好吧,我刚刚错过了一个关键功能,告诉D3如何匹配现有节点和数据。

我替换了

 var node = svg.selectAll(".node")
               .data(nodes);

通过

 var node = svg.selectAll(".node")
               .data(nodes, function(d) {return d.name;});

它有效。 谢谢Lars!