InfoPopup是FlexViewer中在地圖上顯示特征點、線、面彈出詳細資訊的主要展現形式(見下圖),其結構也不是很複雜,在這個将其專門列出來是因為有很多網友問我關于此彈出資訊框的一些問題,如更改樣式、顯示複雜資訊内容等。
InfoPopup的定義在InfoPopup.mxml中,其實作代碼也比較簡單。原理也比較簡單,就是隻要給這個InfoPopup一個InfoData,這個InfoWindow就會出現在地圖上,下面就将這個InfoData的内容和InfoWindow的顯示内容做一個對照講解。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuEzMT50M4ETNwczN3ITMfBzLchjMvwlNwATMwIzLcRnbl1GajFGd0F2LcRXZu5ibkN3YukGavw1LcpDc0RHaiojIsJye.gif)
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;
支援就完成了一個資訊框顯示餅圖的擴充,效果如下: