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.