graphviz基本使用及常見問題

一、認識graphviz

接觸graphviz是幾年前的一個項目,要畫出數據網絡的佈局,使用graphviz能比較清楚的畫出數據之間的關係。
可以在gallery中查看他能完成的圖形:http://www.graphviz.org/gallery/。graphviz最方便的地方在於能夠很快的清晰的畫出點與點之間的關係,並且有許多佈局算法能夠很好的去佈局。
之前使用它畫過流程圖,決策樹。使用twopi畫出數據的關聯關係:

二、安裝graphviz

官網下載:http://www.graphviz.org/download/。
根據自己的版本來選擇:

 

安裝在任意喜歡的位置。但是需要把安裝目錄的graphviz/bin加入環境變量PATH裏,我這裏只寫了相對路徑。
打開cmd,輸入:dot --help,如果彈出以下信息,就是安裝成功:

 

三、使用graphviz

3.1 基本信息

graphviz中包含了衆多的佈局器:

dot            默認佈局方式,主要用於有向圖
neato       基於spring-model(又稱force-based)算法
twopi        徑向佈局
circo        圓環佈局
fdp           用於無向圖

以上佈局我都使用過,但是個人比較傾向dot和twopi,可以根據需求來畫圖。

基本語法


字符串 都要加雙引號, 可以加\n換行符
註釋     雙斜槓// 或/* */
有向圖 digraph, 節點關係: 指向->
無向圖 graph, 節點關係: 連通 --
屬性 node[attribute1=value1, attribute2=value2]
大小: size=”2,2”; 單位爲英寸
標籤: label=”顯示在圖上的內容”
邊:edge [color=red,style=dotted]; 這句話之後生效
節點:node [color=navy]; 這句話之後生效
邊方向:rankdir=參數值;LR(從左到右),RL,BT,TB
節點形狀: a[shape=box]; 默認是橢圓
邊框大小:a[width=.1,height=2.5]; 單位爲英寸
邊框顏色:a[color=red];


構造邊

關係     有向圖    無向圖
一對一     a->b;     a–b;
一對多     a->{b;c;d};    a–{b;c;d};
多對一     {b;c;d}->a;     {b;c;d}–a;
多對多     {m,n,p,q}->{b;c;d};     {m,n,p,q}->{b;c;d}


詳細資料:
官方文檔:http://www.graphviz.org/documentation/
屬性設置:https://graphviz.gitlab.io/_pages/doc/info/attrs.html
節點形狀:https://graphviz.gitlab.io/_pages/doc/info/shapes.html
箭頭形狀:https://graphviz.gitlab.io/_pages/doc/info/arrows.html
顏色配置:https://graphviz.gitlab.io/_pages/doc/info/colors.html

 

3.2 基本使用

以畫一個dot佈局爲例子:
(1)建立一個first.dot腳本:

digraph first1{
    a;
    b;
    c;
    d;
    a->b;
    b->d;
    c->d;
}

解釋:digraph是畫圖類型,接觸高級使用可以有不同的類型,first2可以和文件名first不一樣。畫了abcd4個點。然後a->b表示a點指向b點,如果有線條的指向,可以不用先聲明點。即,上述代碼等價於:

digraph first2{
    a->b;
    b->d;
    c->d;
}

(2)畫圖
打開cmd到first.dot目錄下,運行:
dot -Tpng first.dot -o first.png
可以得到畫好的圖形。
解釋:dot表示使用的是dot佈局,其他佈局相應的修改即可,-T表示格式,即畫成png格式,-o表示重命名爲first.png。

在這裏如果出現syntax error,可看第四部分常見問題解決。

(3)畫圖結果
上面的簡單的代碼得到以下結果:

一對多示例 

digraph demo1 {

    //解決中文亂碼
    node[fontname = "Microsoft YaHei"];
    edge[fontname = "Microsoft YaHei"];
    graph[fontname = "Microsoft YaHei"];

    label="一對多示例"

    {你} -> {
        a;
        b;
        c;
    };

}

 關係

graph gvDemo1 {
    a -- b
    a -- b
    b -- a [color=blue]
}

