基於GephiSDK的數據可視化功能開發

實習結束,能留下這麼個小玩意也是不錯的,功能比較完整的一個小模塊,希望以後可以用到產品裏。

此項目源碼已上傳GitHub:https://github.com/tangyeah/DataVisualization


一、實現環境:

NetBeansIDE 8.1
JDK 1.8
gephi-toolkit-0.9.1-all.jar
注:SDK使用NetBeans環境開發,對eclipse支持不好,儘量使用NetBeans來實現。

二、相關資源:

1.官方API:https://gephi.org/gephi-toolkit/0.9.1/apidocs/
2.Gephi官網:https://gephi.org/
3.GitHub:https://github.com/gephi/gephi
4.官方論壇:http://gephi.forumatic.com/
5.社區Manager郵箱:[email protected]

三、程序清單:

這裏寫圖片描述

四、功能簡述:

對外提供一個調用接口,實現對csv文件讀取,將讀取到的graph信息圖形化顯示;點擊一個節點可高亮顯示該節點以及所有與其相連的節點;可對點、邊的可視化屬性進行用戶自定義。

五、主程序模塊功能說明:

1.初始化一個project,並獲取workspace

ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
pc.newProject();
Workspace workspace = pc.getCurrentWorkspace();

2.獲取graphModel和需要用到的controller

GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getGraphModel();
ImportController importController = Lookup.getDefault().lookup(ImportController.class);
FilterController filterController = Lookup.getDefault().lookup(FilterController.class);

3.輸入文件,將輸入的文件和之前獲取的workspace關聯

根據API中Importer實現的接口來看,可以支持csv,gdf,gexf,gml等文件格式,本說明僅實現對csv文件的讀取,對csv文件格式具體要求是:每行兩個字段,中間用空格隔開,第一個字段表示一條邊的源頂點,第二個字段表示該邊的目的頂點。
這裏寫圖片描述

Container container;
try {
    File file = new File("C:\\graph_data\\D2.csv");
    container = importController.importFile(file);
} catch (Exception ex) {
    ex.printStackTrace();
    return;
}
importController.process(container, new DefaultProcessor(), workspace);

4.根據輸入文件生成有向圖,並輸出該圖的點數和邊數

DirectedGraph graph = graphModel.getDirectedGraph();
System.out.println("Nodes: " + graph.getNodeCount());
System.out.println("Edges: " + graph.getEdgeCount());

5.設置graph佈局,目前API支持如下幾種佈局:

· org.gephi.layout.plugin.force
· org.gephi.layout.plugin.force.quadtree
· org.gephi.layout.plugin.force.yifanHu
· org.gephi.layout.plugin.forceAtlas
· org.gephi.layout.plugin.forceAtlas2
· org.gephi.layout.plugin.fruchterman
· org.gephi.layout.plugin.labelAdjust
· org.gephi.layout.plugin.noverlap
· org.gephi.layout.plugin.openord
· org.gephi.layout.plugin.random
· org.gephi.layout.plugin.rotate
· org.gephi.layout.plugin.scale

本說明中採用fruchterman佈局,其特點是,如果導入的圖中包含N個互相聯通的子圖,可以通過設置合理的參數,將各個子連通圖互相分離開來,效果如下:

這裏寫圖片描述

其他各種佈局的效果可以使用gephi的exe客戶端查看,根據需要替換本說明中的這段代碼:

    //Fruchterman佈局設置,可將聯通的子圖分離開來
    FruchtermanReingold myLayout = new FruchtermanReingold(null);
    myLayout.setGraphModel(graphModel);
    myLayout.setArea(10000.0f);
    myLayout.setGravity(10.0);
    myLayout.setSpeed(500.0);

    myLayout.initAlgo();
    for (int i = 0; i < 20000 && myLayout.canAlgo(); i++) {
        myLayout.goAlgo();
    }
    myLayout.endAlgo();

6.設置Filter,可以根據需要濾除度過大或過小的點,同樣的,也可以分別對入度和出度進行filter

//Filter設置,根據點的度來進行過濾
DegreeRangeFilter degreeFilter = new DegreeRangeFilter();
//InDegreeRangeFilter idf = new InDegreeRangeFilter();
//OutDegreeRangeFilter odf = new OutDegreeRangeFilter();
degreeFilter.init(graph);
degreeFilter.setRange(new Range(10, Integer.MAX_VALUE));     //濾出度大於等於10的點
Query query = filterController.createQuery(degreeFilter);
GraphView view = filterController.filter(query);
graphModel.setVisibleView(view);

7.設置graph的各種可視化屬性,比如點顏色,邊透明度,箭頭大小等。代碼以設置背景顏色爲例:

PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class);
PreviewModel previewModel = previewController.getModel();

previewModel.getProperties().putValue(PreviewProperty.BACKGROUND_COLOR, Color.WHITE);

所有可設置的屬性如下:
https://gephi.org/gephi-toolkit/0.9.1/apidocs/org/gephi/preview/api/PreviewProperty.html

8.創建JFrame並顯示graph

G2DTarget target = (G2DTarget) previewController.getRenderTarget(
RenderTarget.G2D_TARGET);
final PreviewSketch previewSketch = new PreviewSketch(target);
previewController.refreshPreview();

JFrame frame = new JFrame("DisplayWindow");
frame.setLayout(new BorderLayout());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(previewSketch, BorderLayout.CENTER);

frame.setSize(1024, 768);
frame.addComponentListener(new ComponentAdapter(){
    @Override
    public void componentShown(ComponentEvent e){
        previewSketch.resetZoom();
    }
});
frame.setVisible(true);

六、對點擊事件的監聽

1.創建自定義Renderer類,實現Renderer和MouseResponsiveRenderer接口

(1)一定要聲明:

@ServiceProvider(service = Renderer.class)

(2)複寫函數needsPreviewMouseListener(PreviewMouseListener pl) {},使其返回true:


@Override
public boolean needsPreviewMouseListener(PreviewMouseListener pl) {
return true;
}

2.創建自定義MouseListener類,實現PreviewMouseListener接口

(1)聲明:
@ServiceProvider(service = PreviewMouseListener.class)
(2)複寫mouseClicked函數,自定義鼠標點擊事件,詳見源代碼。

特別感謝Gephi社區經理eduramiba,在西班牙隔着6個小時的時差,20封往來電子郵件幫我解答了許多問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章