D3.js强制布局实现可滚动缩放

时间:2014-07-17 11:53:35

标签: d3.js zoom force-layout

我一直试图将缩放到我的d3 froce布局图。我知道鼠标滚轮的功能,但到目前为止,我的所有尝试都导致图表出现在最大变焦状态并且对鼠标滚轮完全无响应。我是d3的新手,到目前为止,我调试代码的所有尝试都证明是徒劳的。任何人都可以帮助我吗?

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 800,
    height = 800;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(5)
    .size([width, height]);

var svg = d3.select("body")
.append("svg")
  .attr({
    "width": "100%",
    "height": "100%"
    })
  .attr("viewBox", "0 0 " + width + " " + height )
  .attr("preserveAspectRatio", "xMidYMid meet")
  .attr("pointer-events", "all")
.call(d3.behavior.zoom().on("zoom", redraw));

var vis = svg
    .append('svg:g');

function redraw() {
    vis.attr("transform",
  "translate(" + d3.event.translate + ")"
  + " scale(" + d3.event.scale + ")");
}

d3.json("graph.json", function(error, graph) {
console.log(graph);
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

var node_drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);

function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

function dragstart(d, i) {
    force.stop() // stops the force auto positioning before you start dragging
    d.fixed = true;
}

function dragmove(d, i) {
    d.px += d3.event.dx;
    d.py += d3.event.dy;
    d.x += d3.event.dx;
    d.y += d3.event.dy; 
    tick(); // this is the key to make it work together with updating both px,py,x,y on d !
}

function dragend(d, i) {
    d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
    tick();
    force.resume();
}

  var node = svg.selectAll(".node")
      .data(graph.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag);

  node.on("mouseover", function(d) {
          d3.select(this)
            .append("text")
              .attr("class", "nodetext")
              .attr("dx", 12)
              .attr("dy", ".35em")
              .text(function(d) { return d.name });
        })
        .on("mouseout", function(d) {
          d3.select(this)
            .select("text")
            .remove()
        });

  force.on("tick", function() {
    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("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  });
});

</script>

0 个答案:

没有答案