How can I avoid d3.zoom translate on first zoom or

2020-05-06 11:39发布

问题:

I try to make an orgchart with zoom and paning. To do so I need to call .nodeSize which translate my "root" to (0,0). Then I re-translate it by width/2 and it's ok. But when I implement d3.zoom, my "root" go back to (0,0)... How can i avoid this behavior ?

Here is the code concerned :

var svg = d3.select("#svg1").append("svg")
  .attr("width", width)
  .attr("height", height)
  .call(d3.zoom().on("zoom", function () {
  svg.attr("transform", d3.event.transform);
  }))
  .append('g').attr("transform","translate(" + width / 2 + "," + 0 + ")");

Thanks for reading.

EDIT : I did a JSFiddle so you can try my current code. Don't pay attention to big traingles (I don't have them on my real project) => https://jsfiddle.net/rhz1n8m4/12/

回答1:

Apply the zoom to a node below the width/2 transform.

Rename your vars to reflect what they contain: svg does not contain the svg element.

var svg = d3.select("#svg1").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().on("zoom", function () { svg.attr("transform", d3.event.transform); }))
.append('g').attr("transform","translate(" + width / 2 + "," + 0 + ")")
.append('g');

Edit

@Zoom proposed a solution with transform-origin (see edit history), clearly a workaround. Better is to re-arrange the g elements.

Apply the zoom to a node above the width/2 transform.

  var svg1 = d3.select("#svg1")
    .append("svg")
      .attr("width", width)
      .attr("height", height)
    .call(d3.zoom().on("zoom", function () { svg1.attr("transform", d3.event.transform); }))
    .append('g');
  var svg = svg1.append('g')
      .attr("transform","translate(" + width / 2 + "," + 0 + ")");

Read the d3-zoom doc page and you might find a different solution that does not use a transform attribute.



标签: d3.js