有向圖

digraph gvDemo2 {
    a -> b
    a -> b
    b -> a [color=blue style=filled]
}

多對多 

digraph gvABC {
    { a b c } -> { d e f }
}

 

digraph gvDemo {
    main -> parse -> execute;
    main -> init;
    main -> cleanup;
    execute -> make_string;
    execute -> printf
    init -> make_string;
    main -> printf;
    execute -> compare;
}
digraph gvDemo{
    node [peripheries=2 style=filled color="#eecc80"]
    edge [color="sienna" fontcolor="green"]
    main -> parse -> execute;
    main -> init [arrowhead = box];
    main -> cleanupi -> main;
    make_string[label = once shape=parallelogram style=filled ]
    execute -> make_string[label=Go style=dashed arrowtail=diamond];
    execute -> printf [shape=box];
    init -> make_string;
    main -> printf[dir=none];
    execute -> compare[dir=both];
}

 

digraph gvDemo3 {
    edge[fontname="Microsoft YaHei"]
    node[fontname="Microsoft YaHei"]
    graph[fontname="Microsoft YaHei"]
    label="遊戲資源更新流程"
    rankdir="TB"
    start[label="啓動遊戲" shape=circle style=filled]
    ifwifi[label="網絡環境判斷是否 WIFI" shape=diamond]
    needupdate[label="是否有資源需要更新" shape=diamond]
    startslientdl[label="靜默下載" shape=box]
    enterhall[label="進入遊戲大廳" shape=box]


    enterroom[label="進入房間" shape=box]
    resourceuptodate[label="資源不完整" shape=diamond]
    startplay[label="正常遊戲" shape=circle fillcolor=blue]
    warning[label="提醒玩家是否更新" shape=diamond]
    startdl[label="進入下載界面" shape=box]
    //{rank=same; needupdate, enterhall}


    {shape=diamond; ifwifi, needupdate}


    start -> ifwifi
    ifwifi->needupdate[label="是"]
    ifwifi->enterhall[label="否"]
    needupdate->startslientdl[label="是"]
    startslientdl->enterhall
    needupdate->enterhall[label="否"]


    enterhall -> enterroom
    enterroom -> resourceuptodate
    resourceuptodate -> warning[label="是"]
    resourceuptodate -> startplay[label="否"]
    warning -> startdl[label="確認下載"]
    warning -> enterhall[label="取消下載"]
    startdl -> enterhall[label="取消下載"]
    startdl -> startplay[label="下載完成"]
}

 

graph gvDemo4{
    "黑海" -- "亞速海";
    "黑海" -- "博斯普魯斯海峽"
    "達達尼爾海峽" -- "愛琴海"
    subgraph cluster_T{//新東西
        label = "黑海海峽";//新東西
        "達達尼爾海峽" -- "馬爾馬拉海" -- "博斯普魯斯海峽";
    }
    subgraph cluster_M{
        label = "地中海海域";
        "中部地中海" -- {"愛琴海" "愛奧尼亞海" "西西里海峽"}; //也是新東西
        "西部地中海" -- {"西西里海峽" "第勒尼安海" "利古里亞海" "伊比利海" "阿爾沃蘭海"};
        "愛奧尼亞海" -- "亞得里亞海";
        "阿爾沃蘭海" -- "直布羅陀海峽";
    }
} 
digraph G{
Country->Narrow;
Country->Middle;
Country->Large;
Narrow->small_underpopulated[label="small population"];
Narrow->small_overpopulated[label="large population"];顦
Large->vast_overpopulated[label="large population"]; 
Large->vast_underpopulated[label="small population"];
Middle->small_overpopulated[label="More than average"];顦
Middle->vast_underpopulated[label="Less than average"];
small_overpopulated->A[label="GDP:HIGH"];
small_overpopulated->B[label="GDP:LOW"];
vast_overpopulated->C[label="GDP:HIGH"];
vast_overpopulated->D[label="GDP:LOW"];
vast_underpopulated->E[label="GDP:HIGH"];
vast_underpopulated->F[label="GDP:LOW"];
F->F[label="NOT EXIST",color="red"];
small_underpopulated->G[label="GDP:HIGH"];
small_underpopulated->H[label="GDP:LOW"];
D->I[label="RoadScattered"];
D->Y[label="HighCoveraged"];
C->J[label="HighCoveraged"];
A->K[label="HighCoveraged"];
B->L[label="RoadScattered"];
G->M[label="HighCoveraged"];
H->H[label="Number Too Less",color="red"];
E->O[label="RoadScattered"];
E->P[label="HighCoveraged"];
M->Q[label="Both"];
K->R[label="Both"];
L->S[label="Oil More"];
O->T[label="Oil More"];
P->U[label="Both"];
J->V[label="Oil More"];
J->W[label="Both"];
K->X[label="Electricity More"];
I->Z[label="Neither"];
Y->1[label="Neither"];
Q->Q[color="red"];
R->R[color="red"];
X->X[color="red"];
S->S[color="red"];
T->T[color="red"];
U->U[color="red"];
V->V[color="red"];
W->W[color="red"];
Z->Z[color="red"];
1->1[label="Number Too Less",color="red"];
} 
 

 

