d3-selection

Selecting Elements with d3-selection

d3.select(selector) returns a selection holding the first element that matches a CSS selector, and d3.selectAll(selector) every match in document order; both also accept an element, as in d3.select(this). Selecting on a selection searches only inside its elements, which keeps one chart's code out of another's:

Scoping, filtering and inspecting selectionsHTMLLive
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<svg id="shelf" width="220" height="126" fill="#1f5f8b">
  <g class="books"><rect x="10" y="30" width="28" height="90"/><rect x="44" y="10" width="28"
    height="110"/><rect x="78" y="40" width="28" height="80"/><rect x="112" y="55" width="28"
    height="65"/><rect x="146" y="20" width="28" height="100"/></g>
  <rect x="0" y="120" width="220" height="6" fill="#263238"/>
</svg>
<pre id="log" style="display:inline-block; vertical-align:top; margin:20px 24px"></pre>
<script>
  const spines = d3.select('#shelf').selectAll('.books rect');   // scoped to #shelf
  spines.filter((d, i) => i % 2 === 1).attr('fill', '#e09a10');   // a function filter
  spines.filter(':last-child').attr('fill', '#b5452f');            // a CSS filter
  d3.select('#log').text(`spines.size()   ${spines.size()}\nall rects       `
    + `${d3.selectAll('rect').size()}\nempty('#none')  ${d3.select('#none').empty()}`);
</script>
Browser output of Listing 6.4
Browser output of 4

The scoped selection counts five spines, not the shelf board. Modifying methods return the selection, so calls chain; node() and nodes() return raw elements. Internally a selection is an array of groups, one per parent element, which is what lets nested data bind rows to groups and cells to rows (Stacks).