ArcGIS API For JavaScript官方文档(二十一)之Popups and Info Windows①

ArcGIS API For JS官方文档解析目录

一、Info windows and graphics

    向ArcGIS JavaScript应用程序添加交互性的一种简单方法是通过Info windows显示信息以响应用户的操作。通过使用其他API,你可能知道info windows是“气球”、“地图提示”、“标注”或者“弹窗”。概念是一样的:用户单击或者悬停在地图上的某个位置上,并看到有关该位置的特定信息。

1、一个info window 是怎样工作的?

    Map有一个信息窗口,可以根据事件显示或隐藏。每一个信息窗口都有一个title(标题)和content(内容)。title是显示在info window顶部的粗体文本,content是下面显示的HTML。当您使用info windows,您将经常调用方法来设置title和content。

    当单击graphic或feature layer时,默认行为是显示info window,但是,为了实现这种情况,您需要为graphic定义一个InfoTemplateInfoTemplate定义了将在info window中显示的title和content。

    虽然info window 通常在graphics layer或feature layer中使用,但也可以响应查询或其他不涉及graphic的操作而显示info window。例如:当用户单击地图时,可以使用lat/lon坐标显示info window。

map.on("click", function(evt) {
  map.infoWindow.setTitle("Coordinates");
  map.infoWindow.setContent("lat/lon : " + evt.mapPoint.y + ", " + evt.mapPoint.x);
  map.infoWindow.show(evt.screenPoint,map.getInfoWindowAnchor(evt.screenPoint));
});

2、可以用info window做什么?

    可以在info window中放置几乎任何东西,因为它支持HTML、图像、超链接、表、动态呈现的图标等等。您可以利用Dojo来增强您的info windows。

    这张图片显示了infow window中的一个由Dojo TabContainer组织的信息。

    下面是一个使用Dojo charting library为info window动态构建图表的例子

    您不应该仅仅因为在info window中可以放置某些东西而总是使用info window。在dojo的布局库中,BorderContainer和其他元素可以帮助您在您的页面中的侧边栏、页脚、accordion containers中组织信息。可以通过Working with Layouts来查看dojo的布局介绍,在某些情况下,这可能是比info window更有效的显示信息的方式。

    下图所示的应用程序没有使用info window,而是使用右侧内容窗格来包含图表和其他信息。这个应用程序可以在ArcGIS.com 代码库中下载

二、格式化info window的content

    InfoTemplate类用于定义一个info window的content和title。如果您使用2.2及以上版本,您可以使用一个字符串或者函数定义content和title,在2.2版本之前,您只能使用一个字符串。

1、调整info window的大小

    默认情况下,一个info window的cantent区域宽为250像素以及高为100像素,如果你想显示的内容高于默认的宽、高,content区域会产生滚动条来滚动内容。可以使用resize方法调整info window的宽、高。

map.infoWindow.resize(300, 200);

2、使用字符串格式化content

    您可以创建一个字符串值来定义要显示的content,该字符串可以包括HTML标记、属性占位符和格式化的函数。让我们来看一些使用字符串格式化content的例子:

    ①连接的字符串

map.infoWindow.setTitle("Coordinates");
map.infoWindow.setContent("lat/lon : " + latitude.toFixed(2) + ", " + longitude.toFixed(2));

    ②使用HTML

map.infoWindow.setTitle("HTML");
map.infoWindow.setContent("This content uses <strong>HTML</strong> for formatting.<p>This is a paragraph</p><p>Another Paragraph</p>");

    ③占位符(字符串替换)

    当graphics图层或者feature图层有info template时,API会在feature(要素)被选中时自动使用该info template来构造info window的content。在info template中,使用${ }表示的占位符指定要显示的属性,在运行时,替换发生,占位符被替换为被选中要素的实际属性值。

    在下面的代码中,${ }中的值对应于属性字段名,在屏幕的快照中,所选feature的属性值替换了相关占位符。

var content = "<b>Status</b>: ${STATUS}" +
  "<br><b>Cummulative Gas</b>: ${CUMM_GAS} MCF" +
  "<br><b>Total Acres</b>: ${APPROXACRE}" +
  "<br><b>Avg. Field Depth</b>: ${AVG_DEPTH} meters";
var infoTemplate = new InfoTemplate("${FIELD_NAME}", content);

    

