How to create selection from DOM element itself
d3.js
Solution
You can turn a DOM node into a D3 selection using `d3.select()`. You cannot turn a DOM node into a D3 selection using `selection.selectAll()`. The code you want is
d3.select(personG)
.selectAll("circle.person") // create new circles within g node
// ...
Note two important points:
- The root of the statement is the global `d3.` not the selection `svg.`
- The selection is made using `select()` not `selectAll()`
Meetamit has it exactly correct.
Problem
In d3.js, if I'm given a CSS selector that uniquely identifies a DOM element, I can create a selection containing only that element, using, for example, ``` svg.selectAll("g.node#"+d.id) ``` Suppose that I'm given the DOM element itself, for example, a particular `<g>` that already exists. Passing the DOM element directly to `selectAll` or `select` generates an error, reported as "SyntaxError: An invalid or illegal string was specified" in Firefox, or "Uncaught SyntaxError: Failed to execute 'querySelectorAll' on 'Element': '[object SVGGElement]' is not a valid selector" in Chrome. How can I create a selection from the reference to DOM element itself? There should be no need to cause D3 to go and search for the element using a CSS selector. At the moment, I've got working code that gets the appropriate selection by constructing a unique CSS selector, but that seems like unnecessary work, since I already have a reference to the DOM element to which I want to append things. EDIT: Thanks to @meetamit and @LarsKotthoff: OK, if it should just work to `selectAll` on the DOM element, there's something I don't understand about my code (not surprising). I was trying to avoid dumping a lot of code into my SO question, but I don't know what else to do. Here is a fiddle. It doesn't run in jsfiddle, and I don't know why, but it runs just fine without jsfiddle in Firefox, Chrome and Safari. (Here's a fiddle that just contains my entire file in the HTML window.) My code is supposed to add a little pack layout to each node in a force layout. There may be a purely idiomatic way to do this, but I've only succeded in getting it to work by calling `each` on the nodes in the force layout, adding the pack layouts from inside a separate function: ``` var svgnodes = svg.selectAll("g.node") .data(data.nodes, function (d) {return d.id;}) .enter() .append("g") .attr("class", "node") .attr("id", function (d) {return d.id;}) .call(layout.drag()) .on("click", click); svgnodes.each(function (d, i) {addPersonCircles(d, svg, this);}); ``` Here's part of the definition of `addPersonCircles`: ``` function addPersonCircles (d, svg, personG) { // makes a data new structure for use by pack layout: function makeroot (id) {return {"name":name, "children":[{"name":"a"}, {"name":"p"}]};} // data structure containing three elements, one for each element generated by makeroot() var pack = d3.layout.pack() .size([personRadius, personRadius]) .value(function (d) {return 1;}) .nodes(makeroot(d.id)); // KLUDGE. Isn't there a way to select using the dom element personG that was passed in? svg.selectAll("g.node#"+d.id) // find particular existing g node in person net .selectAll("circle.person") // create new circles within g node .data(pack) .enter() .append("circle") ... } ``` When I add `console.log(personG)`, i.e. display what was `this` inside of `each()`, what's displayed is something like this: ``` <g class="node" id="sandra" transform="translate(263.59494561798255,242.1803122208288)">...</g> ``` I have been puzzled at times by what `this` refers to, but here it seems to refer to a DOM node, and nothing else. However when I replace `svg.selectAll("g.node#"+d.id)` with `svg.selectAll(personG)`, I get the error messages reported above. The result looks like the following. Thanks for any help.