{
const svg = d3.create("svg")
.attr("viewBox", "0 0 975 610");
const g = svg.append("g")
.attr("fill", "none")
.attr("stroke", "#000")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round");
g.append("path")
.attr("stroke-width", "0.5")
.attr("d", path(topojson.mesh(us, us.objects.states, (a, b) => a !== b)));
g.append("path")
.attr("d", path(topojson.feature(us, us.objects.nation)));
const projection = d3.geoAlbersUsa()
.scale(1300)
.translate([487.5, 305]);
const points = [
{lat: 37.7749, lon: -122.4194},
{lat: 40.7128, lon: -74.0060},
];
svg.selectAll(".dot")
.data(points)
.enter().append("circle")
.attr("class", "dot")
.attr("transform", d => {
const [x, y] = projection([d.lon, d.lat]);
return `translate(${x}, ${y})`;
})
.attr("r", 5)
.attr("fill", "blue");
const brush = d3.brush().on("brush end", brushed);
svg.append("g")
.attr("class", "brush")
.call(brush);
function brushed({selection}) {
if (selection) {
const [[x0, y0], [x1, y1]] = selection;
svg.selectAll('circle')
.classed("selected", d => {
const [x, y] = projection([d.lon, d.lat]);
return x0 <= x && x <= x1 && y0 <= y && y <= y1;
});
} else {
svg.selectAll('circle').classed("selected", false);
}
}
;
const zoom = d3.zoom()
.scaleExtent([1, 8])
.on("zoom", (event) => {
g.attr("transform", event.transform);
svg.selectAll(".dot").attr("transform", d => {
const [x, y] = projection([d.lon, d.lat]);
const transformedX = x * event.transform.k + event.transform.x;
const transformedY = y * event.transform.k + event.transform.y;
return `translate(${transformedX}, ${transformedY})`;
}).attr("r", 5 );
});
svg.call(zoom);
return svg.node();}