使用Graphviz下的dot工具繪制圖像

lixlsj 8年前發布 | 96K 次閱讀 圖表/報表制作

來自: 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

 本文由用戶 lixlsj 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!