Published
Edited
Oct 26, 2021
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
visualization = {
button;
const svg = d3.create("svg").attr("width", width).attr("height", height);

svg
.selectAll(".popLines")
.data(countryData)
.enter()
.append("path")
.attr("d", (d) => lineGen(d.population))
.attr("fill", "none")
.attr("stroke", "blue")
.attr("stroke-width", 0.1);

svg
.append("line")
.attr("x1", margin)
.attr("x2", margin)
.attr("y1", margin)
.attr("y2", height - margin)
.attr("stroke", "red")
.transition()
.duration((tones[tones.length - 1].timing + sustain) * 1000)
.ease(d3.easeLinear)
.attr("x1", width - margin)
.attr("x2", width - margin);
return svg.node();
}
Insert cell
Insert cell
Insert cell
Inputs.table(countryPop)
Insert cell
Insert cell
Insert cell
playChart = {
//when button is pressed *button* updates, and so this code runs.
button;
//create a new synthesizer instrument
const synth = new tone.PolySynth().toDestination();
//adjust the tone of the synth
synth.set({ detune: -1200 });

//capture the time when play starts for note offsets
const tone_now = tone.now();
//optimize for "pre-recorded" audio
tone.setContext(new tone.Context({ latencyHint: "playback" }));

//loop through years
tones.map((year, i) => {
//trigger a note to play
synth.triggerAttackRelease(
//play all the notes for each year
year.pitches,
//play notes as quarter notes, since that's what we set up
year.noteType,
//schedule the note in the future with an incrementally increasing delay
tone_now + year.timing
);
});
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
toneScale = d3
.scaleQuantize()
.domain(
d3.extent(countryData.map((d) => d.population).flat(), (d) => d.population)
)
.range(toneRange)
Insert cell
Insert cell
tonesPerYear = countryData[0].population
.map((d, i) =>
countryData
.map((row) => row.population[i])
.map((d) => toneScale(d.population))
)
.map((d) => [...new Set(d)].filter((d) => d))
Insert cell
Insert cell
tones = tonesPerYear.map((year, i) => ({
pitches: year,
noteType: "8n",
timing: (i + 1) * sustain
}))
Insert cell
Insert cell
height = 500
Insert cell
margin = 50
Insert cell
yearScale = d3
.scaleLinear()
.domain([1960, 2020])
.range([margin, width - margin])
Insert cell
populationScale = d3
.scaleLinear()
.domain(
d3.extent(countryData.map((d) => d.population).flat(), (d) => d.population)
)
.range([height - margin, margin])
Insert cell
lineGen = d3
.line()
.x((d) => yearScale(d.year))
.y((d) => populationScale(d.population))
Insert cell
d3 = require("d3@7")
Insert cell
tone = require("tone")
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