d3.jstopojson

Why can't I get a d3.js map to render using topojson?


I'm having some difficulty getting d3 to render a geoAlbersUsa projection from topoJson data. I'm showing a blank screen, but no errors returned. The geoJson data seems to be coming through fine, but it's not rendering the path for some reason. Any help would be greatly appreciated!

Here's the relevant code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
</head>
<body>
    <script>
        const width = 1000;
        const height = 600;

        const projection = d3.geoAlbersUsa()
            .translate([width / 2, height / 2])
            .scale(800);

        const path = d3.geoPath(projection);

        const svg = d3.select("body")
            .append("svg")
            .attr("height", height)
            .attr("width", width)
            .style("display", "block")
            .style("margin", "auto");

        d3.json("https://d3js.org/us-10m.v1.json").then(data => {
            svg.selectAll(".states")
                .data(topojson.feature(data, data.objects.states).features)
                .attr("d", path)
                .style("fill", "none")
                .attr("class", "states")
                .style("stroke", "black")
                .style("stroke-width", "2px")
        });
    </script>
</body>
</html>

Solution

  • You need to join with an element:

                .data(topojson.feature(data, data.objects.states).features)
                .join("path") // here
                .attr("d", path)
                .style("fill", "none")
                .attr("class", "states")
                .style("stroke", "black")
                .style("stroke-width", "2px")