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
select selects the first matching element whilst d3. selectAll selects all matching elements. Both functions take a string as its only argument. The string specifies which elements to select and is in the form of a CSS selector string (e.g. div.
selectAll() function in D3. js is used to select all the element that matches the specified selector string. Parameters: This function accepts single parameter HTML tag as a parameter. Return Value: This function returns the selected elements.
Selection methods come in two forms: select and selectAll: the former selects only the first matching element, while the latter selects all matching elements in document order. The top-level selection methods, d3.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With