digraph G {
    A -> B;
    A -> C -> B;
    A -> D -> B;
}

 節點形狀

digraph G {
    size = "4, 4";
    main [shape=box]; /* 這是註釋 */
    main -> parse [weight=8];
    parse -> execute;
    main -> init [style=dotted];
    main -> cleanup;
    execute -> { make_string; printf}
    init -> make_string;
    edge [color=red]; // 設置生效
    main -> printf [style=bold,label="100 times"];
    make_string [label="make a\n字符串"];
    node [shape=box,style=filled,color=".7 .3 1.0"];
    execute -> compare;
}

 標籤

digraph G {
    a -> b -> c;
    b -> d;
    a [shape=polygon,sides=5,peripheries=3,color=lightblue,style=filled];
    c [shape=polygon,sides=4,skew=.4,label="hello world"]
    d [shape=invtriangle];
    e [shape=polygon,sides=4,distortion=.7];
}

 類似HTML的樣式

 digraph html {
    abc [shape=none, margin=0, label=<
    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
        <TR>
            <TD ROWSPAN="3"><FONT COLOR="red">hello</FONT><BR/>world</TD>
            <TD COLSPAN="3">b</TD>
            <TD ROWSPAN="3" BGCOLOR="lightgrey">g</TD>
            <TD ROWSPAN="3">h</TD>
        </TR>
        <TR>
            <TD>c</TD>
            <TD PORT="here">d</TD>
            <TD>e</TD>
        </TR>
        <TR>
            <TD COLSPAN="3">f</TD>
        </TR>
    </TABLE>>];
}

二分查找樹 

digraph g {
    node [shape = record,height=.1];
    node0[label = "<f0> |<f1> G|<f2> "];
    node1[label = "<f0> |<f1> E|<f2> "];
    node2[label = "<f0> |<f1> B|<f2> "];
    node3[label = "<f0> |<f1> F|<f2> "];
    node4[label = "<f0> |<f1> R|<f2> "];
    node5[label = "<f0> |<f1> H|<f2> "];
    node6[label = "<f0> |<f1> Y|<f2> "];
    node7[label = "<f0> |<f1> A|<f2> "];
    node8[label = "<f0> |<f1> C|<f2> "];
    "node0":f2 -> "node4":f1;
    "node0":f0 -> "node1":f1;
    "node1":f0 -> "node2":f1;
    "node1":f2 -> "node3":f1;
    "node2":f2 -> "node8":f1;
    "node2":f0 -> "node7":f1;
    "node4":f2 -> "node6":f1;
    "node4":f0 -> "node5":f1;
}

 示例

 


