I'm working on creating a graph that will show unemployment rates by county in the United States. It's based on Mike Bostock's County-level map here, and it looks like this:
It works by pulling data from a CSV, assigning that data to a Javascript Map, and using that to color the various counties with a d3 color scale. My CSV data looks like this:
county,area,rate2007,rate2008,rate2009,rate2010,rate2011,rate2012,rate2013,rate2014,rate2015,rate2016
01001,Autauga County,3.3,5.1,9.7,8.9,8.4,6.9,6.2,5.9,5.3,5.3
01003,Baldwin County,3.1,4.6,9.8,10.0,9.0,7.5,6.6,6.1,5.6,5.4
01005,Barbour County,6.3,8.8,14.3,12.3,11.5,11.5,10.2,10.6,8.8,8.6
01007,Bibb County,4.1,5.8,13.3,11.4,10.5,8.5,7.9,7.2,6.7,6.6
01009,Blount County,3.2,4.7,10.0,9.8,8.7,6.9,6.3,6.1,5.4,5.5
etc...
Here's my issue: I want to be able to change this data over time, and to do so must be able to include multiple values in my Map. However, I cannot get this to work. In attempting to "upgrade" my map, I tweak the code slightly to use an array as the value in the key-value pair in the Map:
d3.queue()
.defer(d3.json, "https://d3js.org/us-10m.v1.json")
.defer(d3.csv, "unemploymentEdited.csv", function(d) {
unemployment.set(d.county, [+d.rate2007, +d.rate2008]);
}) // I use an array here to include multiple values.
.await(ready);
When I log this to the console, my data is indeed formatted as I would expect:
However, I cannot use these values to color my paths correctly. When I use a relatively simple function to access the data from the Map, it logs this error to the console: "TypeError: unemployment.get(...) is undefined."
Even more strangely, when I log this same thing to the console outside of my "fill" attribute, I get the number I would expect, meaning I get the values inside my Map. Like if I write console.log(unemployment.get(d.id)[0]) I get 4.6, or whatever the value is. What am I doing wrong? Why does the "get" function return undefined, even though I can see that the data structure is not?
Here's my full code:
var width = 960;
var height = 600;
var margin = {top: 50, bottom: 0, left: 0, right: 0}
var path = d3.geoPath(); // Geopath generator
var unemployment = new Map();
var color = d3.scaleSequential()
.domain([0.0,30.0])
.interpolator(d3.interpolateInferno);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.style("background-color","lightgrey")
d3.queue()
.defer(d3.json, "https://d3js.org/us-10m.v1.json")
.defer(d3.csv, "unemploymentEdited.csv", function(d){
unemployment.set(d.county, [+d.rate2007,+d.rate2008])
})
.await(ready);
function ready(error, us) {
console.log(unemployment)
svg.append("g")
.attr("class", "counties")
.attr("transform",`translate(0,${margin.top})`)
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.enter().append("path")
.attr("fill", function(d){
return color(unemployment.get(d.id)[0])
})
.attr("d", path)
}


d.idexactly matchesd.county.bl.ocks.orgtoblockbuilder.org(normally). +1 for the well documented question, I wish they were always like that.