By Z.H. Fu 
https://fuzihaofzh.github.io/blog/ 在绘制流程框图时,有许多工具可以采用,最著名的有微软的Viso,而开源的有Graphviz、PGF/TikZ,最近要再Mac上画一个流程图,Graphviz是采用dot语言的一个矢量图生成系统,但是不支持L a T e X LaTeX L a T e X L a T e X LaTeX L a T e X L a T e X LaTeX L a T e X 
 
我们首先要安装Tex环境,Windows系统推荐Texlive  完整安装,Mac系统推荐MacTex   完整安装后,在Windows下,已安装默认编辑器WinEdt,而在Mac下的编辑器则是TeXShop,这两个编辑器都非常好用,直接用就可以了。
我们先从一个最简单的例子开始:画一条直线。
1 2 3 4 5 6 7 \documentclass[tikz]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}         \draw (0,0) -- (1,1);     \end{tikzpicture} \end{document} 
这样,我们得到了一个pdf文件,我们用pdf2svg工具将其转换为svg格式的矢量图。
 
带\的都是LaTeX的宏命令,可以看到,这段代码的核心就一句话 \draw (0,0) -- (1,1); 这句话的意思就是从(0,0)到(1,1)画一条线段。我们还可以画的稍微复杂一点:
1 2 3 4 5 6 7 8 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}         \draw [color=blue!50,->](0,0) node[left]{$A$}-- node [color=red!70,pos=0.25,above,sloped]{Hello}(3,3) node[right]{$B$};     \end{tikzpicture} \end{document} 
输出:
 
  可以看到,`\draw`后面的方括号中跟的是对线的一些设置,`color=blue!50`表示的是用50%的蓝色,因为LaTeX中,%用作了注释,所以这里用!替代,`->`表示的是线形是一个箭头,我们注意到,在起点坐标,--,终点坐标后面,我们分别加入了一个node元素,起点后面的node表示的是加入一个标示,它在坐标点(0,0)的左边,`--`后面的node采用70%的红色,位置在线段的上方0.25的位置,随线段倾斜,花括号中是node的文字,为Hello,终点坐标同理。node经常用于加入一些标注,这一点我们在后面将会看到。
在TikZ中,除了画线段之外,还支持各种复杂的形状,下面一个例子给出了一些常见的形状:
1 2 3 4 5 6 7 8 9 10 11 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}         \draw (0,0) circle (10pt);     %画一个圆心在原点,半径为10pt的圆;         \draw (0,0) .. controls (1,1) and (2,1) .. (2,0);       %画一个起点为(0,0),终点为(2,0),控制点为(1,1),(2,1)的贝塞尔曲线;         \draw (0,0) ellipse (20pt and 10pt);       %画一个中心在原点,长轴、短轴分别为20pt和10pt的椭圆;         \draw (0,0) rectangle (0.5,0.5);       %画一个从(0,0)到(0.5,0.5)的矩形         \filldraw[fill=green!20!white, draw=green!50!black](0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle;画一个扇形,并填充,扇形的边色和填充色的透明度不同。     \end{tikzpicture} \end{document} 
输出:
 
## 属性预定义
  在刚才的例子中我们看到,随着我们对样式需求的多样化,属性越来越长,而且多个实体之间往往具有相同的属性,这样一来,我们希望能预定义一个属性集合,到时候直接赋给相应的实体,TikZ本身就是个宏,因此它为我们提供了强大的属性定义功能,来看这段代码:
1 2 3 4 5 6 7 8 9 10 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}     [L1Node/.style={circle,   draw=blue!50, fill=blue!20, very thick, minimum size=10mm},     L2Node/.style={rectangle,draw=green!50,fill=green!20,very thick, minimum size=10mm}]        \node[L1Node] (n1) at (0, 0){$\int x dx$};        \node[L2Node] (n2) at (2, 0){$n!$};     \end{tikzpicture} \end{document} 
输出:
 
 在这段代码中,我们在最开始定义了两个名为L1Node和L2Node的属性,在生成node结点的时候直接填到属性的位置即可。
