JAVA Jung2 drawing network topology
看到同事用Python写了一个画topology的脚本,感觉很有意思,如果优化下,功能会更实用。最近在看java,是否java也有很好的API可以用?有了这种想法就来Google下吧,在Stackoverflow上发现了两篇需求差不多的文章:
How to dynamically display a simulated network topology in Java
comparing open source java graph drawing frameworks(JUNG and Prefuse) for drawing network topology
上面提到了几个不错的API,JUNG,Prefuse和JGraphX,这偏文章只总结JUNG。关于JUNG的包可以通过下面官网下载:http://jung.sourceforge.net
最新的版本也是5年前的版本了:JUNG 2.0.1,下载下来后是一个zip包,里面包含所有相关的JAR文件,解压后放好,可以随时调用,下面是介绍如何通过Eclipse调用JUNG2:
1. 在project文件夹上右击鼠标,选“Configure Build Path”
2. 在Libraries中点“Add External JARs”,选上刚才解开的JAR包,就加进去了,然后直接import就可以了
网络/图应用开发通用基础架构JUNG
JUNG2-Tutorial
另外配合英文文档中的example,完整代码可以从下面找到:
http://www.grotto-networking.com/JUNG/
1. 首先是简单的数据结构
package pkg; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.SparseMultigraph; public class test { public static void main(String[] args) { // Graph<V, E> where V is the type of the vertices // and E is the type of the edges Graph<Integer, String> g = new SparseMultigraph<Integer, String>(); // Add some vertices. From above we defined these to be type Integer. g.addVertex((Integer)1); g.addVertex((Integer)2); g.addVertex((Integer)3); // Add some edges. From above we defined these to be of type String // Note that the default is for undirected edges. g.addEdge("Edge-A", 1, 2); g.addEdge("Edge-B", 2, 3); // Let's see what we have. Note the nice output from the // SparseMultigraph<V,E> toString() method // Note that we can use the same nodes and edges in two different graphs. System.out.println("The graph g = " + g.toString()); } }
结果为:
The graph g = Vertices:1,2,3 Edges:Edge-B[2,3] Edge-A[1,2]
上面蓝色标记的内容为对象g包含的内容,三个点,两条边,点1和2组成边A,点2和3组成边B
2. 把上面的数据画成图
加入下面代码,可生成图片
import javax.swing.JFrame; import edu.uci.ics.jung.algorithms.layout.CircleLayout; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.visualization.BasicVisualizationServer; //下面代码加入main中 Layout<Integer, String> layout = new CircleLayout(g); BasicVisualizationServer<Integer,String> vv = new BasicVisualizationServer<Integer,String>(layout); JFrame frame = new JFrame("Simple Graph View"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(vv); frame.pack(); frame.setVisible(true);
3. 通过鼠标移动点改变拓扑
注意code,我用的是PICKING,具体有几种什么意思,可以查看文档,不做过多介绍;另外把“BasicVisualizationServer”删除,用“VisualizationViewer”替换,下面是要增加的code:
import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.ModalGraphMouse; VisualizationViewer<Integer,String> vv = new VisualizationViewer<Integer,String>(layout); DefaultModalGraphMouse gm = new DefaultModalGraphMouse(); gm.setMode(ModalGraphMouse.Mode.PICKING); vv.setGraphMouse(gm);
执行后截图如下:
4. 改变点/边的颜色,大小和图例
研究了一个周末,终于把基本的功能都搞定了,把剩下的几个功能都集中到一个实例里了,详细如下code:
package pkg; import edu.uci.ics.jung.algorithms.layout.CircleLayout; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.SparseGraph; import edu.uci.ics.jung.graph.SparseMultigraph; import edu.uci.ics.jung.graph.util.EdgeType; import edu.uci.ics.jung.visualization.BasicVisualizationServer; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.ModalGraphMouse; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import org.apache.commons.collections15.Transformer; public class TopologyGraphView { /** Creates a new instance of TopologyGraphView */ Graph<String, String> g; /** * @frank 2015.4.12 */ public TopologyGraphView() { // Graph<V, E> where V is the type of the vertices // and E is the type of the edges g = new SparseMultigraph<String, String>(); // Add some vertices. From above we defined these to be type String. g.addVertex("R1"); g.addVertex("R2"); g.addVertex("R3"); // Add some edges. From above we defined these to be of type String // Note that the default is for undirected edges. g.addEdge("Edge-A", "R1", "R2", EdgeType.DIRECTED); g.addEdge("Edge-B", "R2", "R3", EdgeType.UNDIRECTED); // Let's see what we have. Note the nice output from the // SparseMultigraph<V,E> toString() method // Note that we can use the same nodes and edges in two different graphs. System.out.println("The graph g = " + g.toString()); } /** * @frank main function */ public static void main(String[] args) { TopologyGraphView sgv = new TopologyGraphView(); // This builds the graph,为了让layout调用构造函数中的对象g,如下面的sgv.g // Layout<V, E>, VisualizationComponent<V,E> Layout<String, String> layout = new CircleLayout(sgv.g); layout.setSize(new Dimension(300,300)); // not frame's size, but layout size VisualizationViewer<String,String> vv = new VisualizationViewer<String,String>(layout); vv.setPreferredSize(new Dimension(350,350)); // 可以改变frame的大小 // 加入通过鼠标互通的代码 DefaultModalGraphMouse gm = new DefaultModalGraphMouse(); gm.setMode(ModalGraphMouse.Mode.PICKING); vv.setGraphMouse(gm); // Setup up a edge to paint transformer... // https://stackoverflow.com/questions/23888613/how-to-change-colour-of-an- //edge-in-jung-graph-visualization-library // 把Edge-B默认的黑色改成红色 Transformer<String,Paint> teColor = new Transformer<String,Paint>() { public Paint transform(String i) { if (i.equals("Edge-B")) return Color.RED; else return Color.BLACK; } }; // Setup up a vertex to paint transformer... // https://stackoverflow.com/questions/8458970/change-size-color-of-vertex-in-jung // 把蓝色通过Transformer返回给vertexPaint Transformer<String,Paint> vertexColor = new Transformer<String,Paint>() { public Paint transform(String i) { if (i.equals("R1")) return Color.GREEN; else return Color.YELLOW ; } }; // Setup up a vertex to Icon transformer... // 用图来替代默认的点 Transformer<String, Icon> vertexIcon = new Transformer<String,Icon>() { public Icon transform(String x) { ImageIcon ic = new ImageIcon("router.png"); if (x.equals("R3")) return ic; else return null; } }; // Change default vertex size to transformer... // https://stackoverflow.com/questions/8458970/change-size-color-of-vertex-in-jung // 注意,前两个(-25,-25)是x,y的坐标,必须用负值,值等于半径(50是总长和总宽) Transformer<String,Shape> vertexSize = new Transformer<String,Shape>(){ public Shape transform(String i){ Ellipse2D circle = new Ellipse2D.Double(-25, -25, 50, 50); return circle; } }; // Set up a new stroke Transformer for the edges // BasicStroke用法:http://momsbaby1986.iteye.com/blog/1462901 // 把设置好的画笔通过Transformer返回给edgeStrokeTransformer Transformer<String, Stroke> edgeStrokeTransformer = new Transformer<String, Stroke>() { float test[] = {10.0f}; final Stroke dottedStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 10.0f, test, 0.0f); final Stroke thickStroke = new BasicStroke(6); public Stroke transform(String s) { if (s.equals("Edge-A")) return dottedStroke; else return thickStroke; } }; vv.getRenderContext().setVertexIconTransformer(vertexIcon); vv.getRenderContext().setVertexFillPaintTransformer(vertexColor); vv.getRenderContext().setVertexShapeTransformer(vertexSize); vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller()); vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller()); vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR); vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer); vv.getRenderContext().setEdgeDrawPaintTransformer(teColor); vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<String,String>()); // How to draw Straight line by JUNG2? // http://stackoverflow.com/questions/29587011/how-to-draw-straight-line-by-jung2 JFrame frame = new JFrame("Simple Graph View"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(vv); frame.pack(); frame.setVisible(true); } }本文出自 Frank's Blog
版权声明:
本文链接:JAVA Jung2 drawing network topology
版权声明:本文为原创文章,仅代表个人观点,版权归 Frank Zhao 所有,转载时请注明本文出处及文章链接