基于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封往来电子邮件帮我解答了许多问题。

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