什么是Graphviz?

Graphviz是开源的图形可视化软件。图形可视化是一种将结构信息表示为抽象图形和网络图的方式。它在网络,生物信息学,软件工程,数据库和网页设计,机器学习以及其他技术领域的可视界面中具有重要的应用。

以上是Graphviz实现作图的示例展示,通过类似于Markdown标记语言的形式,Graphviz使用Dot文本图形描述语言来实现作图。

Hexo添加对Graphviz的支持

  1. 安装相关插件 hexo-graphviz

    在终端cd至hexo博客根目录,通过yarn或者npm包管理器安装

    1
    2
    yarn add hexo-graphviz			# 通过yarn安装
    npm install hexo-graphviz --save # 通过npm安装
  2. 在布局模板中添加相应的JavaScript代码

    cd{博客根目录}/themes/{主题名}/layout/_partial 目录之下,用vim或编辑器打开 after-footer 文件,针对不同类型的模板引擎添加相应代码:

    • ejs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <% if (theme.graphviz.enable) { %>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.7.1/viz.js'></script>
    <script>
    String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
    };

    let vizObjects = document.querySelectorAll('.graphviz')

    for (let item of vizObjects) {
    let svg = undefined
    try {
    svg = Viz(item.textContent.replaceAll('–', '--'), 'svg')
    } catch(e) {
    svg = `<pre class="error">${e}</pre>`
    }
    item.outerHTML = svg
    }
    </script>
    <% } %>
    • swig
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    {% if theme.graphviz.enable %}
    <script src='https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.7.1/viz.js'></script>
    <script>
    String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
    };

    let vizObjects = document.querySelectorAll('.graphviz')

    for (let item of vizObjects) {
    let svg = undefined
    try {
    svg = Viz(item.textContent.replaceAll('–', '--'), 'svg')
    } catch(e) {
    svg = `<pre class="error">${e}</pre>`
    }
    item.outerHTML = svg
    }
    </script>
    {% endif %}
    • pug
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    if theme.graphviz.enable == true
    script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.7.1/viz.js')
    script.
    String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
    };

    let vizObjects = document.querySelectorAll('.graphviz')

    for (let item of vizObjects) {
    let svg = undefined
    try {
    svg = Viz(item.textContent.replaceAll('–', '--'), 'svg')
    } catch(e) {
    svg = `<pre class="error">${e}</pre>`
    }
    item.outerHTML = svg
    }
  1. 在hexo根目录下的 _config.yml 启用 graphviz

    1
    2
    3
    # hexo-graphviz
    graphviz:
    enable: true

示例预览

插件安装完成之后通过Markdown添加代码块方式声明 graphviz 样式即可

  • 示例1:无向图
graph demo1 { a -- b -- c; b -- d; }
1
2
3
4
graph demo1 {
a -- b -- c;
b -- d;
}
  • 示例2:二叉树
digraph demo2 { // bgcolor="beige" // 可设置背景颜色 node [shape="record", height=.1] node0[label=" | G | "] node1[label=" | E | "] node2[label=" | B | "] node0:f0 -> node1:f1 node0:f2 -> node2:f1 }
1
2
3
4
5
6
7
8
9
digraph demo2 {
// bgcolor="beige" // 可设置背景颜色
node [shape="record", height=.1]
node0[label="<f0> | <f1> A | <f2>"]
node1[label="<f0> | <f1> B | <f2>"]
node2[label="<f0> | <f1> C | <f2>"]
node0:f0 -> node1:f1
node0:f2 -> node2:f1
}
  • 示例3:大括号子图形式
graph demo3 { "数据结构三要素" -- {"数据的逻辑结构", "数据的存储结构", "数据的运算"} }
1
2
3
graph demo3 {
"数据结构三要素" -- {"数据的逻辑结构", "数据的存储结构", "数据的运算"}
}
  • 示例4:总示例
digraph demo4 {
label=<<B>Graphviz基本组成结构</B>>;

labelloc=top;            // 标题位置
bgcolor=transparent;    // 背景透明

node[shape=box];        // 结点形状为方形
//edge[style=bold];

// 独立出现的为结点或属性声明, 中括号前为结点名称
graphviz[label="Graphviz"];

subgraph{
    layout[label="Layouts"];
    script[label="Script Files"];
    api[label="APIs"];
    rank=same;
}

graphviz -> layout;
graphviz -> script;
graphviz -> api;

// 设置子图
api -> 
subgraph{
    layout_etc[label="......"];
}

script ->
subgraph{
    element[label="Elements"];
    attribute[label="Attributes"];
    rank=same;
}

layout ->
subgraph{
    layout_dot[label="dot"];
    layout_neato[label="neato"];
}

element ->
subgraph{
    ele_graph[label="Graph"];
    ele_node[label="Node"];
    ele_edge[label="Edge"];
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
digraph demo4 {

label=<<B>Graphviz基本组成结构</B>>;

labelloc=top; // 标题位置
bgcolor=transparent; // 背景透明

node[shape=box]; // 结点形状为方形
//edge[style=bold];

// 独立出现的为结点或属性声明, 中括号前为结点名称
graphviz[label="Graphviz"];

subgraph{
layout[label="Layouts"];
script[label="Script Files"];
api[label="APIs"];
rank=same;
}

graphviz -> layout;
graphviz -> script;
graphviz -> api;

// 设置子图
api ->
subgraph{
layout_etc[label="......"];
}

script ->
subgraph{
element[label="Elements"];
attribute[label="Attributes"];
rank=same;
}

layout ->
subgraph{
layout_dot[label="dot"];
layout_neato[label="neato"];
}

element ->
subgraph{
ele_graph[label="Graph"];
ele_node[label="Node"];
ele_edge[label="Edge"];
}
}