Public
Edited
Jan 5
5 forks
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
unemploymentData
Insert cell
Insert cell
stateToDateToRate = new Map(
unemploymentData
// create one [key, value] array for each state
.map(d => ([
d.state,
new d3.InternMap(
// create one [key, value] array for each month
d.rates.map(({date, rate}) => ([date, rate]))
)
]))
// filter out PR since it is not in our map projection
.filter(([state, rates]) => state !== 'Puerto Rico')
)
Insert cell
Insert cell
minRate = d3.min(stateToDateToRate, ([state, rates]) => d3.min(rates.values()))
Insert cell
maxRate = d3.max(stateToDateToRate, ([state, rates]) => d3.max(rates.values()))
Insert cell
Insert cell
color = d3.scaleSequential()
.domain([minRate, maxRate])
.interpolator(d3.interpolateOrRd)
Insert cell
Insert cell
dates = unemploymentData[0].rates.map(d => d.date)
Insert cell
date
Insert cell
viewof date = Scrubber(dates, {
autoplay: false,
loop: false,
format: d3.timeFormat('%B %Y')
})
Insert cell
Insert cell
{
const width = 600;
const height = 400;

const svg = d3.create('svg')
.attr('width', width)
.attr('height', height);

// draw map
const projection = d3.geoAlbersUsa()
.fitSize([width, height], usaGeo);

const path = d3.geoPath().projection(projection);

svg.selectAll('path')
// Our map projection does not include Puerto Rico
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('d', path)
.attr('fill', d => color(stateToDateToRate.get(d.properties.NAME).get(date)))
.attr('stroke', 'white')

return svg.node();
}
Insert cell
Insert cell
date2
Insert cell
Insert cell
Insert cell
choropleth = {
const width = 600;
const height = 400;

const svg = d3.create('svg')
.attr('width', width)
.attr('height', height);
// draw map
const projection = d3.geoAlbersUsa()
.fitSize([width, height], usaGeo);

const path = d3.geoPath().projection(projection);

// draw the states
const states = svg.selectAll('path')
// Our map projection does not include Puerto Rico
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('d', path)
.attr('stroke', 'white');

// a function that sets the fill attribute for the states for the given date
function update(date) {
states.attr('fill', d => color(stateToDateToRate.get(d.properties.NAME).get(date)));
}

// add the update function to the svg.node() object
// so that we can call it outside of this cell
svg.node().update = update;

return svg.node();
}
Insert cell
Insert cell
choropleth.update(date2)
Insert cell
Insert cell
Insert cell
Insert cell
radius = d3.scaleSqrt()
.domain()
.range()
Insert cell
Insert cell
symbolMap = {
const width = 600;
const height = 400;

const svg = d3.create('svg')
.attr('width', width)
.attr('height', height);

// draw map
const projection = d3.geoAlbersUsa()
.fitSize([width, height], usaGeo);

const path = d3.geoPath().projection(projection);

// draw the states
svg.selectAll('path')
// Our map projection does not include Puerto Rico
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('d', path)
.attr('stroke', 'white')
.attr('fill', '#d3d3d3');

// draw the circles
// set the transform attribute to position the cirlces in the center of the states
// set the color of the circles
// we do not have to set the radius yet

// create the update function that sets the
// r attribute for the circles for the given date
function update(date) {
}

// add the update function to the svg.node() object
// so that we can call it outside of this cell
svg.node().update = update;

return svg.node();
}
Insert cell
Insert cell
// call the update function whenever the scrubber updates
Insert cell
Insert cell
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