rgdonohue
5/24/2016 - 12:09 AM

Dynamic Legends in CartoDB

Dynamic Legends in CartoDB

Extends Dynamic Classification of CartoDB Choropleth Map to include a legend. Makes use of a custom legend example and the cdb.geo.ui.Legend.Custom() method. Default CartoDB.css round bullets are overwritten to produce rectangles.

<!DOCTYPE html>
<html>
<head>
<title>Dynamic Classification of CartoDB Choropleth Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/3.15/themes/css/cartodb.css" />
<style>
  html, body, #map {
    height: 100%;
    padding: 0;
    margin: 0;
    background: #3d3d3d;
  }
  div.cartodb-legend {
    width: 110px;
  }
  div.cartodb-legend.custom ul li .bullet {
    border-radius: 0;
    width: 15px;
    height: 8px;
  }
</style>

</head>
<body>
    
<div id="map">
    <div class="legend"></div>
</div>

<script src="http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simple-statistics/1.0.1/simple_statistics.min.js"></script>

<script>

// instantiate our map
var map = new L.Map("map", {
    center: [-6,-2],
    zoom: 4.5
});

// request the (non-geometry) data first to calculate class ranges
$.getJSON('https://rgdonohue.cartodb.com/api/v2/sql?format=JSON&q=SELECT * FROM uninsured_adults_county', function(data) {
    
    // push all the values into an array
    var values = [];
    data.rows.forEach(function(row,i) {
        if(row.uninsured) {
            values.push(row.uninsured);
        }

    });
     
    // create array of range clusters 
    var clusters = ss.ckmeans(values, 7);
    
    // pull out the low and high values from each cluster
    var ranges = clusters.map(function(cluster){
        return [cluster[0],cluster.pop()];   
    });
    
    makeMap(ranges);

});


function makeMap(ranges) {
    
    var colors = ['#eff3ff','#c6dbef','#9ecae1','#6baed6', '#4292c6','#2171b5','#084594'];
    
    var legendData = []; // array to hold legend data
        
    // build the cartoCSS
    var cartoCSSRules = '#uninsured_adults_county{' +
                        'polygon-opacity: 0.8;' +
                        'polygon-comp-op: lighten;' +
                        'line-color: #FFF;' +
                        'line-width: 0.5;' +
                        'line-opacity: 1;' +
                        '}';

    // loop backwards, high to low
    for(var i = ranges.length; i--;) {

        var value = ranges[i][1],
            color = colors[i]; 

        // build the individual rules
        var thisRule = '#uninsured_adults_county [ uninsured <= ' + 
            value + '] { polygon-fill: ' + color + ';}'

        // add them to the cartoCSS
        cartoCSSRules += thisRule;
        
        // create a single object for the legend
        var legendClass = { name: ranges[i][0] + " - " + ranges[i][1] + "%",  value: colors[i] };
        
        // push single object to legend data array
        legendData.push(legendClass);
    }

    // source object for requesting the tiles
    var countiesLayers = {
        user_name: 'rgdonohue',
        type: 'cartodb',
        sublayers: [{
                sql: "SELECT ST_Transform(the_geom, 2163) AS the_geom_webmercator, cartodb_id, uninsured FROM uninsured_adults_county WHERE statefp != '02' and statefp != '15' and statefp != '72'",
                cartocss : cartoCSSRules
        }, {
            sql: "SELECT ST_Scale(ST_Translate(ST_Transform(the_geom, 102007),-1600000,-2300000),1,1) AS the_geom_webmercator, cartodb_id, uninsured FROM uninsured_adults_county WHERE statefp = '15'",
            cartocss : cartoCSSRules
        }, {
             sql: "SELECT ST_Scale(ST_Translate(ST_Transform(the_geom, 102006),-3563330,-3883900),.7,.7) AS the_geom_webmercator, cartodb_id, uninsured FROM uninsured_adults_county WHERE statefp = '02'",
             cartocss : cartoCSSRules
        }]          
    };
    
    cartodb.createLayer(map, countiesLayers)
        .addTo(map)
        .done(function(layers) {

            // Adds the custom legend
            var customLegend = new cdb.geo.ui.Legend.Custom({
              title: "Uninsured Americans in 2015",
              data: legendData
            });

            // append the rendered legend to the legend div
            $(".legend").append(customLegend.render().$el);
        
        
        })
        .error(function(err) {
            console.log(err);
        });
        
    
       
} // end makeMap()
    

</script>
</body>
</html>