D3: обновление данных с несколькими элементами в группе

У меня есть комбинированная диаграмма/строка. Для каждой строки во входном файле я создаю группу, содержащую несколько элементов (строки, прямоугольники, тексты):

var myGroups = svg.selectAll('g').data(myData)
myGroups.enter().append('g')
...
myGroups.append('line')
...
myGroups.append('polygon')
...
myGroups.append('text')
...

Я сейчас просто

svg.selectAll('*').remove()

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

Я несколько раз проходил этот учебник, но я до сих пор не понимаю, как это сделать в моем случае.

Ответы

Ответ 1

Ключ предназначен для обработки всех выбранных элементов, а не только для ввода:

var myGroups = svg.selectAll('g').data(myData);

// enter selection
var myGroupsEnter = myGroups.enter().append("g");
myGroupsEnter.append("line");
myGroupsEnter.append("polygon");
// ...

// update selection -- this will also contain the newly appended elements
myGroups.select("line").attr(...);
// ...

// exit selection
myGroups.exit().remove();

Здесь есть две вещи, которые требуют дальнейшего объяснения. Во-первых, элементы выбора ввода, в которые были добавлены новые элементы, сливаются с выбором обновления. То есть, нет необходимости устанавливать атрибуты для элементов в выборе ввода, если то же самое происходит в выборе обновления. Это позволяет добавлять новые элементы и обновлять существующие без дублирующего кода.

Вторая вещь становится важной при последующих вызовах с обновленными данными. Поскольку элементы, к которым вы привязываете данные, - это не те, которые действительно нарисованы, новые данные должны быть переданы им. Это то, что делает .select(). То есть, делая myGroups.select("line"), вы распространяете новые данные, привязанные к элементам g, к их дочерним элементам line. Таким образом, код для установки атрибутов такой же, как для случая ввода.

Теперь вы можете просто добавить переходы, если хотите, перед установкой новых атрибутов.