【问题标题】:how do i add a zoom in and zoom out button in a graph on d3如何在 d3 的图表中添加放大和缩小按钮
【发布时间】:2015-06-12 06:42:10
【问题描述】:

我用过

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 + ")"); 
} 

创建平移,但是当我创建一个 .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 文档似乎没有提供太多见解。而且我还没有找到任何教程来介绍每个函数的作用以及如何处理事件。任何关于缩放功能如何实际工作的帮助解释将不胜感激。

【问题讨论】:

  • 改变d3.behaviour.scale()的值
  • 我尝试改变 d3.behavior.zoom.scale() 你是这个意思吗?无论如何它没有用。 d3.select(".zoomin").on("click", function (){ d3.select(".graphmap") .call(zoomlistener.scale(2)) }); 我确实阅读了该问题中的每一篇文章。他们谈论使用鼠标而不是按钮进行缩放行为。我知道如何用鼠标缩放。它仍然给我同样的问题,当我打电话时 d3.event.scale 和 d3.event.transition 是未定义的。
  • 想通了。谢谢阿杰。你带领我朝着正确的方向前进。我还需要在我的选择中添加d3.behavior.zoom.event(),现在它可以工作了!

标签: javascript d3.js


【解决方案1】:

事实证明这很简单。

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() 调用您要更新的页面部分。

【讨论】:

  • 即使翻译值不会改变“居中”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
相关资源
最近更新 更多