D3 Choropleth map not displaying

I am a big fan of d3 but sometimes I feel like as powerful as it us the documentation has a bunch of missing holes.

I have managed to retrieve both data sets, and I believe i’m using the geoPath, and projection properly, but I can’t find any good explanation or tutorial on how to manipulate what goes into the .data() function as far as using topojson files.

So 1) is there a good tutorial somewhere?
and 2) can you see why my map isn’t showing ?

Start here.

The map isn’t showing because you’re trying to select that empty g on svg that may not be there:

      svg
        .select("g")

You need to give it a class or ID when you create it and use the selector or append a new one (appending works). Next, since you’re using projected data (see above) you can’t use a different projection:

        .attr( "d", us_geoPath );

This has to be a plain d3.geoPath().

wow this is insightful, i’ll try to update these changes.

can you tell me what you think is a good source to learn more? I feel like D3 API documentation on github lacs implementation details, the examples on observable assume more knowledge than I have, and most of the tutorials are mostly a cut & paste follow along.

I appreciate your help!

The official D3 documentation on github is the best documentation as it is the only place that stays up-to-date with D3. It’s dense stuff. There are usually linked examples but the documentation and examples are not always beginner-friendly.

Most other sources on the web are copies of stuff on observablehq.com that are out of date. You can search for other sources but just make sure you compare with the official documentation to ensure that everything is correct and current.

1 Like

Thanks so much, I appreciate it. I also read through all those older posts you made, and your input is really helpful. You could easily create your own D3 tutorials that are easy to follow!

I’m so close to finishing this, and my legend LOOKS like it has appropriate HTML created, but it’s not appearing on the final map.

My guess is that it could have something to do with the size if my original SVG and that it’s showing outside of it?

But I fell like I did the same thing with my heat map map.

Would you mind taking a look ?

Here is my code for the legend:

/Legend
      //create div
      let lh = 20
      let lw = 100
      var legend = d3
        .select("body")
        .append("div")
        .attr("id", "legend")
        .attr("height", lh)
        .attr("width", lw)
       
      legend
        .selectAll("rect")
        .data([20,40,60,80,100])
        .enter()
        .append("rect")
        .attr("width", 20)
        .attr("height", 20)
        .attr("fill", (d) => colorScale(d))

And the resulting HTML, which looks like it should display what I want:

<div id="legend" height="20" width="100">
<rect width="20" height="20" fill="#662506"></rect>
<rect width="20" height="20" fill="#fe9929"></rect>
<rect width="20" height="20" fill="#cc4c02"></rect>
<rect width="20" height="20" fill="#662506"></rect>
<rect width="20" height="20" fill="#662506"></rect>
</div>

But it’s not showing at all.

I’ve seen some solutions having a vertically aligned legend. Would you just swap the width and height of the bounding element?

And a final question (ok, probably not my last question)…actually maybe this will solve it…
How would I position my legend over the SVG, rather than as an adjacent element / div?

I guess I can look up absolute positioning for SVG… maybe it’s as simple as just using CSS to position it. I’ll give it a try!

I think i figured it out. It has to be an SVG for d3 to draw on, not a div with rectangles in it!

You can use D3 to manipulate anything in the DOM, including HTML and SVG elements. So if your data would make a good list, you can map data points to li elements.

But like you noticed, it has to be correct so you can only draw SVG elements in the appropriate place in an SVG and likewise for HTML elements.