Published
Edited
Jul 28, 2020
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
allegationsByOfficerPrecinct = d3.csvParse(
await FileAttachment("allegations-per-officer-perprecinct.csv").text()
)
Insert cell
withPrecinct = allegationsByOfficerPrecinct
.filter(d => !!d.command_at_incident)
.sort((a, b) => b.count - a.count)
// .slice(0, 2000)
Insert cell
Insert cell
topOfficers = 200
Insert cell
Insert cell
Insert cell
Insert cell
// parseJson(
// nodes.map(d => {
// return {
// id: d.id,
// name: d.name,
// total: d.total,
// isPrecinct: d.isPrecinct
// };
// })
// )
Insert cell
Insert cell
// parseJson(links)
Insert cell
Insert cell
officerColorScale = d3.scaleSequential([0, 60], d3.interpolateBlues)
// .scaleLinear()
// .domain([0, 60])
// .range(['#2c7fb8', '#2c7fb8'])
Insert cell
officerStrokeScale = d3
.scaleLinear()
.domain([0, 60])
.range([0.25, 5])
Insert cell
height = 750
Insert cell
Insert cell
simpleSVGMap = {
// we create an SVG with the width and height specified
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);

svg
.append("g")
.selectAll("path")
.data(precinctGeometry)
.join("path")
// This line renders our population data
// .attr("fill", d => populationColor(populationByCounty.get(d.id)))
.attr("fill", d => {
if (overlappingPrecincts.get(d.id)) {
return "seagreen";
} else {
return "lightgray";
}
})
.attr("d", d3.geoPath(projection));

svg
.append("g")
.selectAll("circle.centroid")
.data(pGeomCentroids)
.join("circle")
.classed("centroid", true)
// This line renders our population data
// .attr("fill", d => populationColor(populationByCounty.get(d.id)))
.attr("fill", d => {
if (overlappingPrecincts.get(d.precinct)) {
return "black";
} else {
return "gray";
}
})
.attr("r", 5)
.attr(
"transform",
d => `translate(${projection(d.centroid.geometry.coordinates)})`
)
.attr("d", d3.geoPath(projection));

// we need to return a DOM element.
// the .node() function returns the DOM element corresponding to the d3 selection.
return svg.node();
}
Insert cell
overlappingPrecincts = new Map(
precincts
.filter(d => !!centroidLookup.get(weirdToNormal(d.id)))
.map(d => [weirdToNormal(d.id), d.id])
)
Insert cell
// svgbubbles
Insert cell
officerRadiusScale = d3
.scaleLog()
.domain(d3.extent(nodes.filter(d => !d.isPrecinct), d => d.total))
.range([2, 12])
Insert cell
precinctRadiusScale = d3
.scaleLinear()
.domain(d3.extent(nodes.filter(d => d.isPrecinct), d => d.total))
.range([2, 20])
Insert cell
Insert cell
canvasBubbles
Insert cell
// parseJson(canvasBubbles)
Insert cell
function parseJson(data) {
let parser = new json2csv.Parser();
let csv = parser.parse(data);
return csv;
}
Insert cell
Insert cell
md`## Precinct Geometries
`
Insert cell
pGeom = d3.json("https://data.cityofnewyork.us/resource/kmub-vria.json")
Insert cell
precinctGeometry = pGeom.map(d => {
return {
type: "Feature",
id: d.precinct,
precinct: d.precinct,
geometry: d.the_geom
};
})
Insert cell
projection = d3.geoAlbersUsa().fitSize([width, height], {
type: "FeatureCollection",
features: precinctGeometry
})
Insert cell
ejProjection = d3
.geoTransverseMercator()
.rotate([76 + 35 / 60, -40])
.fitExtent([[10, 10], [960 - 20, 500 - 20]], {
type: "FeatureCollection",
features: precinctGeometry
})
Insert cell
Insert cell
projection([-74.01550862599652, 40.70170515792238])
Insert cell
centroidLookup = new Map(pGeomCentroids.map(d => [d.precinct, d.centroid]))
Insert cell
pGeom.map(d => d.precinct)
Insert cell
weirdToNormal = function(pct) {
return String(Number(pct.split(" ")[0]));
}
Insert cell
weirdToNormal("075 PCT")
Insert cell
margin = ({ top: 0, right: 20, bottom: 30, left: 20 })
Insert cell
Insert cell
Insert cell
require('d3-jetpack')
Insert cell
Insert cell
d3tip = require('d3-tip')
Insert cell
json2csv = require("json2csv")
Insert cell
turf = require("@turf/turf")
Insert cell
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