10

I've searched all over the place for an answer to this question and found some resources that I thought may be useful, but ultimately did not lead me to an answer. Here are a few...

The issue

What I am trying to do it append an existing SVG element or string to a DIV on the page and then be able to apply various D3.js properties and attributes on it, so I can later manipulate and work with it (such as apply zooming abilities, etc.).

I was previously using jQuery SVG in which I did this:

var shapesRequest= '"<svg id="shapes" width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg">' +
       '<polygon id="svgSection_Floor" points="222.61,199.75,222.61,295.19,380.62,295.19,380.62,199.75,222.61,199.75,368.46,283.92,233.54,283.92,233.54,209.12,368.46,209.12,368.46,283.92" title="Floor" link="Primary" />' +
       '<text x="302.61" y="289.4705">Floor</text>...and a lot more of the same...</svg>';
$('#svgtmp').append(shapesRequest);
$('#svgtmp #shapes text').attr('fill', 'white').attr('font-size', '9').attr('font-weight', 'bold');
$('#pnlShapes').width(640).height(480).svg().svg('get').add($('#svgtmp #shapes'));

So essentially what jQuery SVG and my code is doing is appending the SVG string to a temporary DIV, manipulating some properties within the SVG, then adding that SVG to its permanent location on the page.

This is exactly what I am trying to do with D3. Although I am not sure if I need to append to a temporary DIV first, as I have access to the SVG string and could just append/attach that to a DOM element with D3.

What I've tried...

var mapSvg = d3.select("#pnlShapes").append("svg").attr("width", svgWidth).attr("height", svgHeight);
d3.xml(shapesRequest, function (xmlData) {
    var svgNode = xmlData.getElementsByTagName("svg")[0];
    mapSvg.node().appendChild(svgNode);
});

But this isn't the correct approach, as I am not hitting an external API endpoint to retrieve the SVG - I already have it stored as a string.

I was also looking at doing something like this

d3.select("#pnlShapes").append('svg').append(shapesRequest).attr("width", svgWidth).attr("height", svgHeight);

but .append() when using D3 isn't used for this kind of appending.


Question

What is the proper way to append an existing SVG string to the DOM using D3 (also I'm using jQuery if that helps)? My ultimate goal is to append this SVG and then allow it to be zoomable using this tutorial as my base.

Community
  • 1
  • 1
james
  • 5,006
  • 8
  • 39
  • 64
  • 1
    If your using d3, you don't need to append html as a text string. Just use `selection.append()` and/or `selection.insert()` to build the svg structure you need. Stick to the idiom at it will work. – Cool Blue Apr 24 '15 at 21:17

1 Answers1

12

You can use .html to insert a string into a DOM node

d3.select('#svgtmp').append('div').html('<svg...')

There may be an even more elegant way without the <div>.

P Varga
  • 19,174
  • 12
  • 70
  • 108
  • Thanks. I ended up just using jQuery to append the SVG string to the DOM (same idea as you had). `$('#pnlShapes').append(shapesRequest);` from there I can manipulate it with D3 by selecting it like you did above. – james Apr 27 '15 at 12:20
  • 2
    It does not seem to work on IE, do you have any solution for that? – gsanta Jul 27 '15 at 09:15
  • 1
    This is not the correct answer. He asked for append or insert method, not just replacing the whole html. What if there is already some content in the div? This is what you are looking for: https://gist.github.com/biovisualize/373c6216b5634327099a – mattti Oct 16 '18 at 09:10
  • 2
    I tried but the result is that it stamped [object SVGSVGElement]. I created an SVG with d3 and I want to append another SVG string. – Stefano Feb 03 '22 at 16:28