Published
Edited
Feb 7, 2021
4 stars
Insert cell
Insert cell
chart = {
const width = 975;
const height = 610;

const zoom = d3
.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);

const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

const g = svg.append("g");

g.append("g")
.attr("fill", "lightgray")
.attr("stroke", "black")
.selectAll("path")
.data(nationGeoJSON.features)
.join("path")
.attr("d", path);

const nation = g
.append("g")
.attr("fill", "transparent")
.attr("stroke", "black")
.attr('stroke-width', 1.5)
.attr("cursor", "pointer")
.selectAll("path")
.data(nationGeoJSON.features)
.join("path")
//.on("click", clicked)
.attr("d", path);

const nationOriginalPath = nation.attr('d');

const states = g
.append("g")
.attr("fill", "transparent")
.attr("cursor", "pointer")
.selectAll("path")
.data(statesGeoJSON.features)
.join("path")
.on("mouseenter", clicked)
.attr("d", path);

// const counties = g.append("g")
// .attr("fill", "transparent")
// .attr("cursor", "pointer")
// .selectAll("path")
// .data(countiesGeoJSON.features)
// .join("path")
// .on("click", clicked)
// .attr("d", path);

// g.append("path")
// .attr("fill", "transparent")
// .attr("stroke", "black")
// .attr("stroke-linejoin", "round")
// .attr("d", path(topojson.mesh(us, us.objects.states, (a, b) => a !== b)));

svg.call(zoom);

function reset() {
// states.transition().style("fill", null);
console.log('reset');

const stateToNationInterpolator = flubber.interpolate(
nation.attr('d'),
nationOriginalPath
);
nation
.transition()
.duration(1250)
.attrTween("d", function() {
return stateToNationInterpolator;
});

// svg.transition().duration(750).delay(1000).call(
// zoom.transform,
// d3.zoomIdentity,
// d3.zoomTransform(svg.node()).invert([width / 2, height / 2])
// );
}

function clicked(event, d) {
const [[x0, y0], [x1, y1]] = path.bounds(d);
event.stopPropagation();

const nationToStateInterpolator = flubber.interpolate(
nation.attr('d'),
path(d)
);
nation
.transition()
.duration(150)
.attrTween("d", function() {
return nationToStateInterpolator;
});

// svg.transition().duration(750).delay(1000).call(
// zoom.transform,
// d3.zoomIdentity
// .translate(width / 2, height / 2)
// .scale(Math.min(8, 0.9 / Math.max((x1 - x0) / width, (y1 - y0) / height)))
// .translate(-(x0 + x1) / 2, -(y0 + y1) / 2),
// d3.pointer(event, svg.node())
// );
}

function zoomed(event) {
const { transform } = event;
g.attr("transform", transform);
g.attr("stroke-width", 1 / transform.k);
}

return svg.node();
}
Insert cell
Insert cell
projection = d3.geoAlbersUsa()
//.fitSize([width, height], countyShapes)
// The default projection parameters used by most other county map examples instead of fitSize:
//.scale(1300)
//.translate([975/2, 610/2])
Insert cell
path = d3.geoPath(projection)
Insert cell
Insert cell
// us = FileAttachment("states-albers-10m.json").json()
us = d3.json("https://unpkg.com/us-atlas@3/counties-10m.json");
Insert cell
nationGeoJSON = topojson.feature(us, us.objects.nation)
Insert cell
statesGeoJSON = topojson.feature(us, us.objects.states)
Insert cell
countiesGeoJSON = topojson.feature(us, us.objects.counties)
Insert cell
Insert cell
flubber = require("flubber@0.4")
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