score:29

Accepted answer

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.

score:3

Use threshold scales. Here is a quick example:

coffee> d3 = require 'd3'
coffee> color = d3.scale.threshold().domain([5,30,100]).range(["red","orange","green"]);
coffee> color 6
'orange'
coffee> color 3
'red'
coffee> color 33
'green'

score:4

Use a Quantitative Scale plus Color Brewer

// pick any number [3-9]
var numColors = 9;

var heatmapColour = d3.scale.quantize()
  .domain(d3.extent(dataset))
  .range(colorbrewer.Reds[numColors]);

// 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(d);})

Related Query