Published
Edited
Mar 24, 2021
Importers
Insert cell
Insert cell
Insert cell
prezCountyResults = allResults
.filter(d => d.race_title == "U.S. President and Vice President")
.select(aq.not('type', 'race_title', 'no_votes'))
Insert cell
Insert cell
prezStateResults = prezCountyResults
.groupby("candidate_name", "party")
.rollup(
{
sum_votes: op.sum('yes_votes')
}
)
.derive(
{ pct: d => d.sum_votes / op.sum(d.sum_votes) }
)
.filter(d => d.sum_votes > 0)
.orderby(aq.desc('sum_votes'))
Insert cell
Insert cell
prezStateResults
.view(
{
format: {
sum_votes: d => d.toLocaleString(),
pct: d => d3.format(".1%")(d),
}
}
)
Insert cell
Insert cell
prezCountyResults
.groupby('county_name')
.orderby(
aq.desc('yes_votes')
)
.derive(
{
rank: op.rank(),
pct: d => d.yes_votes / op.sum(d.yes_votes),
}
)
.derive(
{
pct_margin: d => d.pct - op.nth_value(d.pct, 2)
}
)
.filter(d => d.rank == 1)
.orderby('pct_margin')
.select(aq.not('candidate_id', 'rank'))
.view(
{
format: {
yes_votes: d => d.toLocaleString(),
total_votes: d => d.toLocaleString(),
pct: d => d3.format(".1%")(d),
pct_margin: d => d3.format(".1%")(d),
}
}
)
Insert cell
Insert cell
scale = ({
"domain": ["Democratic", "Republican", "Libertarian", "Green", "Constitution", "Write-in"],
"range": ["blue", "red", "purple", "green", "orange", "grey"]
})
Insert cell
vl
.markBar()
.data(prezStateResults)
.encode(
vl.x().fieldQ('pct'),
vl.y().fieldN('candidate_name').sort('-x'),
vl.color().fieldN('party').scale(scale)
)
.render()
Insert cell
Insert cell
resultsURL = "https://mo-gen-election-results-2020.s3.us-east-2.amazonaws.com/sos/latest.xml"
Insert cell
resultsXML = d3.xml(resultsURL)
Insert cell
reportingTime = resultsXML.getElementsByTagName("ElectionResults")[0].getAttribute('LastUpdated')
Insert cell
candidateElements = resultsXML.querySelectorAll('Candidate')
Insert cell
function parseCandidateElement(e) {
const partyElement = e.parentElement;
const countyResultsElement = partyElement.parentElement;
const countiesElement = countyResultsElement.parentElement;
const raceElement = countiesElement.parentElement;
const typeRaceElement = raceElement.parentElement;
let no_votes;
try {
no_votes = +e.querySelector('NoVotes').textContent;
}
catch(err) {
no_votes = null;
}
return {
type: typeRaceElement.querySelector('Type').textContent,
race_title: raceElement.querySelector('RaceTitle').textContent,
county_name: countiesElement.querySelector('CountyName').textContent,
reporting_precincts: +countyResultsElement.querySelector('ReportingPrecincts').textContent,
total_precincts: +countyResultsElement.querySelector('TotalPrecincts').textContent,
party: partyElement.querySelector('PartyName').textContent,
candidate_id: e.querySelector('CandidateID').textContent,
candidate_name: e.querySelector('LastName').textContent,
yes_votes: +e.querySelector('YesVotes').textContent,
no_votes: no_votes
}
}
Insert cell
allResults = aq.from(
Array.from(candidateElements).map(d => parseCandidateElement(d))
)
Insert cell
Insert cell
d3 = require("d3@6")
Insert cell
import { aq, op } from '@uwdata/arquero'
Insert cell
import {vl} from '@vega/vega-lite-api'
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