Drew Noakes
Drew Noakes

Reputation: 310832

Creating a d3 selection over an existing, detached SVG element

I have a component in JavaScript that will provide an <svg> element to its host. I want to populate the SVG element using d3.js.

If I let d3.js create the SVG element and add it to the <body>, then things work as expected:

var chart = d3.select('body').append('svg');

However I already have an SVG element. I want my code to more closely resemble:

var svg = document.createElement('svg'),
    chart = d3.select(svg);

This latter approach populates the SVG element (as seen in the elements panel of Chrome's developer tools) but it does not render properly.

Am I going about this incorrectly?

I don't mind if d3 creates the SVG element, so long as it doesn't attach it to the DOM and I can access it.


EDIT I've created a jsFiddle that reproduces my problem. You can toggle the APPROACH variable between 1 and 2 to see alternate approaches. I see this issue in both Chrome and Firefox (latest versions on Ubuntu 13.04.)


EDIT 2 I've created a screenshot showing the working and non-working versions side by side:

You can see that the element trees are largely the same. However on the non-working version (left) the Styles panel (to the right of the element tree) is missing some user agent rules. I have no idea why this should be different. I'd suggest it was a bug in Chrome, but the same behaviour is visible in Firefox.

Upvotes: 6

Views: 1190

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The problem is that you're creating the SVG element in the HTML namespace where it gets interpreted incorrectly. If you replace

var svg = document.createElement('svg');

with

var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');

it works fine. D3 takes care of this for you by setting the namespace automatically.

Upvotes: 4

Related Questions