חלוניות ופריסות

חלוניות

ui.Panel הוא מאגר ברמה גבוהה יותר של ממשק המשתמש, שבו אפשר לסדר ווידג'טים. לכל ui.Panel יש אובייקט ui.Panel.Layout שמגדיר את אופן הסידור של הווידג'טים במסך. מידע נוסף זמין בקטע פריסות. בנוסף, הלוחות שומרים רשימה של ווידג'טים (שיכולים לכלול לוחות אחרים) שהוספתם אליהם. כדי לנהל את הווידג'טים בחלונית, אפשר add() או remove() אותם מהחלונית, או לאחזר את רשימת הווידג'טים על-ידי קריאה widgets() בחלונית. רשימת הווידג'טים היא מופע של ui.data.ActiveList, כלומר אפשר להגדיר את החלונית על ידי שינוי הרשימה והווידג'טים שבה.

ui.root

ui.root הוא מופע קבוע של ui.Panel לכל מה שנמצא בעורך הקוד מתחת לסרגל האופקי. כברירת מחדל, הוא מכיל רק ווידג'ט אחד: המפה שמוגדרת כברירת מחדל. באופן ספציפי, הפריט ב-ui.root.widgets().get(0) הוא האובייקט Map (מופע של ui.Map) שמוצג כברירת מחדל בעורך הקוד). בנוסף לכתובת החלופית Map, המאפיין המיוחד היחיד של מפת ברירת המחדל הוא שהיא כוללת כלים לעריכת גיאומטריה. כדי לקבל לוח ריק שבו אפשר ליצור את ממשק המשתמש, צריך ליצור את clear(), מפת ברירת המחדל, מ-ui.root:

Code Editor‏ (JavaScript)

ui.root.clear();

לחלופין, אפשר לשנות את מפת ברירת המחדל בחלונית הבסיסית על ידי הוספת ווידג'טים. באופן ספציפי, אפשר לחשוב על מפה כחלונית עם פריסה מוחלטת (פרטים מופיעים בקטע 'פריסות'). בדוגמה הבאה מתואר שינוי במפה שמוגדרת כברירת מחדל:

Code Editor‏ (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);
});

שימו לב שבדוגמה משנים את מפת ברירת המחדל (Map) על ידי התייחסות אליה כחלונית והוספת ווידג'טים אליה. מאחר למפות יש פריסה מוחלטת, המיקום של ווידג'ט במפה נקבע לפי המאפיין position של המאפיין style של הווידג'ט. פרטים נוספים זמינים בקטע פריסה יחסית.

כשמשתפים קישור ל-Code Editor עם משתמש אחר, כברירת מחדל ui.root תופס את רוב החלון, ועריכת הטקסט, חלונית המסמכים והמסוף מוסתרים. שליטה בפריסה של ui.root מאפשרת לכם לקבוע איך משתמשים אחרים יחוו את הסקריפט.

פריסות

פריסות קובעות איך הווידג'טים בחלונית מסודרים בתצוגה. יש שתי אפשרויות פריסה, שמתוארות בהמשך: פריסה זורמת ופרסה מוחלטת. אפשר לציין פריסות באמצעות הכיתה ui.Panel.Layout. מגדירים את הפריסה של החלונית ב-constructor או באמצעות setLayout(). הסדר שבו מוסיפים את הווידג'טים קובע איך הם ימוקמו בחלונית עם פריסה זורמת. המאפיין position של כל ווידג'ט קובע איך הווידג'ט ימוקם בחלונית עם פריסה מוחלטת.style אם הסגנון של הווידג'ט לא רלוונטי לפריסה שבה הוא ממוקם, המערכת מתעלמת ממנו.

זרימה

בפריסה 'זרימה', הווידג'טים מוצגים בשורה ('horizontal') או בעמודה ('vertical'). הווידג'טים מסודרים לפי הסדר שבו הם נוספו לחלונית. לדוגמה, הלחצנים הבאים נוספו לחלונית:

Code Editor‏ (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);

הפריסה האנכית אמורה להיראות כך:

ui_flow_layout.png

שימו לב שהערך של width בחלונית מוגדר ל-300 פיקסלים, והערך של stretch מוגדר ל-'horizontal' באמצעות המאפיין style. מאפיין הסגנון stretch חל על ווידג'טים בחלונית עם פריסה של זרימה. לדוגמה, הערך {stretch: 'horizontal'} מציין שהווידג'ט יתרחב כדי למלא את השטח האופקי הזמין בחלונית. בדוגמה הקודמת, כדי שהלחצנים ייערכו בשורה במקום בעמודה, צריך לשנות את סוג הפריסה ל-'horizontal'.

בחלונית 'זרימה אופקית', ווידג'ט שהורחב אופקית מתרחב כדי למלא את השטח הזמין אחרי שכל שאר הווידג'טים תופסים את הרוחב הטבעי שלהם. אם יותר מווידג'ט אחד מורחב אופקית, המרחב האנכי הזמין מחולק ביניהם. ווידג'ט שהורחב אנכית מתרחב כדי למלא את הגובה של החלונית.

בחלונית עם פריסת עמודות, ווידג'ט שהורחב אנכית מתרחב כדי למלא את המרחב הזמין אחרי שכל שאר הווידג'טים תופסים את הגבהים הטבעיים שלהם. אם יותר מווידג'ט אחד מורחב אנכית, המרחב האנכי הזמין מחולק ביניהם. ווידג'ט שנמתח אופקית מתרחב כדי למלא את הרוחב של החלונית.

גובה מסוים

בפריסה מוחלטת, הווידג'טים ממוקמים לפי המיקומים שלהם בחלונית. בניגוד למיקום של ווידג'טים בפריסה של זרימה, המיקום של ווידג'ט נקבע לפי המאפיין position של המאפיין style של הווידג'ט, ולא לפי הסדר שבו הוא נוסף ללוח. בדוגמה הבאה מוצג שימוש בחלונית root.ui עם פריסה מוחלטת (ברירת המחדל של הפריסה בחלונית הבסיס היא זרימה אופקית, אבל אפשר להגדיר אותה באמצעות ui.root.setLayout()):

Code Editor‏ (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'));

חלונית הפריסה המוחלטת אמורה להיראות כך:

ui_absolute_layout.png

widgets()

כשאתם מוסיפים ווידג'ט לחלונית, הוא מתווסף לרשימת הווידג'טים של החלונית. קריאה ל-widgets() בחלונית מחזירה את הערך ui.data.ActiveList, שאפשר להשתמש בו כדי לבצע פעולות על הווידג'טים בחלונית. בדוגמה הבאה מוספים ווידג'טים לחלונית, מוסיפים את החלונית לחלונית הבסיסית ואז מעדכנים תרשים כשהמשתמש לוחץ על המפה:

Code Editor‏ (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);

בדוגמה הזו, שימו לב קודם כל שהווידג'טים מתווספים ללוח באמצעות add(). במקום זאת, רשימת הווידג'טים של panel תשתנה בפונקציית הקריאה החוזרת (callback) שרשומה למיפוי קליקים. באופן ספציפי, הווידג'ט השלישי (שעשוי להתקיים או לא) מוגדר כך שיוצג תרשים חדש של מדד NDVI לאורך זמן. מידע נוסף על פונקציות לטיפול באירועים זמין בדף 'אירועים'.