Published
Edited
Oct 6, 2020
4 stars
Insert cell
Insert cell
Insert cell
date = "20200801"
Insert cell
title = "Daily COVID cases per 100k"
Insert cell
Insert cell
+now
Insert cell
+dates[2]
Insert cell
Insert cell
Insert cell
rPopScale = d3
.scaleSqrt()
.domain(popExtent)
.range([2, 20])
Insert cell
projection = d3
.geoAlbersUsa()
.translate([mapWidth / 2, mapHeight / 2 + 20])
.scale([1150])
Insert cell
legendSize = 50
Insert cell
signalMap[signal].extent[1]
Insert cell
lineSize = 13
Insert cell
orientation = "3/8"
Insert cell
// q = d3.scaleQuantize([1, 10], ramp2)
q = d3.scaleQuantize(signalMap[signal].extent, ramp)
Insert cell
color = "#fff"
Insert cell
ramp = [
// textures
// .paths()
// .d("crosses")
// .size(lineSize * 0.75)
// .lighter(),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 0.5)
.lighter(),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 0.7)
.lighter(),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 0.9),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize)
.heavier(1),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 1.1)
.heavier(1.5),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 1.2)
.heavier(2),
textures
.lines()
.stroke(color)
.orientation(orientation)
.size(lineSize * 2)
.heavier(4)
]
Insert cell
import { pathMonth } from "@d3/calendar-view"
Insert cell
now = realDate(date).toDate()
Insert cell
pathMonth(d3.utcMonth(now))
Insert cell
dates = {
let month = d3.utcMonth(now);
return d3.timeDay.range(
month,
d3.timeDay.offset(d3.timeMonth.offset(month, 1), -1)
);
}
Insert cell
d3.utcMonth(now)
Insert cell
d3.timeMonth.offset(d3.utcMonth(now), 1)
Insert cell
cellSize = 11
Insert cell
dates
Insert cell
circles = {
let localNodes = shapesWithData
.map(d => {
let p = projection(d.centroid.geometry.coordinates) || [0, 0];
return {
id: d.id,
metric: d.metric,
name: d.properties.name,
state: d.state,
r: rScale(d.metric), // || 2,
population: d.population,
p: rPopScale(d.population),
cx: p[0],
cy: p[1],
x: p[0],
y: p[1]
};
})
.filter(d => !isNaN(d.r));
// console.log(localNodes);

let simulation = d3
.forceSimulation(localNodes)
.force(
"collide",
d3
.forceCollide()
// .radius(d => d.p) // for spacing by population
.radius(d => d.p * 1.4) // for spacing by metric
.strength(0.85)
)
.force(
"x",
d3.forceX(d => {
return d.cx;
})
)
.force(
"y",
d3.forceY(d => {
return d.cy;
})
);

simulation.tick(200);

localNodes.sort((a, b) => a.metric - b.metric);
return localNodes;
}
Insert cell
Insert cell
// colorScale = d3.scaleSequential(
// // d3.extent(shapesWithData, d => d.metric),
// signalMap[signal].extent,
// // [0, 3000],
// d3.interpolateReds
// )

colorScale = d3.scaleQuantize(
signalMap[signal].extent,
d3.schemeYlGnBu[8].reverse()
)
// colorScale = d3.scaleQuantize(extent, signalMap[signal].colorScheme)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
signal
Insert cell
signalMap
Insert cell
Insert cell
Insert cell
slugify = require("slugify")
Insert cell
slugify("Hello World")
Insert cell
Insert cell
// extent = d3.extent(shapesWithData, d => d.metric)
extent = [0, 200]
Insert cell
Insert cell
Insert cell
data = fetchData(signalMap[signal], date, fips)
Insert cell
metrics = new Map(data.epidata.map(d => [d.geo_value, d.value]))
Insert cell
reduceMetrics = data.epidata.reduce((m, d) => {
m[d.geo_value] = d.value;
return m;
}, {})
Insert cell
Insert cell