//定義節點屬性
digraph g {
    //==========定義節點關係============
    a->b;
    b->c;
    c->a;
    c->d->e->f;
    d->g;
    e->h;
    //==========定義節點屬性============
    //定義a節點爲長方形, 樣式爲填充, 填充顏色爲#ABACBA
    a[shape=box,label="Server1\nWebServer",fillcolor="#ABACBA",style=filled];
    //定義b爲5邊形, 標籤爲"bb", 樣式爲填充, 填充色爲red
    b[shape=polygon,sides=5,label="bb",style=filled,fillcolor=red];
    //c, 默認爲橢圓
    d[shape=circle]; //園
    e[shape=triangle]; //三角形
    f[shape=polygon, sides=4, skew=0.5]; //平行四邊形
    g[shape=polygon, distortion=0.5]; //梯形, 上邊長
    h[shape=polygon, distortion=-.5]; //梯形, 下邊長
}

有向圖

digraph g {
  //edge[style=dashed]; //定義邊的樣式, 虛線
  node[peripheries=2, style=filled, color="#eecc80"];
  a->b [color=red, style=dashed]; //定義邊的顏色, 紅色 (b和方括號之間必須有空格)
  b->c; //箭頭, 三角形; 箭尾, 菱形
  b->d [arrowhead=box]; //箭頭, 長方形
  b->e [dir=none]; //沒有箭頭
  d->f [dir=both]; //雙向箭頭
  f->h [label=go]; //定義edge的標籤
  f->k [arrowhead=diamond]; //更改箭頭形狀
  k->y [headlabel="哈哈", taillabel="洗洗"];
}

無向圖

graph g {
  edge[style=dashed]; //定義邊的樣式, 虛線
  a -- b [color=red]; //定義邊的顏色, 紅色 (b和方括號之間必須有空格)
}

 ER圖

digraph g {
graph [
rankdir = "LR"
];
node [
fontsize = "16"
shape = "ellipse"
];
edge [
];

"user" [
        label = "User| <id> id|username|password|last|status"
        shape = "record"
];

"profile" [
        label = "Profile| <id> id | name | sex | age | address | icq | msn"
        shape = "record"
];

user:id->profile:id [label="1:1"];

"category" [
        label = "Category| <id> id | <pid> pid | name | status"
        shape = "record"
];

category:pid->category:id [label="1:n"];

"article" [
        label = "Article| <id> id| <user_id> user_id | <cid> category_id | title | content | datetime | status"
        shape = "record"
];

article:user_id->user:id [label="1:n"];
article:cid->category:id [label="1:n"];

"feedback" [
        label = "Feedback| <id> id| <user_id> user_id | <article_id> article_id | title | content | datetime | status"
        shape = "record"
];

feedback:user_id->user:id [label="1:n"];
feedback:article_id->article:id [label="1:n"];

}

 複雜標籤

 

 

digraph graphname{
    /* 把節點的形狀設置爲 record,默認的是圓角矩形 */
    node [shape = record];

    root [label = "left|middle|right"];
    left [label = "one|two"];
    right [label = "hello\nworld|{b|{c|d|e}|f}|g|h"];

    root -> left;
    root -> right;
}

 

3.3 高級使用

網上參考一篇博客,寫的比較詳細,對於很多應用場景都有提到: http://icodeit.org/2012/01/%E4%BD%BF%E7%94%A8graphviz%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE/

但是,想要查詢每個屬性的信息,可以看官網的查詢文檔:
Node, Edge and Graph Attributes(屬性):https://graphviz.gitlab.io/_pages/doc/info/attrs.html
Node Shapes(節點形狀):https://graphviz.gitlab.io/_pages/doc/info/shapes.html
Arrow Shapes(箭頭形狀):https://graphviz.gitlab.io/_pages/doc/info/arrows.html

四、常見問題

4.1 編譯問題

如果遇見以下錯誤:

image.png

解決:
1、編碼問題。
把文件另存爲,'utf-8'或'ANSI'(不涉及中文使用時),看是否編譯出問題。
2、對於文件格式的識別。
將文件開頭加2個空格,其識別的時候,對於第一個字符,在windows下會問題,源於文件的編碼格式。

4.2 中文問題

修改文件,Graphviz2.37\etc\fonts\fonts.conf,安裝的相對目錄。
(1)文件修改
將下列代碼:

 

<dir>#WINDOWSFONTDIR#</dir>
<dir>~/.fonts</dir>

