使用Graphviz下的dot工具繪制圖像
來自: http://my.oschina.net/Tsybius2014/blog/617963
一、關于Graphviz下的dot工具
Graphviz是一個畫圖軟件,其中的dot工具可以用于繪制流程圖。dot工具可以根據dot語言代碼生成GIF、PNG、SVG、PDF、PostScript格式的圖片文件。
通過dot工具,可以繪制出如下面這樣復雜的流程圖(摘自dot工具官方幫助手冊):
dot工具畫圖通過以下四個步驟來完成:
第一步:通過翻轉一些循環邊的內部方向,打破在輸入圖中出現的環路。
第二步:將節點分配給不同的等級(rank)和層次(level),自頂向下繪圖,等級決定了縱軸的位置。跨越了多個等級的邊,會被拆分成有多個虛擬節點相連接的鏈條。
第三步:根據節點等級(rank)為節點排序以避免節點的交叉。
第四步:在保持邊長盡量短的情況下,設置節點的橫坐標,同時繪出邊的樣條曲線。
dot工具的繪圖方法,其官網 www.graphviz.org 上面有著詳細地介紹,這里不再做詳盡說明。
二、使用dot工具生成圖片
安裝Graphviz后,新建一個文件夾,建立一個bat文件取名【GenerateJpgsBatch.bat】,代碼如下:
:: 在這里設置調用文件路徑 set dotPath=D:\Graphviz2.38 set sourcePath=C:\Users\Tsybius\Desktop\graphviz_study rem 測試文件XXX %dotPath%\bin\dot.exe -Tjpg %sourcePath%\XXX.dot -o %sourcePath%\XXX.jpg pause
其中dotPath為dot代碼文件地址,sourcePath為生成后文件的地址。
上面的代碼就是用dot.exe,將一個名為XXX.dot的文件,生成為圖片XXX.jpg。
使用dot程序生成帶有漢字信息的圖片,需要注意兩點,否則生成的圖片中漢字會被顯示為亂碼:
1、文件應使用UTF-8編碼保存,而不是Windows默認的ANSI編碼
2、字體應指定為支持漢字的字體,如宋體為SimSun
三、實例一:最簡單的dot圖-高速公路節點圖
下圖是一張高速公路重要節點圖。這張圖是一張較為簡單dot圖,只有節點之間的簡單指向關系。
文件【expressway.dot】內代碼如下:
digraph { edge[fontname="SimSun",fontcolor=red]; node[fontname="SimSun",size="20,20"]; 北京[shape=doublecircle]; 湘潭[shape=plaintext] //高速公路節點關系 北京->石家莊->鄭州->武漢->長沙->廣州[label=京港澳高速,color=red]; 北京->天津->沈陽->長春->哈爾濱[label=京哈高速,color=lawngreen]; 北京->呼和浩特->銀川->蘭州->西寧->拉薩[label=京藏高速,color=purple]; 鄭州->西安->蘭州->烏魯木齊[label=連霍高速,color=blue] 上海->杭州->南昌->湘潭->貴陽->昆明[label=滬昆高速,color=orange]; 福州->南昌->武漢->西安->銀川[label=福銀高速,color=brown]; 湘潭->長沙[style=dotted]; }
生成圖片如下:
四、實例二:類HTML語言編寫復雜的節點-華容道
dot也支持解釋一些類HTML的代碼繪制近似于復雜表格的數據。
下圖是由一個單一節點組成的,這個節點被劃分成很多區域,被繪制成華容道最經典的圖形-橫刀立馬
文件【huarongpass.dot】內代碼如下:
digraph { huarongpass [shape=none, margin=0, fontname="SimSun" label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR><TD>張<BR/>飛</TD><TD COLSPAN="2">曹操</TD><TD>馬<BR/>超</TD></TR> <TR> <TD ROWSPAN="2">趙<BR/>云</TD> <TD COLSPAN="2">關羽</TD> <TD ROWSPAN="2">黃<BR/>忠</TD> </TR> <TR><TD>卒</TD><TD>卒</TD></TR> <TR><TD>卒</TD><TD COLSPAN="2"></TD><TD>卒</TD></TR> </TABLE> >]; }
生成圖片如下:
五、實例三:為圖片添加層次關系-世系樹
世系樹要求將同一個輩分的人放在同一個層次,下面這個例子描繪了漢宣帝從高祖到其自身的世系樹,它設置了5個rank。
文件【familytree.dot】內代碼如下:
digraph { ranksep=2.75; size="15,15"; { edge [fontname="SimSun", fontcolor=red]; //時間線 node [shape=plaintext, fontname="SimSun", fontsize=60]; "高祖輩"->"曾祖輩"->"祖父輩"->"父輩"->"本人"; } { rank = same; }; node [shape=box, fontname="SimSun", fontsize=60]; { rank = same; "高祖輩"; "孝景皇帝劉啟"; "孝景皇后王氏"; "外高祖父衛父"; "外高祖母衛媼"; } { rank = same; "曾祖輩"; "曾祖父世宗武皇帝劉徹"; "曾祖母思皇后衛子夫"; "外曾祖母貞君"; } { rank = same; "祖父輩"; "祖父戾太子劉據"; "祖母戾后史氏"; "外祖父思成侯王乃始"; "外祖母博平君思成夫人王媼"; } { rank = same; "父輩"; "父悼皇考劉進"; "母悼后王翁須" } { rank = same; "本人"; "中宗孝宣皇帝劉詢" } {"孝景皇帝劉啟", "孝景皇后王氏"}->"曾祖父世宗武皇帝劉徹"; {"外高祖父衛父", "外高祖母衛媼"}->"曾祖母思皇后衛子夫"; {"曾祖父世宗武皇帝劉徹", "曾祖母思皇后衛子夫"}->"祖父戾太子劉據"; "外曾祖母貞君"->"祖母戾后史氏" {"祖父戾太子劉據", "祖母戾后史氏"}->"父悼皇考劉進"; {"外祖父思成侯王乃始", "外祖母博平君思成夫人王媼"}->"母悼后王翁須"; {"父悼皇考劉進", "母悼后王翁須"}->"中宗孝宣皇帝劉詢"; }
生成圖片如下:
六、實例四:通過創建子圖對大圖中的節點進行分組-三國君主傳承順序
dot支持可以通過創建子圖(subgraph)對節點進行分區,如下圖總結三國時代魏蜀吳三國君主傳承順序,將魏、蜀、吳三國的君主分到了各自的區域內。
文件【threekingdoms.dot】內代碼如下:
digraph { edge[fontname="SimSun",fontcolor=red]; node[fontname="SimSun",size="20,20"]; subgraph cluster0 { color=red; "曹操(0)","曹丕(1)","曹叡(2)","曹髦(3)","曹芳(4)","曹奐(5)"[shape=box]; fontname="SimSun" label="#1 魏國"; "曹操(0)"->{"曹丕(1)", "曹彰", "曹宇"}; "曹丕(1)"->{"曹叡(2)", "曹霖"}; "曹霖"->"曹髦(3)" "曹彰"->"曹楷"->"曹芳(4)" "曹宇"->"曹奐(5)" } subgraph cluster1 { color=blue; "劉備(0)","劉禪(1)"[shape=box]; fontname="SimSun" label="#2 蜀國"; "劉備(0)"->"劉禪(1)" } subgraph cluster2 { color=purple; "孫堅(0)","孫策(1)","孫權(2)","孫亮(3)","孫休(4)","孫和(5)","孫皓(6)"[shape=box]; fontname="SimSun" label="#3 吳國"; "孫堅(0)"->{"孫策(1)","孫權(2)"}; "孫權(2)"->{"孫和(5)","孫休(4)","孫亮(3)"}; "孫和(5)"->"孫皓(6)"; } "初代君主"->{"曹操(0)","劉備(0)","孫堅(0)"}[style=dotted]; {"曹奐(5)","劉禪(1)","孫皓(6)"}->"末代君主"[style=dotted]; }
生成圖片如下:
END