最近几天老板要出国,很多事儿着急弄完,所以比较忙,没睡一个好觉,反正一句话:够蛋疼的了!难得有点时间,说说最近用metapost画流程图的一点感受吧。

    首先说明一点,很多人都不建议用metapost画流程图,当然这么说肯定是有道理的,比如被广泛推荐的Context,或是其他专门用来画流程图的工具,甚至有人问latex提供了画流程图的宏包为什么还要单独用别的工具画流程图,这里我坚持用metapost的原因很简单,因为我最近在学这个东东,用它画出来的图感觉非常漂亮,所以我确定画个流程图肯定是没有问题的,至于你要用别的工具,我也很赞同,反正达到效果就行了。

    首先,要介绍的是metaflow,从名字也看得出来,这是一个画流程图的专用包,是由Kevin Hamlen写的一个工具包,具体介绍可以参见他的home page,地址在这里:http://www.utdallas.edu/~hamlen/projects.html,我尝试了用这个工具画我需要的流程图,但是遇到了一些小问题(这个后面来讲),先说说怎么用吧,首先当然是下载需要的metaflow.mp mftext.tex,这两个文件就是Kevin Hamlen的劳动成果,下载完事儿了直接放到你的mp文件同一文件夹下就OK了,比如我是这么干的:

metapost画流程图的几种选择metaflow or box?_metapost

    其中chart.mp是我自己写的画流程图的mp文件,当然也能看到生成的eps和pdf文件了,这是后话,重要的还是把代码贴上来吧

input metaflow

prologues := 2;

filenametemplate "%j-%c.eps";

verbatimtex

\documentclass[10pt]{article}

\renewcommand\familydefault{\sfdefault}

\input mftext

\begin{document}

etex


beginfig(1)

z1c = (0,0);

draw rect1(btex he etex);

putitem2 20right of 1;

draw oval2(btex result etex);

drawarrow connector(1,2,right,right);

putitems(2,3) like (1,2);

%z3s = (55,30);

draw diamond3(btex evaluation etex);

drawarrow connector(2,3,right,right);

drawarrow connector1(3,1,down,up);

z4um = point 1.5 of cp1;

drawopen rect4(btex revise etex);

putitems(3,5) like (1,2);

drawopen rect5(btex successful etex);

drawarrow connector(3,5,right,right);

endfig;


verbatimtex

\end{document}

etex

end

    注意红色的两行,这是对metaflow的引用,我的理解是相当于将metaflow.mp mftext.tex的代码直接替换这两行,当然这样理解未必完全是对的,但至少是这么个意思。

    下面写的就是重点了,注意看z1c = (0,0);其实这只是定义一个中心点在(0,0)的点而已,但是每个字符都是有意义的:Z表示定义的是点,1表示这个点的标识,c表示定义的是其中心点,虽然乍看起来这样写是绝对的精简和方便,但是对与初学者来说简直就是蛋疼,第一遍看代码我就完全看不懂啊,虽然后来逐渐接触的多了就能理解每个字符的具体意思了,但是还是对这种极其精简的年做法表示恨不能接受,所以如果你不是经常用这种工具画图的话,你还是别用metaflow了,因为你不可能短时间用到非常熟练,这玩意儿对于用惯了的人来说确实非常方便,但是对于新手,很难记这么多字符对应的意义。

    下面说说我使用的时候碰到的问题,就是流程中的文字总超出边界,比如下面这个图:

metapost画流程图的几种选择metaflow or box?_metapost_02

    很明显,evaluste最后的俩字符都超出边界了,很不美观啊,当然,这里最值得怀疑的就是我还没真的学会用这个东东,所以代码有问题没有进行相应的设定,如果哪位大神知道这么修正,请留言告诉我下,或是我以后能解决这个问题了,也会进行相应的补充的。

    metaflow就说到这里,下面要说的是另一个东东,来自metapost的原作者John_Hobby(我暂且这么认为吧,因为在他写的A User's Manual for MetaPost中我竟然找到了关于box的详细介绍,所以推测box应该就是他写的),其实box的设计本来不是用来画流程图的,但是却非常容易用来画流程图,废话不多说,直接下载boxes.mp和rboxes.mp,下载地址在这里http://ctan.mackichan.com/obsolete/systems/msdos/metapost/mpinputs/,下载完以后的处理方式和metaflow类似,直接放到同一文件夹中就可以了,直接上代码

\input rboxes

beginfig(501);

pair disx,disy;

disx:=(11,0);

disy:=(0,17);


rboxit.a(btex $L$ hears beep at $t_{beep,L}$ etex);

a.n = (0,0);

drawboxed(a);


rboxit.b(btex \begin{tabular}{c} $L$ promoted to leader \\by $A$,  with $t_{beep,L}$ \\corresponding to $t_{beep,A}$ \end{tabular} etex);

b.nw = a.ne+disx;

drawboxed(b);


boxit.c(btex \begin{tabular}{c} $X_L = (X_A \cap N_L) \cup \{A\}$ \\$\Lambda_L = N_L - X_L$ \end{tabular} etex);

c.w=b.e+disx;

drawboxed(c);

drawarrow b.e--c.w;

...............

    代码太长,就不全贴出来了,注意这里只有一个\input rboxes,而没有\input boxes,其实原因很简单,最开始我写了\input boxes,结果编译出错,然后我就查看了rboxes.mp文件,结果人家第一句就是\input boxes,我也是醉了,调了半天竟然是这种原因。。。。。。

    好吧,又到了说问题的时候了,这次碰到的问题是没法用box画菱形,虽然见过各种变化,但是没能变换出菱形(也就是流程图中的判定),不知道哪位大神能够提供个解决方案,最终我选择了画一条封闭路径自己画一个菱形,但是显然不是最好的结果,至少对于内部文字的处理方式和缩放大小的把握不像box那样智能了,要知道,box是不会出现metaflow中那种文字出界的问题的。研究了一下午,我还是决定自己写一个diamond.mp,像box一样自己封装一个,不过现在还没写完,等写完会发出来的。

    这里顺便提醒一句,很多人不知道在box中的文字怎样换行,这里提供一个别人介绍的解决方案,那就是在box内部构建一个表格,具体代码比如下面这个:


rboxit.n(btex \begin{tabular}{c} (3b) Promote $P$ \\to leader with \\ $[t_{beep,L}, X_L]$ \end{tabular} etex);


    最后贴一个效果图吧,这是我论文里面用到的一个流程图,大家看下效果

metapost画流程图的几种选择metaflow or box?_metapost_03


    我感觉还是比较好看的,大家觉的怎样,欢迎提建议。

    好啦,又是吃饭时间了,走起~~~