Pannelli e layout

Pannelli

Un ui.Panel è un contenitore dell'interfaccia utente di livello superiore in cui organizzare i widget. Ogni ui.Panel ha un oggetto ui.Panel.Layout che controlla la disposizione dei suoi widget sullo schermo. Scopri di più nella sezione relativa ai layout. I riquadri gestiscono anche un elenco di widget (che possono includere altri riquadri) che sono stati aggiunti. Per gestire i widget nel riquadro, add() o remove() dal riquadro oppure recupera l'elenco dei widget chiamando widgets() nel riquadro. L'elenco dei widget è un'istanza di ui.data.ActiveList, il che significa che puoi configurare il riquadro manipolando l'elenco e i widget al suo interno.

ui.root

ui.root è un'istanza fissa di ui.Panel per tutti gli elementi nell'editor di codice sotto la barra orizzontale. Per impostazione predefinita, contiene un solo widget: la mappa predefinita. Nello specifico, l'elemento in ui.root.widgets().get(0) è l'oggetto Map (un'istanza di ui.Map) visualizzato per impostazione predefinita nell'editor di codice). Oltre all'alias Map, l'unica altra funzionalità speciale della mappa predefinita è che include strumenti di modifica della geometria. Per ottenere una tela vuota in cui creare l'interfaccia utente, clear() la mappa predefinita su ui.root:

Editor di codice (JavaScript)

ui.root.clear();

In alternativa, è possibile modificare la mappa predefinita nel riquadro principale aggiungendo i widget. Nello specifico, pensa a una mappa come a un riquadro con un layout assoluto (per maggiori dettagli, consulta la sezione Layout). L'esempio seguente illustra una modifica della mappa predefinita:

Editor di codice (JavaScript)

// Load a VIIRS surface reflectance image and display on the map.
var image = ee.Image('NOAA/VIIRS/001/VNP09GA/2022_06_05').select('M.*');
Map.addLayer(image, {bands: ['M5', 'M4', 'M3'], min: 0, max: 4e3, gamma: 1.5});

// Create the title label.
var title = ui.Label('Click to inspect');
title.style().set('position', 'top-center');
Map.add(title);

// Create a panel to hold the chart.
var panel = ui.Panel();
panel.style().set({
  width: '400px',
  position: 'bottom-right'
});
Map.add(panel);

// Register a function to draw a chart when a user clicks on the map.
Map.style().set('cursor', 'crosshair');
Map.onClick(function(coords) {
  panel.clear();
  var point = ee.Geometry.Point(coords.lon, coords.lat);
  var chart = ui.Chart.image.regions(image, point, null, 30);
  chart.setOptions({title: 'Band values'});
  panel.add(chart);
});

Tieni presente che l'esempio modifica la mappa predefinita (Map) trattandola come un riquadro e aggiungendovi widget. Poiché le mappe hanno un layout assoluto, la posizione di un widget su una mappa è determinata da una proprietà position della proprietà style del widget. Per maggiori dettagli, consulta la sezione sul layout assoluto.

Quando condividi un link a Editor di codice con un altro utente, per impostazione predefinita ui.root occupa la maggior parte della finestra e l'editor di testo, il riquadro dei documenti e la console sono nascosti. Controllando il layout ui.root, puoi controllare l'esperienza degli altri utenti con il tuo script.

Layout

I layout controllano il modo in cui i widget in un riquadro vengono disposti per la visualizzazione. Esistono due opzioni di layout, descritte di seguito: layout fluido e layout assoluto. I layout vengono specificati con la classe ui.Panel.Layout. Imposta il layout di un riquadro nel costruttore o con setLayout(). L'ordine in cui vengono aggiunti i widget determina come vengono disposti in un riquadro con layout a flusso. La proprietà position di ogni widget determina il modo in cui un widget verrà disposto in un riquadro con layout assoluto.style Se lo stile di un widget non è pertinente per il layout in cui è inserito, viene ignorato.

Flusso

Un layout a flusso mostra i widget in una riga ('horizontal') o in una colonna ('vertical'). I widget sono disposti in base all'ordine in cui vengono aggiunti al riquadro. Ad esempio, considera i seguenti pulsanti aggiunti a un riquadro:

Editor di codice (JavaScript)

// Create a panel with vertical flow layout.
var panel = ui.Panel({
  layout: ui.Panel.Layout.flow('vertical'),
  style: {width: '300px'}
});

// Add a bunch of buttons.
for (var i = 0; i < 30; i++) {
  panel.add(ui.Button({label: 'Button ' + i, style: {stretch: 'horizontal'}}));
}

ui.root.clear();
ui.root.add(panel);

Il layout verticale dovrebbe avere il seguente aspetto:

ui_flow_layout.png

