當了研究生之後

老師最喜歡看的東西就是圖

其實我對畫圖的工具不是很了解

我也不知道有沒有更好的工具

這是lab同學小翔推薦給我的

因為可以實做出來所以就打出來分享

 

小翔推薦給我的這套工具就是──Graphviz

上網找這個工具其實蠻多人推薦的

因為這拿來畫"關係圖"非常方便

可是如果你想要畫"樹狀圖"你就會發現有些情形就不會很方便了

例如我的狀況是不同層卻是相同名稱的時候

Graphviz他會認為這兩個是相同的東西

以下就是關於我畫圖的時候所遇到狀況的一些解決辦法

 

1.安裝Graphviz

官方網站:http://www.graphviz.org/

因為我是用windows作業系統

所以以下用windows角度去解釋我的實作方法

 

2.Graphviz使用方法

目前為止我會兩種使用方法

第一種是直接使用

第二種是將Graphviz導入Java程式裡面畫圖

 

第一種的意思是只要安裝完就可以馬上用了

點gvedit.exe捷徑就會出現圖形化介面

graphviz-gui  

新增一個檔案之後就可以按Graph-->Setting

裡面可以選擇你要用哪一種工具畫(預設是dot)

跟輸出檔案的格式(預設是png)

還有輸出檔案的位置(預設是在C槽底下)

設定好後就可以畫圖,輸入Graphviz的格式程式碼後按上方那一個正在跑的人形就可以了

下方會出現Output Console顯示的狀態

如果成功就會跳出圖來 如果失敗就會顯示錯誤訊息

 

 

如果你只是要畫難度不高的關係圖,這個階段已經可以了

只要再去學習怎麼畫圖即可

 

 

第二種就是使用Java

通常會用這個方法目的就在於用java自動產生畫圖的指令(我就是這樣)

活用程度比第一種來得高

不過還是要先裝好GraphViz才能用

網路上有人提供已經寫好的java程式碼給別人下載

提供幾個出處

百度知識

GraphViz.java

Proba.java

總共有兩個java檔案(linux適用)

這個程式碼直接複製貼上後改GraphViz.java內的dot.exe路徑

更改如下

private static String TEMP_DIR = "c:/temp"; // Windows<---這個基本上不用改,只要記得打開這個設定就可以了

private static String DOT = "C:\\Program Files (x86)\\Graphviz2.30\\bin\\dot.exe"; // Windows<---路徑記得要打雙斜線

然後Proba.java這個檔案是給畫圖指令的程式

裡面也有output路徑、存檔類型等設定可以改

基本上只要Proba.java可以跑就表示可以畫圖了

 

3.Graphviz程式碼學習

網路上有一大堆Graphviz教學

我是看這一個--->http://www.openfoundry.org/tw/foss-programs/8820-graphviz-

基本上看這一個網頁就應該就會畫了

先練習它給的範例,很快就能熟能生巧

我另外還會看他給的pdf說明--->http://www.graphviz.org/doc/dotguide.pdf

 

4.一邊學Graphviz一邊畫圖

接下來......就是根據自己的狀況

用程式碼寫出自己要畫的圖

所以我的樹狀圖就是這樣畫出來的

我要畫的東西是windows系統的資料夾結構

我用的方法就是利用Graphviz的label功能

label這個功能平常沒有設定的話就是變數名稱本身

例如

A -> B -> C

但是如果加上設定

A [label = "a"]; 

B [label = "b"]; 

C [label = "c"];

效果就會跟

a -> b -> c

一樣 

舉這個例子是想要說明

第一點,變數跟label可以是兩個完全不同的名字 

然後再舉一個例子

如果我的label這樣設定 

A [label = "a"]; 

B [label = "c"]; 

C [label = "c"];

第二點,變數不能用相同名稱表示不同東西,但是label可以

這樣的效果就可以讓相同名字分開

變成它不能呈現的

a -> c -> c 

 

知道這兩點之後,我的問題就解決了

在面對不同東西卻相同名稱的時候

