ArcGIS API For JavaScript官方文档(二十一)之Popups and Info Windows①
一、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定义一个InfoTemplate。InfoTemplate定义了将在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