Проблема в ссылке на circleGroup
. Когда вы впервые используете circleGroup
, вы делаете следующее:
var circleGroup = svg
.selectAll("g")
.data(rootNodes)
Прямо сейчас circleGroup
- это выбор update
. Именно при использовании enter()
или exit()
он становится желаемым выбором для ввода. Это сделано правильно здесь:
circleGroup.enter() // Enter selection
.append('g')
.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
, но не здесь:
circleGroup.append("circle") // no enter(), so update selection
.attr("r", function (d) {
if (d.id === thisuser) {
return radius * 2
} else { return radius; }
})
.attr("class", "chara")
.attr("fill", function (d) {
return (d.id === thisuser) ? "red" : "blue"
})
.style("stroke", "#ffffff")
.on("click", update);
Что вы можете сделать, так это напрямую использовать enter () в переменной circleGroup, чтобы она представляла выбор ввода . Если вам также нужно использовать выбор обновления и выхода, используйте другую переменную:
var circleGroup = svg
.selectAll("g")
.data(rootNodes) // update
var circleGroupEnter = circleGroup.enter()
circleGroupEnter
.append("circle")
.append('g')
.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')'; //work not nested data
})
.call(d3.drag() //need the drag so you can play with the nodes - links should follow - try to group it for show text beside circle
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
circleGroupEnter
.attr("r", function (d) {
if (d.id === thisuser) {
return radius * 2
} else { return radius; }
})
.attr("class", "chara")
.attr("fill", function (d) {
return (d.id === thisuser) ? "red" : "blue"
})
.style("stroke", "#ffffff")
.on("click", update);
Использование selection.join()
Вышеупомянутое немного сложно. Вы можете использовать selection.join()
для упрощения - чтобы понять, как это работает, см. Этот учебник .
var circleGroup = svg
.selectAll("g")
.data(rootNodes)
circleGroup
.join('g')
.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
circleGroup
.join("circle")
.attr("r", function (d) {
if (d.id === thisuser) {
return radius * 2
} else { return radius; }
})
.attr("class", "chara")
.attr("fill", function (d) {
return (d.id === thisuser) ? "red" : "blue"
})
.style("stroke", "#ffffff")
.on("click", update);
selection.join()
также работает для обработки трех вариантов выбора: вот пример из более позднего в вашем коде:
var link = svg.append("g")
.attr("class", "link")
.selectAll("line")
.data(rootLinks);
link.join(
enter => enter.append('line'),
update => update,
exit => exit.remove()
)