Абсолютно нет необходимости выбирать родительскую группу, получать ее данные и привязывать их к дочерним элементам, как это делается в коде вашего вопроса и другого ответа.Это наклоняется назад.Кроме того, не удаляйте / повторно добавляйте элементы, как это было предложено, что является , а не идиоматическим подходом D3.
Дело в том, что для дочерних элементов в«введите» выбор.Вам просто нужно использовать родительский выбор (с select()
) для их распространения.
Вот базовая демонстрация с использованием (большей части) вашего кода.Код генерирует от 1 до 5 объектов данных со случайным свойством, которое называется someProperty
.Вы увидите, что, используя ваш each()
, изменяются только дочерние элементы в выборе «enter»:
var svg = d3.select("svg");
d3.interval(function() {
var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
return {
id: "id" + d,
"someProperty": ~~(Math.random() * 100)
}
});
update(data);
}, 2000);
function update(my_data) {
var my_group = svg.selectAll(".data_group")
.data(my_data, function(d) {
return d.id
});
my_group.exit().remove();
var enter = my_group.enter()
.append("g")
.attr("class", "data_group");
enter.append("text").attr("class", "group_item group_text")
enter.append("circle").attr("class", "group_item group_circle");
my_group = my_group.merge(enter);
console.log("---")
d3.selectAll(".group_text").each(function(d) {
console.log(JSON.stringify(d))
});
}
.as-console-wrapper { max-height: 100% !important;}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
Теперь, если мы используем выбор вашего родителя ...
my_group.select(".group_text").each(function(d) {
console.log(d)
})
... вы увидите, что все свойства обновлены:
var svg = d3.select("svg");
d3.interval(function() {
var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
return {
id: "id" + d,
"someProperty": ~~(Math.random() * 100)
}
});
update(data);
}, 2000);
function update(my_data) {
var my_group = svg.selectAll(".data_group")
.data(my_data, function(d) {
return d.id
});
my_group.exit().remove();
var enter = my_group.enter()
.append("g")
.attr("class", "data_group");
enter.append("text").attr("class", "group_item group_text")
enter.append("circle").attr("class", "group_item group_circle");
my_group = my_group.merge(enter);
console.log("---")
my_group.select(".group_text").each(function(d) {
console.log(d)
})
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
Наконец, в своем теперь удаленном ответе вы используете my_group.selectAll()
.Проблема в том, что selectAll()
не распространяет данные.
Посмотрите на эту таблицу, которую я сделал:
+------------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+------------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+------------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+------------------+----------------------------------+----------------------------+
| Data propagation | Propagates data | Doesn't propagate data |
+------------------+----------------------------------+----------------------------+
Обратите внимание, что распространяет данные против не распространяет данные .