拖动整个节点强制导向图d3

时间:2014-10-10 03:33:01

标签: javascript d3.js

我在d3中使用了强制定向布局。我已经看过这篇文章http://bl.ocks.org/eyaler/10586116,但似乎我很难将如何应用它。这是我到目前为止所做的事情。

 var width = 960,
 height = 500,
 root;

 var force = d3.layout.force()
.linkDistance(90)
.charge(-1000)
.gravity(.100)
.size([width, height])
.on("tick", tick);

 var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

var link = svg.selectAll(".link"),
node = svg.selectAll(".node");

var div = d3.select("body")
.append("div")  // declare the tooltip div 
.attr("class", "tooltip")
.style("opacity", 0);

d3.json("graph.json", function(error, json) {
root = json;
update();
});

  function update() {
  var nodes = flatten(root),
  links = d3.layout.tree().links(nodes);

//重新启动强制布局。

  force
  .nodes(nodes)
  .links(links)
  .start();

//更新链接。

 link = link.data(links, function(d) { return d.target.id; });

 link.exit().remove();

 link.enter().insert("line", ".node")
  .attr("class", "link")
  .style("stroke", function(d) { return d.target.level; });

//更新节点。

  node = node.data(nodes, function(d) { return d.id; });

  node.exit().remove();

  var nodeEnter = node.enter().append("g")
  .attr("class", "node")
  .on("click", click)
  .call(force.drag);

  var defs = node.append("defs").attr("id", "imgdefs");

  var imgPattern = defs.append("pattern")
  .attr("id", "imgPattern")
  .attr("height", 30)
  .attr("width", 30)
  .attr("x", "0")
  .attr("y", "0");

  imgPattern.append("image")
  .attr("height", 30)
  .attr("width", 30)
  .attr("xlink:href", function(d) { return d.image; });

  node.select("circle")
  .style("fill", "url(#imgPattern)");

  nodeEnter.append("circle")
  .attr("r", 15)
  .style("stroke",color)
  .style("stroke-width", 4)
  .style("fill", "url(#imgPattern)")
  .on("mouseover", function(d) {

                  circlePos = this.getBoundingClientRect();

                  div.transition()
                      .duration(500)
                      .style("opacity", 1)
                      .style("cursor","pointer")
                      .style("left", (circlePos.left + circlePos.width+window.scrollX) + 'px')
                      .style("top", (circlePos.top + window.scrollY) + 'px')
                      .style("position", "absolute")

                        div.html(
                          "<div style='position: absolute; border:2px solid red; background-color: yellow; z-index=-1'>" +
                            "<div class='container'>" +
                              "<div id='wrap'>" +
                                "<div class='col-md-3'>" +
                                  "<div class='g-hover-card'>"  +                                   
                                      "<div class='user-avatar'>" +
                                        "<img src='"+ d.image +"' alt='' style='margin-top:50px;'/>" +
                                      "</div>" +
                                      "<div class='info'>" +
                                        "<div class='description'>" +
                                          "<font size='5px' color='black'>" + d.name + "</font>" +

                                        "</div>" +  
                                      "</div>" +
                                      "<div class='bottom'>" +
                                        "<br/>" +
                                        "<a id='thisLink' onclick=\"window.open('http://facebook.com/" + d.pid  + "');\" >" + "Follow on Facebook" +
                                        "</a>" +
                                      "</div>" +
                                  "</div>" +
                                "</div>" +
                              "</div>" +
                            "</div>" +
                          "</div>"
                        )

                      })

                    .on("mouseout", function(d) {
                        div.transition()
                            .duration(500)
                            .style("opacity", 0)
                            .each('end', function(d) {
                                d3.select(this).html("");
                            });
                    });

                    div.on("mouseover", function(d) {
                        d3.select(this).transition()
                            .duration(500)
                            .style("opacity", .9);

                    }).on("mouseout", function(d) {
                        d3.select(this).transition()
                            .duration(500)
                            .style("opacity", 0)
                            .each('end', function(d) {
                                d3.select(this).html("");
                            });
                    }); 

  nodeEnter.append("text")
  .attr("dy", ".35em")
  .text(function(d) { return d.name; });


  }

  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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
   }

   function color(d) {
   return d._children ? "#800000" // collapsed package
   : d.children ? "#008000" // expanded package
  : "#68228b"; // leaf node

}

 // Toggle children on click.
      function click(d) {
      if (d3.event.defaultPrevented) return; // ignore drag
      if (d.children) {
      d._children = d.children;
      d.children = null;
      } else {
      d.children = d._children;
      d._children = null;
      }
      update();
      }

//返回根目录下所有节点的列表。

     function flatten(root) {
     var nodes = [], i = 0;

     function recurse(node) {
     if (node.children) node.children.forEach(recurse);
     if (!node.id) node.id = ++i;
     nodes.push(node);
     }

     recurse(root);
     return nodes;
     }

我想拖动所有节点,因为我要将我的iframe滚动设置为no。

1 个答案:

答案 0 :(得分:1)

尝试调用'selectAll'的返回值而不是'append'