I'd like to deal with overlapping SVG elements in D3.js using this method from StackOverflow.
However, due to the nature of my code, I want to use a D3 selector rather than this
to re-add the element to the DOM. My question is: how can I use a D3 selector to get the relevant node?
This is how the original example does it:
this.parentNode.appendChild(this);
This is my attempt, which fails with "Uncaught TypeError: Cannot call method 'appendChild' of undefined":
var thisNode = d3.select("#" + id);
thisNode.parentNode.appendChild(thisNode);
This JSFiddle (adapted from the original example) demonstrates the problem: http://jsfiddle.net/cpcj5/
How is my D3 selection different from the this
in the original example? I tried using thisNode.node().parentNode.appendChild(thisNode)
but that also failed.
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.
# d3.select(selector) · Source. Selects the first element that matches the specified selector string. If no elements match the selector, returns an empty selection. If multiple elements match the selector, only the first matching element (in document order) will be selected.
SVG is text-based, and it is an image format that is vector-based. SVG is the same as the HTML structure. It can be illustrated as the DOM (Document Object Model). The properties of SVG can be described as attributes.
append() function is used to append a new element to the HTML tag name as given in the parameters to the end of the element. If the type that is given is a function then it must be evaluated for each element that is in the selection. Syntax: selection.
The .parentNode
method is for a DOM element, not a d3 selection.
To access the DOM element from a d3 selection is a little tricky, and there are often better ways to achieve what you want to do. Regardless, if you have a single element selected, it will be the first and only item within the first item of a d3.selection - i.e. you need to access it like so:
var someIdDOMelement = d3.select("#someid")[0][0];
An edited example of your original using this: http://jsfiddle.net/cpcj5/1/
If you have the id and specifically want to get the DOM element, I'd just go with getElementById:
var someIdDOMElement = document.getElementById("someid")
Looking at d3 documentation for binding events using on, we can see that, within the function you bind, the this
variable is the DOM element for the event which was triggered. So, when dealing with event handling in d3, you can just use this
to get the DOM element from within a bound function.
But, looking at your code, I think it's easier to stick with the original implementation for re-appending the node using the original javascript methods, and then creating a d3 selection using d3.select
on the dom element bound to this
. This is how the original code does it: http://jsfiddle.net/cpcj5/3/
If you have any difficulties caused by this, please comment so I can address them.
You can also use selection.node() in D3:
var thisNode = d3.select("#" + id);
thisNode.node().parentNode.appendChild(thisNode.node());
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