5
votes

I've got a topology map with pan and zoom functionality.

Clicking on the country, I'm zoom/panning into the country, using this:

  if (this.active === d) return

  var g = this.vis.select('g')
  g.selectAll(".active").classed("active", false)
  d3.select(path).classed('active', active = d)

  var b = this.path.bounds(d);
  g.transition().duration(750).attr("transform","translate(" +
    this.proj.translate() + ")" +
    "scale(" + .95 / Math.max((b[1][0] - b[0][0]) / this.options.width, (b[1][1] - b[0][1]) / this.options.height) + ")" +
    "translate(" + -(b[1][0] + b[0][0]) / 2 + "," + -(b[1][1] + b[0][1]) / 2 + ")");

  g.selectAll('path')
    .style("stroke-width", 1 / this.zoom.scale())

However, if I continue to drag pan, the map jerks back into the initial position before the click happens, before panning. Code to pan/zoom is here:

  this.zoom = d3.behavior.zoom().on('zoom', redraw)
  function redraw() {

    console.log('redraw')

    _this.vis.select('g').attr("transform","translate(" +
      d3.event.translate.join(",") + ")scale(" + d3.event.scale + ")")

    _this.vis.select('g').selectAll('path')
      .style("stroke-width", 1 / _this.zoom.scale())
  }
  this.vis.call(this.zoom)

In another words, after zooming into a point by clicking, and then dragging by the redraw function, the redraw does not pick up the correct translate+scale to continue from.

1
d3.select(path).classed('active', active = d) sets the active class on everything in path. This is probably not causing the problem (unless you have some code to focus on active paths elsewhere), but I think you meant == there. - musically_ut
path is just the clicked on country path. there is not code on active class. - bcm
I have removed my answer so this question may get more attention. I don't think I fully understand the problem. Adding an working example with the problem might help. - musically_ut
I think I don't fully understand d3.event.translate and d3.event.scale... and how those 2 properties can be incorrect/unexpected after running the first block of (click to center ) code... - bcm
Looks like the same problem here: groups.google.com/forum/#!topic/d3-js/-qUd_jcyGTw/discussion but the resolution is using D3 version 2.... I'm trying to upgrade to version 3 - bcm

1 Answers

8
votes

To continue at the right 'zoom' after the transition, I had to set the zoom to the new translate and scale.

Example of reset which is applied similarly to my click and zoom event, the set new zoom point is the critical bit:

_this.vis.select('g').transition().duration(1000)
   .attr('transform', "translate(0,0)scale(1)")

/* SET NEW ZOOM POINT */
_this.zoom.scale(1);
_this.zoom.translate([0, 0]);