在java程序中调用graphviz

来源:互联网 发布:miui9卡刷会清除数据 编辑:程序博客网 时间:2024/06/05 07:58

前言

日常的开发工作中,为代码添加注释是代码可维护性的一个重要方面,但是仅仅提供注释是不够的,特别是当系统功能越来越复杂,涉及到的模块越来越多的时候,仅仅靠代码就很难从宏观的层次去理解。因此我们需要图例的支持,图例不仅仅包含功能之间的交互,也可以包含复杂的数据结构的示意图,数据流向等。

graphviz简介

本文介绍一个高效而简洁的绘图工具graphvizgraphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局。graphviz提供丰富的导出格式,如常用的图片格式,SVG,PDF格式等。

graphviz[http://graphviz.org]  不想下载的话有网页版[http://www.webgraphviz.com]  基本教程[http://icodeit.org/2015/11/using-graphviz-drawing/]

而且,graphviz还可以由eclipse调用,直接生成图片于文件夹中,这里通过本人的实验分享一下在eclipse中调用graphviz的方法

这边将用到window版本的graphviz,找到dot.exe的路径,在我的电脑是C:\Program Files (x86)\Graphviz2.38\bin\dot.exe


首先,在你的package中再创建一个名为Graphviz.java的文件

然后在此文件中输入

package pair_programming;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
class GraphViz {
 //private static String TEMP_DIR = "/tmp"; // Linux
 private static String TEMP_DIR = "C:\\temp"; // Windows,此处为生成图片的未知(不能为c盘根目录,原因未知)
 //private static String DOT = "dot"; // Linux
 private static String DOT = "C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe";//dot.exe的位置
 private StringBuilder graph = new StringBuilder();
 public GraphViz() {
 }
 public String getDotSource() {
  return graph.toString();
 }
 public void add(String line) {
  graph.append(line);
 }
 public void addln(String line) {
  graph.append(line + "\n");
 }
 public void addln() {
  graph.append('\n');
 }
 public byte[] getGraph(String dot_source, String type) {
  File dot;
  byte[] img_stream = null;
  try {
   dot = writeDotSourceToFile(dot_source);
   if (dot != null) {
    img_stream = get_img_stream(dot, type);
    //if (dot.delete() == false)
    // System.err.println("Warning: " + dot.getAbsolutePath() + " could not be deleted!");
    return img_stream;
   }
   return null;
  } catch (java.io.IOException ioe) {
   return null;
  }
 }
 public int writeGraphToFile(byte[] img, String file) {
  return writeGraphToFile(img, new File(file));
 }
 public int writeGraphToFile(byte[] img, File to) {
  try {
   FileOutputStream fos = new FileOutputStream(to);
   fos.write(img);
   fos.close();
  } catch (java.io.IOException ioe) {
   ioe.printStackTrace();
   return -1;
  }
  return 1;
 }
 private byte[] get_img_stream(File dot, String type) {
  File img;
  byte[] img_stream = null;
  try {
   img = File.createTempFile("graph_", "." + type, new File(GraphViz.TEMP_DIR));
   Runtime rt = Runtime.getRuntime();
   String[] args = { DOT, "-T" + type, dot.getAbsolutePath(), "-o", img.getAbsolutePath() };
   Process p = rt.exec(args);
   p.waitFor();
   FileInputStream in = new FileInputStream(img.getAbsolutePath());
   img_stream = new byte[in.available()];
   in.read(img_stream);
   if (in != null) in.close();
   if (img.delete() == false)
    System.err.println("Warning: " + img.getAbsolutePath() + " could not be deleted!");
  } catch (java.io.IOException ioe) {
   System.err.println("Error:    in I/O processing of tempfile in dir " + GraphViz.TEMP_DIR + "\n");
   System.err.println("       or in calling external command");
   ioe.printStackTrace();
  } catch (java.lang.InterruptedException ie) {
   System.err.println("Error: the execution of the external program was interrupted");
   ie.printStackTrace();
  }
  return img_stream;
 }
 public File writeDotSourceToFile(String str) throws java.io.IOException {
  File temp;
  try {
   temp = File.createTempFile("graph_", ".dot", new File(GraphViz.TEMP_DIR));
   FileWriter fout = new FileWriter(temp);
   fout.write(str);
   fout.close();
  } catch (Exception e) {
   System.err.println("Error: I/O error while writing the dot source to temp file!");
   return null;
  }
  return temp;
 }
 public String start_graph() {
  return "digraph G {";
 }
 
 public String end_graph() {
  return "}";
 }
 public void readSource(String input) {
  StringBuilder sb = new StringBuilder();
  try {
   FileInputStream fis = new FileInputStream(input);
   DataInputStream dis = new DataInputStream(fis);
   BufferedReader br = new BufferedReader(new InputStreamReader(dis));
   String line;
   while ((line = br.readLine()) != null) {
    sb.append(line);
   }
   dis.close();
  } catch (Exception e) {
   System.err.println("Error: " + e.getMessage());
  }
  this.graph = sb;
 }
} // end of class GraphViz

然后就可以在主程序中调用graphviz的方法啦

给出一个我自己的例子

 public static void showDirectedGraph(MatrixDG Graph) {
  GraphViz gv = new GraphViz();
  gv.addln(gv.start_graph());
  for (int i = 0; i < Graph.mVexs.length; i++)
   for (int j = 0; j < Graph.mVexs.length; j++)
    if (Graph.mMatrix[i][j] != 0)
     gv.addln(Graph.mVexs[i] + "->" + Graph.mVexs[j] + "[label=\"" + Graph.mMatrix[i][j] + "\"]" + ";");
  gv.addln(gv.end_graph());
  // System.out.println(gv.getDotSource());
  gv.getDotSource();
  String type = "png";
  File out = new File("C:\\temp\\graphOut." + type);
  gv.writeGraphToFile(gv.getGraph(gv.getDotSource(), type), out);
  byte[] image = image2byte("C:\\temp\\graphOut.png");  
  ScaleIcon icon = new ScaleIcon(new ImageIcon(image));
  JLabel label = new JLabel(icon);
  JFrame frame = new JFrame();
  
  int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
  int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
  JScrollPane jsp = new JScrollPane(label, v, h);
  
  frame.getContentPane().add(jsp, BorderLayout.CENTER);
  // frame.getContentPane().add(new JButton("click"),BorderLayout.NORTH);
  frame.setSize(icon.getIconWidth(),icon.getIconHeight());
  frame.setLocationRelativeTo(null);
  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  frame.setVisible(true);
 }

就这样可以成功啦

原创粉丝点击