Ubuntu 14.04 64bit上玩转graphviz绘图工具
簡介
關于Graphviz: Graphviz(英文:Graph Visualization Software的縮寫)是一個由AT&T實驗室啟動的開源工具包,用于繪制DOT語言腳本描述的圖形。它也提供了供其它軟件使用的庫。Graphviz是一個自由軟件,其授權為Eclipse Public License。其Mac版本曾經獲得2004年的蘋果設計獎。
Graphviz是大名鼎鼎的貝爾實驗室的幾位牛人開發的一個畫圖工具。它的理念和一般的“所見即所得”的畫圖工具不一樣,是“所想即所得”。Graphviz提供了dot語言來編寫繪圖腳本。dot的語言專門用來定義關系。我們必須先在某個文件中寫上代碼,最后調用命令行生成。沒有找到可邊寫邊改的集成環境。
關于dot的具體語法參看官方文檔,這里就不多說。這里僅用來入門。
http://www.graphviz.org/
另外也有專門渲染DOT腳本的瀏覽器xdo,直接在窗口渲染,不需要生成圖像文件,強烈推薦。
很多圖都比較適合用DOT來定義,比如流程圖,組織關系圖,類圖,狀態轉換圖等等。
在剛接觸DOT不到3天的時間里,我就分別在代碼性能優化,協議棧狀態機定義兩件事情用到了DOT,感覺非常方便。
性能優化:gprof可以對一個程序運行時進行profiling,生成報告,包括函數調用關系,每個函數被調用的次數,花費的時間。但這個報告是文本的,不夠直觀。可以通過一個gprof2dot.py腳本,把gprof的輸出翻譯成一個DOT文件,然后再用Graphviz轉成圖片或者直接用xdot來查看。
安裝graphviz?????sudo apt-get install graphviz graphviz-doc 這樣會安裝dot語言的執行文件,執行文件路徑在 /usr/bin/dot 繪圖方法 先根據業務需要編寫dot文件,參見下面的示例部分,然后編譯運行。輸出格式可以根據自己的需要來靈活選擇 例如test.dot, 產生圖片: dot -Tpng test.dot -o test.png
dot -Tsvg test.dot -o test.svg dot test.dot -Tpdf -o test.pdf
典型示例(更多例子可以參見官方文檔)
1.Fancy Graph
digraph G { edge[fontname="FangSong"];node[peripheries=2, fontname="FangSong"];size="16, 16";main[shape="box"];main[label="從這里開始"]main->parse[weight=8]parse->execute;main->init[style=dotted]; main->cleanup;execute->{make_string; printf;}edge[color=red];init->make_string[label="1000次的感動"];main->printf[label="make a \n string"];node[shape=box,style=filled,color=".7 .3 1.0"];execute->compare;
}
效果圖
2.Polygon Graph
digraph G{size = "4, 4"a->b->c;b->d;a[shape=polygon, sides=5, peripheries=3, color=lightblue, style=filled];c[shape=polygon, sides=4, skew=0.4, label="hello world"];d[shape=invtriangle]; e[shape=polygon, side=4, distortion=.7];}
效果圖
3.list Graph
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;
}
4.hash table Graph
digraph G { nodesep=.05;rankdir=LR;node[shape=record, width=.1, height=.1];node0[label="<f0> |<f1> |<f2> |<f3> |<f4> |<f5> |<f6> |", height=2.5]node[width=1.5];node1[label="{<n> n14 | 719 |<p>}"];node2[label="{<n> a1 | 719 |<p>}"];node3[label="{<n> i9 | 512 |<p>}"];node4[label="{<n> e5 | 632 |<p>}"];node5[label="{<n> t20 | 959 |<p>}"];node6[label="{<n> o15 | 794 |<p>}"];node7[label="{<n> s19 | 659 |<p>}"];node0:f0->node1:n;node0:f1->node2:n;node0:f2->node3:n;node0:f5->node4:n;node0:f6->node5:n;node2:p->node6:n;node4:p->node7:n;
}
5.Process Graph
digraph G { subgraph cluster0 {node[style=filled, color=white];style=filled;color=lightgrey;a0->a1->a2->a3;label="process #1";} subgraph cluster1 {node[style=filled];color=blue;b0->b1->b2->b3;label="process #2";} start->a0;start->b0;a1->b3;b2->a3;a3->end;b3->end;start[shape=Mdiamond];end[shape=Msquare];
}
6.directed Graph
digraph G { {a b c} -> {d e f g}
}
7.化學分子式
graph s{C_0 -- H_0;C_0 -- H_1;C_0 -- H_2;C_0 -- C_1;C_1 -- H_3;C_1 -- H_4;C_1 -- H_5;
}
8.函數調用關系圖
digraph s {node [shape=ellipse, style=filled, color="#40e0d0"];edge [color="#606060", penwidth=3];main [color=green];main -> init[color=blue, label="hello, I'm \llable of edge"];main -> mainloop;main -> exit;init -> a_init;init -> b_init;init -> c_init;mainloop -> select;
}
這個是有向圖(directional graph), 腳本的第一個詞需要換成"digraph"。常用的屬性有color, style, shape, penwidth, label等。label中 \r, \l, \n 都表示換行,但對齊方式分別是 右對齊,左對齊,居中 。
9.ATS中插件collapsed_connection的流程圖,一個更復雜的例子
dot -Tpng collapsed_connection.dot -o collapsed_connection.png
digraph collapsed_connection { accept -> TS_HTTP_POST_REMAP_HOOK;TS_HTTP_POST_REMAP_HOOK -> "check request method (and header)";"check request method (and header)" -> "get CacheUrl hash_key using MurmurHash3" [label = "GET request (required_header present)"];"check request method (and header)" -> "pass request" [label = "others"];"get CacheUrl hash_key using MurmurHash3" -> "check hash_key from hashTable";"check hash_key from hashTable" -> "lock URL in hashTable" [label = "not found"];"check hash_key from hashTable" -> "pass request" [label = "found, but marked pass"];"check hash_key from hashTable" -> "check hash_key from hashTable" [label = "locked or unable to get mutex, wait insert_lock_retry_time"];"lock URL in hashTable" -> TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK;TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK -> "remove URL from hashTable(1)" [label = "hit_fresh or skipped"];TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK -> "request origin server" [label = "miss or stale"];"request origin server" -> TS_HTTP_READ_RESPONSE_HDR_HOOK;TS_HTTP_READ_RESPONSE_HDR_HOOK -> "remove URL from hashTable(1)" [label = "not 200/OK response"];TS_HTTP_READ_RESPONSE_HDR_HOOK -> "check read_while_writer config";"check read_while_writer config" -> "remove URL from hashTable(1)" [label = "enabled"];"check read_while_writer config" -> TS_HTTP_TXN_CLOSE_HOOK [label = "disabled"];TS_HTTP_READ_RESPONSE_HDR_HOOK -> "mark pass in hashTable" [label = "non-cacheable"];"remove URL from hashTable(1)" -> TS_HTTP_TXN_CLOSE_HOOK;"mark pass in hashTable" -> TS_HTTP_TXN_CLOSE_HOOK;"pass request" -> TS_HTTP_TXN_CLOSE_HOOK;TS_HTTP_TXN_CLOSE_HOOK -> "remove URL from hashTable(2)";TS_HTTP_TXN_CLOSE_HOOK -> "check keep_pass_record_time" [label = "non-cacheable"];"check keep_pass_record_time" -> "add into KeepPassList" [label = "> 0"];"check keep_pass_record_time" -> "remove URL from hashTable(2)" [label = "= 0"];"add into KeepPassList" -> "transaction close";"remove URL from hashTable(2)" -> "transaction close";"transaction close" -> accept; TS_HTTP_POST_REMAP_HOOK [shape = box];TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK[shape = box];TS_HTTP_READ_RESPONSE_HDR_HOOK [shape = box];TS_HTTP_TXN_CLOSE_HOOK [shape = box];"check request method (and header)" [shape = diamond];"check hash_key from hashTable" [shape = diamond];"check read_while_writer config" [shape = diamond];"check keep_pass_record_time" [shape = diamond];
}
10.使用Makefile文件來批量執行
在閱讀源碼過程中,如果我們編寫了大量的dot文件,需要處理和展示,如果逐個編譯和操作,未免太為繁瑣,我們這里推薦使用一個Makefile來將所有的dot文件都包括過來。
生成圖像命令
make png
清除圖像命令
make clean
下面是Makefile文件
SVG_FILES = \HttpProxyServer-callgraph.svg \HttpSM-callgraph.svg \HttpTransact-callgraph.svg \HttpTransact-state-diagram.svg \HttpTransactAndSM-callgraph.svgPNG_FILES = $(SVG_FILES:.svg=.png)PDF_FILES = $(SVG_FILES:.svg=.pdf)svg: ${SVG_FILES}png: ${PNG_FILES}pdf: ${PDF_FILES}clean:rm -f ${SVG_FILES} ${PNG_FILES} ${PDF_FILES}.SUFFIXES: .dot .svg .png .pdf.dot.svg:dot -Tsvg $< -o $@.dot.png:dot -Tpng $< -o $@.dot.pdf:dot -Tpdf $< -o $@
截圖如下
注意事項
1.中文亂碼
graphviz默認情況下對中文支持不好,如果代碼中有中文,則必須使用UTF-8的格式保存文件,并且在代碼中指定字體。
進一步深究可以查看官方文檔
http://www.graphviz.org/Documentation.php
下面給出幾個頗具震撼力的效果圖,來自官網文檔
總結
以上是生活随笔為你收集整理的Ubuntu 14.04 64bit上玩转graphviz绘图工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu 14.04 64位升级搜狗
- 下一篇: Ubuntu 14.04 64bit上安