Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 create object without appending

I'm using d3 for graphing, and I'm trying to create an svg object, to add to the DOM later.

I used to have

var svg = d3.select(el).append("svg");
var graph = svg.append("g")
...etc...

and for reasons I won't go into, I wanted to create the svg element before appending it to the DOM.

So I did

var svg = d3.select(document.createElementNS(d3.ns.prefix.svg, 'svg'))
var graph = svg.append("g")
...etc...

, which works, and while debugging, I can see that svg is a 1-element array, with the children nicely attached.

The problem comes at the append step:

d3.select(el).append(svg);

There, I get an error Error: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('[object SVGSVGElement]') contains the invalid name-start character '['. I've taken a look here: How to create "svg" object without appending it? but it seems that's exactly how they suggest it.

Any idea why this is so? I've tried appending svg[0], but no luck either. It seems append() only takes strings as an argument.


edit: the d3 reference at https://github.com/mbostock/d3/wiki/Selections#append states

selection.append(name) ... ... ... "The name may be specified either as a constant string or as a function that returns the DOM element to append."

Consequently I've tried

d3.select(el).append(function(){return svg;});

but that fails with a Error: Failed to execute 'appendChild' on 'Node': The new child element is null.

like image 869
ElRudi Avatar asked Aug 26 '14 22:08

ElRudi


2 Answers

You might be better off using the regular element.appendChild function for this.

You can get a reference to your parent element using d3.select(el).node() then, you can call .appendChild on that, passing in svg.node() as the element to append.

So, all together:

d3.select(el).node().appendChild(svg.node());
like image 133
jshanley Avatar answered Oct 16 '22 08:10

jshanley


If svg is a selection, svg.node() returns the DOM element, e.g.:

d3.select(el).append(function(){return svg.node();});

(Mind you, I'm not certain that svg in your case is a true selection, but you could give it a try.)

like image 16
Stephen Thomas Avatar answered Oct 16 '22 07:10

Stephen Thomas