Published
Edited
Mar 3, 2020
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
chartWidth = 225
Insert cell
selectedBarColor = '#EA5919'
Insert cell
selectedState = '19'
Insert cell
selectedRace = 'White'
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