當了研究生之後
老師最喜歡看的東西就是圖
其實我對畫圖的工具不是很了解
我也不知道有沒有更好的工具
這是lab同學小翔推薦給我的
因為可以實做出來所以就打出來分享
小翔推薦給我的這套工具就是──Graphviz
上網找這個工具其實蠻多人推薦的
因為這拿來畫"關係圖"非常方便
可是如果你想要畫"樹狀圖"你就會發現有些情形就不會很方便了
例如我的狀況是不同層卻是相同名稱的時候
Graphviz他會認為這兩個是相同的東西
以下就是關於我畫圖的時候所遇到狀況的一些解決辦法
1.安裝Graphviz
因為我是用windows作業系統
所以以下用windows角度去解釋我的實作方法
2.Graphviz使用方法
目前為止我會兩種使用方法
第一種是直接使用
第二種是將Graphviz導入Java程式裡面畫圖
第一種的意思是只要安裝完就可以馬上用了
點gvedit.exe捷徑就會出現圖形化介面
新增一個檔案之後就可以按Graph-->Setting
裡面可以選擇你要用哪一種工具畫(預設是dot)
跟輸出檔案的格式(預設是png)
還有輸出檔案的位置(預設是在C槽底下)
設定好後就可以畫圖,輸入Graphviz的格式程式碼後按上方那一個正在跑的人形就可以了
下方會出現Output Console顯示的狀態
如果成功就會跳出圖來 如果失敗就會顯示錯誤訊息
如果你只是要畫難度不高的關係圖,這個階段已經可以了
只要再去學習怎麼畫圖即可
第二種就是使用Java
通常會用這個方法目的就在於用java自動產生畫圖的指令(我就是這樣)
活用程度比第一種來得高
不過還是要先裝好GraphViz才能用
網路上有人提供已經寫好的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的方法
剩下就是程式的問題了
我的方法是在程式裡面加上判斷層數的變數
用名稱+層數來當作變數
但是這樣還是會有問題
因為這樣如果遇到相同層數而且也相同名稱一樣是無法判斷
所以我就會再針對這部分修改變數名稱
這個就是畫完的樣子
另外上面的教學網頁裡面有提到一個很好用的小技巧
就是使用引號
上面我通通沒有用引號
那是因為我們的內容都沒有空格或是特殊符號
但是我的資料有阿......orz|||
以下用範例解釋關於空格與特殊符號
第三點,變數如果沒有使用引號,不能使用空格或是特殊符號,連數字開頭的中英夾雜都會判斷錯誤
這張Grapgviz產生的圖可以幫助我們了解許多性質
裡面的 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()吧......

請先 登入 以發表留言。