// metricExtent = d3.extent(shapesWithData, s => {
// return s.metric;
// })
Insert cell
rScale = d3
.scaleSqrt()
.domain(extent)
.range([0.1, 12])
Insert cell
popExtent = d3.extent(shapesWithData, s => {
return s.population;
})
Insert cell
rPopScale(762)
Insert cell
Insert cell
Insert cell
Insert cell
signal
Insert cell
usShapes = d3.json("https://cdn.jsdelivr.net/npm/us-atlas@3/counties-10m.json")
Insert cell
countyShapes = topojson
.feature(usShapes, usShapes.objects.counties)
.features.sort((a, b) => +a.id - +b.id)
Insert cell
stateShapes = topojson
.feature(usShapes, usShapes.objects.states)
.features.sort((a, b) => +a.id - +b.id)
Insert cell
statefips = d3.group(
stateShapes.map(d => {
return {
id: d.id,
name: d.properties.name
};
}),
d => d.id
)
Insert cell
shapesWithData = countyShapes.map(s => ({
...s,
state: statefips.get(s.id.slice(0, 2))[0].name,
population: pops.get(s.id),
metric: metrics.get(s.id),
centroid: turf.centroid(s)
}))
Insert cell
Insert cell
Insert cell
sensors = [
{
key: 'doctor-visits-smoothed_adj_cli',
name: 'Doctor Visits',
id: 'doctor-visits',
tooltipText:
'Percentage of daily doctor visits that are due to COVID-like symptoms',
mapTitleText:
'Percentage of daily doctor visits that are due to COVID-like symptoms',
chartTitleText:
'Percentage of daily doctor visits that are due to COVID-like symptoms',
yAxis: 'Percentage',
format: 'percent',
signal: 'smoothed_adj_cli',
levels: ['county', 'msa', 'state'],
type: 'early',
extent: [0, 11],
colorScheme: d3.schemePuRd[8]
},
{
key: 'hospital-admissions-smoothed_adj_covid19',
name: 'Hospital Admissions',
id: 'hospital-admissions',
tooltipText:
'Percentage of daily hospital admissions with COVID-19 associated diagnoses',
mapTitleText:
'Percentage of daily hospital admissions with COVID-19 associated diagnoses',
chartTitleText:
'Percentage of daily hospital admissions with COVID-19 associated diagnoses',
yAxis: 'Percentage',
format: 'percent',
signal: 'smoothed_adj_covid19',
levels: ['county', 'msa', 'state'],
type: 'late',
extent: [0, 22],
colorScheme: d3.schemeRdPu[8]
},
{
key: 'fb-survey-smoothed_cli',
name: 'Symptoms (FB)',
id: 'fb-survey',
tooltipText:
'Percentage of people with COVID-like symptoms, based on Facebook surveys',
mapTitleText:
'Percentage of people with COVID-like symptoms, based on Facebook surveys',
chartTitleText:
'Percentage of people with COVID-like symptoms, based on Facebook surveys',
yAxis: 'Percentage',
format: 'percent',
signal: 'smoothed_cli',
levels: ['county', 'msa', 'state'],
type: 'early',
extent: [0, 1.8],
colorScheme: d3.schemeBlues[8]
},
{
key: 'fb-survey-smoothed_hh_cmnty_cli',
name: 'Symptoms in Community (FB)',
id: 'fb-survey',
tooltipText:
'Percentage of people who know someone in their local community with COVID-like symptoms, based on Facebook surveys',
mapTitleText:
'Percentage of people who know someone in their local community with COVID-like symptoms, based on Facebook surveys',
chartTitleText:
'Percentage of people who know someone in their local community with COVID-like symptoms, based on Facebook surveys',
yAxis: 'Percentage',
format: 'percent',
signal: 'smoothed_hh_cmnty_cli',
levels: ['county', 'msa', 'state'],
type: 'early',
extent: [0, 38.8],
colorScheme: d3.schemePuBu[8]
},
{
key: 'safegraph-full_time_work_prop',
name: 'Away from Home 6hr+ (SG)',
id: 'safegraph',
tooltipText:
'Proportion of people spending 6 hours or more away from home, based on SafeGraph mobility data',
mapTitleText:
'Proportion of people spending 6 hours or more away from home, based on SafeGraph mobility data',
chartTitleText:
'Proportion of people spending 6 hours or more away from home, based on SafeGraph mobility data',
yAxis: 'Proportion',
format: 'raw',
signal: 'full_time_work_prop',
levels: ['county', 'state'],
type: 'public',
extent: [0, 0.14],
colorScheme: d3.schemeGnBu[8]
},
{
key: 'indicator-combination-nmf_day_doc_fbc_fbs_ght',
name: 'Combined',
id: 'indicator-combination',
tooltipText:
'Combination of COVID-19 indicators available at this geographic level',
mapTitleText: 'Combination of COVID-19 indicators',
chartTitleText: 'Combination of COVID-19 indicators',
yAxis: 'Combined value (arbitrary scale)',
format: 'raw',
signal: 'nmf_day_doc_fbc_fbs_ght',
levels: ['county', 'msa', 'state'],
type: 'early',
extent: [0.24, 2],
colorScheme: d3.schemeYlGnBu[8]
},
{
key: 'indicator-combination-confirmed_7dav_incidence_prop',
name: 'Cases per 100,000 People',
id: 'indicator-combination',
tooltipText:
'Daily new confirmed COVID-19 cases per 100,000 people (7-day average), based on data reported by USAFacts and Johns Hopkins University',
mapTitleText:
'Daily new confirmed COVID-19 cases per 100,000 people (7-day average)',
chartTitleText:
'Daily new confirmed COVID-19 cases per 100,000 people (7-day average)',
yAxis: 'Cases per 100,000 people',
format: 'raw',
signal: 'confirmed_7dav_incidence_prop',
levels: ['msa', 'county', 'state'],
type: 'late',
extent: [0, 50],
colorScheme: d3.schemeOranges[8]
},
{
key: 'indicator-combination-deaths_7dav_incidence_prop',
name: 'Deaths per 100,000 People',
id: 'indicator-combination',
tooltipText:
'Daily new COVID-19 deaths per 100,000 people (7-day average), based on data reported by USAFacts and Johns Hopkins University',
mapTitleText:
'Daily new COVID-19 deaths per 100,000 people (7-day average)',
chartTitleText:
'Daily new COVID-19 deaths per 100,000 people (7-day average)',
yAxis: 'Deaths per 100,000 people',
format: 'raw',
signal: 'deaths_7dav_incidence_prop',
levels: ['msa', 'county', 'state'],
type: 'late',
extent: [0, 1.8],
colorScheme: d3.schemeReds[8]
}
]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
moment = require('moment')
Insert cell
Insert cell
textures = require("textures")
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