[GIS] CartoDB adding custom legend to sublayer

cartocarto-jscartocss

Here's what I'm trying to do:

I have a map with selectors that load data from the same table (using SQL) based on what you selected. This all works great (code below). What I want is for a legend to be visible and for it to only show the values included in the current layer. For example, if the layer has only two possible categories, then I want the legend to show only those two categories.

Bonus points for being able to customize the legend (category names) as I create the layer.

I have no idea where to include anything about legends in this code:

function createSelector(layer) {
    var sql = new cartodb.SQL({ user: 'myusername' });
    var $options = $('#layer_selector li');
    $options.click(function(e) {
      // get the area of the selected layer
      var $li = $(e.target);
      var attribute = $li.attr('data');
      // deselect all and select the clicked one
      $options.removeClass('selected');
      $li.addClass('selected');
      // create query based on data from the layer
      var query = "select * from attribute_table";
      if(attribute == 'gender') {
        query = "select *  from attribute_table where "+ attribute + " > '0'";

        new_css = '#attribute_table{marker-width: 4;}#attribute_table[gender=2]{marker-fill: #A6CEE3;}#attribute_table[gender=1] {marker-fill: #1F78B4;}'

      }
        else if(attribute == 'marital') {
       query = "select *  from attribute_table where "+ attribute + " > '0'";

        new_css = '#attribute_table{marker-width: 4;}#attribute_table[marital=1] {marker-fill: #7B00B4;}#attribute_table[marital=2] {marker-fill: #136400;}'

      }
      else if(attribute == 'religion') {
        query = "select *  from attribute_table where "+ attribute + " > '0'";

        new_css = '#attribute_table{marker-width: 4;}#attribute_table[religion=1] {marker-fill: #A6CEE3;}#attribute_table[religion=3] {marker-fill: #1F78B4;}#attribute_table[religion=4] {marker-fill: #B2DF8A;}#attribute_table[religion=5] {marker-fill: #33A02C;}#attribute_table[religion=2] {marker-fill: #FB9A99;}#attribute_table[religion=7] {marker-fill: #E31A1C;}#attribute_table[religion=8] {marker-fill: #FDBF6F;}#attribute_table[religion=6] {marker-fill: #FF7F00;}'

      }
      else if(attribute == 'all') {
        query = "select *  from attribute_table";
        new_css = '#attribute_table{marker-width: 4;}#attribute_table{marker-fill: #2e5387;}'

      }
      // change the query in the layer to update the map
      layer.setSQL(query);
      layer.setCartoCSS(new_css);

    });
  }
  function main() {
    cartodb.createVis('map', 'https://myusername.cartodb.com/api/v2/viz/f6b34e86-b382-11e4-b544-0e853d047bba/viz.json', {
      tiles_loader: true,
      center_lat: 39.8282,
      center_lon: -98.5,
      zoom: 5,
      legends:true,
      fullscreen:true,

    })

    .done(function(vis, layers) {
      var subLayer = layers[1].getSubLayer(0);
      createSelector(subLayer);
    })
    .error(function(err) {
      console.log(err);
    });
  }
  window.onload = main;

Best Answer

There's a working example in the CartoDB.js library's example section that does most of what you seem to be looking for.

Key portion--you can define your legend as follows:

var customLegend = new cdb.geo.ui.Legend.Custom({
        title: "Custom Legend",
        data: [
          { name: "Natural Parks",  value: "#58A062" },
          { name: "Villages",       value: "#F07971" },
          { name: "Rivers",         value: "#54BFDE" },
          { name: "Fields",         value: "#9BC562" },
          { name: "Caves",          value: "#FABB5C" }
        ]
      });

Note that the value for the key data can be dynamically changed and updated depending on user interactions, data types, etc...

Related Question