如何使用ViewBox而不是变换使用D3缩放行为

时间:2016-05-16 20:26:10

标签: d3.js svg zoom viewbox

我想利用D3的缩放行为功能,但我需要使用viewBox属性而不是转换方法对SVG进行所有翻译/缩放,如D3示例所示:http://bl.ocks.org/mbostock/3680999

如何仅使用viewBox实现相同的缩放/翻译?到目前为止,这是我的代码,它不像转换方法那样有效。

function zoomed(d) {
  if (!scope.drawLine) {
    var scale = d3.event.scale;
    var translation = d3.event.translate;

    //This works, but I can't use it for reason's I won't go into now
    //mapSVG_G.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");

    var newViewBox = [
      initialViewBox[0] - translation[0],
      initialViewBox[1] - translation[1],
      initialViewBox[2]/scale,
      initialViewBox[3]/scale
      ];
      mapSVG.attr('viewBox', newViewBox);
    }
}

1 个答案:

答案 0 :(得分:1)

有点偏,但可以作为一个开始:

主要内容:

var newViewBox = [
    -translate[0] / scale,
    -translate[1] / scale,
    width / scale,
    height / scale
].join(" ");

整个例子:

var width = 960,
  height = 500;

var randomX = d3.random.normal(width / 2, 80),
  randomY = d3.random.normal(height / 2, 80);

var data = d3.range(2000).map(function() {
  return [
    randomX(),
    randomY()
  ];
});

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("viewBox", [0, 0, width, height].join(" "))

var vis = svg.append("g")
  .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
  .append("g");

vis.append("rect")
  .attr("class", "overlay")
  .attr("width", width)
  .attr("height", height);

vis.selectAll("circle")
  .data(data)
  .enter().append("circle")
  .attr("r", 2.5)
  .attr("transform", function(d) {
    return "translate(" + d + ")";
  });

function zoom() {
  var scale = d3.event.scale;
  var translate = d3.event.translate;

  var newViewBox = [
    -translate[0] / scale,
    -translate[1] / scale,
    width / scale,
    height / scale
  ].join(" ");
  
  svg.attr('viewBox', newViewBox);

}
.overlay {
  fill: none;
  pointer-events: all;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>