本文介绍利用Java的第三方API JUNG 实现图的可视化
通过对示例代码分析,解析可视化方法。
JUNG 下载地址
https://sourceforge.net/projects/jung/files/
JUNG api参考文档:
http://jung.sourceforge.net/doc/api/overview-summary.html
预处理
JUNG 中的图可视化方法基于JUNG内置图类,本文基于自定义图呈现可视化图,故需要先将自定义图转存为JUNG图对象。
JUNG 提供 泛型接口,进行转化或创建时利用自定义边类型与节点类型即可。
以以下代码为例:
/**
* 将graph.Graph 转为 JUNG.graph.Graph 过滤掉超边.
*
* @param g - 基于 graph.Graph
* @return edu.uci.ics.jung.graph.Graph
*/
public static edu.uci.ics.jung.graph.Graph<Vertex, Edge> graphTransform(Graph<Vertex, Edge> g) {
edu.uci.ics.jung.graph.Graph<Vertex, Edge> graph = new SparseGraph<>(); // 稀疏图
for (Vertex vertex : g.vertices()) {
graph.addVertex(vertex);
}
for (Edge edge : g.edges()) {
if (edge.sourceVertices().size() == 0) {
// 超边
continue;
}
if (edge.sourceVertices().size() == 1) {
// 有向边
graph.addEdge(edge, getVertex(edge.sourceVertices()),
getVertex(edge.targetVertices()), EdgeType.DIRECTED);
} else {
// 无向边
Vertex existV = getVertex(edge.vertices());
graph.addEdge(edge, existV, getVertexExcept(edge.vertices(), existV),
EdgeType.UNDIRECTED);
}
}
return graph;
}
如此,获得一个jung 图对象。
类成员属性:
public class GraphVisualizationHelper { SparseGraph<Vertex, Edge> graph; // 稀疏图对象 BasicVisualizationServer<Vertex, Edge> vv; // 简单可视化类 Transformer<Vertex, Paint> vertexPaint; Transformer<Edge, Stroke> edgeStrokeTransformer; Transformer<Vertex, Shape> vertexShape; JFrame frame; // JFrame 框架展现图
……
构造方法
通过调用具体方法,工厂化构件图。
/** * constructor to create the graph. * @param originGraph - user-defined graph. */ public GraphVisualizationHelper(graph.Graph<Vertex, Edge> originGraph) { createWindow(); // 初始化窗口 createGraph(originGraph); // 图转换:自定义图对象 - jung图对象 createTransformers(); // 设置图变换器 showGraph(); // 设置图参数 ,呈现图信息 }
1.createWindow() 方法 初始化窗口
private void createWindow() { frame = new JFrame("Simple Graph View"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
2.createGraph(originGraph) 方法 转化图:自定义图对象 - jung图对象
private void createGraph(graph.Graph<Vertex, Edge> originGraph) { // Graph<V, E> where V is the type of the vertices and E is the type of // the edges graph = (SparseGraph<Vertex, Edge>) helper.Transformer.graphTransform(originGraph); }
3.createTransformers() 方法 设置图变换器
具体信息见代码注释:
private void createTransformers() { // Setup up a new vertex to paint transformer... // Transformer <V,Paint> vertexPaint = new Transformer<Vertex, Paint>() { @Override public Paint transform(Vertex s) { if (s.getLabel().equals("John")) { return Color.GREEN; } else { return Color.YELLOW; } } }; // 设置顶点形状的显示尺寸为:字符数*8+16 Transformer<Vertex, Integer> vst = new Transformer<Vertex, Integer>() { @Override public Integer transform(Vertex i) { int len = i.toString().length(); if (len < 10) { len = 10; } return new Integer(len * 10); } }; // 高宽比变换器 Transformer<Vertex, Float> vart = i -> { int len = i.toString().length(); if (len < 5) { len = 5; } return new Float(10 / len); }; // 构造顶点形状工厂 final VertexShapeFactory<Vertex> vsf = new VertexShapeFactory<Vertex>(vst, vart); // 设置顶点形状变换器 vertexShape = new Transformer<Vertex, Shape>() { @Override public Shape transform(Vertex s) { return vsf.getEllipse(s); } }; // Set up a new stroke Transformer for the edges float[] dash = {10.0f}; // (width of line, , ) final Stroke edgeStroke = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f); // Transformer <E,Stroke> edgeStrokeTransformer = new Transformer<Edge, Stroke>() { @Override public Stroke transform(Edge s) { return edgeStroke; } }; }
4.showGraph() 方法 设置图参数,呈现图信息
具体信息见代码注释:
private void showGraph() { // The Layout<V, E> is parameterized by the vertex and edge types Layout<Vertex, Edge> layout = new CircleLayout<>(graph); layout.setSize(new Dimension(1440, 1440)); // sets the initial size of the // space // The BasicVisualizationServer<V,E> is parameterized by the edge types vv = new BasicVisualizationServer<Vertex, Edge>(layout); // ( width , height) vv.setPreferredSize(new Dimension(1920, 1920)); // Sets the viewing area // size // 修改顶点字体大小 vv.getRenderContext().setVertexFontTransformer(new Transformer<Vertex, Font>() { @Override public Font transform(Vertex i) { return new Font("宋体", Font.PLAIN, 32); } }); // 修改边字体大小 vv.getRenderContext().setEdgeFontTransformer(new Transformer<Edge, Font>() { @Override public Font transform(Edge i) { return new Font("宋体", Font.PLAIN, 24); } }); // apply transformers vv.getRenderContext().setVertexShapeTransformer(vertexShape); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer); vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Vertex>()); vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<Edge>()); vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR); frame.getContentPane().add(vv); frame.pack(); frame.setVisible(true); }