使用自定义tikz-flowchart宏包绘制传统流程图

TiKZ-PGF 2019-10-08 09:13  浏览 :4588
由于工作需要,经常需要在各类文档中绘制**传统程序流程图**。流程图当然可以在Visio、亿图等工具进行绘制,截图(**位图,不推荐**)或是导出为PDF(**矢量图,推荐**)后,再通过graphicx宏包的`\includegraphics`命令插入到LaTeX实现排版。这是一种简单直接的方法,但这种方法会存在如下问题: - 需要额外的软件支持,降低了文档的独立性。 - 字体、字号无法与正文匹配,整体效果不协调。 - 缩放时字号会产生变化,无法满足字号比正文小1号的常规要求。 - 不便后期修改、编辑和维护。 因此,在LaTeX中直接使用TikZ工具绘制流程图,是一个相对较好的选择。 ## 直接绘制 流程图的基本形状有矩形、菱形、平行四边形、圆角矩形等。可以使用TikZ的`\node`命令布置这些形状结点,然后绘制对应流程线就可以实现流程图的绘制。 为绘制不同形状的结点,可以为`\\node`命令的可选参数中设置`rectangle`、`diamond`、`trapezium`、`rounded corners`等绘制属性。 显然,直接用TikZ代码进行流程图绘制是一个比较烦琐的过程,并且不符合LaTeX**内容与格式分离**的基本思想。同时,当有多个流程图需要绘制时,代码过于冗余,不便维护,代码的复用性也较差,不同流程图也容易产生不一致现象。 ## 使用`flowchart`宏包绘制 为简化流程图的绘制代码,可以引入合适的LaTeX宏包进行流程图绘制。一个比较方便的宏包是`flowchart`宏包,它提供了如下基本的流程图形状:
显然,该宏包提供的基本流程图形状不能完全符合我国的绘制习惯。关于该宏包的使用细节,请在命令行用`texdoc flowchart`命令查阅其使用说明书。 ## 设置node样式绘制 当然,可以将`\\node`命令的可选参数中的`rectangle`、`diamond`、`trapezium`、`rounded corners`等绘制属性用`tikzset`命令定义为绘图样式,以实现代码的简化和代码的复用。在[Brent Longborough](http://www.texample.net/tikz/examples/author/brent-longborough/)中,给出了使用这一方式的绘制样例和实现代码。 ## 自定义宏包绘制 根据LaTeX**内容与格式分离**的基本思想,显然将`\\tikzset`样式定义及其它的设置封装为宏包,使用起来则更为方便。在完成这一封装之前,笔者刚好阅读了**tikz-imagelabels**宏包的源代码,发现其`key-value`实现思路非常值得借鉴。因此,基于[Brent Longborough](http://www.texample.net/tikz/examples/author/brent-longborough/)的代码,结合tikz-imagelabels宏包的`key-value`思路,笔者设计与制作了**tikz-flowchart**宏包,以便在LaTeX中用TikZ实现流程图绘制,详见[https://github.com/registor/tikz-flowchart/](https://github.com/registor/tikz-flowchart/ "https://github.com/registor/tikz-flowchart/")。 在`tikzpicture`环境中,使用该宏包绘制流程图的**基本过程**是: 1. 用`\\flowchartset`命令设置全局(导言区)或局部绘制参数。 2. 使用类似`\\node [proc, join] (p1) {$k -= 1$};`命令采用`proc`、`test`、`io`或`term`各个node样式参数分别布置需要的流程框结点。 3. 使用类似`\\node [coord, right=0.8 of t1] (c1) {}; cmark{1}`命令采用`coord`样式布置其它需要的坐标点(用于流程线的转接)。 4. 使用类似`\\path (t1.south) to node [near start, xshift=1em] {$y$} (p2);`命令进行流程线条件标注。 5. 使用类似`\\draw [norm] (t1.south) -- (p2);`命令绘制流程线。 个人建议在绘制流程前最好先用纸和笔绘制一个草图,然后再用tikz-flowchart宏包进行绘制,如下图是一个素数判断的流程图草图:
根据该草图可以使用如下代码: ```xml \documentclass[margin=10pt]{standalone} % 支持中文 \usepackage{ctex} % 流程图绘制宏包 \usepackage{tikz-flowchart} \begin{document} %在document环境中撰写文档 % 可以局部更改各参数 \flowchartset{ proc fill color = orange!10, % 顺序处理框填充颜色(默认取白色) test fill color = green!30, % 判断框填充颜色(默认取白色) io fill color = blue!30, % 输入/输出框填充颜色(默认取白色) term fill color = red!30, % 开始/结束框填充颜色(默认取白色) proc text width = 6em, % 顺序处理框宽度(默认取8em) } \begin{tikzpicture} % 布置结点单元 \node [term] (st) {开始}; \node [proc, join] (p1) {\\verb|int divisor|}; \node [test, join] (t1) {\\verb|n <= 1|}; \node [proc, ] (p2) {\\verb|divisor = 2|}; % 可以根据需要指定结点当前属性(如文字宽度) \node [test, text width = 10em, join] (t2) {\\verb|divisor * divisor <= n|}; \node [test, text width = 8em] (t3) {\\verb|n % divisor == 0|}; \node [proc, text width = 6em] (p3) {\\verb|divisor++|}; \node [term, below = 1.6 of p3] (end) {结束}; \node [proc, left = 4.8 of t2] (p4) {\\verb|return 0|}; \node [proc, right = 3.5 of p3] (p5) {\\verb|return 0|}; \node [proc, right = 5.8 of t3] (p6) {\\verb|return 1|}; % 布置用于连接的坐标结点,同时为其布置调试标记点。 \node [coord] (c1) at ($(p2.south)!0.5!(t2.north)$) {}; \\cmark{1} \node [coord, below = 0.25 of p3] (c2) {}; \\cmark{2} \node [coord, above = 0.5 of end] (c3) {}; \\cmark{3} \node [coord, left = 0.5 of t2] (ct) {}; \\cmark{t} \node [coord] (c4) at (c3 -| p5) {}; \\cmark{4} \node [coord] (c5) at (c2 -| ct) {}; \\cmark{5} % 判断框连线,每次绘制时,先绘制一个带有一个固定 % 位置标注的路径(path),然后再绘制箭头本身(arrow)。 \path (t1.south) -- node [near start, right] {$N$} (p2.north); \draw [norm] (t1.south) -- (p2.north); \path (t1.west) -| node [near start, above] {$Y$} (p4.north); \draw [norm] (t1.west) -| (p4.north); \path (t2.south) -- node [near start, right] {$Y$} (t3.north); \draw [norm] (t2.south) -- (t3.north); \path (t2.east) -| node [near start, above] {$N$} (p6.north); \draw [norm] (t2.east) -| (p6.north); \path (t3.south) -- node [near start, right] {$N$} (p3.north); \draw [norm] (t3.south) -- (p3.north); \path (t3.east) -| node [near start, above] {$Y$} (p5.north); \draw [norm] (t3.east) -| (p5.north); % 其它连线 \draw [norm](p3.south) |- (c5) |- (c1); \draw [norm](p4.south) |- (c3); \draw [norm](p4.south) |- (c3) -- (end); \draw [norm](p5.south) -- (c4); \draw [norm](p6.south) |- (c3); \draw [norm](p6.south) |- (c3) -- (end); \end{tikzpicture} \end{document} ``` 绘制如下流程图:
关于tikz-flowchart宏包的使用细节,请参阅 [https://github.com/registor/tikz-flowchart/](https://github.com/registor/tikz-flowchart/) 中的相关文档说明及使用LaTeX样例代码。 Happy TikZing!
发布评论
登录后方可评论!点击登录
全部评论 (0)
暂无评论, 快来抢沙发!