A Leaflet tutorial uses the following hard-coded getColor
function to return colors.
// get color function getColor(n) { return n > 30 ? '#b10026' : n > 25 ? '#e31a1c' : n > 25 ? '#fc4e2a' : n > 20 ? '#fd8d3c' : n > 15 ? '#feb24c' : n > 10 ? '#fed976' : n > 5 ? '#ffeda0' : n > 0 ? '#ffffcc' : '#ffffff'; }
However, I wanted to use Chroma.js to generate the legend colors dynamically. So I needed a new getColor
function.
Chroma.js has a variety of methods to return colors. The one I choose was using scale and classes. These can then be sent as variables to a getColor
function to return colors to use in legend and map.
scale can be single value or an array of two colors (either as hex values or color words). In my case, the first is a light blue and the second is a darker blue. Chroma.js will then return gradients between these two colors. See colorHex variable below.
classes is an array of legend ‘breaks’ for the color gradients. For example they could be the numerical values from the Leaflet tutorial getColor
function above (eg 10, 20, 50, etc). See classBreaks variable below.
The new getColor
function is shown below:
var classBreaks = [1,50,100,250,500,1000,2000,3000,6000,9000]; var colorHex = ['#deebf7','#08306b']; function getColor(n,classBreaks,colorHex) { var mapScale = chroma.scale(colorHex).classes(classBreaks); if (n === 0) { var regionColor = '#ffffff'; } else { var regionColor = mapScale(n).hex(); } return regionColor }
This getColor
function can then be used as described in the Leaflet tutorial to set choropleth polygon fill colors. It also be used similarly to create the legend by looping through the classes to get a color for each legend entry.
However there is important consideration when creating the legend. Using scale and classes, Chroma.js only returns classes – 1 colors. For example the variable classBreaks array with 10 elements will only return 9 colors. To hack this I push a dummy element (‘999’) to the array so Chroma.js would return 10 colors and then ignore the dummy element when creating the legend.
The legend code is below includes hard-coded zero (0) value set to color white (#ffffff). Looping through the classBreaks each time using getColor
function to return legend color based on break value.
var legend = L.control({position: 'topright'}); legend.onAdd = function (map) { var div = L.DomUtil.create('div', 'legend'); div.innerHTML += '<i style="background: #ffffff;"></i>0 '; classBreaks.push(999); // add dummy class to extend to get last class color, chroma only returns class.length - 1 colors for (var i = 0; i < classBreaks.length; i++) { if (i+2 === classBreaks.length) { div.innerHTML += '<i style="background: ' + getColor(classBreaks[i], classBreaks, colorHex) + ';"></i> ' + classBreaks[i] + '+'; break } else { div.innerHTML += '<i style="background: ' + getColor(classBreaks[i], classBreaks, colorHex) + ';"></i> ' + classBreaks[i] + '–' + classBreaks[i+1] + ' '; } } return div; }; legend.addTo(map);
The final map legend looks like this: