Посмотрите на это:
svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
//etc...
Вы добавляете новый элемент <g>
каждый раз, когда запускаете цикл, и все выбранные элементы (текстовые или любые другие) послеэто будет ссылаться на эту недавно добавленную группу, то есть selectAll
выделяет все тексты внутри этой новой добавленной группы. Очевидно, нет ни одного. Вот почему у вас всегда есть только выбор ввода, но не выбор обновления.
Посмотрите на эту демонстрацию, воспроизводящую вашу проблему:
var body = d3.select("body");
function foo(data) {
var div = body.append("div")
.selectAll("p")
.data(data)
.join(
enter => enter.append("p").html(d => "enter: " + d),
update => update.html(d => "update: " + d)
);
};
foo([Math.random()]);
d3.interval(function() {
foo([Math.random()])
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>
Предположим, что вы хотите добавить группу только один раз , вы можете сделать что-то вроде этого:
var g = svg.selectAll(".myGroup")
.data([true]);
g = g.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.merge(g);
g.selectAll("text")
.data(data)
.join(
enter => enter.append("text").text(d => "enter: " + d),
update => update.text(d => "update: " + d)
);
Здесь data([true])
означает, что сами данные не имеют значения, это просто одно истинное значение для добавления одного элемента группы.
Вот демонстрация, показывающая, как это работает:
var body = d3.select("body");
function foo(data) {
var div = body.selectAll(".myDiv")
.data([true]);
div = div.enter()
.append("div")
.attr("class", "myDiv")
.merge(div);
div.selectAll("p")
.data(data)
.join(
enter => enter.append("p").html(d => "enter: " + d),
update => update.html(d => "update: " + d)
);
};
foo([Math.random()])
d3.interval(function() {
foo([Math.random()])
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>