Graphviz

来自智得网
跳转至: 导航、​ 搜索

简介

Graphviz编写的Hash结构

Graphviz 是一个开源的图形编辑语言,可以进行图形的可视化编辑,绘制结构化的图标和图形非常方便。

Graphviz 使用 DOT 语言来表示图形。

DOT语言可以用简单的文本来表示结点,连线,布局等。

原理

DOT语言描述结点,连线,布局的文本都非常简单,而且从文本本身可以推测中起含义。

结点

DOT语言描述结点的方式是`NodeName`[label=`LabelName`]。

结点可以分为普通的节点和列表节点,列表节点可以使用竖线分隔多个Label来表示,`NodeName`[label=`LabelName1|LabelName2|LabelName3|...|LabelNameN`]。

列表节点的展示可以横排或者竖排,横排使用中括号[]还包裹列表元素,竖排使用{}包裹列表元素。

连线

使用`NodeName1`->`NodeName2`的方式可以绘制一条从节点1到结点2的直线。

`NodeName1`->{`NodeName2` `NodeName3`},可以使NodeName1的结点指向用{}包裹,空格分隔的多个结点。

splines=false;可以强制连线都是直线。

布局

布局可以分为水平布局(左右布局)和垂直布局,rankdir=LR;指定水平布局,在全局范围内生效。

水平布局的时候,可能有一些record需要垂直摆放,label="{}",如果和randdir一致,则不需要{}。

技巧

绘图过程中可以创建一些隐藏结点使得图形对齐。

示例

Hash表

digraph G {
    nodesep=.05;
    rankdir=LR;
    splines=false;
    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> user1 | name=jack |sex=m", width=.1];
    node2 [label = "<n> user2  | name=andy |sex=m", width=.1];
    node3 [label = "<n> user3  | name=will |sex=m", width=1.12];
    node4 [label = "<n> user4  | name=great |sex=m", width=.1];
    node5 [label = "<n> user5  | name=lina |sex=f", width=1.12] ;
    node6 [label = "<n> user6  | name=lida |sex=f", width=.1] ;
    node7 [label = "<n> user7  | name=lily |sex=f", width=.1] ;

    node0:f0:e -> 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;
}

B+树

digraph {
    rankdir = UD;
    splines = false;
    nodesep = .3;
    node [shape = record,width = .1,height = .1];
    
    node01 [label = "15|<n01>|58|<n02>|89|<n03>"]
    node11 [label = "<n11>15|<n12>|<n13>25|<n14>|<n15>37|<n16>"]
    node12 [label = "......"]
    node13 [label = "......"]
    
    node21 [shape = none, margin = 0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>15</td></tr>
        <tr><td port="0">37</td></tr>
        <tr><td>Will</td></tr>
        </table>>]
    node22 [shape =none, margin = 0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>21</td></tr>
        <tr><td port="0">56</td></tr>
        <tr><td>Eric</td></tr>
        </table>>]
    node23 [shape = none, margin = 0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>25</td></tr>
        <tr><td port="0">12</td></tr>
        <tr><td>Bob</td></tr>
        </table>>]
    node24 [shape = none, margin = 0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>21</td></tr>
        <tr><td port="0">53</td></tr>
        <tr><td>Jim</td></tr>
        </table>>]
    node25 [shape = none, margin= 0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>37</td></tr>
        <tr><td port="0">2</td></tr>
        <tr><td>Eric</td></tr>
        </table>>]
    node26 [shape = none, margin =0, label = <
        <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
        <tr><td>87</td></tr>
        <tr><td port="0">7</td></tr>
        <tr><td>ROSE</td></tr>
        </table>>]
    
    node01 : n01 -> node11
    node01 : n02 ->node12
    node01 : n03 -> node13
    
    node11 : n11 :s -> node21 : n
    node11 : n12 -> node22 : n
    node11 : n13 -> node23 
    node11 : n14 -> node24
    node11 : n15 -> node25 : n
    node11 : n16 -> node26 :n 
    
    {
    rankdir = LR
    rank = same;
    node21 -> node22 -> node23 ->node24 -> node25 -> node26
    }

}
叶子节点对齐的时候注意,如果是普通的record节点,rank=same,不同的weight权重,以及constraint=false都不能实现对齐,所以使用了HTML like labels