Published
Edited
Mar 3, 2020
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
censusVariables = ['NAME', ...raceCensusVariables.values()]
Insert cell
raceCensusVariables = new Map([
['Total', 'B01001_001E'], // total population
['White (including Hispanic)', 'B01001A_001E'], // white population (warning, includes hispanic)
['Black', 'B01001B_001E'], // black popultation
['American Indian and Alaska Native', 'B01001C_001E'], // native population
['Asian', 'B01001D_001E'], // asian popultation
['Native Hawaiian and Other Pacific Islander', 'B01001E_002E'], // pacific islander population
['Some Other Race', 'B01001F_001E'], // other population
['Two or more Races', 'B01001G_001E'], // 2+ population
['White', 'B01001H_001E'], // white alone population
['Hispanic or Latino (of any race)', 'B01001I_001E'] // hispanic/latino population
])
Insert cell
censusVintage = 2018
Insert cell
censusSourcePath = ['acs', 'acs5']
Insert cell
censusGeoHierarchy = ({
state: '*'
})
Insert cell
rawData = census({
vintage: censusVintage,
geoHierarchy: censusGeoHierarchy,
sourcePath: censusSourcePath,
values: censusVariables
})
Insert cell
value = state =>
state[raceCensusVariables.get(selectedRace)] / state['B01001_001E']
Insert cell
data = rawData.map(d => Object.assign(d, { value: value(d) }))
Insert cell
selectedStateData = data.find(d => d.state === selectedState)
Insert cell
trendValue = {
const totalPop = d3.sum(data, d => d['B01001_001E']);
const slicePop = d3.sum(data, d => d[raceCensusVariables.get(selectedRace)]);
return slicePop / totalPop;
}
Insert cell
Insert cell
label = `${(selectedStateData.value * 100).toFixed(0)}% ${selectedRace}`
Insert cell
trendLineColor = 'rgba(0,0,0,.4)'
Insert cell
barColor = '#E2E3DB'
Insert cell
legendTextColor = '#757575'
Insert cell
labelTextColor = '#272727'
Insert cell
showLegend = true
Insert cell
Insert cell
d3 = require('d3-array@2', 'd3-selection', 'd3-scale')
Insert cell
padding = ({
top: 0,
right: 25,
bottom: 0,
left: 0
})
Insert cell
legendMargin = ({
top: 25,
right: 0,
bottom: 18,
left: 25
})
Insert cell
chartHeight = (chartWidth * 9) / 16
Insert cell
x = d3
.scaleLinear()
.domain([0, data.length])
.range([0, chartWidth])
Insert cell
y = d3
.scaleLinear()
.domain([0, 1])
.range([chartHeight, 0])
Insert cell
function* drawChart() {
const svg = d3.select(
DOM.svg(
chartWidth +
padding.left +
padding.right +
legendMargin.left +
legendMargin.right,
chartHeight +
padding.top +
padding.bottom +
legendMargin.top +
legendMargin.bottom
)
);
const g = svg.append('g');

const stateBarsG = g
.append('g')
.attr('transform', `translate(${legendMargin.left},${legendMargin.top})`);

stateBarsG
.selectAll('.state-bar')
.data(data.sort((a, b) => d3.ascending(a.value, b.value)))
.join('rect')
.attr('class', 'state-bar')
.attr('transform', (d, i) => `translate(${x(i)},${y(d.value)})`)
.attr('width', Math.ceil(chartWidth / data.length))
.attr('height', d => y.range()[0] - y(d.value))
.attr('fill', d =>
d.state === selectedState ? selectedBarColor : barColor
);

stateBarsG
.append('rect')
.attr('width', chartWidth)
.attr('height', 2)
.attr('x', 0)
.attr('y', y(trendValue))
.attr('fill', trendLineColor);

if (showLegend) {
const legendG = g.append('g').attr('fill', legendTextColor);
legendG
.append('text')
.attr('transform', `translate(${legendMargin.left},0)`)
.attr('fill', labelTextColor)
.attr('alignment-baseline', 'hanging')
.attr('font-size', '.75rem')
.attr('font-weight', 700)
.attr('font-family', 'Arial')
.text(label);
legendG
.append('text')
.attr(
'transform',
`translate(${legendMargin.left},${padding.top +
legendMargin.top +
chartHeight})`
)
.attr('font-size', '12px')
.attr('alignment-baseline', 'hanging')
.text('State Ranking →');
legendG
.append('text')
.attr('transform', `translate(0,${legendMargin.top + y(trendValue)})`)
.attr('font-size', '12px')
.attr('alignment-baseline', 'middle')

.text('U.S.');
}
yield svg.node();
}
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