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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more