1

I have an svg that I'm trying to access and modify using d3.js. The svg file name is us-map.svg. I've included a reference to the svg in my html like this:

<object id="imgMap" data="us-map.svg" type="image/svg+xml">
</object>

I can select imgMap in my chrome watch panel like this:

var imgMap = d3.select('#imgMap')

However, I'm not able to select child elements. For example, my imgMap svg has several child <g> elements but the child elements are not returned with this function:

d3.select('#imgMap').selectAll('g')

Am I missing something here? I was thinking that d3 could be used to traverse and manipulate an existing svg?

1 Answer 1

3

I was thinking that d3 could be used to traverse and manipulate an existing SVG

This is pretty much what d3 does best. But when you write:

d3.select('#imgMap')

You are not selecting the SVG (unless you have an SVG with id = "imgMap", which is not your case). You're using an <object>. Thus, you have to write:

var mySVG = d3.select(document.getElementById("imgMap").contentDocument);

And then select your groups using mySVG.

var myGroups = mySVG.selectAll("g");

Have in mind that this selection only works after the object has been loaded.

Source: https://benfrain.com/selecting-svg-inside-tags-with-javascript/

EDIT:

As requested by the OP, this is a basic working demo: https://plnkr.co/edit/RJOznJROiqTpo5dm9M7L?p=preview

In this plunkr, "mysvg.svg" is an external file (in your code, you'll have to provide the correct path). The code finds the SVG:

var mySVG = d3.select(document.getElementById("imgMap").contentDocument);

And then selects the blue circle inside the SVG, moving it to the right:

var myCircle = mySVG.select("#blueCircle"); 
myCircle.transition().duration(2000).attr("cx", 180);

Pay attention to this: I set a setTimeout of 1000ms, just to make sure that the object is loaded before the code runs.

3
  • this doesn't work for me. contentDocument appears to return a reference to the parent html but I don't see any type of interface into the svg markup Commented Sep 23, 2016 at 16:04
  • can you post a basic jsbin or similar online demo with the most basic implementation for this? Commented Sep 23, 2016 at 16:25
  • figured it out. I needed to access the svg node a little more specifically: var mySvg = d3.select(document.getElementById("imgMap").contentDocument.childNodes[1]); I'm sure this is due to some special formatting/nesting within my particular svg Commented Sep 26, 2016 at 22:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.