Пожалуйста, помогите мне понять разницу между select() и selectAll()

Я чувствую, что неправильно понимаю что-то очень основное, в чем разница между этими двумя?

У меня не было причины, почему второй не добавит мне тег p.

divSelection = d3.select('#div-vis').selectAll('p').data(['dummy']).enter().append('p');

divSelection = d3.select('#div-vis').select('p').data(['dummy']).enter().append('p');

Ответ 1

От Вложенные выборки:

Выбор гнезда имеет еще один тонкий, но критический побочный эффект: он устанавливает родительский node для каждой группы. Родительский node является скрытым свойством при выборе, который определяет, где добавлять входящие элементы.... Существует важная разница между select и selectAll: select сохраняет существующую группировку, тогда как selectAll создает новую группировку. Таким образом, выбор вызова сохраняет данные, индекс и даже родительский node исходного выбора!

Когда вы говорите d3.select("#vis"), родительский node выбора по-прежнему является элементом документа. Когда вы скажете selectAll("p"), вы определяете родительский node как ранее выбранный элемент #vis, потому что selectAll является оператором вложенности. Это происходит только с selectAll и не выбирается.

Ответ 2

В этом документе HTML:

<html>
<body>

  <div id="viz">
  </div>

<body>
</html>

Применение этого кода:

var viz = d3.select('#viz').selectAll('p').data([0])
  .enter().append('p');

Дает этот результат:

<html>
<body>

  <div id="viz">
    <p></p>
  </div>

<body>
</html>

Это потому, что selectAll() определяет родительский элемент на основе предыдущего метода select, который равен select('#viz'). Таким образом:

console.log(viz[0].parentNode) // <div id="viz">

Если в первом документе HTML выполняется следующий код:

var viz = d3.select('#viz').select('p').data([0])
  .enter().append('p');

Он дает вам следующий результат:

<html>
<body>

  <div id="viz">
  </div>

<body>
<p></p> <!-- your p element is appended to <html> as its parent element
</html>

Поскольку a selectAll() требуется переопределить родительский элемент выбора, родительский элемент вашего выбора по-прежнему <html>, который установлен по умолчанию. Если мы запишем родительский выбор node:

console.log(viz[0].parentNode) // <html>

Помните, что выбор - это массивы (группы) массивов элементов. Написание viz[0] получает первую группу элементов, а не первый элемент вашего выбора. Чтобы получить первый элемент, вы должны написать:

console.log(viz[0][0].parentNode)

Что даст вам родительский элемент этого конкретного элемента в дереве DOM, а не в вашей группе выбора d3.