Zoom on multiple areas in d3.js

Posted by t2k32316 on Stack Overflow See other posts from Stack Overflow or by t2k32316
Published on 2013-06-28T21:02:39Z Indexed on 2013/06/28 22:21 UTC
Read the original article Hit count: 384

Filed under:
|
|
|

I'm planning to have a geoJSON map inside my svg alongside other svg elements. I would like to be able to zoom (zoom+pan) in the map and keep the map in the same location with a bounding box. I can accomplish this by using a clipPath to keep the map within a rectangular area. The problem is that I also want to enable zooming and panning on my entire svg. If I do d3.select("svg").call(myzoom); this overrides any zoom I applied to my map. How can I apply zoom to both my entire svg and to my map? That is, I want to be able to zoom+pan on my map when my mouse is in the map's bounding box, and when the mouse is outside the bounding box, zoom+pan on the entire svg.

Here's example code: http://bl.ocks.org/nuernber/aeaac0e8edcf7ca93ade. (how do I get around the cross domain issue to load the map?)

<svg id="svg" width="640" height="480" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <clipPath id="rectClip">
      <rect x="150" y="25" width="400" height="400" style="stroke: gray; fill: none;"/>
    </clipPath>
  </defs>
  <g id="outer_group">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
    <g id="svg_map" style="clip-path: url(#rectClip);">
    </g>
  </g>
</svg><br/>
<script type="text/javascript">
  var svg = d3.select("#svg_map");
  var mapGroup = svg.append("g");
  var projection = d3.geo.mercator();
  var path = d3.geo.path().projection(projection);

  var zoom = d3.behavior.zoom()
      .translate(projection.translate())
      .scale(projection.scale())
      .on("zoom", zoomed);
  mapGroup.call(zoom);

  var pan = d3.behavior.zoom()
      .on("zoom", panned);
  d3.select("svg").call(pan);

  mapGroup.attr("transform", "translate(200,0) scale(2,2)");
  d3.json("ne_110m_admin_0_countries/ne_110m_admin_0_countries.geojson", function(collection) {
      mapGroup.selectAll("path").data(collection.features)
        .enter().append("path")
        .attr("d", path)
        .attr("id", function(d) { return d.properties.name.replace(/\s+/g, "")})
        .style("fill", "gray").style("stroke", "white").style("stroke-width",1);
    }
  );

  function panned() {
    var x = d3.event.translate[0];
    var y = d3.event.translate[1];
    d3.select("#outer_group").attr("transform", "translate("+x+","+y+") scale(" + d3.event.scale + ")");
  }

  function zoomed() {
    previousScale = d3.event.scale;
    projection.translate(d3.event.translate).scale(d3.event.scale);
    translationOffset = d3.event.translate;
    mapGroup.selectAll("path").attr("d", path);
  }
</script>

© Stack Overflow or respective owner

Related posts about svg

Related posts about d3.js