Reputation: 73
In a d3 program I need to get a node (with d3.selection) and then I want to insert in the same svg.
I know there are some functions like append, and insert, but these functions are for new elements.
var node = d3.select("rect#someId"); //node with some attributes and listeners
Now my var node got the following attributes: {_groups, _parents}
var anotherNode = d3.select("anotherNode").insert(node); //It work but it would be great a similar function or a workaround
Note. I need to preserve the listeners of the node
Upvotes: 7
Views: 8423
Reputation: 102194
D3 v5.0 introduced selection.clone
, which:
Inserts clones of the selected elements immediately following the selected elements and returns a selection of the newly added clones.
Here is a demo:
var copy = d3.select("#group").clone(true).attr("transform", "translate(120,100)");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="200">
<g id="group">
<rect x="10" y="10" width="50" height="20" fill="teal"></rect>
<circle cx="35" cy="40" r="20" fill="red"></circle>
</g>
</svg>
Note that, just as the solution in the original answer, selection.clone
will not clone the listeners.
Use this function to clone your selection:
function clone(selector) {
var node = d3.select(selector).node();
return d3.select(node.parentNode.insertBefore(node.cloneNode(true), node.nextSibling));
}
Then, you can call it with clone("#foo")
(by ID) or clone(".foo")
(by class).
Here is an example, where the group (one rect and one circle) with ID "group" is cloned (the translate is just to better see the clone):
function clone(selector) {
var node = d3.select(selector).node();
return d3.select(node.parentNode.insertBefore(node.cloneNode(true),
node.nextSibling));
}
var copy = clone("#group").attr("transform", "translate(120,100)");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="200" height="200">
<g id="group">
<rect x="10" y="10" width="50" height="20" fill="teal"></rect>
<circle cx="35" cy="40" r="20" fill="red"></circle>
</g>
</svg>
PS: This will not clone the listeners. Also, this function is not mine, it was written by Bostock.
Upvotes: 14