birdeye繪制拓撲關系圖
1.flex簡單介紹
Flex 是一個高效、免費的開源框架,可用於構建具有表現力的 Web應用程序,這些應用程序利用Adobe Flash Player和Adobe AIR, 可以實現跨瀏覽器、桌面和操作系統。雖然只能使用 Flex 框架構建 Flex應用程序,但Adobe Flash Builder™(之前稱為 Adobe Flex Builder™)軟件可以通過智能編碼、交互式遍歷調試以及可視設計用戶界面布局等功能加快開發。
另外,FLEX的另一個組件Springgraph也可以做關系圖,剛開始做項目的時候選擇的就是這個,后來感覺SPRINGGRAPH的示例沒有Birdeye詳細,就依然拋棄掉了,不過在這里為大家提供一些幫助信息
http://www.chaosreigns.com/code/springgraph/
2.birdeye簡單介紹
BirdEye是一個開源的Adobe Flex圖表制作組件。用於創建多維數據分析可視化界面。birdeye 可以繪制 拓撲圖,關系圖,流程圖,星空圖,地圖,餅圖 等等..
birdeye官網的源碼現在如果不翻牆已經無法下載了,不過網上可以搜到非官網的源碼以及一官網demo
3.birdeye應用於項目實戰
使用birdeye繪制出一個人員關系圖,完成后的效果如下
初始化加載的時候,將某一人員的下一級全部展示出來,點擊某一個人員選擇人員關系,再將所有人員返回展示
4.一步步實現birdeye人員關系圖
1.借助官方demo的Level4示例
官方展示出的圖如下
1>首先修改渲染的樣式,代碼如下:
vgraph.edgeRenderer = new DirectedBalloonEdgeRenderer(vgraph.edgeDrawGraphics); //將這句改為 vgraph.itemRenderer=new ClassFactory(DefaultNodeRenderer);
2>修改圖形圖標
修改圖標需要修改birdeye的源碼,把下載好的源碼導入項目,打開EmdeddedIcons.as這個類,添加圖片綁定
[Bindable] [Embed(source="nodes/99.png")] static public var treeIcon:Class;
接着在generateImage方法中添加如下代碼:
case "tree": img.source = EmbeddedIcons.treeIcon;
操作完成之后,在數據源里邊即可使用新添加的圖標
3>初始化加載數據
我在做測試的時候使用的是WebService,接口編寫這里不再贅述,直接使用
先添加WebService類
<mx:WebService id="ws1" wsdl="http://localhost:5000/FlexService.asmx?wsdl" result="onResult(event)"> <mx:operation name="getChildNodeXMLByID"> </mx:operation> <mx:operation name="getXml"> </mx:operation> <mx:operation name="getNodeXMLByFTID"> <mx:request> <name>1</name> </mx:request> </mx:operation> </mx:WebService>
簡單介紹一下,wsdl是接口地址,result是一回調函數,執行獲取數據之后的操作,operation是接口中的方法,request是參數
完成之后,接下來完成AS代碼
在creationComplete里邊,初始化數據
//初始化加載 數據 ws1.getOperation("getChildNodeXMLByID").send(1);
這里的初始化數據,只是去調用webservice,卻並未能對返回的數據進行展示
還需要再對Webservice的回調函數中,進行如下操作:
//webservice返回數據之后的處理 internal function onResult(evt:ResultEvent):void { try { /* init a graph object with the XML data */ graph = new org.un.cava.birdeye.ravis.graphLayout.data.Graph("XMLAsDocsGraph",false,new XML(evt.result)); /* set the graph in the VGraph object, this automatically * initializes the VGraph items; * note: vgraph is the id of the mxml specified VisualGraph component */ vgraph.graph = graph; /* set the default layouter type */ layouter = new ConcentricRadialLayouter(vgraph); vgraph.layouter = layouter; /* set autofit */ layouter.autoFitEnabled = true; /* set the layouter */ // vgraph.edgeRenderer =new DefaultEdgeRenderer; vgraph.itemRenderer=new ClassFactory(DefaultNodeRenderer); /* set the layouter */ //vgraph.edgeRenderer = new DirectedBalloonEdgeRenderer(vgraph.edgeDrawGraphics); /* set the visibility limit options, default 2 * a.k.a degrees of separation */ vgraph.maxVisibleDistance = 2; /* select a root node, most layouters requires a root node * Note: Id 1 is referring to node id in the XML file */ startRoot = graph.nodeByStringId("1").vnode; /* set if edge labels should be displayed */ vgraph.displayEdgeLabels = true; /* the following kicks it off .... */ vgraph.currentRootVNode = startRoot; initDone = true; vgraph.draw(); }catch(e:Error) { Alert.show("沒有下個節點!"); } }
至此,如果沒有意外,關系圖應該可以繪制出來了。
4>添加右鍵菜單
選中節點之后,彈出一個對話窗口,選擇人員關系,繪制圖形
數據初始化完成之后,執行如下AS代碼
private function showContextMenu():void{ var myContextMenu:ContextMenu=new ContextMenu(); var GoUrl1:ContextMenuItem=new ContextMenuItem("人員關系"); GoUrl1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,rightContextMenu); var GoUrl2:ContextMenuItem=new ContextMenuItem("人檔查詢"); GoUrl2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,rightContextMenu); var GoUrl3:ContextMenuItem=new ContextMenuItem("刪除節點"); GoUrl3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,rightContextMenu); var GoUrl4:ContextMenuItem=new ContextMenuItem("刪除子節點"); GoUrl4.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,rightContextMenu); myContextMenu.customItems.push(GoUrl1); myContextMenu.customItems.push(GoUrl2); myContextMenu.customItems.push(GoUrl3); myContextMenu.customItems.push(GoUrl4); myContextMenu.hideBuiltInItems(); vgraph.contextMenu=myContextMenu; //this.contextMenu=myContextMenu; } private function rightContextMenu(event:ContextMenuEvent):void { if(event.mouseTarget["className"]=="DefaultNodeRenderer") { var sid:String=event.mouseTarget["data"].node.stringid; if(event.currentTarget.caption=="人員關系"){ //彈出選擇窗口 var ww:MyWindow; ww = MyWindow(PopUpManager.createPopUp(this.parent,MyWindow)); ww.nodeid=sid; PopUpManager.centerPopUp(ww); GraphRefush.dis.addEventListener(GraphRefush.EVENT_REFUSH,onfefush); //ws1.getOperation("getChildNodeXMLByID").send(sid); }else if(event.currentTarget.caption=="人檔查詢"){ ExternalInterface.call("rygxList",""); }else if(event.currentTarget.caption=="刪除節點"){ Alert.show("確定要刪除當前節點嗎?"); }else{ Alert.show("確定要刪除當前節點的所有子節點嗎?"); } } else { Alert.show("請選中節點","提示信息"); } }
代碼說明:
showContextMenu()方法的功能,主要是創建右鍵時的彈出菜單
rightContextMenu()方法的功能,主要是根據點擊執行不同的操作。
rightContextMenu()方法里邊有一個。MyWindow,該類是自定義的一MXML組件,主要是顯示所有人員關系類型。代碼如下:
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" close="titlewindow1_closeHandler(event)" title="人員關系選擇"> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.CloseEvent; import mx.managers.PopUpManager; protected function titlewindow1_closeHandler(event:CloseEvent):void { // TODO Auto-generated method stub PopUpManager.removePopUp(this); } protected function all_clickHandler(event:MouseEvent):void { // TODO Auto-generated method stub if(all.selected) { tz.selected=true; tx.selected=true; thk.selected=true; t1.selected=true; t2.selected=true; t3.selected=true; t4.selected=true; t5.selected=true; t6.selected=true; } else { tz.selected=false; tx.selected=false; thk.selected=false; t1.selected=false; t2.selected=false; t3.selected=false; t4.selected=false; t5.selected=false; t6.selected=false; } } public var nodeid:String=""; protected function save():void { // TODO Auto-generated method stub var b:Birdeye =new Birdeye(); var result:String=""; if(tz.selected) { result="選中了同住"; } if(tx.selected) { if(result!="") { result+=";"; } result+="選中了同鄉"; } if(thk.selected) { if(result!="") { result+=";"; } result+="選中了同戶口"; } //b.ws1.getOperation("getChildNodeXMLByID").send(nodeid); b.reflash(result,nodeid); PopUpManager.removePopUp(this); } ]]> </fx:Script> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; .img{ } </fx:Style> <fx:Declarations> <!-- 將非可視元素(例如服務、值對象)放在此處 --> </fx:Declarations> <s:VGroup top="5" width="100%" horizontalAlign="center" verticalAlign="middle"> <s:HGroup width="100%" horizontalAlign="center"> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x1.png')" styleName="img"/><mx:CheckBox label="同住" id="tz"></mx:CheckBox> </s:VGroup> <s:VGroup width="34%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x2.png')" styleName="img"/><mx:CheckBox label="同鄉" id="tx"></mx:CheckBox> </s:VGroup> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x3.png')" styleName="img"/><mx:CheckBox label="同戶口" id="thk"></mx:CheckBox> </s:VGroup> </s:HGroup> <s:HGroup width="100%"> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x4.png')" styleName="img"/><mx:CheckBox label="同住宿" id="t1"></mx:CheckBox> </s:VGroup> <s:VGroup width="34%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x5.png')" styleName="img"/><mx:CheckBox label="同車" id="t2"></mx:CheckBox> </s:VGroup> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x6.png')" styleName="img"/><mx:CheckBox label="同學" id="t3"></mx:CheckBox> </s:VGroup> </s:HGroup> <s:HGroup width="100%"> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x7.png')" styleName="img"/><mx:CheckBox label="朋友" id="t4"></mx:CheckBox> </s:VGroup> <s:VGroup width="34%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x8.png')" styleName="img"/><mx:CheckBox label="同事" id="t5"></mx:CheckBox> </s:VGroup> <s:VGroup width="33%" horizontalAlign="center"> <s:Image source="@Embed('assets/imgs/x8.png')" styleName="img"/><mx:CheckBox label="同村" id="t6"></mx:CheckBox> </s:VGroup> </s:HGroup> <s:HGroup width="100%" paddingTop="5" horizontalAlign="center"> <s:HGroup horizontalAlign="left"> <mx:CheckBox id="all" label="全選" click="all_clickHandler(event)" horizontalCenter="left"></mx:CheckBox> </s:HGroup> <s:HGroup horizontalAlign="center"> <s:Button label="確定" click="save()"> </s:Button> </s:HGroup> </s:HGroup> </s:VGroup> </s:TitleWindow>
5.中文亂碼或報錯問題解決
源代碼中的例子中,默認情況下輸入中文是不顯示的。原因是Ravis的例子中的內嵌了字體庫MyriadWebPro.ttf和 MyriadWebPro-Bold.ttf,並通過style/main.css文件將這個字體庫構造字體作為工程的默認字體,但是這個庫沒有包含中文 字體。
內嵌中文字體的最大問題是生成swf文件非常大,內嵌入網頁很不合適。
解決辦法是:打開style/main.css文件,刪除下面這兩個樣式
@font-face
{
src: url("assets/fonts/MyriadWebPro.ttf");
font-family: main;
font-style: normal;
font-weight: normal;
}
@font-face
{
src: url("assets/fonts/MyriadWebPro-Bold.ttf");
font-family: main;
font-style: normal;
font-weight: bold;
}
6.總結
據上所述,需求功能基本上都已實現。里邊有很多細節沒有仔細去介紹,比如birdeye的節點單擊事件,雙擊事件,右鍵時的事件操作,以及節點之間的關系,屬性展示等,這些在官網的DEMO里邊都有詳細的說明。