Here's an example function that creates an unattached group element:
function createSomething(){
return function(){
var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
// Add stuff...
return group.node();
}
}
You can call it like so:
node.append(createSomething());
Explanation
Let's say you are rendering a collapsible tree and you want to have plus/minus icons with a circle border as the toggles. Your draw function is already enormous so you want the code for drawing the plus sign in it's own function. The draw/update method will take care of proper positioning.
One option is to pass the existing container into a function:
createPlus(node).attr({
x: 10,
y: 10
});
function createPlus(node){
var group = node.append('g');
// Add stuff...
return group;
}
We can make this better by applying the technique from @Drew and @Paul for creating unattached elements.
node.append(createPlus())
.attr({
x: 10,
y: 10
});
function createPlus(){
var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
// Add stuff...
return group;
}
Except that throws an error because append()
expects either a string or a function.
The name may be specified either as a constant string or as a function that returns the DOM element to append.
So we just change it to:
node.append(function(){
return createPlus();
});
But that still doesn't work. It causes the following error:
TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
Luckily I found selection.node()
which does work! Though, admittedly, I have no idea why.
function createPlus(){
var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
// Add stuff...
return group.node();
}
We can save us a little more time by moving the anonymous function into createPlus
:
node.append(createPlus())
function createPlus(){
return function(){
var group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
// Add stuff...
return group.node();
}
}