title: d3 focus on node on click
body: <p>I am trying to implement a force layout where clicking on a node will enable focusing on the area around the node. I have looked at a few examples but I am getting an error which says <code>link.bounds is not defined</code>. I think the bounds are not defined for force layout and are applicable for this example from where I have taken the focusing functions <a href="http://bl.ocks.org/mbostock/9656675" rel="nofollow noreferrer">http://bl.ocks.org/mbostock/9656675</a> </p>
  
  <p>What should be the values for <code>var dx, dy, x</code> and <code>y</code>? </p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;body&gt;
  &lt;script src="https://d3js.org/d3.v3.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
  
  var width = 960,
      height = 500,
      active = d3.select(null);
  
  var zoom = d3.behavior.zoom()
      .translate([0, 0])
      .scale(1)
      .scaleExtent([1, 8])
      .on("zoom", zoomed);    
  
  var force = d3.layout.force()
      .size([width, height])
      .charge(-400)
      .linkDistance(40)
      .on("tick", tick);
  
  var drag = force.drag()
      .on("dragstart", dragstart);
  
  var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .on("click", reset);
  
  var link = svg.selectAll(".link"),
      node = svg.selectAll(".node");
  
  var g = svg.append("g");    
  
  d3.json("miserables.json", function(error, graph) {
    if (error) throw error;
  
    force
        .nodes(graph.nodes)
        .links(graph.links)
        .start();
  
    link = link.data(graph.links)
      .enter().append("line")
        .attr("class", "link");
  
    node = node.data(graph.nodes)
      .enter().append("circle")
        .attr("class", "node")
        .attr("r", 12)
        .on("click", clicked)
        .call(drag);
  });
  
  function tick() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });
  
    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  }
  
  function clicked(d){
      if (active.node() === this) return reset();
    active.classed("active", false);
    active = d3.select(this).classed("active", true);
  
    var bounds = link.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 = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
        translate = [width / 2 - scale * x, height / 2 - scale * y];
  
    svg.transition()
        .duration(750)
        .call(zoom.translate(translate).scale(scale).event);
  } 
  
  function reset() {
    active.classed("active", false);
    active = d3.select(null);
  
    svg.transition()
        .duration(750)
        .call(zoom.translate([0, 0]).scale(1).event);
  }    
  
  
  function dragstart(d) {
    d3.select(this).classed("fixed", d.fixed = true);
  }
  
  function zoomed() {
    g.style("stroke-width", 1.5 / d3.event.scale + "px");
    g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
  }    
  
  &lt;/script&gt;
  </code></pre>