我們可以使用不同變數卻相同label的方法

剩下就是程式的問題了

我的方法是在程式裡面加上判斷層數的變數

用名稱+層數來當作變數

但是這樣還是會有問題

因為這樣如果遇到相同層數而且也相同名稱一樣是無法判斷

所以我就會再針對這部分修改變數名稱

 

這個就是畫完的樣子

out  

 

另外上面的教學網頁裡面有提到一個很好用的小技巧

就是使用引號

上面我通通沒有用引號

那是因為我們的內容都沒有空格或是特殊符號

 

但是我的資料有阿......orz|||

5e8767bd042b4180228122ca11e0154a  

 

 

以下用範例解釋關於空格與特殊符號

第三點,變數如果沒有使用引號,不能使用空格或是特殊符號,連數字開頭的中英夾雜都會判斷錯誤

這張Grapgviz產生的圖可以幫助我們了解許多性質

out  

裡面的 98 跟 98M12RKB 就是Graphviz判讀錯誤的範例

因為程式碼的原文是這個樣子的:

98m12rkb4 [label = "98M12RKB"];

 

其實我也不知道為什麼它會判讀錯誤

剛開始我不知道可以加引號(沒有好好讀教學文件Q_Q)

所以我會在前面加上英文字母,這樣就可以解決這個問題

a98m12rkb4 [label = "98M12RKB"];

 

但是其實加上引號就可以避免這種狀況了

"98m12rkb4" [label = "98M12RKB"];

 

我的意思是,如果你的內容並沒有這麼單純的時候,變數加上引號是一個減少麻煩的方法

 

第四點,label設定可以使用空格(甚至沒有值也可以)或是特殊符號,除了反斜線需要用雙斜線之外

我們是這樣寫是會通過的

"A" [label = ""];

"B" [label = "hi~"];

"C" [label = "You and I"];

但是如果我們想要打反斜線"\"的話就要打成"\\"才行

"D" [label = "\\"];

 

第五點,在Java中要產生Graphviz的指令,其中引號需要用\"表示,反斜線必須要用四條斜線表示

例如我們要寫出下面的指令  

"89a7c9ef4" [label = "89A0007C9EF"]; 

在Java裡面是這樣寫的

gv.addln("\"89a7c9ef4\" [label = \"89A0007C9EF\"];");

 

如果指令裡面有反斜線

A [label = "aa\\a"];

在Java裡面是這樣寫的

gv.addln("A [label = \"aa\\\\a\"];");

 

剛剛我們在第四點有講到在Graphviz中如果想要在圖中顯示一個\就必須要打\\才可以

但是在Java中如果要給Graphviz指令一個\也必須要打\\才可以

所以在Java中如果想要在圖中顯示一個\就必須打\\\\才可以

 

以上解釋完畢

列出上面那張圖的Java程式跟Graphviz指令對照一下

Java code

GraphViz gv = new GraphViz();
gv.addln(gv.start_graph());

gv.addln("\"B/#\" -> D;");
gv.addln("\"89a7c9ef4\" [label = \"89A0007C9EF\"];");
gv.addln("98m12rkb4 [label = \"98M12RKB\"];");    //沒有加上\"\"所以會錯誤

gv.addln("A [label = \"aa\\\\a\"];");

gv.addln(gv.end_graph());
System.out.println(gv.getDotSource());    //印出指令

 

印出來的Graphviz指令

digraph G {
"B/#" -> D;
"89a7c9ef4" [label = "89A0007C9EF"];
98m12rkb4 [label = "98M12RKB"];
A [label = "aa\\a"];
}

 

 

我花了一個禮拜才把圖畫出來

就是因為花了好多時間在這些符號上面Q_Q

因為我的變數沒有用引號

所以我還用了replaceAll()把這些東西都移除

改天寫一下關於Java的replaceAll()吧......

 

 

 

創作者介紹
創作者 daisuki's Box 的頭像
Hui

daisuki's Box

Hui 發表在 痞客邦 留言(0) 人氣( 3047 )