天天看點

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

這一節我們來看看彈窗的位置和彈窗上能放什麼。

先一句話總結:

位置:可以随便(點選時出現或者一直固定在某個位置),也可以指定位置

能放什麼:四種,文字、媒體(圖檔等)、表格、附件。

【Part I 位置】

這一例子和下一個例子中,CDN的引用多了一行

<link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.2/dijit/themes/claro/claro.css">
  <script src="https://js.arcgis.com/4.2/"></script>      

我也不知道多出來這個claro.css是幹嘛的,不過還是注意的好。

這個例子官方給的很複雜,盡管實作上很簡單。從html代碼開始看看吧!

<body>
  <div id="viewDiv">
    <div class="docking-control">
      <label for="dockPositionControl">Popup Dock Position</label>
      <select id="dockPositionControl">
        <option selected value="auto">Auto</option>
        <option value="top-left">Top Left</option>
        <option value="top-center">Top Center</option>
        <option value="top-right">Top Right</option>
        <option value="bottom-left">Bottom Left</option>
        <option value="bottom-center">Bottom Center</option>
        <option value="bottom-right">Bottom Right</option>
      </select>
    </div>
  </div>
</body>      

可以看到有一個select選擇表單,内含7個可選項,第一個被定義為預設選中的項目。每個option标簽的value對應PopupTemplate的position的值。

引用

照常,給出引用。

require(
    [
        "esri/Map","esri/views/MapView","esri/WebMap",
        "dojo/dom", "dojo/on", "dojo/domReady!"
    ],
    function(Map,MapView,WebMap,dom,on){
    }
);      

好的,沒有疑問。下一個。

函數參數骨架

function(Map,MapView,WebMap,dom,on){
    var webmap = new WebMap({...});
    var view = new MapView({...});
    popup = view.popup;
    view.then(function(){...});
}      

好的,沒有疑問,下——好吧,有疑問,這個popup是什麼?就是view執行個體化後的内置預設彈窗對象啊!(看我上一篇随筆)

——既然說到這個就貼多一部分代碼。

var view = new MapView({
  map: webmap,
  popup: {
    dockEnabled: true,
    dockOptions: {
      buttonEnabled: false,
      breakpoint: false
    }
  },
  container: "viewDiv"
});      

對,就是MapView的執行個體化代碼。

其他的地方沒什麼不同,就popup這個不同,與上一節方法略微不同,上一節說的是先聲明一個匿名對象,而這裡直接把匿名對象在構造函數裡寫上了。

dockEnabled就是是否能停靠在頁面旁邊。

dockOptions是Object類型,這裡寫了buttonEnabled和breakpoint兩個屬性。意義分别為“停靠按鈕是否隐藏”、“是否在點選的地方顯示”(後一個參數不确定是什麼意思,我猜的,英文水準不是很好哈哈)

view.then()這個方法見我第七篇随筆。

總之,資料(用的是WebMap)和視圖都準備好後,就要在then()方法裡設定相關的操作了。

then()方法回調函數

view.then(function(){
    var centerPoint = view.center.clone();

    popup.open({});
    popup.watch("currentDockPosition", function(value){...});

    var selectNode = dom.byId("dockPositionControl");
    on(selectNode,"change",funcion(e){});
});      

整體大概是上面的樣子。

解讀如下:

首先,擷取view的中央位置。

然後,打開view的預設彈窗。

之後,預設彈窗監聽自己的currentDockPosition屬性,如果currentDockPosition屬性發生更改,就重新打開一次彈窗。

最後擷取下拉可選框裡的值,把popup的position屬性更改。

——————

是不是很亂?

我也覺得很亂。

實際在頁面操作的結果如下:

剛打開的頁面是這樣的:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

中間的下拉框選擇控件是html組織的,并不是AJS的widget;右上角是“buttonEnabled: false,breakpoint: false”+預設position的結果。

當我切換中間下拉框的選項時,如:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

預設的彈窗的位置就發生了變化。這裡,是觸發了上面代碼中“on(selectNode,"change",function(e){...});”這段代碼。

而點選視圖任意位置時,如:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

view的彈窗的内容(content)就發生了變化(至于popup的content屬性是怎麼更改的,不知道,代碼裡沒有,可能是WebMap的特殊性吧)

好了,官方繞了這麼大一圈就是想說:

要想改popup的位置,隻需更改dockOptions這個屬性下的position屬性即可。

目前隻支援上下×左中右配對的6個位置。

是以各位看官看到這裡知道原理就行啦,給出on(selectNode,"change",function(e){...});這段完整的代碼,就更加清晰了。

on(selectNode, "change", function (e) {
  popup.set("dockOptions", {
    breakpoint: false,
    buttonEnabled: false,
    position: e.target.value
  });
});
      

