Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selections in D3: how to use parentNode.appendChild?

Tags:

d3.js

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.

like image 768
Richard Avatar asked May 07 '13 21:05

Richard


People also ask

What do the select () and selectAll () functions in D3 do?

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.

What is D3 selection?

# 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.

What is use of DOM and SVG in D3?

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.

What is append in D3?

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.


2 Answers

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.

like image 96
minikomi Avatar answered Sep 28 '22 03:09

minikomi


You can also use selection.node() in D3:

var thisNode = d3.select("#" + id);
thisNode.node().parentNode.appendChild(thisNode.node());
like image 30
ChristianT Avatar answered Sep 28 '22 02:09

ChristianT