Public
Edited
Apr 8
1 fork
1 star
Insert cell
Insert cell
chart = {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;");
const path = d3.geoPath();

// The counties feature collection is all U.S. counties, each with a
// five-digit FIPS identifier. The statemap lets us lookup the name of
// the state that contains a given county; a state’s two-digit identifier
// corresponds to the first two digits of its counties’ identifiers.
const states = topojson.feature(us, us.objects.states);
const statemap = new Map(states.features.map(d => [d.id, d]));

// The statemesh is just the internal borders between states, i.e.,
// everything but the coastlines and country borders. This avoids an
// additional stroke on the perimeter of the map, which would otherwise
// mask intricate features such as islands and inlets. (Try removing
// the last argument to topojson.mesh below to see the effect.)
const statemesh = topojson.mesh(us, us.objects.states, (a, b) => a !== b);

//US shape
svg.append("path")
.datum(topojson.mesh(us, us.objects.nation))
.attr("fill", "#E7E7E7")
.attr("stroke", "#B1B1B1")
.attr("stroke-linejoin", "round")
.attr("d", path);
//State lines
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b))
.attr("fill", "none")
.attr("stroke", "#FFFFFF")
.attr("stroke-linejoin", "round")
.attr("d", path);

let simulation = d3
.forceSimulation(data3)
.force(
"x",
d3
.forceX()
.x((d) => d.position[0])
.strength(0.5)
)
.force(
"y",
d3
.forceY()
.y((d) => d.position[1])
.strength(0.5)
)
.force(
"collision",
d3.forceCollide().radius(radius)
)
.on("tick", function () {
let u = svg.selectAll(".nodes").data(data3);

u.enter()
.append("circle")
.attr("class", "nodes")
.attr("r", radius)
.attr("fill", (d) => d.arrests=="Y" ? "#ff7900" : "#4e4e4e")
.attr("fill-opacity", 1)
.attr("stroke", "#E7E7E7")
.attr("stroke-width", 0.8)
.merge(u)
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y)
.append("title")
.text(
(d) => `${d.id}`
);

u.exit().remove();
});

return svg.node();
}
Insert cell
data3 = data2
.map((d) => ({
id: d["University"],
position: projection([
parseFloat(d["lon"]),
parseFloat(d["lat"])
]),
x: projection([parseFloat(d["lon"]), parseFloat(d["lat"])])[0],
y: projection([parseFloat(d["lon"]), parseFloat(d["lat"])])[1],
city: d["City"],
state: d["State"],
arrests: d["Arrests"],
}))
Insert cell
data2 =
FileAttachment("2024-04-24-protest-data - map_final_0501.csv").csv()
Insert cell
Insert cell
Insert cell
width = 975
Insert cell
height = 610
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
us = FileAttachment("us-states-albers-10m.json").json()
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@6")
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