最近公司給我一個任務,就是利用arcgis api for flex實現在地圖上點(業務數據)直接顯示餅狀圖以及柱狀圖的專題圖制作,而不是通過點擊點顯示氣泡窗口的形式來實現,這個公司已經實現了。
經過一段時間的摸索,參照一些網上資源,目前大概弄出來了,里面還有待完善的地方的。
效果圖如下:
(1)Chart.mxml,主要的展示地圖專題圖效果的頁面
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:esri="http://www.esri.com/2008/ags" pageTitle="Charts in infowindow" xmlns:symbols="com.esri.ags.symbols.*"> <fx:Style> .chartStyle { borderThickness: 0; infoPlacement: center; backgroundAlpha: 0; infoOffsetX: 0; infoOffsetY: 0; paddingLeft: 0; paddingRight: 0; paddingTop: 0; paddingBottom: 0; } </fx:Style> <fx:Script> <![CDATA[ import com.esri.ags.geometry.MapPoint; import com.esri.ags.FeatureSet; import com.esri.ags.Graphic; import com.esri.ags.events.MapEvent; import com.esri.ags.tasks.QueryTask; import com.esri.ags.tasks.supportClasses.Query; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.events.FlexEvent; import mx.rpc.AsyncResponder; protected function myMap_initializeHandler(event:MapEvent):void { var pie:MapPoint = new MapPoint(113.55185,22.82289); var column:MapPoint = new MapPoint(113.59637985600011,22.758225999000047); var bar:MapPoint = new MapPoint(113.52757794,22.84012158); var gpie:Graphic = new Graphic(pie); var gcolumn:Graphic = new Graphic(column); var gbar:Graphic = new Graphic(bar); //g.attributes = new Object(); var thematic:ArrayCollection = new ArrayCollection( [ { Name: "危化品1", Rate: 25 }, { Name: "危化品2", Rate: 15 }, { Name: "危化品3", Rate: 23 } ]); //g.attributes.thematic = thematic; gpie.attributes = thematic; gcolumn.attributes = thematic; gbar.attributes = thematic; this.myGraphicsLayerpie.add(gpie); this.myGraphicsLayercolumn.add(gcolumn); this.myGraphicsLayerbar.add(gbar); } ]]> </fx:Script> <fx:Declarations> <esri:InfoSymbol id="infoSymbolpie" infoRenderer="InfoRendererPieChart" containerStyleName="chartStyle"> </esri:InfoSymbol> <esri:InfoSymbol id="infoSymbolcolumn" infoRenderer="InfoRendererColumnChart" containerStyleName="chartStyle"> </esri:InfoSymbol> <esri:InfoSymbol id="infoSymbolbar" infoRenderer="InfoRendererBarChart" containerStyleName="chartStylee"> </esri:InfoSymbol> </fx:Declarations> <esri:Map id="myMap" load="myMap_initializeHandler(event)"> <esri:extent> <esri:Extent xmin="113.284171273203" ymin="22.6348519473499" xmax="113.774816132605" ymax="22.9103935318251"> <esri:spatialReference> <esri:SpatialReference wkid="4326"/> </esri:spatialReference> </esri:Extent> </esri:extent> <esri:ArcGISTiledMapServiceLayer url="http://localhost:6080/ArcGIS/rest/services/ns_new/MapServer"/> <esri:GraphicsLayer id="myGraphicsLayercolumn" symbol="{infoSymbolcolumn}"> </esri:GraphicsLayer> <esri:GraphicsLayer id="myGraphicsLayerpie" symbol="{infoSymbolpie}"> </esri:GraphicsLayer> <esri:GraphicsLayer id="myGraphicsLayerbar" symbol="{infoSymbolbar}"> </esri:GraphicsLayer> </esri:Map> </s:Application>
(2)InfoRendererBarChart.mxml、InfoRendererColumnChart.mxml、InfoRendererPieChart.mxml,分別是柱狀圖以及餅狀圖實現的頁面
1.InfoRendererBarChart.mxml
<?xml version="1.0" encoding="utf-8"?> <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true" creationComplete="creationCompleteHandler()" implements="mx.core.IDataRenderer" width="100" height="100"> <!-- This is used by the QueryResultsWithChart sample. --> <fx:Script> <![CDATA[ private var _data:Object; [Bindable] // implement IDataRenderer public function get data():Object { return _data; } public function set data(value:Object):void { _data = value; } private function creationCompleteHandler():void { } ]]> </fx:Script> <mx:BarChart id="columnChart" width="100%" height="100%" dataProvider="{data}" showDataTips="true"> <mx:series> <mx:BarSeries id="barSeries" xField="Rate"/> </mx:series> <mx:verticalAxis> <mx:CategoryAxis id="barAxis" categoryField="Name"/> </mx:verticalAxis> <mx:verticalAxisRenderers> <mx:AxisRenderer axis="{barAxis}" showLabels="false"/> </mx:verticalAxisRenderers> </mx:BarChart> </s:VGroup>
2.InfoRendererColumnChart.mxml
<?xml version="1.0" encoding="utf-8"?> <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true" creationComplete="creationCompleteHandler()" implements="mx.core.IDataRenderer" width="100" height="100"> <!-- This is used by the QueryResultsWithChart sample. --> <fx:Script> <![CDATA[ private var _data:Object; [Bindable] // implement IDataRenderer public function get data():Object { return _data; } public function set data(value:Object):void { _data = value; } private function creationCompleteHandler():void { } ]]> </fx:Script> <mx:ColumnChart id="columnChart" width="100%" height="100%" dataProvider="{data}" showDataTips="true"> <mx:series> <mx:ColumnSeries id="columnSeries" yField="Rate"/> </mx:series> <mx:horizontalAxis> <mx:CategoryAxis id="columnAxis" categoryField="Name"/> </mx:horizontalAxis> <mx:horizontalAxisRenderers> <mx:AxisRenderer axis="{columnAxis}" showLabels="false"/> </mx:horizontalAxisRenderers> </mx:ColumnChart> </s:VGroup>
3.InfoRendererPieChart.mxml
<?xml version="1.0" encoding="utf-8"?> <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true" creationComplete="creationCompleteHandler()" implements="mx.core.IDataRenderer" width="100" height="100"> <!-- This is used by the QueryResultsWithChart sample. --> <fx:Script> <![CDATA[ private var _data:Object; [Bindable] // implement IDataRenderer public function get data():Object { return _data; } public function set data(value:Object):void { _data = value; } private function creationCompleteHandler():void { } ]]> </fx:Script> <mx:PieChart id="pieChart" width="100%" height="100%" dataProvider="{data}" showDataTips="true" > <mx:series> <mx:PieSeries field="Rate" labelPosition="callout" nameField="Name"> </mx:PieSeries> </mx:series> </mx:PieChart> </s:VGroup>
上述的總體實現思路是這樣的:核心是InfoSymbol,InfoSymbol自定義infoRenderer綁定專題圖的模版,比如InfoRendererBarChart.mxml、InfoRendererColumnChart.mxml、InfoRendererPieChart.mxml;程序初始化的時候生成了一些帶有統計信息的Graphic添加到地圖上,這些Graphic對象的attributes屬性集合來保存各個統計的對象,每個統計的對象包含兩個字段:Name表示危化品名稱,Rate表示占有比重,下面我們會在InfoSymbol的定義中再次看到這兩個字段。當定義好這些Graphic對象以后,我們就可以把它們添加到設置了InfoSymbol符號的GraphicLayer上了。在InfoSymbol的定義中,我們可以看到,在這個InfoSymbol中添加了一個餅圖組件PieChart,這個餅圖的dataProvider屬性綁定的是{data},它代表的其實就是Graphic對象的attributes屬性。你可以簡單地這樣認為:InfoSymbol中的data代表的就是其對應的Graphic對象的attributes屬性。其他的柱狀圖也是同理的。
既然在InfoSymbol中可以獲得Graphic的屬性信息,那么根據Graphic的屬性信息來繪制不同的專題圖就是水到渠成的事情了。
樣式代碼解析:
.chartStyle { borderThickness: 0; /*顯示專題圖的邊框寬度*/ infoPlacement: center;/*顯示專題圖的位置,這里是中心*/ backgroundAlpha: 0;/*顯示專題圖的背景透明度,這里設置為0,是為了隱藏背景*/ infoOffsetX: 0;/*顯示專題圖的X偏移,設置0,不然會偏離原始點位置*/ infoOffsetY: 0;/*顯示專題圖的Y偏移,設置0,不然會偏離原始點位置*/ paddingLeft: 0;/*顯示專題圖的位置偏移,設置0,不然會偏離原始點位置*/ paddingRight: 0;/*顯示專題圖的位置偏移,設置0,不然會偏離原始點位置*/ paddingTop: 0;/*顯示專題圖的位置偏移,設置0,不然會偏離原始點位置*/ paddingBottom: 0;/*顯示專題圖的位置偏移,設置0,不然會偏離原始點位置*/ }
需要完善優化之處:目前GraphicsLayer定義了三個(pie,bar,column),然后各自綁定不同的infoSymbol(pie,bar,column)。這樣顯的有點冗余了,其實只要定義一個GraphicsLayer,然后動態的判斷綁定的是哪個infoSymbol。
備注:
GIS技術交流QQ群:432512093