修改爲:

 

<dir>C:\WINDOWS\Fonts</dir>
<dir>~/.fonts</dir>

(2)文本設置
2.1 文本保存的編碼爲"utf-8"
2.2 文本中的字體設置
使用的dot文件按照規則屬性,設置fontname屬性即可:

 

fontname="Microsoft YaHei"
edge [fontname="Microsoft YaHei"];
node [fontname="Microsoft YaHei"];
digraph gvDemo3 {
    edge[fontname="Microsoft YaHei"]
    node[fontname="Microsoft YaHei"]
    graph[fontname="Microsoft YaHei"]

}

 

以上分別是全局、邊、節點的設置。

可用的中文,有很多:

黑體:SimHei 
宋體:SimSun 
新宋體:NSimSun 
仿宋:FangSong 
楷體:KaiTi 
新細明體:PMingLiU
細明體:MingLiU
標楷體:DFKai-SB
微軟正黑體:Microsoft JhengHei
微軟雅黑體:Microsoft YaHei 

2.3 dot文件中的中文前後加空格
如:label="節點"應爲label=" 節點 "

Java中使用

//GraphViz.java - a simple API to call dot from Java programs
/*$Id$*/
/*
******************************************************************************
*                                                                            *
*              (c) Copyright 2003 Laszlo Szathmary                           *
*                                                                            *
* This program is free software; you can redistribute it and/or modify it    *
* under the terms of the GNU Lesser General Public License as published by   *
* the Free Software Foundation; either version 2.1 of the License, or        *
* (at your option) any later version.                                        *
*                                                                            *
* This program is distributed in the hope that it will be useful, but        *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public    *
* License for more details.                                                  *
*                                                                            *
* You should have received a copy of the GNU Lesser General Public License   *
* along with this program; if not, write to the Free Software Foundation,    *
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                              *
*                                                                            *
******************************************************************************
*/

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;

/**
* <dl>
* <dt>Purpose: GraphViz Java API
* <dd>
*
* <dt>Description:
* <dd> With this Java class you can simply call dot
*      from your Java programs
* <dt>Example usage:
* <dd>
* <pre>
*    GraphViz gv = new GraphViz();
*    gv.addln(gv.start_graph());
*    gv.addln("A -> B;");
*    gv.addln("A -> C;");
*    gv.addln(gv.end_graph());
*    System.out.println(gv.getDotSource());
*
*    String type = "gif";
*    File out = new File("out." + type);   // out.gif in this example
*    gv.writeGraphToFile( gv.getGraph( gv.getDotSource(), type ), out );
* </pre>
* </dd>
*
* </dl>
*
* @version v0.4, 2011/02/05 (February) -- Patch of Keheliya Gallaba is added. Now you
* can specify the type of the output file: gif, dot, fig, pdf, ps, svg, png, etc.
* @version v0.3, 2010/11/29 (November) -- Windows support + ability 
* to read the graph from a text file
* @version v0.2, 2010/07/22 (July) -- bug fix
* @version v0.1, 2003/12/04 (December) -- first release
* @author  Laszlo Szathmary (<a href="[email protected]">[email protected]</a>)
*/
public class Graphviz
{
/**
 * The dir. where temporary files will be created.
 */
//private static String TEMP_DIR = "/tmp"; // Linux
private static String TEMP_DIR = "c:/temp"; // Windows

/**
 * Where is your dot program located? It will be called externally.
 */
// private static String DOT = "/usr/bin/dot"; // Linux
private static String DOT = "C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe"; // Windows

/**
 * The source of the graph written in dot language.
 */
private StringBuilder graph = new StringBuilder();

/**
 * Constructor: creates a new GraphViz object that will contain
 * a graph.
 */
public Graphviz() {
}

/**
 * Returns the graph's source description in dot language.
 * @return Source of the graph in dot language.
 */
public String getDotSource() {
   return graph.toString();
}

/**
 * Adds a string to the graph's source (without newline).
 */
public void add(String line) {
   graph.append(line);
}

/**
 * Adds a string to the graph's source (with newline).
 */
public void addln(String line) {
   graph.append(line + "\n");
}

/**
 * Adds a newline to the graph's source.
 */
public void addln() {
   graph.append('\n');
}

/**
 * Returns the graph as an image in binary format.
 * @param dot_source Source of the graph to be drawn.
 * @param type Type of the output image to be produced, e.g.: gif, dot, fig, pdf, ps, svg, png.
 * @return A byte array containing the image of the graph.
 */
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; }
}

