D3.js rewrites the scaling example in version4

Drag and Drop Example

I am trying to rewrite part of this example above for use in my code, in particular this part:

function centerNode(source) { scale = zoomListener.scale(); x = -source.y0; y = -source.x0; x = x * scale + viewerWidth / 2; y = y * scale + viewerHeight / 2; d3.select('g').transition() .duration(duration) .attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")"); zoomListener.scale(scale); zoomListener.translate([x, y]); } 

However, I am stuck as the v4 package has changed a lot. I wrote a zoomListener function as

  var zoomListener = d3.zoom() .scaleExtent([0.3,2]) .on("zoom", zoomed); function zoomed() { transform = d3.event.transform; console.log(d3.event); svg.attr("transform", transform); } function centerNode(source){ t = transform; console.log(t); x = tx*tk; //I only want things to be centered vertically y = (ty + -source.x0)*tk + (viewerHeight)/2 ; svg.transition() .duration(duration) .attr("transform","translate(" + x + "," + y +")scale(" + tk + ")"); transform.scale(tk); //DOES NOT WORK transform.translate([x, y]); //DOES NOT WORK } 

and I know that according to the document, everything has changed and the information is no longer stored on what would be my zoomListener D3 V4 Release note on zoom I think I'm just confused about how I expect to do this with the new version. The last few lines of my centerNode function do not work, which has an effect when I center the node zooming and panning reset ...

Any suggestion?

+8
javascript tree zooming d3.js-v4
source share
2 answers

So, after much digging, trial and error, I answer a question that is very well suited for my purposes. Please note that the code below is only the corresponding part of my code, and not all the code, the specific variable was self-evident, therefore did not include them. IT'S ALSO IN VERSION 4 of d3.js.

 var zoom = d3.zoom() .scaleExtent([0.3,2]) .on("zoom", zoomed); var svg = d3.select("body") .append("svg") .attr("width", viewerWidth) .attr("height", viewerHeight); var zoomer = svg.append("rect") .attr("width", viewerWidth) .attr("height", viewerHeight) .style("fill", "none") .style("pointer-events", "all") .call(zoom); var g = svg.append("g"); zoomer.call(zoom.transform, d3.zoomIdentity.translate(150,0)); //This is to pad my svg by a 150px on the left hand side function zoomed() { g.attr("transform", d3.event.transform);//The zoom and panning is affecting my G element which is a child of SVG } function centerNode(source){ t = d3.zoomTransform(zoomer.node()); console.log(t); x = tx; y = source.x0; y = -y *tk + viewerHeight / 2; g.transition() .duration(duration) .attr("transform", "translate(" + x + "," + y + ")scale(" + tk + ")") .on("end", function(){ zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(tk))}); } 

According to the examples for v4 on page d3.js, I used a rectangle to apply scaling to

The scaling behavior applies to an invisible rectangular overlay SVG element; this ensures that it receives an input, and that the pointer to a coordinate change is not affected. Pan and Zoom Example

In the Center node function, I use d3.zoomTransform(zoomer.node()); to get the current conversion applied to the page. The purpose of this function is only to center the compressible tree vertically, not horizontally, so I keep the current transform.x (here tx ) the same. The coordinate in my svg is upside down, so y= source.x0 , the source is what node pressed in my collapsible tree. ("See the example at the top of this thread to see what I'm trying to convert to version 4)

I apply the transformation to my G element, and then I want to commit these changes to transform the zoom, for this I use .on("end", function(){}) , otherwise he did strange behavior with the transition, doing everything that it does sets the current state of conversion.

 zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(tk)) 

The above line applies the x and y transformation, and the scale - that is, the current state - to the identification matrix, needs to get a new transformation for G, then apply it to zoomer which is the element that I called zoom earlier.

It worked like a charm for me!

+13
source share

Calling transform.scale and transform.translate returns a new transformation and does not change anything. Therefore:

 transform = transform.translate([x, y]).scale(k) svg.call(zoomListener.transform, newTransform) 

(At the moment, zoomListener is a rather inaccurate name for this, but whatever ...)

k , x and y can be obtained from source , perhaps while you are showing, but I'm not sure, because I do not know what source . But for me, tx*tk looks suspicious because it multiplies the existing transformations of x by its scale. It looks like this will trigger a feedback loop.

For more information on scaling in version v4, see https://stackoverflow.com/a/165268/ or this mbostock example , which demonstrates programmatic control over the zoom of an object (canvas in this case) and includes transitions.

0
source share

All Articles