1.ArcGIS API for Flex实现在MapTips中显示饼图进行数据统计展示,在本例子中可以点击城市的MapTip后显示详细人口年龄段的统计饼图的功能。
准备工作:
1.在ArcGIS.Server.9.3发布一个叫California的Map Service,并且把这个Service启动起来,这次需要一些数据用来进行图表显示了,California的数据比较齐全了所以本例采用这个数据。
2.底图的话采用Esri在线数据http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer
完成后的效果图:
开始:
1.启动Flex Builder3新建工程以及引入1.0正式版的ArcGIS API for Flex library的开发包。
2.新建chartInfowindow.mxml页面,添加Map、ArcGISTiledMapServiceLayer、ArcGISDynamicMapServiceLayer、GraphicsLayer等。具体代码如下:
1<esri:Extent id="myExtent" xmin="-124.162751982246" ymin="32.5782548652585" xmax="-114.589241057072" ymax="40.9473919319488" />
2 <mx:Canvas width="669" height="600" borderStyle="solid" borderThickness="3" verticalCenter="0" left="10">
3 <esri:Map id="myMap" extent="{myExtent}">
4 <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer" />
5 <esri:ArcGISDynamicMapServiceLayer url="http://jh-53a435fbc0e8/ArcGIS/rest/services/California/MapServer">
6 <esri:visibleLayers>
7 <mx:ArrayCollection>
8 <mx:Number>1</mx:Number>
9 </mx:ArrayCollection>
10 </esri:visibleLayers>
11 </esri:ArcGISDynamicMapServiceLayer>
12 <esri:GraphicsLayer id="myGraphicsLayer"/>
13 </esri:Map>
14 </mx:Canvas>
3.上面的代码以ESRI_StreetMap_World_2D的ArcGISTiledMapServiceLayer为底图。在底图上只显示California的Cities的点图层,具体看ArcGISDynamicMapServiceLayer部分的设置。添加了一个GraphicsLayer用来显示MapTip了,同时设置了以California的范围为当前底图的Extent。2 <mx:Canvas width="669" height="600" borderStyle="solid" borderThickness="3" verticalCenter="0" left="10">
3 <esri:Map id="myMap" extent="{myExtent}">
4 <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer" />
5 <esri:ArcGISDynamicMapServiceLayer url="http://jh-53a435fbc0e8/ArcGIS/rest/services/California/MapServer">
6 <esri:visibleLayers>
7 <mx:ArrayCollection>
8 <mx:Number>1</mx:Number>
9 </mx:ArrayCollection>
10 </esri:visibleLayers>
11 </esri:ArcGISDynamicMapServiceLayer>
12 <esri:GraphicsLayer id="myGraphicsLayer"/>
13 </esri:Map>
14 </mx:Canvas>
4.接下来需要用esri:InfoSymbol来实现mapTip,代码如下:
1<esri:InfoSymbol id="ifs">
2 <esri:infoRenderer>
3 <mx:Component>
4 <mx:VBox width="100%" height="100%" backgroundColor="0xEEEEEE" click="clickHandler()" rollOver="rollOverHandler()" rollOut="rollOutHandler()" >
5 <mx:Style>
6 .InfoCloseButton
7 {
8 disabledSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonDisabledSkin");
9 downSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonDownSkin");
10 overSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonOverSkin");
11 upSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonUpSkin");
12 }
13 .InfoExpandButton
14 {
15 disabledSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonDisabledSkin");
16 downSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonDownSkin");
17 overSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonOverSkin");
18 upSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonUpSkin");
19 }
20 </mx:Style>
21 <mx:Script>
22 <![CDATA[
23 import mx.collections.ArrayCollection;
24 private function clickHandler():void
25 {
26 switch(currentState )
27 {
28 case "" :
29 currentState = "TitleState";
30 break;
31 case "TitleState":
32 currentState = "DetailState";
33 break;
34 case "DetailState":
35 currentState = "TitleState";
36 break;
37 }
38 }
39 private function rollOverHandler() : void
40 {
41 if(currentState == null || currentState == "" )
42 {
43 currentState = "TitleState";
44 }
45 }
46 private function rollOutHandler() : void
47 {
48 if( currentState == "TitleState" )
49 {
50 currentState = "";
51 }
52 }
53 ]]>
54 </mx:Script>
55 <mx:states>
56 <mx:State name="TitleState">
57 <!-- relativeTo相对于其添加子项的对象、position子项的位置 -->
58 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
59 <mx:Label id="titleLabel" fontWeight="bold" fontSize="15" text="{data.getItemAt(0).AREANAME}"/>
60 </mx:AddChild>
61 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
62 <mx:Button id="expandButton" styleName="InfoExpandButton" width="18" height="18" />
63 </mx:AddChild>
64 </mx:State>
65 <!-- basedOn属性可以设置是基于哪个State -->
66 <mx:State name="DetailState" basedOn="TitleState">
67 <mx:RemoveChild target="{expandButton}" />
68 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
69 <mx:Spacer width="100%" />
70 </mx:AddChild>
71 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
72 <mx:Button id="closeButton" styleName="InfoCloseButton" width="18" height="18" />
73 </mx:AddChild>
74 <mx:AddChild relativeTo="{this}">
75 <mx:PieChart id="pieChart" dataProvider="{data}" width="250" height="200" showDataTips="true">
76 <mx:series>
77 <mx:PieSeries field="VALUE" nameField="AGE" labelPosition="callout">
78 <mx:calloutStroke>
79 <mx:Stroke weight="0" color="0x000000" alpha="100"/>
80 </mx:calloutStroke>
81 <mx:radialStroke>
82 <mx:Stroke weight="0" color="#FFFFFF" alpha="20"/>
83 </mx:radialStroke>
84 <mx:stroke>
85 <mx:Stroke color="0" alpha="20" weight="2"/>
86 </mx:stroke>
87 </mx:PieSeries>
88 </mx:series>
89 </mx:PieChart>
90 </mx:AddChild>
91 <mx:AddChild>
92 <mx:Legend dataProvider="{pieChart}" direction="horizontal" horizontalGap="10" width="250" />
93 </mx:AddChild>
94 </mx:State>
95 </mx:states>
96 <!--状态切换时的动画效果 -->
97 <mx:transitions>
98 <mx:Transition fromState="*" toState="TitleState">
99 <mx:Resize target="{this}" duration="100"/>
100 </mx:Transition>
101 <mx:Transition fromState="TitleState" toState="DetailState">
102 <mx:Resize target="{this}" duration="100"/>
103 </mx:Transition>
104 <mx:Transition fromState="DetailState" toState="*">
105 <mx:Resize target="{this}" duration="100"/>
106 </mx:Transition>
107 <mx:Transition fromState="TitleState" toState="*">
108 <mx:Resize target="{this}" duration="100"/>
109 </mx:Transition>
110 </mx:transitions>
111 <mx:HBox id="titleBar" width="100%" height="100%" >
112 <mx:Image source="@Embed(source='assets/pie_chart.gif')" width="18" height="18" />
113 </mx:HBox>
114 </mx:VBox>
115 </mx:Component>
116 </esri:infoRenderer>
117 </esri:InfoSymbol>
5.上面的代码有点多了但是并不复杂了,整个代码就是定义一个id为ifs的esri:InfoSymbol,主要部分为TitleState和DetailState的2种视图状态的设置和鼠标移上去的rollOverHandler方法、鼠标移开的rollOutHandler方法、鼠标点击的clickHandler方法定义。2 <esri:infoRenderer>
3 <mx:Component>
4 <mx:VBox width="100%" height="100%" backgroundColor="0xEEEEEE" click="clickHandler()" rollOver="rollOverHandler()" rollOut="rollOutHandler()" >
5 <mx:Style>
6 .InfoCloseButton
7 {
8 disabledSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonDisabledSkin");
9 downSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonDownSkin");
10 overSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonOverSkin");
11 upSkin: Embed(source="assets/skins.swf",symbol="Callout_closeButtonUpSkin");
12 }
13 .InfoExpandButton
14 {
15 disabledSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonDisabledSkin");
16 downSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonDownSkin");
17 overSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonOverSkin");
18 upSkin: Embed(source="assets/skins.swf",symbol="Callout_expandButtonUpSkin");
19 }
20 </mx:Style>
21 <mx:Script>
22 <![CDATA[
23 import mx.collections.ArrayCollection;
24 private function clickHandler():void
25 {
26 switch(currentState )
27 {
28 case "" :
29 currentState = "TitleState";
30 break;
31 case "TitleState":
32 currentState = "DetailState";
33 break;
34 case "DetailState":
35 currentState = "TitleState";
36 break;
37 }
38 }
39 private function rollOverHandler() : void
40 {
41 if(currentState == null || currentState == "" )
42 {
43 currentState = "TitleState";
44 }
45 }
46 private function rollOutHandler() : void
47 {
48 if( currentState == "TitleState" )
49 {
50 currentState = "";
51 }
52 }
53 ]]>
54 </mx:Script>
55 <mx:states>
56 <mx:State name="TitleState">
57 <!-- relativeTo相对于其添加子项的对象、position子项的位置 -->
58 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
59 <mx:Label id="titleLabel" fontWeight="bold" fontSize="15" text="{data.getItemAt(0).AREANAME}"/>
60 </mx:AddChild>
61 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
62 <mx:Button id="expandButton" styleName="InfoExpandButton" width="18" height="18" />
63 </mx:AddChild>
64 </mx:State>
65 <!-- basedOn属性可以设置是基于哪个State -->
66 <mx:State name="DetailState" basedOn="TitleState">
67 <mx:RemoveChild target="{expandButton}" />
68 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
69 <mx:Spacer width="100%" />
70 </mx:AddChild>
71 <mx:AddChild relativeTo="{titleBar}" position="lastChild">
72 <mx:Button id="closeButton" styleName="InfoCloseButton" width="18" height="18" />
73 </mx:AddChild>
74 <mx:AddChild relativeTo="{this}">
75 <mx:PieChart id="pieChart" dataProvider="{data}" width="250" height="200" showDataTips="true">
76 <mx:series>
77 <mx:PieSeries field="VALUE" nameField="AGE" labelPosition="callout">
78 <mx:calloutStroke>
79 <mx:Stroke weight="0" color="0x000000" alpha="100"/>
80 </mx:calloutStroke>
81 <mx:radialStroke>
82 <mx:Stroke weight="0" color="#FFFFFF" alpha="20"/>
83 </mx:radialStroke>
84 <mx:stroke>
85 <mx:Stroke color="0" alpha="20" weight="2"/>
86 </mx:stroke>
87 </mx:PieSeries>
88 </mx:series>
89 </mx:PieChart>
90 </mx:AddChild>
91 <mx:AddChild>
92 <mx:Legend dataProvider="{pieChart}" direction="horizontal" horizontalGap="10" width="250" />
93 </mx:AddChild>
94 </mx:State>
95 </mx:states>
96 <!--状态切换时的动画效果 -->
97 <mx:transitions>
98 <mx:Transition fromState="*" toState="TitleState">
99 <mx:Resize target="{this}" duration="100"/>
100 </mx:Transition>
101 <mx:Transition fromState="TitleState" toState="DetailState">
102 <mx:Resize target="{this}" duration="100"/>
103 </mx:Transition>
104 <mx:Transition fromState="DetailState" toState="*">
105 <mx:Resize target="{this}" duration="100"/>
106 </mx:Transition>
107 <mx:Transition fromState="TitleState" toState="*">
108 <mx:Resize target="{this}" duration="100"/>
109 </mx:Transition>
110 </mx:transitions>
111 <mx:HBox id="titleBar" width="100%" height="100%" >
112 <mx:Image source="@Embed(source='assets/pie_chart.gif')" width="18" height="18" />
113 </mx:HBox>
114 </mx:VBox>
115 </mx:Component>
116 </esri:infoRenderer>
117 </esri:InfoSymbol>
6.完成上面的工作后,接下来要做的就是在地图上显示MapTip了,这里就去部分的California的Cities的点图层数据了,在<mx:Application 添加mx:initialize用来实现初始化载入MapTip的显示,具体代码和说明如下:
1<mx:initialize>
2 <![CDATA[
3 var queryTask : QueryTask = new QueryTask("http://jh-53a435fbc0e8/ArcGIS/rest/services/California/MapServer/1");
4 var query : Query = new Query();
5 //查询条件取OBJECTID大于600的;
6 query.where="OBJECTID >600";
7 //返回Geometry
8 query.returnGeometry = true;
9 //设置返回字段
10 query.outFields = ["AREANAME","AGE_UNDER5","AGE_5_17","AGE_18_21","AGE_22_29","AGE_30_39","AGE_40_49","AGE_50_64","AGE_65_UP"];
11 //进行查询
12 queryTask.execute(query, new AsyncResponder( onResult, onFault ));
13 //查询成功后执行方法
14 function onResult( featureSet : FeatureSet, token : Object = null ) : void
15 {
16 for each ( var myGraphic : Graphic in featureSet.features )
17 {
18 //设置显示的symbol
19 myGraphic.symbol = ifs;
20 //添加到GraphicsLayer中进行显示
21 myGraphicsLayer.add( myGraphic );
22 //属性数组
23 var object : ArrayCollection = new ArrayCollection
24 ([
25 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄低于5岁" , VALUE : myGraphic.attributes.AGE_UNDER5},
26 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄5-17岁", VALUE : myGraphic.attributes.AGE_5_17},
27 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄18-21岁",VALUE : myGraphic.attributes.AGE_18_21},
28 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄22-29岁",VALUE : myGraphic.attributes.AGE_22_29},
29 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄30-39岁",VALUE : myGraphic.attributes.AGE_30_39},
30 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄40-49岁",VALUE : myGraphic.attributes.AGE_40_49},
31 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄50-64岁",VALUE : myGraphic.attributes.AGE_50_64},
32 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄65岁以上",VALUE : myGraphic.attributes.AGE_65_UP}
33 ]);
34 //设置属性
35 myGraphic.attributes = object;
36 }
37 }
38 //查询失败后执行方法
39 function onFault( info : Object, token : Object = null ) : void
40 {
41 Alert.show(info.toString());
42 }
43 ]]>
44 </mx:initialize>
7.这样就完成的功能的开发,这个例子的代码相对简单了主要的是esri:InfoSymbol的定义以及mx:PieChart控件的使用。2 <![CDATA[
3 var queryTask : QueryTask = new QueryTask("http://jh-53a435fbc0e8/ArcGIS/rest/services/California/MapServer/1");
4 var query : Query = new Query();
5 //查询条件取OBJECTID大于600的;
6 query.where="OBJECTID >600";
7 //返回Geometry
8 query.returnGeometry = true;
9 //设置返回字段
10 query.outFields = ["AREANAME","AGE_UNDER5","AGE_5_17","AGE_18_21","AGE_22_29","AGE_30_39","AGE_40_49","AGE_50_64","AGE_65_UP"];
11 //进行查询
12 queryTask.execute(query, new AsyncResponder( onResult, onFault ));
13 //查询成功后执行方法
14 function onResult( featureSet : FeatureSet, token : Object = null ) : void
15 {
16 for each ( var myGraphic : Graphic in featureSet.features )
17 {
18 //设置显示的symbol
19 myGraphic.symbol = ifs;
20 //添加到GraphicsLayer中进行显示
21 myGraphicsLayer.add( myGraphic );
22 //属性数组
23 var object : ArrayCollection = new ArrayCollection
24 ([
25 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄低于5岁" , VALUE : myGraphic.attributes.AGE_UNDER5},
26 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄5-17岁", VALUE : myGraphic.attributes.AGE_5_17},
27 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄18-21岁",VALUE : myGraphic.attributes.AGE_18_21},
28 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄22-29岁",VALUE : myGraphic.attributes.AGE_22_29},
29 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄30-39岁",VALUE : myGraphic.attributes.AGE_30_39},
30 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄40-49岁",VALUE : myGraphic.attributes.AGE_40_49},
31 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄50-64岁",VALUE : myGraphic.attributes.AGE_50_64},
32 {AREANAME : myGraphic.attributes.AREANAME,AGE : "年龄65岁以上",VALUE : myGraphic.attributes.AGE_65_UP}
33 ]);
34 //设置属性
35 myGraphic.attributes = object;
36 }
37 }
38 //查询失败后执行方法
39 function onFault( info : Object, token : Object = null ) : void
40 {
41 Alert.show(info.toString());
42 }
43 ]]>
44 </mx:initialize>