0

I am currently using this function to zoom in on a state:

function clicked(d) {
  if (active.node() === this) return reset();

  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bounds = path.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,

      scale = .9 / Math.max(dx / width, dy / height),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  g.transition()
      .duration(750)
      .style("stroke-width", 1.5 / scale + "px")
      .attr("transform", "translate(" + translate + ")scale(" + scale + ")");    
}

And I have this on click listener on the path:

   .on("click", clicked)

I want to be able to select a d3 element by class name and then zoom on to it. Preferably, I'd like to call which state to zoom in on from a function like this:

function zoomIn(state) {
   //zoom into the state
}

How do I go about doing this?

carte
  • 1,033
  • 2
  • 13
  • 29

2 Answers2

0

You just need to change the select statement to grab the selection by class name instead of using this which was being populated by the click handler. I haven't tested it, but it would look something like this:

function zoomIn(state) {
  var node = d3.select(state);

  if (active.node() === node) return reset();

  active.classed("active", false);
  active = node.classed("active", true);

  var bounds = path.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,

      scale = .9 / Math.max(dx / width, dy / height),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  g.transition()
      .duration(750)
      .style("stroke-width", 1.5 / scale + "px")
      .attr("transform", "translate(" + translate + ")scale(" + scale + ")");    
}

And you would call it using the desired classname:

zoomIn(".washington");
Bill
  • 25,119
  • 8
  • 94
  • 125
  • Follow up question: My states don't have a class associated with them, but they do have ids. How do I modify this to use the id number? – carte Jul 21 '14 at 17:04
  • Just pass in `"#washington` instead of `.washington`. – Bill Jul 21 '14 at 17:05
  • I'm getting a `TypeError: undefined is not a function` whenever I call `zoomIn(".s11");` to zoom in an a path with the class name s11. I believe this is because of the line `var bounds = path.bounds(d),` where `d` isn't defined. What should I replace `d` with? – carte Jul 21 '14 at 18:27
0

I found out a solution to my own problem using code from this SO question: How to invoke "click" event programmatically in d3?

I copied this function:

jQuery.fn.d3Click = function () {
  this.each(function (i, e) {
    var evt = document.createEvent("MouseEvents");
    evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

    e.dispatchEvent(evt);
  });
};

and made this zoomIn function:

function zoomIn(id) {
  $(id).d3Click();
}

To zoom in to a path using the class name, I used:

zoomIn(".className");


Hope this helps someone in a similiar situation like me!

Community
  • 1
  • 1
carte
  • 1,033
  • 2
  • 13
  • 29