TikZ相比于Viso的一个优势就在于其循环功能,Viso里面要循环画十个圆就得复制十次,还要调节各自的位置,如果遇到需要调整位置又得重来,TikZ这种命令行的方式能直接画出来,如果需要调整位置,更改参数即可,我们在上一个例子上生成十个结点:
1 2 3 4 5 6 7 8 9 10 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}     [L1Node/.style={circle,   draw=blue!50, fill=blue!20, very thick, minimum size=10mm},     L2Node/.style={rectangle,draw=green!50,fill=green!20,very thick, minimum size=10mm}]        \foreach \x in {1,...,5}         \node[L1Node] (w1_\x) at (2*\x, 0){$\int_\Omega x_\x$};     \end{tikzpicture} \end{document} 
输出:
 
## node树
node结点不但可以用于添加标识,还可以来绘制树形图,下面看一个例子
1 2 3 4 5 6 7 8 9 10 11 12 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}         \node {root}             child {node {a1}}             child {node {a2}                 child {node {b1}}                 child {node {b2}}}             child {node {a3}};     \end{tikzpicture} \end{document} 
输出:
 
稍微加点样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 \documentclass[tikz,convert=pdf2svg]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}     [every node/.style={fill=blue!30,draw=blue!70,rounded corners},      edge from parent/.style={blue,thick,draw}]         \node {root}             child {node {a1}}             child {node {a2}                 child {node {b1}}                 child {node {b2}}}             child {node {a3}};     \end{tikzpicture} \end{document} 
输出:
 
## 绘制函数图像
TikZ提供了强大的函数绘制功能,下面的代码展示了如何绘制函数,当然,绘制数据图表并非TikZ擅长的事情,也并非其设计初衷,TikZ着眼于定性的图表,定量数据的演示还是用其他工具绘制较好。
1 2 3 4 5 6 7 8 9 10 11 12 13 \documentclass[tikz]{standalone} \usepackage{tikz} \begin{document}     \begin{tikzpicture}[domain=0:4]   \draw[very thin,color=gray] (-0.1,-1.1) grid (3.9,3.9);   \draw[->] (-0.2,0) -- (4.2,0) node[right] {$x$};   \draw[->] (0,-1.2) -- (0,4.2) node[above] {$f(x)$};   \draw[color=red]    plot (\x,\x)             node[right] {$f(x) =x$};   % \x r 表示弧度   \draw[color=blue]   plot (\x,{sin(\x r)})    node[right] {$f(x) = \sin x$};   \draw[color=orange] plot (\x,{0.05*exp(\x)}) node[right] {$f(x) = \frac{1}{20} \mathrm e^x$}; \end{tikzpicture} \end{document} 
输出:
 
## 图
TikZ提供了图的支持,通过类似于dot语言的方式来生成图关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \documentclass[tikz]{standalone} \usepackage{tikz} \usetikzlibrary{graphs} \begin{document} \begin{tikzpicture}     \graph {         "$x_1$" -> "$x_2$"[red] -> "$x_3,x_4$";         "$x_1$" ->[bend left] "$x_3,x_4$";     };   \end{tikzpicture} \begin{tikzpicture}     \graph  {      a -> {         b -> c,         d -> e      } -> f     }; \end{tikzpicture} \end{document} 
输出:
 
 
## 总结
关于TikZ的入门就写到这里,通过上面几个例子我们可以看出,TikZ能精确绘制各种复杂的示意图,能非常好地完成Viso,Graphviz等工具完成的功能。参考文献中给出了一个例子的网站,通常想绘制的图形都能在这上面搜到,自己稍微改一改就能直接使用。
## 参考文献
 [1] http://www.texample.net/tikz/examples/ (提供了大量示例)
 [2] The TikZ and PGF Packages Manual(TikZ的手册)
 [3] A very minimal introduction to TikZ (一个入门教程)