{
let data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);
const width = 500;
const height = 50;
const margin = {top: 10, bottom: 10, left: 50, right: 10}
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
const g = svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
const yScale = d3.scalePoint()
.domain(['enter', 'update', 'exit'])
.range([0, height]);
const xScale = d3.scalePoint()
.domain(alphabet)
.range([10, width])
g.append("g")
.call(d3.axisLeft(yScale))
while (true) {
yield svg.node()
yield data
g.selectAll(".letter")
.data(data, d => d)
.join(
enter => enter.append("text")
.attr("fill", "green")
.attr("class", "letter")
.attr("x", d => xScale(d))
.attr("y", yScale('enter') + 5)
.style("font", "14px sans-serif")
.text(d => d),
update => update
.attr("fill", "black")
.call(update => update.transition()
.attr("y", yScale('update') + 5)),
exit => exit
.attr("fill", "red")
.call(exit => exit.transition()
.attr("y", yScale('exit') + 5)
.transition()
.remove())
);
g.selectAll(".letter")
.data(data, d => d)
.join("text")
.attr("class", "letter")
.attr("y", yScale('enter') + 5)
.attr("x", d => xScale(d))
.style("font", "14px sans-serif")
.text(d => d)
await Promises.delay(3000);
data = d3.shuffle(alphabet.slice())
.slice(Math.floor(Math.random() * 10) + 5)
.sort(d3.ascending);
}
}