Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use D3 zoom behavior with ViewBox instead of transform

I would like to take advantage of D3's zoom behavior functionality, but I need to do all translations/scaling of my SVG using the viewBox property instead of the transform method as shown in the D3 example: http://bl.ocks.org/mbostock/3680999

How can I achieve this same scale/translate using only the viewBox? Here's my code so far, which doesn't work well like the transform method.

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);
    }
}
like image 850
Doughy Avatar asked May 16 '16 20:05

Doughy


People also ask

How do you get the current zoom level in Diablo 3?

As of D3 v4 there are two documented ways of retrieving the zoom state. To quote d3/d3-zoom README (under Zoom Transforms): To retrieve the zoom state, use event. transform on a current zoom event within a zoom event listener (see zoom.

Which of these methods help alter zoom modes in d3 JS?

With the help of the d3. zoom function you can alter zoom modes in d3 js.

What does transform and translate do in d3?

translate() Function. The transform. translate() function in D3. js library is used to get the transformation whose translation tx1 and ty1 is equal to tx0 + tk x and ty0 + tk y, where tx0 and ty0 is the transform's translation and tk is the transform's scale.


1 Answers

a bit off, but could serve you as a start:

main piece:

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

whole example:

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>
like image 51
eagor Avatar answered Nov 15 '22 10:11

eagor