map = {
let svg = d3.create("svg").attr("width", w).attr("height", h);
let map = svg.append("g").attr("id", "map");
let path = d3.geoPath().projection(projection);
map
.selectAll("path")
.data(contiguous_states.features)
.join("path")
.attr("d", path)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 2);
let nodes = contiguous_states.features.map(function (o, id) {
let [x0, y0] = projection([o.properties.longitude, o.properties.latitude]);
return {
id: o.properties.postal,
neighbors: o.properties.neighbors,
x: x0,
y: y0
};
});
let link = svg.append("g").attr("class", "links");
link
.selectAll("line")
.data(state_adjacencies)
.join("line")
.attr("x1", (d) => d.x1)
.attr("y1", (d) => d.y1)
.attr("x2", (d) => d.x2)
.attr("y2", (d) => d.y2)
.attr("class", (d) => `${d.source} ${d.target}`)
.attr("stroke-width", 0.1)
.attr("stroke", "black");
let node = svg.append("g");
node
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("id", function (d) {
return d.id;
})
.attr("r", 5)
.attr("fill", "black")
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y)
.on("pointerenter", function (_, n) {
d3.select(this).attr("fill", "green");
let state = n.id;
link.selectAll(`.${state}`).attr("stroke-width", 2);
n.neighbors.forEach(function (i) {
node
.selectAll(`#${contiguous_states.features[i].properties.postal}`)
.attr("fill", "red");
});
})
.on("pointerleave", function () {
link.selectAll("line").attr("stroke-width", 0.1);
node.selectAll("circle").attr("fill", "black");
});
return svg.node();
}