Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 - Append elements to external SVG file

Tags:

svg

d3.js

I have a graphic I'd like to load as a background to my d3 visualization (or simply as an svg that I can append circle elements to). The illustration is in svg format. I have tried to load it into my html file in such a way that would allow me to then append elements (such as circles) to the (or on top of) the svg file or to the div that it is in. Here are two approaches I have tried:

<script>

d3.xml("bal.svg", "image/svg+xml", function(xml) {
  document.body.appendChild(xml.documentElement);
});

var circle = svg.append("circle")
                .attr("cx", 100)
                .attr("cy", 100)
                .attr("r", 20)
                .style("fill", "red");

</script>

The svg image appears perfectly fine, but no circle shows up. In Firefox, the html for the external svg file shows up as:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
width="250px" height="250px" viewBox="0 0 250 250" 
enable-background="new 0 0 250 250" xml:space="preserve">

I have also tried:

<div id="htmlEmbed"></div>

<script>

d3.select("#htmlEmbed")
.append("object")
.attr("data", "tba2.svg")
.attr("width", 500)
.attr("height", 500)
.attr("type", "image/svg");

d3.select("#htmlEmbed")
.append("circle")
.attr("cx", 600)
.attr("cy", 600)
.attr("r", 20)
.style("fill", "red"); 

Again, the svg image appears perfectly fine, but no circle shows up. In this case, the html shows in the browser as:

<object width="500" height="500" data="tba2.svg" type="image/svg">
#document
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
width="500px" height="500px" viewBox="0 0 250 250" 
enable-background="new 0 0 250 250" xml:space="preserve"> … </svg>
</object>

I have the feeling this should be rather straightforward to do, but I don't know. Any help would be greatly appreciated.

like image 682
whistler Avatar asked Dec 25 '22 17:12

whistler


1 Answers

There were two issues with the code you've tried. First, you need to define svg properly and second, you need to execute the code that modifies the SVG after it's been loaded. Because of the asynchronous nature of d3.xml, this was not the case.

So the code you need to run is this.

d3.xml("http://openvz.org/images/1/17/Warning.svg", function(xml) {
  document.body.appendChild(xml.documentElement);

  var circle = d3.select("svg").append("circle")
            .attr("cx", 100)
            .attr("cy", 100)
            .attr("r", 20)
            .style("fill", "red");
});

Working fiddle (modulo security restrictions) here.

like image 174
Lars Kotthoff Avatar answered Jan 04 '23 15:01

Lars Kotthoff