利用Flex組件birdeye繪制拓撲關系圖


birdeye繪制拓撲關系圖

1.flex簡單介紹

  Flex 是一個高效、免費的開源框架,可用於構建具有表現力的 Web應用程序,這些應用程序利用Adobe Flash PlayerAdobe 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里邊都有詳細的說明。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM