Когда я впервые столкнулся с объединением данных d3 как enter() , я интуитивно почувствовал себя очень легко. Но поскольку я закодировал свой собственный график с помощью exit().remove() и merge() , это было настолько сложно, что я потратил часы, чтобы понять логику, стоящую за сценой.

Объединение данных выполняется легко. Вот как я понимаю enter update exit :

К selection.enter() вы можете использовать неиспользуемые данные для создания новых элементов.

С помощью selection.exit() вы можете выбрать эти элементы без привязки данных. И в большинстве случаев вы просто хотите удалить их из DOM на selection.exit().remove() .

Что сложно, так это тонкие детали.

Перед обсуждением давайте настроим страницу как:

<!DOCTYPE html>
<meta charset="utf-8">
<svg width="720" height="120">
    <circle cx="40" cy="60" r="10"></circle>
    <circle cx="80" cy="60" r="10"></circle>
    <circle cx="120" cy="60" r="10"></circle>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script></script>

1, только selection.data(data) дает вам ввод и выход из выбора

Первое, что мы делаем, это создаем некоторые данные:

var data = d3.range(10).map(function(d){
   return { x: Math.random() * 720, y: Math.random() * 120 };
});

Затем выбираем круги:

var circle = d3.select("svg").selectAll("circle");

Если мы сделаем что-то вроде ниже:

circle.data(data);
circle.attr('fill', 'red')
       .enter().append("circle")
       .attr("cx", function(d) { return d.x; })
       .attr("cy", function(d) { return d.y; })
       .attr("r", 2.5).attr('fill', 'blue').merge(circle);

Я полагал, что как только вы привязываете данные к элементам, элементы автоматически получают доступ к enter() . Это не так.

Если мы console.log(circle) , мы не сможем получить поля входа и выхода.

То, что выше, будет генерировать три красные точки вместо 20 точек.

Только selection.data(data) может возвращать выбор enter() и exit().

Поэтому мы должны сохранить возвращенные данные (данные). Как показано ниже,

circle = circle.data(data);
// now circle will have access to enter and exit
circle.attr('fill', 'red')
       .enter().append("circle")
       .attr("cx", function(d) { return d.x; })
       .attr("cy", function(d) { return d.y; })
       .attr("r", 2.5).attr('fill', 'blue').merge(circle);

Теперь, если мы console.log(circle) , отображаются новые поля.

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

В разделе 1 мы выбрали круг,

var circle = d3.select("svg").selectAll("circle");

Затем d3 сохранит своего родителя как svg

И когда мы .enter().append("circle") , круги будут добавлены под svg . В этом случае мы видим точки на графике.

Что, если мы выберем круги,

var circle = d3.select("circle");

Его родитель изменится на html , и мы не можем видеть точки на графике. Он добавлен в html. Как показано ниже,

Куи в Пекине