Можно ли вводить() выбор повторно использовать после добавления/вставки?

У меня есть сценарий, в котором я хочу использовать объединение данных для добавления двух новых элементов для каждого элемента данных.

Я изначально делал что-то вроде этого:

var y = d3.selectAll("line")
    .data([123, 456]);

y.enter().append("line");  // assume attr and style set
y.enter().append("line");

y.transition()...

Прежде чем я это продумал, я ожидал, что выбор обновления, используемый в моем переходе, будет содержать объединенные добавления из выбора ввода. Но, конечно, это не сработало, потому что в выборке для каждого элемента данных есть только 1 слот.

Итак, я изменил код таким образом, что он все еще использовал один и тот же ввод() дважды, но затем повторно выбран для новых элементов, чтобы сделать переход.

Этот подход сработал, но мой вопрос в том, является ли это рекомендуемым способом решения каких-либо вещей. Должен ли я прекратить использование enter() после добавления/вставки? Или он в порядке, чтобы использовать его для создания нескольких элементов, если помню, что выбор обновления будет содержать только созданные элементы?

Если окажется, что это неправильно, что лучше для этого?

Ответ 1

Нет. Цель объединения данных - синхронизировать элементы с данными, создавая, удаляя или обновляя элементы по мере необходимости. Если вы создадите элементы дважды, элементы перестанут соответствовать друг другу с привязанным массивом данных.

Если вы хотите, чтобы два элемента соответствовали каждому объекту, добавить элемент группы (G) сначала, чтобы установить сопоставление "один к одному" от данных к элементам. Затем добавить дочерние элементы по мере необходимости. Результирующая структура выглядит так:

<g>
  <line class="line1"></line>
  <line class="line2"></line>
</g>
<g>
  <line class="line1"></line>
  <line class="line2"></line>
</g>

Например:

var g = svg.selectAll("g")
    .data([123, 456]);

var gEnter = g.enter().append("g");
gEnter.append("line").attr("class", "line1");
gEnter.append("line").attr("class", "line2");