Published
Edited
Oct 13, 2021
Insert cell
Insert cell
rawData = FileAttachment("CEIP Citations_Titles_RBhargava - Programming Basics Course.csv").csv()
Insert cell
Insert cell
approvedData = rawData.filter((e) => e['Primary Approval Option'] === 'Entry Approved')
Insert cell
Insert cell
Insert cell
dataCounts = d3.rollups(approvedData, v => v.length, d => d['Focus Category'])
Insert cell
// add random positions for each element to draw itself at
data = dataCounts.map(d => ({
...d,
targetLeft: `${d3.randomUniform(100,width-250)()}px`,
targetTop: `${d3.randomUniform(100,height-100)()}px`,
}))
Insert cell
// set up a scale so we can map frequency to text size, like a word cloud
textSizeScale = d3.scaleLinear()
.domain(d3.extent(data, d => d[1]))
.range([10, 100])
.nice()
Insert cell
Insert cell
{
let len = 0;
const div = d3.create('div')
.style('height', `${height}px`)
.style('width', `${width}px`);

const ticker = d3.interval(elapsed => {
len += 1;
const newData = data.slice(0, len);
div.selectAll('div')
.data(newData, d => d[0])
.join(
enter => enter.append('div')
.style('left', d => d.targetLeft)
.style('top', d => d.targetTop)
.style('opacity',0)
.transition()
.duration(2000)
.style('opacity', 1),
update => update,
exit => exit.remove()
)
.attr('width', `400px`)
.style('position', 'absolute')
.style('font-size', d => `${textSizeScale(d[1])}px`)
.attr('text-align', 'center')
.text(d => d[0]);
if (len == data.length ) ticker.stop();
}, 1000);
return div.node();
}
Insert cell
Insert cell
viewof currentLength = Scrubber(
d3.range(0, data.length, 1),
{ autoplay: false, delay: 800, loop: false }
)
Insert cell
// wire things up so when the Scrubber changes we call the `handleNewLength` function inside the `chartAnimate` variable below
chartAnimate.handleNewLength(currentLength)
Insert cell
chartAnimate = {
const wrapper = d3.create('div')
.style('height', `${height}px`)
.style('width', `${width}px`);

const handleNewLength = (newLength) => {
const newData = data.slice(0, newLength);
wrapper.selectAll('div')
.data(newData, d => d[0])
.join(
enter => enter.append('div')
.style('left', d => d.targetLeft)
.style('top', 0)
.transition()
.ease(d3.easeBounceOut)
.duration(3000)
.style('top', d => `${height-10-textSizeScale(d[1])}px`),
update => update,
exit => exit.remove()
)
.attr('width', `400px`)
.style('position', 'absolute')
.style('font-size', d => `${textSizeScale(d[1])}px`)
.attr('text-align', 'center')
.text(d => d[0]);
}

return Object.assign(wrapper.node(), { handleNewLength });
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more