Question

I have a standard 50-state map built with d3 in which I'm dynamically coloring states according to various datasets. Whatever the dataset, the values are normalized on a scale of 0 to 1, where 1 corresponds to the state with the highest value. I'm looking for a way to calculate the shade of the state using the value of the normalized data point.

In the past, I've chosen a base color that I like -- say, #900 -- and set the fill of each state to that color and the opacity to the normalized value. This works okay save for two problems:

  • when the canvas has a background color, it requires drawing a blank white state beneath every shaded state; and
  • fading out colors this way can look pasty

But I really like being able to set the color dynamically rather than dealing with bins for the data and preset arrays of RGB values for the gradient. So I'm wondering if there's a better way. I can take care of conversion if an alternate color system would work better.

d3 has a baked-in HSL converter, so I tried this:

// 0 <= val <= 1 
function colorize(val) {
    // nudge in the extremes
    val = 0.2 + 0.6 * val;
    return d3.hsl(0, val, 1 - val);
}

It works okay -- This is a map of fishing jobs, which are most prevalent in Maine and Oregon -- but I suspect there's a better way. Ideas?

enter image description here

Was it helpful?

Solution

I like what you did actually, but if you wish to do something different, you can always do a D3 scale. For example:

 var scale =  d3.scale.linear().domain([rangeMin, rangeMid,
 rangeMax]).range(["#Color1","#Color2","#Color3"]);

And then set each state by

return scale(dataValue);

You can set your rangeMin and rangeMax variables to be the minimum and maximum values of your data. The median number, rangeMid, that I added is optional. I would suggest using this if you would like some variety in your color. I have used this scale feature to make a word frequency heatmap that came out pretty nice. I hope that I was able to help in some way!

Note: I used this with css hex values, but I believe RGB and HSL could also work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top