/**
 * Writes the graph's image in a file.
 * @param img   A byte array containing the image of the graph.
 * @param file  Name of the file to where we want to write.
 * @return Success: 1, Failure: -1
 */
public int writeGraphToFile(byte[] img, String file)
{
   File to = new File(file);
   return writeGraphToFile(img, to);
}

/**
 * Writes the graph's image in a file.
 * @param img   A byte array containing the image of the graph.
 * @param to    A File object to where we want to write.
 * @return Success: 1, Failure: -1
 */
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;
}

/**
 * It will call the external dot program, and return the image in
 * binary format.
 * @param dot Source of the graph (in dot language).
 * @param type Type of the output image to be produced, e.g.: gif, dot, fig, pdf, ps, svg, png.
 * @return The image of the graph in .gif format.
 */
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();
      
      // patch by Mike Chenault
      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);
      // Close it if we need to
      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;   }
/**
 * Writes the source of the graph in a file, and returns the written file
 * as a File object.
 * @param str Source of the graph (in dot language).
 * @return The file (as a File object) that contains the source of the graph.
 */
public File writeDotSourceToFile(String str) throws java.io.IOException
{
   File temp;
   try {
      temp = File.createTempFile("graph_", ".dot.tmp", 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;
}

/**
 * Returns a string that is used to start a graph.
 * @return A string to open a graph.
 */
public String start_graph() {
   return "digraph G {" ;
}

/**
 * Returns a string that is used to end a graph.
 * @return A string to close a graph.
 */
public String end_graph() {
   return "}";
}

/**
 * Read a DOT graph from a text file.
 * 
 * @param input Input text file containing the DOT graph
 * source.
 */
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
import java.io.File;

public class GTest {
    public static void main(String[] args){
        GTest gtest = new GTest();
        String[] nodes = {"A","B","C","D","E","F","G"};
        String[] preline = {"B -> A","D -> B","E -> D","C -> E","G -> C","F -> G"};
        gtest.start(nodes, preline);
    }
    private void start(String[] nodes,String[] preline){
           
           Graphviz gv = new Graphviz();
           //定義每個節點的style
           String nodesty = "[shape = polygon, sides = 6, peripheries = 2, color = lightblue, style = filled]";
           //String linesty = "[dir=\"none\"]";
           
           gv.addln(gv.start_graph());//SATRT
           gv.addln("edge[fontname=\"DFKai-SB\" fontsize=15 fontcolor=\"black\" color=\"brown\" style=\"filled\"]");
           gv.addln("size =\"8,8\";");
           //設置節點的style
           for(int i=0;i<nodes.length;i++){
               gv.addln(nodes[i]+" "+nodesty);
           }
           for(int i=0;i<preline.length;i++){
               gv.addln(preline[i]+" "+" [dir=\"none\"]");
           }
           gv.addln(gv.end_graph());//END
           //節點之間的連接關係輸出到控制檯
           System.out.println(gv.getDotSource());
           //輸出什麼格式的圖片(gif,dot,fig,pdf,ps,svg,png,plain)
           String type = "png";
           //輸出到文件夾以及命名
           File out = new File("C:/Users/fanghui/Desktop/GraphTest/test." + type);   // Linux
           //File out = new File("c:/eclipse.ws/graphviz-java-api/out." + type);    // Windows
           gv.writeGraphToFile( gv.getGraph( gv.getDotSource(), type ), out );
       }
}

 

控制檯輸出

 

輸出生成的圖片

 


參考 : 

https://www.jianshu.com/p/6d9bbbbf38b1

https://www.cnblogs.com/fanghuiplus/p/10072937.html

 

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