原文转自:http://blog.csdn.net/wufeishimeng/article/details/5699235
Flex Viewer解析-----InfoPopup(InfoWindow)
InfoPopup是FlexViewer中在地图上显示特征点、线、面弹出详细信息的主要展现形式(见下图),其结构也不是很复杂,在这个将其专门列出来是因为有很多网友问我关于此弹出信息框的一些问题,如更改样式、显示复杂信息内容等。
InfoPopup的定义在InfoPopup.mxml中,其实现代码也比较简单。原理也比较简单,就是只要给这个InfoPopup一个InfoData,这个InfoWindow就会出现在地图上,下面就将这个InfoData的内容和InfoWindow的显示内容做一个对照讲解。
InfoData的定义:
* var infoData:Object =
* {
* icon: icon, //a Image object
* title: "a title string",
* content: "a string",
* link: "http://a.url.com",
* point: point, //a Point object
* geometry: geom //a Geometry object
* };
其中
icon参数,对应InfoWindow中的特征点图标,即上图中的”望远镜”图标
title参数:顾名思义就是InfoWindow的标题,即上图中的”成都市大港分公司……”
content参数:就是InfoWindow的显示内容部分,即上图中的”STAT_ADDR:成都市大港分公司……”
link参数:超链接地址,图中没有显示出来。
Point参数:就是Infowindow的显示的坐标点位置。
Geometry参数:同样是其显示的坐标点位置。
我们可以知道,拥有了上述的参数,一个Infowindow就确定了位置和内容,那么它就可以在地图上显示出来。下面我们进一步看看InfoPopup.mxml里面是如何实现的。
首先,我们需要给这个InfoWindow设置一个显示的地图,也就是它是那个地图的信息框。也就是下面的几行代码。比较简单。
private var _map:Map;
public function set map(value:Map):void
{
_map = value;
}
public function get map():Map
{
return _map;
}
其次,为其设置了地图之后,要使其显示出来就要为其设置InfoData,设置方法同样是Get和Set的方式。
private var _infoData:Object;
public function set infoData(value:Object):void
{
_infoData = value;
if (value)
{
setInfoParameters();
}
else
{
currentState = "";
}
}
public function get infoData():Object
{
return _infoData;
}
我们可以看到,在设置的infodata是可用的时候,执行了函数setInfoParameters();这个函数就是将infodata的内容显示在窗体上。函数中首先调用另外一个函数positionInfo();下面的代码就比较简单了,就是将infodata里面的内容赋给对应的控件进行显示。我们看下这个positionInfo();函数。
public function positionInfo():void
{
if ((map.extent) && (infoData))
{
// 获取InfoData中的point属性,得到信息框显示的位置
var pt:MapPoint = infoData.point;
//将地图坐标转化成屏幕坐标,以便绘制信息框
var infoPt:Point = map.toScreen(pt);
//下面是判断,信息框的位置,如果在屏幕的靠右位置,这是主信息框显示在左边
//如果在靠左位置,主信息显示在右边。
var reg:String = "regLeft";
if (infoPt.x > map.width / 2)
reg = "regRight";
currentState = reg;
//设置信息框的显示位置,(infoIconCanvas.x + 20)这个的作用是
//将信息框图标绘制在特征点的中央。
this.x = infoPt.x - (infoIconCanvas.x + 20);
this.y = infoPt.y - (infoIconCanvas.y + 20);
}
}
这是函数就决定了信息框的显示位置和状态。
这是就会有个疑问,我们设置这个信息框的时候使用的是屏幕坐标,为什么信息框会随着地图的平移而移动呢?我们注意到在程序的一开始,就是程序加载的时候执行了这样一个函数:
private function init():void
{
map.addEventListener(PanEvent.PAN_UPDATE, repositionInfo);
map.addEventListener(ExtentEvent.EXTENT_CHANGE, repositionInfo);
}
这就为地图平移和地图显示范围改变加了响应函数,就是当地图平移或者显示范围改变时,就会执行repositionInfo函数,此函数同positionInfo函数类似。相当于移动一下这个infowindow。
关于窗体的设计部分,这里主要说一下主要信息显示的容器infoCanvas内容。该容器里面包含的infoTitle用来显示标题,infoContent用来显示信息内容。其他属于窗体设计部分,在此就不介绍了。那么我们需要将这个Infowindow做扩展显示复杂内容的时候,我们就可以从这里入手,将一些复杂的控件等加入到里面。
上述就是整个InfoWindow的实现原理。还是比较简单的。
实例:InfoPopup扩展,加入饼图显示
下面实现一个扩展,使用这个InfoWindow显示一个饼图。
首先,更改InfoData的结构,增加一个为饼图提供数据的项PieData,这个PieData同样是一个Object,定义方式为:
var PieData1:Object=
{
num:40,//饼图中其中一项占得比例
name: "40%"//鼠标移上饼图后显示的内容
};
var PieData2:Object=
{
num:60,//饼图中其中一项占得比例
name: "60%"//鼠标移上饼图后显示的内容
};
//然后将定义好的饼图的数据加入到一个数组里面
var PieDatas:Array=new Array();
PieDatas.push(PieData1);
PieDatas.push(PieData2);
var infoData:Object =
{
icon: icon,
title: title,
content: content,
PieDatas:PieDatas,
link: link,
point: point,
geometry: gra.geometry
};
然后在Infopopup.mxml中加入对饼图的设计内容。加到infoCanvas里面的VBOx里面。
<mx:PieChart id="pieChart" width="90" height="90" showDataTips="true">
<mx:series>
<mx:PieSeries field="num" labelField="name" labelPosition="inside">
</mx:PieSeries>
</mx:series>
</mx:PieChart>
在setInfoParameters()函数中为这个饼图定义数据源,即
pieChart.dataProvider=infoData.PieDatas;
支持就完成了一个信息框显示饼图的扩展,效果如下