格式化日期、时间和数字值

    使用格式化程序来格式化日期和时间值。这个功能被添加到api的2.2版本中。使用格式函数的语法如下:

${FIELD_NAME:FORMAT_FUNCTION_NAME(OPTION_A: value, OPTION_B: value)}

    format dates in an info window sample有如何使用下面描述的各种格式函数的示例:

  • DateString

    将日期格式化为人类可读的格式。支持下列选项:


  • DateFormat

使用dojo/data/locale.format方法将日期字段转换为人类可读的格式。支持与dojo/date/locale.format相同的选项集。


  • NumberFormat

    使用dojo/number.format方法将数字格式化成各种格式。支持与dojo/number.format相同的选项集。


3、使用自定义函数格式化content

    有时候,您希望在信息窗口中显示更多的文本。您可能想要显示图表,将信息归类到标签页中,或者在info窗口中使用dojo小部件。在这种情况下,您可以编写一个函数,该函数返回字符串、HTML元素的引用或deferred object(延迟对象)。单击graphic时,函数将执行,返回值显示在info窗口中。当前被点击graphic被作为参数传入该函数,为该函数提供了当前graphic的属性信息。注意,定制格式化函数需要全局访问。

    ①返回一个字符串

    使用自定义函数绕过了info window和info template的默认字符串替换,因此从自定义函数返回的字符串不应包含占位符。若要使用要素属性,请直接在自定义函数中访问它们。下面的示例使用graphic的qSpecies属性的值来构建一个URL。

var template = new InfoTemplate();
template.setContent(getTextContent);

function getTextContent(graphic) {
  var attr = graphic.attributes.qSpecies.replace('"', "").split("::");
  var commonName = string.trim((attr[1] === "") ? attr[0] : attr[1]);
  var scientificName = string.substitute("${0}_${1}", attr[0].split(" "));
  var plantDate = locale.format(new Date(graphic.attributes.PlantDate), {
    selector: 'date',
    datePattern: 'MMMM d, y'
  });
  return "<a href=https://en.wikipedia.org/wiki/" +
    scientificName + "><i>" + string.substitute("${0} ${1}", attr[0].split(" ")) +
    "</i></a><br>Maintained By: " + graphic.attributes.qCaretaker +
    "<br>Planted: " + plantDate;
}

也可以在每个属性基础上使用函数。下面的示例计算百分比变化,并根据正或负变化显示一个向上或向下箭头。

var infoTemplate = new InfoTemplate();
infoTemplate.setTitle("Population in ${NAME}");
infoTemplate.setContent("<b>2007 :D: </b>${POP2007:compare}<br/>" +
  "<b>2007 density: </b>${POP07_SQMI:compare}<br/><br/>" +
  "<b>2000: </b>${POP2000:NumberFormat}<br/>" +
  "<b>2000 density: </b>${POP00_SQMI:NumberFormat}");

compare = function (value, key, data) {
  var result = "", diff, pctChange;

  switch (key) {
    case "POP2007":
      result = value > data.POP2000 ? "images/up.png" : "images/down.png";
      diff = data.POP2007 - data.POP2000;
      pctChange = (diff * 100) / data.POP2000;
      break;

    case "POP07_SQMI":
      result = value > data.POP00_SQMI ? "images/up.png" : "images/down.png";
      diff = data.POP07_SQMI - data.POP00_SQMI;
      pctChange = (diff * 100) / data.POP00_SQMI;
      break;
  }

  return number.format(value) +
    "   <img src='" + result + "'>" +
    "  <span style='color: " +
    (pctChange < 0 ? "red" : "green") + ";'>"
     + number.format(pctChange, { places: 3 }) +
    "%</span>";
};

②引用HTML元素

通过programatically返回一个html元素的引用,使用dojo/dom-construct.create创建一个html元素,或者创建dojo Dijit并返回该dijit的dom节点。


dojo/dom-construct.create包装了浏览器的原生document.createElement和appendChild方法,并规范跨浏览器的差异。使用dom-construct.create创建元素的示例:

require(["dojo/dom-construct"], function(domConstruct){
  var node = domConstruct.create("div", { innerHTML: "Text Element inside an HTML div element." });
});

另一个选项是创建一个dijit并返回其dom节点。这被展示在info window with chart sample的屏幕截图中,其中创建了多个layout dijits,并将它们作为info window的content。要注意的关键在于格式化函数返回的是dijit的dom节点,而不是dijit本身。

