Reputation: 315
If I have a set of data numbers that are percentages ranging from -0.75 to 0.3, and I want to create a heat map where -0.75 are "bright red" tiles and .3 values are "bright green values" and everything in between is scaled between that.
I currently have this:
js
var color = d3.scale.quantize()
.domain([-.7, .3])
.range(d3.range(11).map(function(d) { return "q" + d + "-11"; }));
css
.RdYlGn .q0-11{fill:rgb(255,0,0)}
.RdYlGn .q1-11{fill:rgb(255,50,50)}
.RdYlGn .q2-11{fill:rgb(255,100,100)}
.RdYlGn .q3-11{fill:rgb(255,150,150)}
.RdYlGn .q4-11{fill:rgb(255,200,200)}
.RdYlGn .q5-11{fill:rgb(255,255,255)}
.RdYlGn .q6-11{fill:rgb(200,255,200)}
.RdYlGn .q7-11{fill:rgb(150,255,150)}
.RdYlGn .q8-11{fill:rgb(100,255,100)}
.RdYlGn .q9-11{fill:rgb(50,255,50)}
.RdYlGn .q10-11{fill:rgb(0,255,0)}
But the numbers don't seem to scale right. The percentages seem to be scaled like so:
.3 = q0 Green
.0 = q2
-.1 = q4
-.5 = q5 White
-.7 = q11 Red
It makes sense that -.5 is my middle value of white, because that is the median of .3 and -.7, but I don't want it to be that. Any help?
Upvotes: 0
Views: 1052
Reputation: 2517
Take a look at d3's built in color interpolators here
In your case it would look something like this:
var interpolator = d3.interpolateHsl('rgb(255,0,0)', 'rgb(0,255,0)');
var scale = d3.scale.linear()
.domain([-.7, .3])
.range([0, 1])
// interpolator(scale(0)) will return a color in between red and green
Upvotes: 2
Reputation: 2994
Fortunately there is a very simple way to accomplish what you want. Just use a polylinear scale, which is just a regular d3.scale.linear()
with anchor points at each value where a new color should start.
To have red for negative values, white at zero, and green for positive, use:
polylinear_color = d3.scale.linear()
.domain([-0.3, 0, 0.7])
.range(['rgb(255,0,0)','rgb(255,255,255)','rgb(0,255,0)'])
The scale does all the interpolation and instead of using classes you just set .attr('fill',function(d){return polylinear_color(d);});
on the things being colored.
I made a jsfiddle to illustrate, here.
Upvotes: 5