網頁標題: Graphviz: 使用文字指令畫圖的工具

Warning: fopen(/home/crazy/www/cmsb/bcj/has_read.php): failed to open stream: Permission denied in /home/crazy/www/compose/reading.php on line 2070

Warning: fputs() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2072

Warning: fclose() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2073
 
﹗﹗﹗觀看留言:此文章已經有3則留言 ﹗﹗﹗


 Graphviz 是一個可以把文字指令變成簡單圖像的工具,我目前為止不能說徹底了解其能力範圍,但是它替我畫了很多流程圖 (flow chart), 讓我得以給明眼人迅速有效率的途徑理解我的想法。

 注意,它並不能幫全盲者「閱讀」圖形,只能讓全盲打出給人看的圖,它生成的圖中原件的位置往往跟全盲者心目中想像的不一樣,卻是我們想像中的圖的同構。至於要如何知道輸出的圖片外觀上是否給明眼人「一目了然」的感覺?這就要請人代看了,用 Graphviz 跟不用的差別在於,全盲者可以主動修改圖形內容,不是等著明眼的助理來畫。

 它的輸入「文字指令」就是「DOT 語言」,這不是一般的程式語言,而是針對描述圖形設計的。先在此釐清一個觀念,這裡的圖形 (graph) 是計算機科學裡的圖形,不是隨手亂畫或拍照所得到的圖 (picture).

 「圖形」裡由點 (node) 與邊 (edge) 組成,兩個點中間有邊相連。高中以下數學遇到的多邊形就是一種圖形,但是平面或空間中的函數圖形並不是這裡的「圖形」。圖上的點通常表示人、地或物,比如在捷運站會看到整個市區捷運路線簡圖,上面各點表示每個站,在網際網路連結的圖中每個點代表連上網路的電腦。圖上的邊通常展現點與點之間的關係,如捷運地圖中兩站之間的連線表示軌道的鋪設,網路圖上的邊表示兩台電腦正在通訊。

 剛才的例子中,地圖上的邊只要表示兩地之間有路可達就夠了,但是網路的圖上我們通常又會想知道這個連線是誰發起的?當我點了某個超連結,瀏覽器就會發起連線到該伺服器索取網頁資料。於是網路的圖上我們會把每個邊畫成箭頭的樣子,然後定義說箭頭尾端的電腦發出請求到箭頭前面的伺服器。地圖上的邊沒有標示方向,稱為「無向圖」 (undirected graph), 說圖形一般指的是此類,網路的圖上邊有標示方向,稱為「有向圖」 (directed graph). DOT 語言可以畫出以上這兩類的圖形。


 以下是我所使用的 Graphviz 操作方法:

  1. 點此下載,頁面上的 graphviz-2.38.msi 是安裝檔,graphviz-2.38.zip 是免安裝版本。
  2. 把 DOT 語法編輯好存成純文字檔,副檔名沒有限制,不過為了與一般 .txt 區別,我喜歡改副檔名為 .gv
  3. 將下面的一行指令存成 .bat 檔:
    "C:\Program Files (x86)\Graphviz2.38\bin\dot" -T jpg test.gv 1>gviz.jpg 2>error.txt
    指令中的路徑指定的是 Graphviz 裡的 dot.exe, 指令裡的路徑是參考用的。test.gv 是剛才編輯的 DOT 語法檔案,也可以是檔案的絕對或相對路徑。
  4. 執行 .bat 檔,將產生 gviz.jpg, 可以用任何圖片檢視的軟體給明眼人看。它也支援其他圖片格式,比如要改成輸出 png 圖片則將 -T 後的 jpg 及 1> 後的輸出檔副檔名都改成 png 即可。
  5. 另外會產生 error.txt, 當語法有錯而 gviz.jpg 為空時,這裡面就會記錄 dot.exe 回報的錯誤原因。


 這是一個無向圖的例子:

 一開始的 /**/ 夾著一行註解,它跟許多程式語言一樣都接受 /*...*/ 的多行註解方式,也可以用 // 的單行註解方式。

 graph 表示以下描述的是一個無向圖,後面可空白再接這個圖的名字,也可以不寫名字。圖上的點與邊放在左大括號到右大括號之間。

 大括號間有多個敘述,可以用換行或分號區隔,如果用換行區隔敘述的劃分號就不一定需要,不過大家通常為了美觀或程式語言寫習慣了,都匯換行又加上分號。序數可用來設定點、邊以及整張圖的內容。

 最基本的敘述如範例所展示,用來描述點之間的邊,字母代表點的名字,兩個連字號或減號代表邊。一個邊應該由兩點和 -- 組成,這樣寫成一行最明顯,不過 DOT 語言允許把多個連續的邊一次寫完。從語法可知 b 跟其他三點都有邊相連,在做圖者心中它應該是中心點或樹根。

 產生的圖上也會看到四個圓圈,分別標上 a 到 d, b 跟另外三點有連線但不一定是直線。本文不會描述產生圖片的實際外觀,這個部份留給讀者自己執行後跟身邊的明眼朋友溝通,趁機建立一套你與明眼朋友間共同看待這張圖的方式。


 下面是一個有向圖的範例:

 範例中的點,名字都跟無向圖範例相同,這二個範例的差別在兩個地方。一為關鍵字 graph 變成 digraph, 二為點之間有連線的符號從 -- 變成 ->.

 digraph 可以當成英文 directed graph 的簡寫,被它宣告的圖,邊必須用 -> 標明,這個符號外觀有如箭頭指向右方,產生的圖上邊的箭頭也將指向寫在右邊的點。

 想像做圖者的思維,假設這是一張流程圖,表示任務 a 先開始,完成後進行任務 b, 接下來才可以進行 c 跟 d, 不過因為 b 是一起連到兩點的,那 c 跟 d 應該可以同時進行。


 接下來淺談圖上的屬性 (attribute). 屬性可以針對很多地方,如整張圖、圖上所有點或所有邊、圖上某個點或某個邊,子圖 (subgraph) 與叢集 (cluster) 也可以被賦予屬性,不過這二者不在本文範圍內。屬性主要控制顯示的外觀,比如點或邊上的文字、顏色、形狀等,或者圖上點的排列方式。

 下例簡短展示數個屬性用法:

 許多 name=value 寫法的部份就是「屬性」。第二行 rankdir="LR" 就是把這張圖的 rankdir 屬性設為 "LR", 第三行 node [shape="rectangle"] 將圖上所有點的 shape 屬性設為 "rectangle", 四五行設置 A, B 兩點的 label 屬性,第六行設置 A 到 B 邊的 label 及 style 屬性。

 每個屬性都有其使用場合及值的限制,詳細內容請參閱 Graphviz 官方網頁的說明,下面只解析上例所用到的屬性。「值」的部份也可不用引號圍住,不過習慣上多數會加引號。

 rankdir 設定圖上的點擺放順序,"LR" 表示順序為「由左往右」,預設是「由上網下」的。「由左往右」表示之後的 A 跟 B 相對位置會是左右放置,A -> B 邊也隨之成為左右方向。要是在設置 rankdir="LR" 的情況下想要 A, B 兩點相對位置變成上下,還可用 {rank="same"; A, B} 要求它們被擺在相同順序,以左右分順序的話相同順序就是上下的區別了。

 在此 node 是一個關鍵字,不像之後的 A, B 指的都是某個點。shape="rectangle" 表示圍出該點的外框形狀設為矩形,預設值則是橢圓形。注意當屬性設置的目標是點或邊時,必須以中括號包圍。

 兩個點 A, B 都有被設定 label, 一旦被設定 label 後,圖上顯示在框線裡的就是 label 指定的字串,未指定則會顯示該點在 DOT 語法裡的名稱,即此處的 A 與 B. 這個屬性應該是未來最常被使用的屬性,下一段將進行更詳細示範。

 A -> B 邊上被設了二個屬性,多個屬性之間可用逗號區隔。label 意義也是標註的字串,不過在此被標註於邊附近,未指定則邊的周圍不會有文字。style 設定邊的線條樣式,設為 "dotted" 表示該邊看起來會一點一點的,不是預設的連續線條。


 本段提的是 label 屬性的用法,它負責在點、邊上呈現文字,在圖上不可或缺。

 假如捷運的地圖上「台北車站」寫做 Taipei Station, 但因為兩個字都很長導致圖片不好看,分行寫會看起來比較舒服,可在 label 值的引號裡用 \n 表示換行,見下例:

 如此一來,點 TPS 看起來就比較雲稱,不會把整張圖左右拉開。

 另外,很多情況下需要對 label 內的文字安排特殊效果,以更簡潔地表示這個點或邊有某些特質,比如紅色的字是重點。當然可以用 fontcolor 屬性,改變整個 label 的文字顏色,但無法處理只想把 label 的某些字染紅的狀況。

 Graphviz 提供了另一種 label 值的寫法,以角括號 < 和 > 圍住文字內容,其中的文字可用網頁 HTML 寫法指定字段的特效。見下例:

 點 example 會顯示 ABCDE, 但是 A 有粗體效果,B 有底線效果,E 是紅色。

 這裡的 label 等於後面不是雙引號圍住內容而使用小於跟大於圍住。其中使用的是 HTML 格式的修飾語法,<b>, <u> 各代表粗體和底線,<font color="red"> 展示了有參數的 HTML 標籤,將字體改為紅色。

 提醒:給明眼人看製圖效果時可能會有「文字距離對應的線太遠,反而跟別的線較靠近」的回饋,此時可用空白來改變 label 與左右線條的距離,用換行改變與上下線條的距離。須特別注意的是 HTML 格式的 label 換行也要用 <br/> 跟 HTML 一樣。


回 · 介紹對我有幫助又友善的工具程式 這一篇文章封面
回 · 介紹對我有幫助又友善的工具程式 這一篇文章封面


本文張貼者:Bo-Cheng Jhan〔張貼時間:民國105年7月13日(星期三)17點01分 | 更新次數 #4 | 最後更新:民國105年7月22日(星期五)22點36分〕

部落格首頁


學習的故鄉首頁
本站公告:〔您越需要我們,我們就越有創意〕 本站說明書:〔發現故鄉還有改進的地方,請來信告訴原丁們〕
觀察應用學習點數 :〔咱的故鄉有您的參與,會使我們有更大的發揮空間,展現更豐富精彩的學習畫面〕 〔期待藉由無障礙網頁設計,能讓視障小朋友更愛看書、更愛寫作且更愛學習〕:盲用電腦「心得分享」
〔為了讓我們有乾淨的學習環境,請勿任意在本站散播商業廣告與不合法文件或聯結〕:本站宣示