Public
Edited
May 7
Insert cell
Insert cell
nycGeo
Insert cell
Insert cell
nycGeo.features[0]
Insert cell
Insert cell
nycGeo.features[0].properties.zcta
Insert cell
Insert cell
mapWidth = 640
Insert cell
mapHeight = 640
Insert cell
Insert cell
projection = d3.geoAlbers()
.fitSize([mapWidth, mapHeight], nycGeo)
Insert cell
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
Insert cell
path(nycGeo)
Insert cell
<svg width=${mapWidth} height=${mapHeight}>
<path
d=${path(nycGeo)}
fill="#d3d3d3"
stroke="white"
/>
</svg>
Insert cell
path(nycGeo).length
Insert cell
Insert cell
path(nycGeo.features[10])
Insert cell
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', mapWidth)
.attr('height', mapHeight);

svg.selectAll("path")
.data(nycGeo.features)
.join("path")
.attr("d", path) // same as `d => path(d)`
.attr("fill", '#d3d3d3')
.attr("stroke", "white");

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', mapWidth)
.attr('height', mapHeight);

// draw one svg path for the entire map
svg.append("path")
.attr("d", path(nycGeo))
.attr("fill", '#d3d3d3')
.attr("stroke", "white");

return svg.node();
}
Insert cell
Insert cell
zipToInjuries
Insert cell
maxInjuriesForZip = d3.max(Object.values(zipToInjuries))
Insert cell
Insert cell
Insert cell
viewof t = Inputs.range([0, 1], {label: "interpolator input", step: 0.01})
Insert cell
t
Insert cell
d3.interpolateBlues(t)
Insert cell
Insert cell
color = d3.scaleSequential()
.domain([0, maxInjuriesForZip])
.interpolator(d3.interpolateBlues)
.unknown('#d3d3d3')
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', mapWidth)
.attr('height', mapHeight);

// create one path for each zip code
svg.selectAll("path")
.data(nycGeo.features)
.join("path")
// use the geographic path generator to set the shape of the path
.attr("d", path)
// use the color scale to set the color of the path
.attr("fill", d => color(zipToInjuries[d.properties.zcta]))
.attr("stroke", "white");

return svg.node();
}
Insert cell
Insert cell
maxRadius = 10
Insert cell
radius = d3.scaleSqrt()
.domain([0, maxInjuriesForZip])
.range([0, maxRadius])
Insert cell
Insert cell
path.centroid(nycGeo.features[0])
Insert cell
{
const svg = d3.create('svg')
.attr('width', mapWidth)
.attr('height', mapHeight);

// draw map

svg.selectAll("path")
.data(nycGeo.features)
.join("path")
.attr("d", path)
.attr("fill", '#d3d3d3')
.attr("stroke", "white");

// draw circles

svg.append("g")
.selectAll("circle")
.data(nycGeo.features)
.join("circle")
.attr("stroke", "steelblue")
.attr("fill", "steelblue")
.attr("fill-opacity", 0.5)//.attr('cx',d=>path.centroids(d)[0])
// set the position of the circles
.attr("transform", d => `translate(${path.centroid(d)})`)
// set the size of the circles
.attr("r", d => radius(zipToInjuries[d.properties.zcta]));

// add legend

const legendGroup = svg.append("g")
.attr('transform', `translate(${maxRadius * 2}, 10)`)
.attr('font-family', 'sans-serif')
.attr('font-size', 12);
legendGroup.append('text')
.attr('dominant-baseline', 'hanging')
.attr('font-weight', 'bold')
.text('Vehicle collision injuries, 2019');
const legendRows = legendGroup.selectAll("g")
.data([100, 200, 400, 800])
.join("g")
.attr("transform", (d, i) => `translate(0, ${30 + i * 2.5 * maxRadius})`);
legendRows.append("circle")
.attr("r", d => radius(d))
.attr("stroke", "steelblue")
.attr("fill", "steelblue")
.attr("fill-opacity", 0.5);

legendRows.append("text")
.attr("dominant-baseline", "middle")
.attr("x", maxRadius + 5)
.text(d => d);

return svg.node();
}
Insert cell
Insert cell
d3 = require("d3@7")
Insert cell
import {legend} from "@d3/color-legend"
Insert cell
nycGeo = FileAttachment("nyu-2451-34509-geojson.json").json()
Insert cell
dataset = (await d3.csv(url, crash => ({
date: d3.timeParse('%m/%d/%Y')(crash.date),
zip: crash.zip,
borough: crash.borough,
injured: +crash.injured,
}))).filter(d => d.borough !== '' && d.injured >= 1 && d.zip !== '')
Insert cell
injuriesByMonth = {
const counts = d3.rollup(dataset,
collisions => d3.sum(collisions, c => c.injured),
d => d3.timeMonth(d.date).getTime());
return Array.from(counts, (([date, count]) => ({
date: new Date(date),
injuries: count
})));
}
Insert cell
zipToInjuries = Object.fromEntries(d3.rollup(dataset,
collisions => d3.sum(collisions, c => c.injured),
d => d.zip))
Insert cell
url = 'https://gist.githubusercontent.com/DanielKerrigan/d01fc44e4cee0c5c2434f464497ba260/raw/982bcefac49be9fd29887cbaead524e033f6dad4/nyc-collisions-2019-reduced.csv'
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