var tc = new TabContainer({
  style: "width:100%;height:100%;"
}, domConstruct.create("div"));

return tc.domNode;

③Deferred Object(延迟对象)

    在某些情况下,您想要显示的content并不立即可用,它可能需要您使用esri/request从服务器下载,然后它返回一个dojo/Deferred的实例。单击某个要素时,将通过自定义函数返回deferred object。一旦deferred object被解析后,信息窗口将相应更新。

    当使用3.4或更高版本的api时,此工作流不受支持,因为一个esri/dijit/Popup实例是Map的默认infoWindow。若要在InfoWindow content中使用deferred,则必须使用一个esri/dijit/InfoWindow实例作为Map的Info Window或监听map单击事件、初始化一个异步操作,然后在异步操作完成时调用Popup.setContent()和Popup.setTitle()。

    当单击map上的polyline时,它将作为输入发送到一个生成高程剖面的Server Object Extension(SOE—服务器对象扩展)。一旦剖面可用,它将显示在info window中。

function getTextContent(graphic) {
  var geometry = webMercatorUtils.webMercatorToGeographic(graphic.geometry);
  soeParams.InputPolyline = JSON.stringify(geometry.toJson());
  var def =  esriRequest({
    url: soeURL,
    content: soeParams,
    callbackParamName: "callback",
    load: function(fset) {
      return "<img src='" + fset.profileImageUrl + "'/>";
    }
  });
  return def;
}


三、自定义Info Window

    可以自定义Info Window,使其具有不同的外观和行为。例如,您可能希望info window的背景与组织的网站颜色方案相匹配,或者具有更大的字体大小、不同的边框颜色,您也可能希望改变info window的行为,或者想创建一个仅仅显示title和有一个被点击时显示额外content的选项。请参考Making your pop-up pop!使您能够自定义popup(弹窗)或者info window的外观和行为。

    info window可以通过修改CSS、创建一个图像作为info window的背景来自定义。

1、通过使用CSS自定义info window外观

    在2.2版本以及更高的版本中,您可以使用标准的info window,或者使用require()加载InfoWindowLite模块来显示info window的简化版本。

    您可以通过创建样式规则来自定义Lite info window的外观。在以下代码中,我们将对info window 应用新的边框颜色和渐变背景。

#map_infowindow.simpleInfoWindow {
    border: 2px solid #455268;
    background-color: #dfe5d7; 
    background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfff4), color-stop(40%,#dfe5d7), color-stop(100%,#b3bead)); 
}

    结果是:info window的边框颜色变为深色,背景颜色为白-绿渐变颜色。

2、使用图片自定义info window

    您可以通过使用图片编辑程序创建一张png图片作为info window的背景、关闭按钮或者指针。或者,您可以下载png图片并且使用您选择的照片编辑器修改。

    自定义图像后,可以向应用程序添加新的CSS规则以覆盖默认图像。以下代码中,我们将重写popup的默认info window图像。

.claro .infowindow .sprite {
   background-image: url('images/javainfowindow.png') !important;
}

3、创建自定义的info window

    在2.2版本中引入的InfoWindowBase类提供了扩展info window,从而创建自定义info window的能力。要扩展该类,您需要为几个必需的方法、属性和事件提供一个实现,以确保自定义window提供了一个最低级别的预期功能。您还可以定义新方法、属性和事件来增强info window。您可以使用此类创建带有自定义外观和行为的info window。

    在本例中,当单击向下箭头时,info window的content会展开,而当map被平移时,info window将隐藏。若要构建有此功能的自定义info window,请扩展InfoWindowBase类并向标题栏中添加一个新按钮。当用户单击“向下”按钮时,使用dojo/fx/Toggler类定义的动画效果显示信息窗口的content部分。


    创建自定义info window之后,您可以使用新的infoWindow选项将它与map关联:

var infoWindow = new myModules.InfoWindow({
  domNode: dojo.create("div", null, dojo.byId("map"))
});
map = new esri.Map("map", {
  extent: initExtent,
  infoWindow:infoWindow
});

查看扩展InfoWindowBase类的示例

转载自:https://blog.csdn.net/qq_35732147/article/details/79835676

You may also like...

退出移动版