I am trying to create a linear color scale for a heatmap. I want to color scale to go through a large set of specific colors, where the first color corresponds to the min of the data and the last color should be given to the max of the data.
I know that I can do this by also giving the domain 17 values in between the min and max, but I do not know how to do this dynamically if the user is able to change the dataset (and thus change the coloring of the heatmap)
In essence I would like to following, but I know it does not work
var colorScale = d3.scale.linear() .range(["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB", "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"]) .domain([d3.min(dataset, function(d) {return d;}), d3.max(dataset, function(d) {return d;})]);
Can anybody please tell me what I need to put into 'domain' to make it work?
EDIT: I did find something that does what I want. Using R I calculated 256 colors in between the 17 from above with the designer.colors functions and put this into the range. This does give the feeling of a continous color scale
var colorScale = d3.scale.linear() .range(["#6363FF", "#6364FF", "#6364FF", "#6365FF", "... several other lines with color codes ..." "#FF6764", "#FF6564", "#FF6464", "#FF6364"]) .domain(d3.range(1,257)); var quantize = d3.scale.quantile() .range(d3.range(1,257)) .domain([d3.min(dataset, function(d) {return d;}), d3.max(dataset, function(d) {return d;})]);
Now I can use the color in this fashion
colorScale(quantize(dataset))
But I'm wondering if this can also be done in less lines of code?
You want to split the problem up. First define a scale for your heatmap that maps 0-1 to your colours. Then define a second (dynamic) scale that maps your dataset to 0-1. You can then combine the scales to paint your shapes.
var colours = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB", "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"]; var heatmapColour = d3.scale.linear() .domain(d3.range(0, 1, 1.0 / (colours.length - 1))) .range(colours); // dynamic bit... var c = d3.scale.linear().domain(d3.extent(dataset)).range([0,1]); // use the heatmap to fill in a canvas or whatever you want to do... canvas.append("svg:rect") .data(dataset) .enter() // snip... .style("fill", function(d) { return heatmapColour(c(d));
Plus you can use the d3.extent function to get the min and max of the dataset in one go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With