function redraw() {
const t = d3.transition().duration(2000)
const allGs = d3.select("#root")
.selectAll(".edge")
.data(createData())
.join(
enter => {
const newGs = enter.append("g").classed("element", true)
const newCircles = newGs.append("circle")
.classed("circ", true)
.attr("stroke", "#000000")
.attr("stroke-width", 2)
.attr("fill", "#000000")
.transition(t)
.attr("fill", "#FF0000")
const newKeyTexts = newGs.append("text").classed("keytext", true).text(d => d.key + ": ").attr("x", 0).attr("y", 6)
const newValTexts = newGs.append("text").classed("valuetext", true).attr("x", 0).attr("y", 20)
return newGs
},
// ### update ### called for all elements that received new data
update => {
// We only want to re-color the elements when they receive new data
// Alternative All "surviving" elements receive the same color
// "hsl(" + Math.random() * 360 + ",100%,50%)" is calculated once
// update.select(".circ").transition(t).attr("fill", "hsl(" + Math.random() * 360 + ",100%,50%)")
// If we want to give each surviving element its own color, we have to write the value as a function (see the d => in the beginning). This function is evaluated once for each element / datum d.
update.select(".circ").transition(t).attr("fill", d => "hsl(" + Math.random() * 360 + ",100%,50%)")
return update
},
// ### exit ### called for all elements that lost their data
exit => {
// transition all circles to become 0-radius, black and fully opaque
exit.select(".circ")
.transition(t)
.attr("r", 0)
.attr("fill", "#000000")
.attr("fill-opacity", 1)
// exit all gs to the top-right corner, after that remove the gs
// typically the last method call in the exit part is "remove"
return exit.transition(t)
.attr("transform", "translate(1000, 0)")
.remove()
}
)
// ### all ### called for all elements that either entered or updated
// all elements, new and updated, should move to their target location
allGs
.transition(t)
.attr("transform", d => `translate(${100 + d.x}, ${100 + d.y})`)
// all circles of all elements, new and updated, should transition their radius and opacity value to their target values
allGs
.select(".circ")
.transition(t)
.attr("r", d => d.val / 2)
.attr("fill-opacity", 0.2)
// all value texts of all elements, new and updated, should change their text to their target values
allGs
.select(".valuetext")
.text(d => d.val)
}