Published
Edited
Nov 5, 2020
Importers
3 stars
Insert cell
Insert cell
groupedByFIPS = _.chain(data)
.filter(d => time >= d.time.getTime())
.groupBy('FIPS')
.map((issues, FIPS) => {
// extract state, county, sum the num precincts & delay
// and add in demographics data from 2018 + election data from 2016
const {state, county, income, blackPop, margin} = issues[0]
return {
state, county, FIPS,
numPrecincts: _.sumBy(issues, 'numPrecincts'),
delay: _.sumBy(issues, 'delay'),
income, blackPop, margin,
issues,
}
}).filter()
.value()
Insert cell
groupedByState = _.chain(groupedByFIPS)
.groupBy('state')
.value()
Insert cell
swingStates = ['Arizona', 'Florida', 'Georgia', 'Iowa', 'Michigan', 'Minnesota', 'Nevada', 'New Hampshire', 'North Carolina', 'Ohio', 'Pennsylvania', 'Texas', 'Wisconsin']
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.markPoint()
.data(groupedByFIPS)
.encode(
vl.x().fieldQ('margin'),
vl.y().fieldQ('income'),
vl.color().fieldQ('delay'),
vl.size().fieldQ('numPrecincts'),
).render()
Insert cell
demoYear = 2018
Insert cell
presYear = 2016
Insert cell
Insert cell
data = d3.csv(`https://docs.google.com/spreadsheets/d/1pfawvp_5cxehn9PyCl9dWHZ9ZBaDMKZqRbXhMrRvpwo/gviz/tq?tqx=out:csv&sheet=Data`)
.then(data => {
return _.chain(data)
.map(d => {
const FIPS = d['County FIPS'].toString().padStart(5, 0)
const timeString = d['Time of occurrence (EST)']
const date = `11/3/2020 ${timeString} EST`

const electionData = _.find(allElectionsData, d => d.FIPSCode === FIPS)
const demoData = _.find(allDemographicsData, d => d.FIPSCode === FIPS)
if (!electionData || !demoData) return
const {repMargin, totalVotes} = electionData
const {B19301_001E, B02001_003E, B01003_001E} = demoData
const income = B19301_001E[demoYear]
const blackPop = B02001_003E[demoYear] / B01003_001E[demoYear]
const margin = repMargin[presYear] / totalVotes[presYear]

return {
state: d.State,
county: d.County,
FIPS,
description: d['Voting problem description'],
numPrecincts: +d['Precincts affected'] || 1,
url: d['Article URL'],
delay: +d['Delay duration (hours)'],
type: d.Type,
time: new Date(date),
date,
// demographic data
margin, income, blackPop,
}
}).filter().value()
})
Insert cell
medianIncome = d3.median(allDemographicsData, d => d.B19301_001E[demoYear])
Insert cell
timeRange = {
const sorted = _.sortBy(data, 'time')
return [sorted[1].time, _.last(sorted).time]
}
Insert cell
timezoneOffset = (new Date()).getTimezoneOffset()
Insert cell
Insert cell
_.filter(data, d => _.isNaN(d.time.getTime()))
Insert cell
new Date("11/3/2020 1:15 PM EST")
Insert cell
contributors = d3.csv(`https://docs.google.com/spreadsheets/d/1pfawvp_5cxehn9PyCl9dWHZ9ZBaDMKZqRbXhMrRvpwo/gviz/tq?tqx=out:csv&sheet=Contributors`)
Insert cell
d3 = require('d3')
Insert cell
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
import {colors, linearGradient, arrowMarker} from '678eab71089ff43a'
Insert cell
import {allDemographicsData, allElectionsData} from '@sxywu/all-project-data-cached'
Insert cell
import {slider} from "@jashkenas/inputs"
Insert cell
chroma = require('chroma-js')
Insert cell
style = html`
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@900&family=Work+Sans:wght@400;500;700;900&display=swap" rel="stylesheet">

<style>
body, select, option {
font-family: 'Work Sans', sans-serif;
line-height: 1.5;
color: ${colors.black}
}

h1, h2 {
font-family: 'Playfair Display', serif;
}

select {
padding: 2px 5px;
font-size: 16px;
max-height: 100px;
min-width: 300px;
}

.highlight {
display: inline-block;
background-color: ${colors.highlight};
padding: 0px 10px;
margin-top: 5px;
border-radius: 5px;
}

.textblock {
position: absolute;
font-size: 12px;
width: 175px;
}

.center {
transform: translate(-50%, -50%);
text-align: center;
}

.bold {
font-weight: bold;
}
</style>
`
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