如何在d3上的图形中添加放大和缩小按钮

时间:2015-04-07 15:37:06

标签: javascript d3.js

我用过

d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 

创建pan,但是当我创建一个.on事件监听器并使用除了我拥有它以外的任何方式调用redraw()时,它返回d3.event.translate和d3.event.scale ,所以我无法更新转换。我已经看到那里的代码用于缩放地图按钮而不是图形。一定有可能是怎样的,但我不知道如何。我到目前为止的代码是......

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

.node {
  stroke: #000;
  stroke-width: 0px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}
.graphmap {
  border: 1px solid black;
}
</style>
</head>
<body>
<div class="graph"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

// start draw zoom buttons
var zoom = d3.select(".zoom").append("svg")
    .attr("width", 40)
    .attr("height", 40);



// start zoom behavior
var mapZoom = d3.behavior.zoom()
   .on("zoom", redraw);


function zoomButton(zoomDirection) {
  if (zoomDirection == "in") {
    var newZoom = mapZoom.scale() * 1.5; 
    var newX = 
      ((mapZoom.translate()[0] - (width / 2)) * 1.5) + width / 2;
    var newY = 
      ((mapZoom.translate()[1] - (height / 2)) * 1.5) + height / 2; 
  }
  else if (zoomDirection == "out") {
    var newZoom = mapZoom.scale() * .75;
    var newX = ((mapZoom.translate()[0] - (width / 2)) * .75) + width / 2;
    var newY = ((mapZoom.translate()[1] - (height / 2)) * .75) + height / 2;
  }
  mapZoom.scale(newZoom).translate([newX,newY]) 
  redraw();   
}

function zoomed() {
    projection.translate(mapZoom.translate()).scale(mapZoom.scale());
    d3.selectAll("path.graticule").attr("d", geoPath); 
    d3.selectAll("path.countries").attr("d", geoPath);
    d3.selectAll("circle.cities")
        .attr("cx", function(d) {return projection([d.x,d.y])[0]}) 
        .attr("cy", function(d) {return projection([d.x,d.y])[1]});
}

d3.select(".zoomin").on("click", function (){
    zoomButton("in");
    console.log(d3.behavior.zoom().event(d3.select(".zoomin")))
});


d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

d3.select(".zoomin")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", redraw);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 


// start svg

var width = 1100,
    height = 900;

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(.05)
    .charge(-700)
    .linkDistance(150)
    .size([width, height]);

var svg = d3.select(".graph").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "graphmap");

zoomin = svg.append("g")
    .attr("class", "zoomin");

zoomin.append("rect")
    .attr("x", 10)
    .attr("y", 10)
    .attr("width", 30)
    .attr("height", 30)
    .attr("rx", 4)
    .attr("ry", 4)
    .attr("fill", "#dadae6");



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


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

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

  var node = g.selectAll("g")
      .data(graph.nodes)
      .enter().append("g")
      .attr("class","node")
      .call(force.drag);

  node.append("circle")
    .attr("r", function(d) { return Math.sqrt(d.group * 20); })
    .style("fill", function(d) { return color(d.group); })
    .attr("pointer-events", "auto")
    .attr("class", "circlenode");

  node.append("text")
    .attr("text-anchor", "right") 
    .attr("fill","black")
    .style("pointer-events", "none")
    .attr("font-size", function(d) { 20 + 'px'; })
    .attr("font-weight", function(d) { return "bold"; })
    .text( function(d) { return d.name + ' (' + d.group + ')';});

  setTimeout(function() {
    node.classed("fixed", function(d) { return d.fixed = true; });
  }, 9000);

  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; })
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")";});
  });
});
function dump(obj) {
    var out = '';
    for (var i in obj) {
        out += i + ": " + obj[i] + "\n";
    }

    // or, if you wanted to avoid alerts...

    var pre = document.createElement('pre');
    pre.innerHTML = out;
    document.body.appendChild(pre)
}
</script>

</body>
</html>

你会看到我正在玩制作zoomButton功能,但我不知道如何设置它以使其工作。我已经看到了一些关于缩放功能的不同想法的演示,但我真的不了解它们是如何工作的以及它们的功能是什么。而d3文档似乎并没有提供太多的见解。我还没有发现任何教程可以解释每个函数的功能以及如何处理事件。任何帮助解释缩放功能如何实际工作将不胜感激。

1 个答案:

答案 0 :(得分:3)

事实证明这很简单。

var zoomfactor = 1;

var zoomlistener = d3.behavior.zoom()
.on("zoom", redraw);

d3.select(".zoomin").on("click", function (){
    zoomfactor = zoomfactor + 0.2;
    zoomlistener.scale(zoomfactor).event(d3.select(".graph"));
});

d3.select(".zoomout").on("click", function (){
    zoomfactor = zoomfactor - 0.2;
    zoomlistener.scale(zoomfactor).event(d3.select(".graph"));
});

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 

scale()设置您要缩放的金额,event()调用您要更新的页面部分。