Stophface Stophface - 2 months ago 22x
Javascript Question

Dynamically create legend in d3

I am using

and the
to get a colorscale.

var extent = d3.extent(collection.features, function(d) {

var colorScale = d3.scale.quantize()

That gives me
different colors, corresponding to certain ranges of given values.
I then use
to fill the

.attr("fill-opacity", 0.1)
.attr("stroke", "grey")
.style("fill", function(d) {
return colorScale(;

How do I know which range of values corresponds to the color
? How would I access these values?
I want to make a legend that changes dynamically when I change the number of input colors, i.e. from
as well as the color used in the colorscale, i.e. from

I think I am very close.
I have this

var scale = d3.scale.ordinal()

I only need to fill the
with the corresponding values which I then can use to easily create my legend...
However, I do not know how to extract them dynamically.
Something like
is to static since I would need to change the colors etc. whenever I change my colorscale.


If you want to create an automatic legend, my suggestion is that you create a dataset based on your colorScale domain and range, and bind this dataset to your legend. This way, the dataset changes whenever you change the domain or the range of you scale.

For instance, if you have this scale, with the domain going from 0 to 500:

var colorScale = d3.scale.quantize()
    .domain([0, 500])
    .range(["#d73027", "#f46d43", "#fdae61", "#fee090", "#e0f3f8",
           "#abd9e9", "#74add1", "#4575b4"]);//this is colorBrewer.RdYlBu[8]

You could create an array that has all the ranges of values. This will be our dataset, named colorRange:

var colorRange = [];    
for(var i = 0; i < colorScale.range().length; i++){

Based on the previous code, if we console.log this array, we get:

console.log(colorRange);// returns [0, 62.5, 125, 187.5, 250, 312.5, 375, 437.5]

Which contains the corresponding domain values for your 8 colors. If we for instance remove two colors from colorScale range, we have now:

console.log(colorRange);// returns [0, 83.333, 166.666, 250, 333.333, 416.666]

Once you have this colorRange array, you not only have the domain values for your legend, but you can easily set the colors as well, using:


Where i goes from the first value to the last.

PS: If you were using a quantile scale instead, we could drop the cumbersome for loop and simply use [0].concat(colorScale.quantiles()) to create our array.