scotthmurray / d3-book

Code examples for “Interactive Data Visualization for the Web”
http://d3book.com
Other
2.4k stars 1.79k forks source link

Question: Storing Selections in Variables #41

Closed seanlacey closed 4 years ago

seanlacey commented 4 years ago

I think I'm missing something, sorry if this is a dumb question:

In chapter 9 (page 179 in the 2nd edition) you say "When storing the results of these selection methods, the most specific result....is the reference handed off to the variable" and provide the following example saying that paragraphs contains a selection of all p elements in the DOM.

var paragraphs = d3.select("body").selectAll("p");

However, chapter 12 (page 236) you provide the following example saying that it will store a selection of all the circle elements on the page contained within g elements:

var allCirclesInGroups = d3.selectAll("g").selectAll("circle")

What's the difference between these two examples? I imagine I'm just misunderstanding something.

Also thank you for writing this book, it's great!

scotthmurray commented 4 years ago

@seanlacey Thank you! Great question.

Part of the chaining structure is that selections get "handed off" to each subsequent link in the chain. When we're talking about selections, usually (but not always) we'll start with a broader selection, then narrow down, so later parts of the chain are dealing with more specific selections.

For example, going from broad to specific in the DOM:

html > body > p

The HTML element is parent to the body element, which is parent to the p element. So you could select that p with:

d3.select("html").select("body").select("p")

This is a verbose, clunky way to write D3 code, but bear with me. This moves from general to specific. d3.select("html") selects the HTML element, then "hands off" that reference to the next link in the chain. select("body") starts with the HTML element selection, then within that searches for the first body element. (Spoiler: There's only one!) Then the selection pointing to body is handed off to the final select("p"), which looks inside of the body selection to find a p.

When you store the result of a chained sequence like this in a variable, whatever is left at the end of the chain is stored in the variable. So:

var paragraph = d3.select("html").select("body").select("p")

Here, the selections of html and body are used briefly, just to get to p, which is then stored in paragraph for later reference.

Does that help?

seanlacey commented 4 years ago

I think so, I think I was reading the chapter 9 example as the selection would contain all p elements regardless of if they were in the body element (though there wouldn't be any) which was leading to my confusion.

Also here's a link to my first D3 project (with a lot of help from your mapping chapter). Thank you again, the book has been great! https://slacey.net/DIBNovember2019/DIBNOV2019.html

scotthmurray commented 4 years ago

Wow, you made an interactive map!! 👏 I love it! I accidentally stumbled into a Rubik's competition once. That blew my mind. Little kids, solving them in just a few seconds!

When working with selections, use console.log() liberally, or just check things in the console. Don't trust me when I say "this will include paragraphs" or whatever. Just log that value out and poke at it yourself. :) That will help it all make sense!