Home > Mobile >  How to programmatically zoom to Elements in D3 in responsive map?
How to programmatically zoom to Elements in D3 in responsive map?

Time:10-06

I have an SVG which I have imported using d3.xml and I am trying to zoom in when I have clicked one of the ellipses in my SVG. This almost works, though I am missing some functionality of locating the elements when the size of the SVG changes. Here is the code I am using to zoom:

svg.transition().duration(750).call(
    zoom.transform,
    d3.zoomIdentity
      .translate(widthContainer/2 , heightContainer/2)
      .scale(2)
      .translate(-d3.select(this).attr('cx'), -d3.select(this).attr('cy')),
    d3.pointer(event, svg.node())
);

This works when the size of the browser window represents the size in which the svg was created, because the cx and cy values of the ellipses then can be used to locate them, though when I increase the size of the browser window this of course doesn't work anymore because the cx and cy values are now way off. How can I center and zoom to an element independent of the current context? I'm guessing there is a way to find out the current scale of the parent div and then calculate the translate parameters from there but I haven't found anything after a couple hours of trying.

CodePudding user response:

I found a solution to my problem, my biggest error was assuming that to make my map responsive I would need to update my vars widthContainer and heightContainer (which are used to make calculations in my code for the zoom position etc.) with the current viewport width when the page is loaded and on resize. This introduced a bunch of very weird behavior and led to me spending hours on debugging that could have been avoided.

The solution to making a map with zoom features responsive is to have these two vars set to fixed values. If you are using an SVG that you are reading as xml with d3, then use the values that are set in the SVG's viewbox attribute, e.g. viewBox="0 0 657.58 344.67".

Then you can handle your container, where your SVG element is in, as usual in css and set your width to 100% or whatever you please, and the map should act responsively. I'm a total noob in d3 and JS so this behaviour didn't seem logical to me, especially because the documentation on d3's zoomIdentity is very poor. To regular d3 users this probably seems obvious but I hope this reaches fellow d3 beginners out there.

  • Related