Tieni presente che width del riquadro è impostato su 300 pixel e stretch su 'horizontal' con la proprietà style. La proprietà di stile stretch si applica ai widget in un riquadro con layout dinamico. Ad esempio, {stretch: 'horizontal'} indica che il widget si espande per riempire lo spazio orizzontale disponibile all'interno del riquadro. Nell'esempio precedente, imposta il tipo di layout di flusso su 'horizontal' per vedere i pulsanti disposti in una riga anziché in una colonna.

In un riquadro di flusso orizzontale, un widget allungato orizzontalmente si espande per riempire lo spazio disponibile dopo che tutti gli altri widget hanno occupato le loro larghezze naturali. Se più widget sono allungati orizzontalmente, lo spazio orizzontale disponibile viene suddiviso tra di essi. Un widget allungato verticalmente si espande per riempire l'altezza del riquadro.

In un riquadro di flusso verticale, un widget allungato verticalmente si espande per riempire lo spazio disponibile dopo che tutti gli altri widget hanno occupato le loro altezze naturali. Se più di un widget è allungato verticalmente, lo spazio verticale disponibile viene suddiviso tra i widget. Un widget allungato orizzontalmente si espande per riempire la larghezza del riquadro.

Assoluto

Un layout assoluto posiziona i widget in base alle posizioni nel riquadro. A differenza del layout a flusso, la posizione di un widget è determinata dalla proprietà position della proprietà style del widget, non dall'ordine in cui viene aggiunto al riquadro. L'esempio seguente mostra l'utilizzo del riquadro root.ui con un layout assoluto (per impostazione predefinita, il layout del riquadro principale è un flusso orizzontale, ma può essere impostato con ui.root.setLayout()):

Editor di codice (JavaScript)

ui.root.clear();
ui.root.setLayout(ui.Panel.Layout.absolute());

// A function to make buttons labeled by position.
function makeButton(position) {
  return ui.Button({
    label: position,
    style: {position: position}
  });
}

// Add labeled buttons to the panel.
ui.root.add(makeButton('top-left'));
ui.root.add(makeButton('top-center'));
ui.root.add(makeButton('top-right'));
ui.root.add(makeButton('middle-left'));
ui.root.add(makeButton('middle-right'));
ui.root.add(makeButton('bottom-left'));
ui.root.add(makeButton('bottom-center'));
ui.root.add(makeButton('bottom-right'));

Il riquadro del layout assoluto dovrebbe avere il seguente aspetto:

ui_absolute_layout.png

widgets()

Quando aggiungi un widget a un riquadro, questo viene aggiunto all'elenco di widget del riquadro. La chiamata a widgets() nel riquadro restituisce il valore ui.data.ActiveList che puoi utilizzare per manipolare i widget nel riquadro. Prendi in considerazione il seguente esempio, che aggiunge widget a un riquadro, aggiunge il riquadro al riquadro principale e poi aggiorna un grafico quando l'utente fa clic sulla mappa:

Editor di codice (JavaScript)

// Load and display NDVI data.
var ndvi = ee.ImageCollection('NOAA/VIIRS/001/VNP13A1')
    .filterDate('2021-01-01', '2022-01-01').select('NDVI');
Map.addLayer(
  ndvi.median(), {min: 0, max: 10000, palette: ['99c199', '006400']}, 'NDVI');

// Configure the map.
Map.setCenter(-94.84497, 39.01918, 8);
Map.style().set('cursor', 'crosshair');

// Create an empty panel in which to arrange widgets.
// The layout is vertical flow by default.
var panel = ui.Panel({style: {width: '400px'}})
    .add(ui.Label('Click on the map'));

// Set a callback function for when the user clicks the map.
Map.onClick(function(coords) {
  // Create or update the location label (the second widget in the panel)
  var location = 'lon: ' + coords.lon.toFixed(2) + ' ' +
                 'lat: ' + coords.lat.toFixed(2);
  panel.widgets().set(1, ui.Label(location));

  // Add a red dot to the map where the user clicked.
  var point = ee.Geometry.Point(coords.lon, coords.lat);
  Map.layers().set(1, ui.Map.Layer(point, {color: 'FF0000'}));

  // Create a chart of NDVI over time.
  var chart = ui.Chart.image.series(ndvi, point, ee.Reducer.mean(), 200)
      .setOptions({
        title: 'NDVI Over Time',
        vAxis: {title: 'NDVI'},
        lineWidth: 1,
        pointSize: 3,
      });

  // Add (or replace) the third widget in the panel by
  // manipulating the widgets list.
  panel.widgets().set(2, chart);
});

// Add the panel to the ui.root.
ui.root.add(panel);

In questo esempio, osserva che innanzitutto i widget vengono aggiunti al riquadro utilizzando add(). Nella funzione di callback registrata per mappare i clic, viene modificato l'elenco di widget di panel. Nello specifico, il terzo widget (che può o meno esistere) è impostato in modo da visualizzare un nuovo grafico dell'NDVI nel tempo. Scopri di più sulle funzioni di gestione degli eventi nella pagina Eventi.