phantom phantom - 1 month ago 17
Javascript Question

d3 add zoom functionality to d3.xml loaded element

I am dynamically loading an svg image using

d3.xml
. I then want to attach zoom functionality to this svg by using
d3.behavior.zoom()
.

Can anyone explain how to link
d3.behavior.zoom()
with the loaded svg? I cannot find anything online.

See current code below:

JS

<script src="http://d3js.org/d3.v3.js"></script>

d3.xml("map.svg").mimeType("image/svg+xml").get(function(error, xml) {
if (error) throw error;
var svg = d3.select(xml.documentElement)
.call(d3.behavior.zoom().on("zoom", function () {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
}))
.append("g");
});

Answer

You actually have two questions here:

Problem 1: Loading and appending the external SVG

In your code, you're not appending the SVG to the document. So, the first step is actually appending the SVG:

d3.xml("externalSVG.svg").mimeType("image/svg+xml").get(function(error, xml) {
    if (error) throw error;
    document.body.appendChild(xml.documentElement);
    //rest of the code here
});

Problem 2: Adding the zoom

The code you provide is adding the zoom to the <g> element, not to the entire SVG. Thus, it will not work zooming the external SVG. To do that, you can write something like this:

var svg = d3.select("svg")
    .call(d3.behavior.zoom().on("zoom", function () {
        svg.selectAll("*")
        .attr("transform", "translate(" + d3.event.translate + ")" 
        + " scale(" + d3.event.scale + ")")
}))

Check the demo:

d3.xml("https://boxy-svg.com/images/logos/boxy-svg.svg").mimeType("image/svg+xml").get(function(error, xml) {
  if (error) throw error;
  document.body.appendChild(xml.documentElement);
	 var svg = d3.select("svg")
   .call(d3.behavior.zoom().on("zoom", function () {
       svg.selectAll("*").attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
   }))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>