源代碼也給完:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素
ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Dock Positions with Popup - 4.2</title>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
    
    .docking-control {
      font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;
      position: absolute;
      z-index: 10;
      top: 50%;
      left: 50%;
      width: 250px;
      height: 80px;
      padding: 10px;
      box-sizing: border-box;
      margin: -40px 0 0 -125px;
      background-color: #fff;
      color: #323232;
      text-align: center;
      -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
      box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    }
    
    .docking-control label {
      display: inline-block;
      font-weight: bold;
      margin: 0 0 10px 0;
      padding: 0;
      font-size: 16px;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.2/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css">
  <script src="https://js.arcgis.com/4.2/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/WebMap",

      "dojo/dom",
      "dojo/on",
      "dojo/domReady!"
    ], function (
      Map, MapView, WebMap,
      dom, on
    ) {

        var webmap = new WebMap({
          portalItem: { // autocasts as new PortalItem()
            id: "3af548bac6054938b615d08104197ba0"
          }
        });

        var view = new MapView({
          map: webmap,
          popup: {
            dockEnabled: true,
            dockOptions: {
              // Disables the dock button from the popup
              buttonEnabled: false,
              // Ignore the default sizes that trigger responsive docking
              breakpoint: false,
            }
          },
          container: "viewDiv"
        });

        popup = view.popup;

        view.then(function () {

          var centerPoint = view.center.clone();

          popup.open({
            title: "Popup dock positions",
            location: centerPoint,
            content: "Use the control in the center of the map to change the location where the popup will dock."
          });

          // Watch currentDockPosition of the popup and open the 
          // popup at the at position. 
          popup.watch("currentDockPosition", function (value) {
            popup.open();
          });

          var selectNode = dom.byId("dockPositionControl");

          // Let user change the position dockOptions.position property of the 
          // popup at runtime from the drop-down list. 
          on(selectNode, "change", function (e) {
            popup.set("dockOptions", {
              breakpoint: false,
              buttonEnabled: false,
              position: e.target.value
            });
          })

        });
      });
  </script>
</head>

<body>
  <div id="viewDiv">
    <div class="docking-control">
      <label for="dockPositionControl">Popup Dock Position</label>
      <select id="dockPositionControl">
        <option selected value="auto">Auto</option>
        <option value="top-left">Top Left</option>
        <option value="top-center">Top Center</option>
        <option value="top-right">Top Right</option>
        <option value="bottom-left">Bottom Left</option>
        <option value="bottom-center">Bottom Center</option>
        <option value="bottom-right">Bottom Right</option>
      </select>
    </div>
  </div>
</body>

</html>      

Position源代碼

記住記住關鍵是popup.dockOptions的position屬性即可(規定好的6種)! 

【Part II 能放什麼】

這個例子資料又切換回了Map而不是上面的WebMap。

這個例子用的是PopupTemplate而不是Popup,是以資料用了featureLayer。

是以,給出預覽圖:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

哇!彈出窗的内容豐富了有木有!

其實就是Popup的content的内容可以定制而已!(上一篇已經着重說過,PopupTemplate這個類的content和Popup的類有點不同,PopupTemplate這個類的content可以是string,也可以是Object[]。

這就有意思了,Object類型的數組就可以指定很多東西給它。

給出featureLayer的聲明骨架代碼:

var featureLayer = new FeatureLayer({
    url: "...",
    popupTemplate: {
        title: "..."
        content: [{...},{...},{...},{...}]
    },
    outFields: ["*"]
});      

可以看到content是Object[]類型的了,具體代碼是:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素
ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素
content: [
{
    type: "fields",
    fieldInfos: [
    {
        fieldName: "Point_Count",
        visible: false,
        label: "Count of Points",
        format: 
        {
          places: 0,
          digitSeparator: true
        }
    }, 
    {
        fieldName: "relationships/0/Point_Count_COMMON",
        visible: true,
        label: "Sum of species tree count",
        format: 
        {
          places: 0,
          digitSeparator: true
        },
        statisticType: "sum"
    }, 
    {
        fieldName: "relationships/0/COMMON",
        visible: false,
        label: "Common Name"
    }, 
    {
        fieldName: "BLOCKCE10",
        visible: true,
        label: "Block"
    }]
},
{
    type: "text",
    text: "There are {Point_Count} trees within census block {BLOCKCE10}"
},
{
    type: "media",
    mediaInfos: [
    {
        title: "<b>Count by type</b>",
        type: "pie-chart",
        caption: "",
        value:
        {
          theme: "Grasshopper",
          fields: ["relationships/0/Point_Count_COMMON"],
          normalizeField: null,
          tooltipField: "relationships/0/COMMON"
        }
    }, 
    {
        title: "<b>Welcome to Beverly Hills</b>",
        type: "image",
        value: 
        {
          sourceURL: "https://www.beverlyhills.org/cbhfiles/storage/files/13203374121770673849/122707_039r_final.jpg"
        }
    }, 
    {
        title: "<b>Palm tree lined street</b>",
        type: "image",
        value: 
        {
        sourceURL: "https://cdn.loc.gov/service/pnp/highsm/21600/21679r.jpg"
         }
    }]
},
{
  type: "attachments"
}
]      

content

一顆很龐大的樹,縮起來就成了:

ArcGIS API for JavaScript 4.2學習筆記[14] 彈窗的位置、為彈窗添加元素

四個紅框框,看type和對應的資訊即可。

第一個是fields類型的,是以就是fieldInfos,再往下展開設定輸出文本的格式等等即可。(表格,資料源自PopupTemplate.fieldInfos屬性,如果沒有就要先進行設定,本例中featureLayer來源自ESRI的伺服器,應該是有的)

第二個是text,文本類型的,格式在這截圖可以看到。

第三個是media,是以就是mediaInfos,往下還能再分pie-chart(餅圖)、image(圖檔)等等。

第四個是附着物,就是附件,提供下載下傳功能,如PDF文檔。

media的類型可以是:image | pie-chart | bar-chart | column-chart | line-chart

再往下就不細看了,需要什麼就對應找到PopupTemplate的參考文檔即可。下面給出超連結

PopupTemplate

(發文時是4.2,如果有更新請自行尋找4.2的SDK中的API Reference)

繼續閱讀