1

I have a map with many classes that I want to display in an Earth Engine App. I want to include a legend that lists map class color with a label. I can do this for a single column of classes, but there are so many classes that the legend extends beyond the bounds of the page. How can I create a multi-column legend?

Here is a minimal example of how I'm creating a single column legend.

// Class color and label info.
var classInfo = [
  {name: 'Forest', color: 'green'},
  {name: 'Rock', color: 'grey'},
  {name: 'Water', color: 'blue'},
  {name: 'Grass', color: 'yellow'}
];

// Makes a legend entry: color and label side-by-side in a panel.
function legendEntry(info) {
  var color = ui.Panel({style: {
    width: '20px',
    height: '20px',
    backgroundColor: info.color,
    margin: '6px 0px 0px 0px'
  }});
  var label = ui.Label({
    value: info.name,
  });
  return ui.Panel({
    widgets: [color, label],
    layout: ui.Panel.Layout.flow('horizontal'),
    style: {
      stretch: 'horizontal',
      margin: '-6px 0px 0px 0px'
    }});
}

// Define a panel to hold all legend entries.
var legend = ui.Panel({
  style: {
    position: 'bottom-left',
    padding: '8px 8px 0px 8px' 
  }
});

// Loop through the map classes, add each entry to the legend panel.
for (var i = 0; i < classInfo.length; i++) {
  legend.add(legendEntry(classInfo[i]));
}

// Show legend on the map.
Map.add(legend);

1 Answer 1

1

To get multiple columns you can follow your current workflow, except that you need to add a second dimension to the classInfo object to define columns and rows and also do a nested for loop to cycle through both dimensions.

Here is an approach based on the provided code.

// Class color and label info.
var classInfo = [
  [  // Column 1
    {name: 'Forest', color: 'green'},  // Row 1
    {name: 'Rock', color: 'grey'},     // Row 2
  ],
  [  // Column 2
    {name: 'Water', color: 'blue'},    // Row 1
    {name: 'Grass', color: 'yellow'},  // Row 2
  ]
];

// Makes a legend entry: color and label side-by-side in a panel.
function legendEntry(info) {
  var color = ui.Panel({style: {
    width: '20px',
    height: '20px',
    backgroundColor: info.color,
    margin: '6px 0px 0px 0px'
  }});
  var label = ui.Label({
    value: info.name,
  });
  return ui.Panel({
    widgets: [color, label],
    layout: ui.Panel.Layout.flow('horizontal'),
    style: {
      stretch: 'horizontal',
      margin: '-6px 0px 0px 0px'
    }});
}

// Make a grid of legend entries.
var columns = [];
classInfo.forEach(function(column) {
  var rows = [];
  column.forEach(function(row) {
    rows.push(legendEntry(row));
  });
  columns.push(ui.Panel(rows));
});

// Add the legend components grid to a parent legend panel. 
var legend = ui.Panel({
  widgets: columns,
  layout: ui.Panel.Layout.flow('horizontal'),
  style: {
    position: 'bottom-left',
    padding: '8px 8px 0px 8px' 
  }
});

// Show legend on the map.
Map.add(legend);

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.