前言
我之前在幾篇文章新一代Ntopng網絡流量監控—可視化和架構分析、 數據可視化(一)思維利器 OmniGraffle 繪圖指南 |201601,都曾提到了力導圖,在關於 OmniGraffle 的文章結尾還吐槽了一番自動佈局按鈕的坑。在本文中我力求將這個坑填上。
OmniGraffle 生成自動佈局圖形的基礎是 Graphviz 引擎。Graphviz(Graph Visualization Software)是一個由AT&T實驗室啓動的開源工具包,能夠支持基於 DOT 腳本,文件擴展名通常是 .gv 或 .dot 的描述繪製圖形。DOT 是一種文本圖形描述語言,將生成的圖形轉換成多種輸出格式的命令行工具,其輸出格式包括PostScript,PDF,SVG,PNG,含註解的文本等。DOT 本身非常原始,提供了一種非常簡單的描述圖形的方法,同時意味着可以在命令行終端使用,或者被其它編程語言調用(Graphviz 就可以作爲一個庫使用)。這一點非常關鍵,基於 Graphviz 應用開發者不必掌握佈局的複雜算法,而是可以把精力放在業務方面,將最後的圖對象交給繪圖引擎來處理即可。
有趣的是 Graphviz(Mac 版) 和 OmniGraffle 都曾獲得蘋果設計獎 Apple Design Awards。
在深入掌握 Graphviz 及其相關衍生應用之前,我們有必要了解一些基礎理論 —— 圖論(Graph theory)。
一、背景知識:圖論(Graph theory)
- 柯尼斯堡七橋問題
東普魯士柯尼斯堡(今日俄羅斯加里寧格勒)市區跨普列戈利亞河兩岸,河中心有兩個小島。小島與河的兩岸有七條橋連接。在所有橋都只能走一遍的前提下,如何才能把這個地方所有的橋都走遍?
許多數學家都嘗試去尋找這類問題的解決方案,後來發展成爲了數學中的圖論。圖論史上第一篇重要文獻是萊昂哈德·歐拉在1736年發表在聖彼得堡科學院的《柯尼斯堡的七橋》。該論文證明了柯尼斯堡七橋問題中,符合條件的走法並不存在,同時提出和解決了一筆畫問題。過橋問題可以抽象簡化爲平面上的點與線組合,每一座橋視爲一條線,橋所連接的地區視爲點。從這個點出發的線有奇數條稱爲奇點,從這個點出發的線有偶數條稱爲偶點。任意一種河──橋圖能否全部走一次的判定法則: 如果存在兩個以上(不包括兩個)奇頂點,路線不存在;且有n個奇頂點的圖至少需要n/2筆畫出。
1、經典適用場景
- 路徑問題(柯尼斯堡七橋問題),最小生成樹問題,斯坦納樹
- 網絡流與匹配問題:最大流問題,最小割問題,最大流最小割定理,最小費用最大流問題,二分圖及任意圖上的最大匹配,帶權二分圖的最大權匹配
- 覆蓋問題:最大團、最大獨立集、最小覆蓋集、最小支配集
2、經典算法
- 戴克斯特拉算法(D.A)
- 克魯斯卡爾算法(K.A)
- 普里姆算法(P.A)
- 拓撲排序算法(TSA)
- 關鍵路徑算法(CPA)
- 廣度優先搜索算法(BFS)
- 深度優先搜索算法(DFS)
二、Graphviz 簡明指南
1、Graphviz 佈局器
總的來說,Graphviz 支持兩類圖:無向圖(graph,用“ - - ”表示節點之間)和 有向圖(digraph,用“ ->” 表示節點之間)。頂點和邊都具有各自的屬性,比如形狀,顏色,填充模式,字體,樣式等。主要的佈局器如下:
- dot: 默認佈局方式,主要用於有向圖;
- neato:基於 sprint model 模型,又稱force-based 或者 energy minimized;
- twopi:徑向佈局,放射狀;
- circo:圓環佈局;
- fdp:無向圖;
- dotty:一個用於可視化與修改圖形的圖形用戶界面程序;
- lefty:一個可以顯示 DOT 圖形的可編程控件,並允許用戶用鼠標在圖上執行操作。
2、Hello World!
$ brew install graphviz
$ dot -Tpng demo.dot -o demo.png
digraph demo{
label="兒茶酚胺合成代謝路徑";
酪氨酸 -> L多巴 -> 多巴胺 -> 去甲腎上腺素 -> 腎上腺素;
下丘腦 -> 多巴胺;
交感神經元 -> 去甲腎上腺素;
腎上腺髓質 -> 去甲腎上腺素,腎上腺素;
酪氨酸 [label="酪氨酸",color=green];
多巴胺 [label="多巴胺", color=red];
腎上腺素 [label="腎上腺素", color=red];
下丘腦 [shape=box];
交感神經元 [shape=box];
腎上腺髓質 [shape=box];
}
3、twopi 徑向佈局
## 缺省爲 dot 佈局
$ dot -Kcirco -Tpng demo.dot -o demo.png
三、應用場景
1、軟件工程領域
軟件工程領域的複雜系統數據結構分析和軟件包依賴關係管理。例如 Linux 內核內部結構非常複雜,從概念上就由五個主要的子系統構成:進程調度器模塊、內存管理模塊、虛擬文件系統、網絡接口模塊和進程間通信模塊。這些模塊之間通過函數調用和共享數據結構進行數據交互,在涉及內核版本、應用程序升級等場景中,弄清楚模塊之間的依賴關係非常重要。
lsmod 命令用於顯示已經加載到內核中的模塊的狀態信息,Used by表示依賴的內容。通過 lsmod 命令獲取依賴信息之後,簡單處理就可以轉化爲圖形,而且圖形生成的全過程可以由程序固化。
$ lsmod
Module Used by
vboxdrv vboxnetadp,vboxnetflt,vboxpci
nf_reject_ipv4 ipt_REJECT
ebtables ebtable_filter
ip6_tables ip6table_filter
ip6_udp_tunnel vxlan
udp_tunnel vxlan
xor btrfs
raid6_pq btrfs
nf_nat_masquerade_ipv4 ipt_MASQUERADE
xfrm_algo xfrm_user
nf_defrag_ipv4 nf_conntrack_ipv4
......
digraph kernel{
vboxdrv->vboxnetadp,vboxnetflt,vboxpci;
nf_reject_ipv4->ipt_REJECT;
ebtables->ebtable_filter;
ip6_tables->ip6table_filter;
ip6_udp_tunnel->vxlan;
udp_tunnel->vxlan;
xor->btrfs;
raid6_pq->btrfs;
nf_nat_masquerade_ipv4->ipt_MASQUERADE;
xfrm_algo->xfrm_user;
nf_defrag_ipv4->nf_conntrack_ipv4;
......
}
基於 Graphviz 的一個開源項目 PlantUML 支持快速繪製各類 UML 圖形:時序圖、用例圖、類圖、活動圖、組件圖、狀態圖、對象圖等。
@startuml
scale 600 width
[*] -> State1
State1 --> State2 : Succeeded
State1 --> [*] : Aborted
State2 --> State3 : Succeeded
State2 --> [*] : Aborted
state State3 {
state "Accumulate Enough Data\nLong State Name" as long1
long1 : Just a test
[*] --> long1
long1 --> long1 : New Data
long1 --> ProcessData : Enough Data
}
State3 --> State3 : Failed
State3 --> [*] : Succeeded / Save Result
State3 --> [*] : Aborted
@enduml
2、通信工程領域
- nwdiag 是一個基於 Python 的、支持 Dot 腳本生成網絡圖的庫
- 結合 GIS 信息追蹤網絡路由
pip install nwdiag
nwdiag simple.diag
nwdiag -Tsvg simple.diag
nwdiag {
network dmz {
address = "210.x.x.x/24"
web01 [address = "210.x.x.1"];
web02 [address = "210.x.x.2"];
}
network internal {
address = "172.x.x.x/24";
web01 [address = "172.x.x.1"];
web02 [address = "172.x.x.2"];
db01;
db02;
}
}
[root@li1437-101 ~]# traceroute www.google.com
traceroute to www.google.com (216.58.216.36), 30 hops max, 60 byte packets
1 23.92.24.2 (23.92.24.2) 0.704 ms 0.736 ms 23.92.24.3 (23.92.24.3) 0.575 ms
2 173.230.159.16 (173.230.159.16) 0.910 ms 173.230.159.14 (173.230.159.14) 2.265 ms
173.230.159.0 (173.230.159.0) 0.731 ms
3 as15169.sfmix.org (206.197.187.50) 4.039 ms eqixsj-google-gige.google.com (206.223.116.21) 0.718 ms
as15169.sfmix.org (206.197.187.50) 3.944 ms
4 108.170.242.227 (108.170.242.227) 4.902 ms
108.170.242.226 (108.170.242.226) 3.003 ms
108.170.243.2 (108.170.243.2) 3.064 ms
5 216.239.47.37 (216.239.47.37) 4.836 ms 64.233.174.91 (64.233.174.91) 1.476 ms 1.447 ms
6 216.239.54.22 (216.239.54.22) 12.464 ms 29.292 ms 64.233.174.204 (64.233.174.204) 9.032 ms
7 209.85.245.172 (209.85.245.172) 10.633 ms
108.170.230.130 (108.170.230.130) 20.010 ms
108.170.230.124 (108.170.230.124) 8.988 ms
10 lax02s22-in-f4.1e100.net (216.58.216.36) 10.358 ms 10.383 ms 10.301 ms
digraph {
label="Google Trace Sample";
"23.92.24.2" [label="23.92.24.2 \n Fremont,California \n location:37.5670,-121.9829"] ;
as15169 [label="as15169.sfmix.org \n San Francisco \n Metropolitan Internet Exchange"];
"108.170.242.227" [label="108.170.242.227 \n California \n location:37.4192,-122.0574"];
lax02s22 [label="ax02s22-in-f4.1e100.net \n Los_Angeles,California \n location:46.07305,-100.546"];
"23.92.24.2" -> as15169 -> "108.170.242.227" -> lax02s22;
}
3、社會工程領域
- 決策樹(Decision Tree):人羣鄙視鏈
- 複雜人物關係鏈分析(《紅樓夢》、《權力的遊戲》)
注意: 如果需要使用分組(Group)特性,子圖的名稱必須以“cluster”開頭,否則無法識別
digraph family {
label ="《紅樓夢》人物關係譜·主要角色";
subgraph cluster_皇族{
label ="皇族";
bgcolor="mintcream";
node [ color="lightyellow", style="filled"];
北靜王 [label = "北靜王",shape="Mrecord"];
義忠順王 [label = "義忠順王",shape="Mrecord"];
賈元春 [label = "賈元春(長女)\n 鳳藻宮尚書·賢德妃",shape="Mrecord"];
}
subgraph cluster_寧國公{
label ="寧國公(西府)";
bgcolor="mintcream";
node [ color="green", style="filled"];
賈演 [label = "賈演 \n 寧國公"];
賈代化[label = "賈代化 \n 爵位:一等神威將軍 \n 職務(武官):京營節度使",shape="Mrecord"];
賈演 -> 賈代化[label = "子"];
......
}
......
}
擴展閱讀:數據可視化
- 數據可視化(一)思維利器 OmniGraffle 繪圖指南
- 數據可視化(二)跑步應用Nike+ Running 和 Garmin Mobile 評測
- 數據可視化(三)基於 Graphviz 實現程序化繪圖
- 數據可視化(四)開源地理信息技術簡史(Geographic Information System
- Preview:數據可視化(五)可視化數據圖表製作方法
- 數據可視化(六)常見的數據可視化儀表盤(DashBoard)
- 數據可視化(七)Graphite 體系結構詳解
更多精彩內容掃碼關注公衆號:RiboseYim's Blog:http://riboseyim.github.io/2017/09/15/Visualization-Graphviz/