我以前在幾篇文章新一代Ntopng網絡流量監控—可視化和架構分析、 數據可視化(一)思惟利器 OmniGraffle 繪圖指南 |201601,都曾提到了力導圖,在關於 OmniGraffle 的文章結尾還吐槽了一番自動佈局按鈕的坑。在本文中我力求將這個坑填上。node
OmniGraffle 生成自動佈局圖形的基礎是 Graphviz 引擎。Graphviz(Graph Visualization Software)是一個由AT&T實驗室啓動的開源工具包,可以支持基於 DOT 腳本,文件擴展名一般是 .gv 或 .dot 的描述繪製圖形。DOT 是一種文本圖形描述語言,將生成的圖形轉換成多種輸出格式的命令行工具,其輸出格式包括PostScript,PDF,SVG,PNG,含註解的文本等。DOT 自己很是原始,提供了一種很是簡單的描述圖形的方法,同時意味着能夠在命令行終端使用,或者被其它編程語言調用(Graphviz 就能夠做爲一個庫使用)。這一點很是關鍵,基於 Graphviz 應用開發者沒必要掌握佈局的複雜算法,而是能夠把精力放在業務方面,將最後的圖對象交給繪圖引擎來處理便可。python
有趣的是 Graphviz(Mac 版) 和 OmniGraffle 都曾得到蘋果設計獎 Apple Design Awards。git
在深刻掌握 Graphviz 及其相關衍生應用以前,咱們有必要了解一些基礎理論 —— 圖論(Graph theory)。github
東普魯士柯尼斯堡(今日俄羅斯加里寧格勒)市區跨普列戈利亞河兩岸,河中心有兩個小島。小島與河的兩岸有七條橋鏈接。在全部橋都只能走一遍的前提下,如何才能把這個地方全部的橋都走遍?web
許多數學家都嘗試去尋找這類問題的解決方案,後來發展成爲了數學中的圖論。圖論史上第一篇重要文獻是萊昂哈德·歐拉在1736年發表在聖彼得堡科學院的《柯尼斯堡的七橋》。該論文證實了柯尼斯堡七橋問題中,符合條件的走法並不存在,同時提出和解決了一筆畫問題。過橋問題能夠抽象簡化爲平面上的點與線組合,每一座橋視爲一條線,橋所鏈接的地區視爲點。從這個點出發的線有奇數條稱爲奇點,從這個點出發的線有偶數條稱爲偶點。任意一種河──橋圖可否所有走一次的斷定法則: 若是存在兩個以上(不包括兩個)奇頂點,路線不存在;且有n個奇頂點的圖至少須要n/2筆畫出。算法
總的來講,Graphviz 支持兩類圖:無向圖(graph,用「 - - 」表示節點之間)和 有向圖(digraph,用「 ->」 表示節點之間)。頂點和邊都具備各自的屬性,好比形狀,顏色,填充模式,字體,樣式等。主要的佈局器以下:編程
$ 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]; }
## 缺省爲 dot 佈局 $ dot -Kcirco -Tpng demo.dot -o demo.png
軟件工程領域的複雜系統數據結構分析和軟件包依賴關係管理。例如 Linux 內核內部結構很是複雜,從概念上就由五個主要的子系統構成:進程調度器模塊、內存管理模塊、虛擬文件系統、網絡接口模塊和進程間通訊模塊。這些模塊之間經過函數調用和共享數據結構進行數據交互,在涉及內核版本、應用程序升級等場景中,弄清楚模塊之間的依賴關係很是重要。bash
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
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; }
注意: 若是須要使用分組(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 = "子"]; ...... } ...... }
更多精彩內容掃碼關注公衆號:RiboseYim's Blog:http://riboseyim.github.io/2017/09/15/Visualization-Graphviz/