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
      // 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

  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,


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

1 Answer 1


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...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.