Google Earth Engine – How to Update Chart Time Series When Changing ui.Select in GEE App

google-earth-enginegoogle-earth-engine-javascript-api

I would like to generate a chart time series of a region based on the user's drawing and the y-axis of a chart based on the user's selection. For example, when I clicked and drawed a polygon (step 1 on the image attached), then select the vege index such as EVI (step 2), then the app will generate an EVI chart and on the map, it only shows the drawing polygon with the boundary, not the filled one. If I change the vege index into NDVI, then the app will generate a NDVI chart. However, my script automatically drawed a chart after step 1 without using step 2 or when I changed the select from NDVI to EVI, the chart did not update. How to fix this? Below are my script

var drawingTools = Map.drawingTools();
drawingTools.setShown(false);
while (drawingTools.layers().length() > 0) {
  var layer = drawingTools.layers().get(0);
  drawingTools.layers().remove(layer);
}
var dummyGeometry =
    ui.Map.GeometryLayer({geometries: null, name: 'geometry', color: 'red'});

drawingTools.layers().add(dummyGeometry);

function clearMap() {
  var mapLayers = Map.layers();
  if (mapLayers.length() > 0) {
    mapLayers.reset();
  }
}   
function clearGeometry() {
  var layers = drawingTools.layers();
  layers.get(0).geometries().remove(layers.get(0).geometries().get(0));
}
function drawRectangle() {
  clearMap();
  clearGeometry();
  drawingTools.setShape('rectangle');
  drawingTools.draw();
}

var symbol = {
  rectangle: '⬛',
};
var controlPanel = ui.Panel({
  widgets: [
    ui.Label('1. Select a drawing mode.'),
    ui.Button({
      label: symbol.rectangle + ' Rectangle',
      onClick: drawRectangle,
      style: {stretch: 'horizontal'}
    }),
  ],
  style: {position: 'top-left'},
  layout: null,
});
Map.add(controlPanel); 
var chartPanel = ui.Panel({
  style:
      {height: '235px', width: '600px', position: 'bottom-right', shown: false}
});
Map.add(chartPanel);
var index_chose;
function chartNdviTimeSeries() {
  // Make the chart panel visible the first time a geometry is drawn.
  if (!chartPanel.style().get('shown')) {
    chartPanel.style().set('shown', true);
  }
  var aoi = drawingTools.layers().get(0).getEeObject();
  var aoiFc = ee.FeatureCollection(aoi);
  var empty = ee.Image().byte();
  var outline = empty.paint({
    featureCollection: aoiFc,
    color: 1,
    width: 3
  });
  
  Map.addLayer(outline, {palette: 'red'}, 'AOI');
  clearGeometry();

  // Set the drawing mode back to null; turns drawing off.
  drawingTools.setShape(null);
  
  // Chart NDVI time series for the selected area of interest.
  var chart = ui.Chart.image
                  .seriesByRegion({
                    imageCollection: ee.ImageCollection('MODIS/006/MOD13A2'),
                    regions: aoi,
                    reducer: ee.Reducer.mean(),
                    band:index_chose,
                    xProperty: 'system:time_start'
                  })
                  .setOptions({
                    titlePostion: 'none',
                    legend: {position: 'none'},
                    hAxis: {title: 'Date'},
                    vAxis: {title: select_index.getValue()},
                    series: {0: {color: '23cba7'}}
                  });

  // Replace the existing chart in the chart panel with the new chart.
  chartPanel.widgets().reset([chart]);
}

// Index set-up
var label_index= ui.Label('Select vege index');
var index=['NDVI','EVI'];
var select_index=ui.Select({
  items:index,
  onChange:function(){
    index_chose=select_index.getValue();
    return index_chose
  }
});

Map.add(ui.Panel([label_index,select_index],ui.Panel.Layout.flow('horizontal')));
drawingTools.onDraw(ui.util.debounce(chartNdviTimeSeries, 500));
drawingTools.onEdit(ui.util.debounce(chartNdviTimeSeries, 500));

The link for my code is
https://code.earthengine.google.com/fcc81cfebae226157ba7dc4e67db4851

Best Answer

The main problem is clearGeometry(). So, an easy way is just deleted it. In that case each time that you run (change de vegetation index), you will create another AOI, if you want to keep it (because you will have the geometry drawn as area of analisis in the map), I would recommend just change this:

Map.addLayer(outline, {palette: 'red'}, 'AOI');

to this:

var area=ui.Map.Layer(outline, {palette: 'red'}, 'AOI').setShown(0)
Map.layers().set(0, area) 

In other hand, I also would recommend update the ee.Imagecolection and the band selection (because, currently you'r code show the same values for NDVI and EVI). So, this is the suggested function to chartNdviTimeSeries:

function chartNdviTimeSeries() {
  // Make the chart panel visible the first time a geometry is drawn.
  if (!chartPanel.style().get('shown')) {
    chartPanel.style().set('shown', true);
  }
  var aoi = drawingTools.layers().get(0).getEeObject();
  var aoiFc = ee.FeatureCollection(aoi);
  var empty = ee.Image().byte();
  var outline = empty.paint({
    featureCollection: aoiFc,
    color: 1,
    width: 3
  });
  
  
//Map.addLayer(outline, {palette: 'red'}, 'AOI').setShown(1);
var area=ui.Map.Layer(outline, {palette: 'red'}, 'AOI').setShown(1)
Map.layers().set(0, area)  


  // Set the drawing mode back to null; turns drawing off.
  drawingTools.setShape(null);

  
  // Chart NDVI time series for the selected area of interest.
  var chart = ui.Chart.image
                  .seriesByRegion({
                    imageCollection: ee.ImageCollection('MODIS/061/MOD13A2'),
                    regions: aoi,
                    reducer: ee.Reducer.mean(),
                    band:select_index.getValue(),
                    xProperty: 'system:time_start'
                  })
                  .setOptions({
                    titlePostion: 'none',
                    legend: {position: 'none'},
                    hAxis: {title: 'Date'},
                    vAxis: {title: select_index.getValue()},
                    series: {0: {color: '23cba7'}}
                  });

  // Replace the existing chart in the chart panel with the new chart.
  chartPanel.widgets().reset([chart]);

// move this lines of code here to skip the initial chart
drawingTools.onDraw(ui.util.debounce(chartNdviTimeSeries, 500));
drawingTools.onEdit(ui.util.debounce(chartNdviTimeSeries, 500));

//add this code to hide the geometry
dummyGeometry.setShown(false)
}

here the link

Related Question