An Introduction to GraphViz and dot

33 篇文章 1 订阅
4 篇文章 0 订阅

来源:http://www.linuxdevcenter.com/pub/a/linux/2004/05/06/graphviz_dot.html

by Michele Simionato
05/06/2004

You must give a presentation tomorrow and you haven't prepared any figures yet; you must document your last project and you need to plot your most hairy class hierarchies; you are asked to provide ten slightly different variations of the same picture; you are pathologically unable to put your finger on a mouse and draw anything more complex than a square. In all these cases, don't worry! dot can save your day!

明天你必须准备一个演讲,你有没有准备任何图片,但你必须文档化你的最后一个项目,你需要画出大多数毛茸茸的类层次结构;要求您提供同一图片的10种稍微变化; 你不能用鼠标画出任何比一个正方形更为复杂的东西。在所有这些情况下,不用担心!dot可以节省你的生命!

What is dot?

dot is a tool to generate nice-looking diagrams with a minimum of effort. It's part of GraphViz, an open source project developed at AT&T and released under an MIT license. It is a high-quality and mature product, with very good documentation and support, available on all major platforms, including Unix/Linux, Windows, and Mac. There is an official home page and a supporting mailing list.

dot是一个以最小的努力用来生成好看的图表的工具。她是由AT&T开发并在MIT许可下发布的开源项目GraphViz的一部分。它是一个高品质和成熟产品,具有很好的文档和支持,可在所有主流平台,包括Unix / Linux上,Windows和Mac上。GraphViz有一个官方主页和支持的邮件列表。

What Can I Do with dot?

First of all, let me make clear that dot is not just another paint program, nor a vector graphics program. dot is a scriptable, batch-oriented graphing tool; it is to vector drawing programs as LaTeX is to word processors. If you want to control every single pixel in your diagram, or if you are an artistic person who likes to draw free hand, then dot is not for you. dot is a tool for the lazy developer, the one who wants the job done with the minimum effort and without caring too much about the details.

首先,让我说清楚,dot既不是画图程序,也不是矢量图形程序。dot是一个脚本,面向批处理的绘图工具; 它和矢量绘图软件的关系类似Latex和字处理器。如果你想控制你的图中的每一个像素,或者如果你是一个艺术的人喜欢放开手脚来画,dot是不适合你的。Dot是懒惰的开发者的工具,是一个花最小的努力和不关心太多的细节就可以完成任务的工具。

Since dot is not a WYSIWYG tool—even if it comes with a WYSIWYG tool, dotty—it is not primarily an interactive tool. Its strength is the ability to generate diagrams programmatically. To fulfill this aim, dot uses a simple but powerful graph description language. Give dot very high level instructions and it will draw the diagrams for you, taking into account all the low level details. Though you have a large choice of customization options and can control the final output in many ways, it is not at all easy to force dot to produce exactly what you want, down to the pixel.

由于Dot是不是一个所见即所得的工具,即使它带有一个所见即所得的工具-dotty,但它不是主要的交互式工具。Dot强项在于能以编程方式生成图表的能力。为了实现这一目标,dot使用一个简单但功能强大的图形描述语言。提供dot高层次的指令,它将为你考虑到所有低级别的细节并绘制图形。虽然有很大的选择可以定制选项,并在许多方面控制最终输出,但并不容易让dot以你想要的精确到像素的方式生成图像。

Expecting that would mean to fight with the tool. You should think of dot as a kind of smart boy, who likes to do things his own way and who is very good at it, but becomes nervous if the master tries to put too much pressure on him. The right attitude with dot (just as with LaTeX) is to trust it and let it to do the job. At the end, when dot has finished, you can always refine the graph by hand. (dotty, the dot diagram interactive editor, comes with GraphViz and can read and generate dot code.) In most cases, you do not need to do anything manually, since dot works pretty well. The best approach is to customize dot options, so that you can programmatically generate one or one hundred diagrams with the least effort.

这将意味着与工具对抗。你应当将dot看作一种聪明的男孩,他喜欢按自己的方式做事他并且很擅长做事,但如果主人试图施加过多的压力,他就变得神经兮兮的。对待dot(类似LaTeX)的正确态度是信任它并让它来完成这项工作。最后,当dot完成后,可以随时手动优化的图形(dotty,dot的图形互动编辑器,GraphViz自带的,可以读取并生成dot代码)。在大多数情况下,你不需要做任何手动工作,因为dot工作得很好。最好的方法是自定义点的选项,这样你可以通过编程以最少的努力生成一个或百图。

dot is especially useful in repetitive and automatic tasks, since it easy to generate dot code. For instance, dot comes in handy for automatic documentation of code. UML tools can also do this work, but dot has an advantage over them in terms of ease of use, a flatter learning curve, and greater flexibility. On top of that, dot is very fast and can generate very complicated diagrams in fractions of second.

由于生成dot代码非常容易,Dot是在重复和自动任务特别有用。例如,dot在代码自动文档化中就能派上用场。UML工具也可以做这项工作,但dot的优势是易用,平坦的学习曲线以及强大的灵活性方面。最重要的是,dot是非常快的,可以在几分之一秒生成非常复杂的图表。

Hello World from dot

dot code has a C-ish syntax and is quite readable even to people who have not read the manual. For instance, this dotscript:

点代码有类似C语言的语法,有着不看手册都能理解的可读性。例如:下面的这个dot脚本:

graph hello {

// Comment: Hello World from ``dot``

// a graph with a single node Node1

Node1 [label="Hello, World!"]

}

generates the image shown in Figure 1.


Figure 1. "Hello, World!" from GraphViz

Save this code in a file called hello.dot. You can then generate the graph and display it with a simple one-liner:

将代码保存在一个名为hello.dot文件。然后,使用一行命令可以生成并显示图表:

$ dot hello.dot -Tps | gv

The -Tps option generates PostScript code, which is then piped to the ghostview utility. I've run my examples on a Linux machine with ghostview installed, but dot works equally well under Windows, so you may trivially adapt the examples.

该 -Tps选项生成PostScript代码,然后通过管道输送到给Ghostview工具。作者在安装了Ghostview的Linux机器运行例子,但dot在Windows下同样适用,所以你可以正常适应的例子。(ubuntu的软件源中gv的界面非常丑,我安装了又卸载了,而且上面的那个命令也没有成功执行过)

If you're satisfied with the output, save it to a file:

如果你满意的输出,将其保存到一个文件:

$ dot hello.dot -Tps -o hello.ps

You'll probably want to tweak the options, for instance adding colors and changing the font size. This is not difficult:

你可能会想调整的选项,例如添加颜色并改变字体大小。这不难:

graph hello2 {

// Hello World with nice colors and big fonts

Node1 [label="Hello, World!", color=Blue, fontcolor=Red,fontsize=24, shape=box]

}

This draws a blue square with a red label, shown in Figure 2.


Figure 2. A stylish greeting

You can use any font or color available to X11.
Editor's note: or presumably to Windows, if you're not running an X server.
dot is quite tolerant: the language is case insensitive and quoting the options color="Blue", shape="box" will work too. Moreover, in order to please C fans, you can use semicolons to terminate statements; dot will ignore them.

您可以使用X11上的任何字体或颜色可。注:如果使用Windows,就不用运行X服务器。

Dot容错性高:语言不区分大小写并且对选项添加引号也能工作,如 color="Blue", shape="box"。为了迎合C的粉丝,可以使用分号来终止语句;但点不会理会他们。

Basic Concepts of dot

A generic dot graph is composed of nodes and edges. Our hello.dot example contains a single node and no edges. Edges enter in the game when there are relationships between nodes, for instance hierarchical relationships as in this example, which produced Figure 3:

通用的Dot图是由节点和边组成的。hello.dot示例包含一个的节点且没有边。当节点之间存在关系时,需要用边,例如在下面例子中分层关系,将产生图3:

//simple_hierarchy.dot

digraph simple_hierarchy {

B [label="The boss"]      // node B

E [label="The employee"]  // node E

B->E [label="commands", fontcolor=darkgreen] // edge B->E

}


Figure 3. A hierarchical relationship

dot is especially good at drawing directed graphs, where there is a natural direction. (GraphViz also includes the similarneato tool to produce undirected graphs). In this example the direction is from the boss, who commands, to the employee, who obeys. Of course dot gives you the freedom to revert social hierarchies, as seen in Figure 4:

dot在画有向图时,特别自然。(GraphViz的还包括一个类似的工具 neato来生成无向图)。在该示例中,方向是从boss到员工。当然,dot给您翻转社会层次结构的自由,如图4所示:

//revolution.dot

digraph revolution {

B [label="The boss"]      // node B

E [label="The employee"]  // node E

B->E [label="commands", dir=back, fontcolor=red]  

// revert arrow direction 

}


Figure 4. An inverted hierarchy

Sometimes, you want to put things of the same importance on the same level. Use the rank option, as in the following example, which describes a hierarchy with a boss, two employees, John and Jack, of the same rank, and a lower ranked employee Al who works for John. See Figure 5 for the results.

有时候,你想放的同样重要的事情在同一层次上。使用rank选项,如下面的例子,它描述了一个老板两个员工的层次结构,约翰和杰克,同一职级,以及一个排名较低员工的Al谁的作品为约翰。 参见图5的结果。

//hierarchy.dot

digraph hierarchy {

nodesep=1.0 // increases the separation between nodes

node [color=Red,fontname=Courier]

edge [color=Blue, style=dashed] //setup options

Boss->{ John Jack } // the boss has two employees

{rank=same; John Jack} //they have the same rank

John -> Al // John has a subordinate 

John->Jack [dir=both] // but is still on the same level as Jack

}


Figure 5. A multi-level organizational chart

This example shows a nifty feature of dot: if you forget to give explicit labels, it will use the name of the nodes as default labels. You can also set the default colors and style for nodes and edges respectively. It is even possible to control the separation between (all) nodes by tuning the nodesep option. I'll leave it as an exercise for the reader to see what happens without the rank option (hint: you get a very ugly graph).

这个例子显示dot的一个极好的功能:如果你忘了给明确的标签,它会使用节点名称作为默认标签。您还可以分别设置节点和边的默认颜色及样式。通过调整nodesep选项甚至可以控制(全部)节点之间的距离。读者可以自行查看没有秩的选项的输出(提示:你得到一个非常难看的图形),这个难看的图片显示如下:


dot is quite sophisticated, with dozen of options which you can find in the excellent documentation. In particular, the man page (man dot) is especially useful and well done. The documentation also explains how to draw graphs containing subgraphs. However, those advanced features are outside the scope of this brief article.

dot相当复杂的,有十几个选项,可以从出色的文档中找到。尤其是手册页 (man dot)是非常有用非常好。该文档还介绍如何绘制包含子图的图表。然而,这些高级的功能超出这篇简短的文章的范围以外。

We'll discuss another feature instead: the ability to generate output in different formats. Depending on your requirements, different formats can be more or less suitable. For the purpose of generating printed documentation, the PostScript format is quite handy. On the other hand, if you're producing documentation to convert to HTML format and put on a Web page, PNG format can be handy. It is quite trivial to select an output format with the -T output format type flag:

我们将讨论另一种功能,而不是生成输出不同格式的能力。根据要求确定不同的图片格式。对生成于打印需要的文档,PostScript格式也很方便。在另一方面,如果制作转换为HTML格式的文档并放在网页上,PNG格式可能更好。使用-T选项输出格式类型标志是很微不足道的选择:

dot hello.dot -Tpng -o hello.png

There are many others available formats, including all the common ones such as GIF, JPG, WBMP, FIG and more exotic ones.

还有许多其他可用的格式,包括所有常见的如GIF,JPG,WBMP以及更奇特的图。

Generating dot Code

dot is not a real programming language, but it is pretty easy to interface dot with a real programming language. Bindings exist for many programming languages—including Java, Perl, and Python. A more lightweight alternative is just to generate the dot code from your preferred language. Doing so will allow you to automate the entire graph generation.

Here is a simple Python example using this technique. This example script shows how to draw Python class hierarchies with the least effort; it may help you in documenting your code.

dot不是一个真正的编程语言,但它是很容易与真正的编程交互。可以绑定多种编程语言,包括Java,Perl和Python。更轻量级替代是从喜欢的语言中生成dot代码。 这样做将使您自动化整个图形生成过程。

下面是使用该技术的Python的例子。 此示例脚本展示了如何以最小的努力绘制的Python类层次,它可以帮助您记录您的代码

# dot.py 

"Require Python 2.3 (or 2.2. with from __future__ import generators)"

def dotcode(cls):
    setup='node [color=Green,fontcolor=Blue,fontname=Courier]\n'
    name='hierarchy_of_%s' % cls.__name__
    code='\n'.join(codegenerator(cls))
    return "digraph %s{\n\n%s\n%s\n}" % (name, setup, code)
 
def codegenerator(cls):
    "Returns a line of dot code at each iteration."
    # works for new style classes; see my Cookbook
    # recipe for a more general solution
    for c in cls.__mro__:
        bases=c.__bases__
        if bases: # generate edges parent -> child
            yield ''.join([' %s -> %s\n' % ( b.__name__,c.__name__)
                           for b in bases])
        if len(bases) > 1: # put all parents on the same level
            yield " {rank=same; %s}\n" % ''.join(
                ['%s ' % b.__name__ for b in bases])

if __name__=="__main__": 
    # returns the dot code generating a simple diamond hierarchy
    class A(object): pass
    class B(A): pass
    class C(A): pass
    class D(B,C): pass
    print dotcode(D)

The function dotcode takes a class and returns the dot source code needed to plot the genealogical tree of that class.codegenerator generates the code, traversing the list of the ancestors of the class (in the Method Resolution Order of the class) and determining the edges and the nodes of the hierarchy. codegenerator is a generator which returns an iterator yielding a line of dot code at each iteration. Generators are a tool recent addition to Python; they come particularly handy for the purpose of generating text or source code.

The output of the script is the following self-explanatory dot code:

函数dotcode需要一个类,并返回绘制类的系谱树所需的dot源代码。codegenerator生成的代码,遍历类的祖先的列表(类的方法解析序列中),并确定边和节点的层次结构。Codegenerator是一个在每次迭代中返回一行的dot代码的生成器。返回一个迭代产生点阵码在每次迭代。生成器是最近添加到Python中的工具,

在处理生成文本或源代码的目的问题时特别方便。脚本的输出是如下不言自明的dot代码:

digraph hierarchy_of_D {

node [color=Green,fontcolor=Blue,font=Courier]

 B -> D

 C -> D

 {rank=same; B C }

 A -> B

 A -> C

 object -> A

}

Now the simple one-liner输入简单的命令:

$ python dot.py | dot -Tpng -o x.png

generates Figure 6.


Figure 6. A Python class diagram

References

You may download dot and the others tool coming with GraphViz at the official GraphViz homepage. You will also find plenty of documentation and links to the mailing list.

Perl bindings (thanks to Leon Brocard) and Python bindings (thanks to Manos Renieris) are available. Also, Ero Carrera has written a professional-looking Python interface to dot.

The script dot.py I presented in this article is rather minimalistic. This is on purpose. My Python Cookbook recipe,Drawing inheritance diagrams with Dot, presents a much more sophisticated version with additional examples.

Michele Simionato is employed by Partecs, an open source company headquartered in Rome. He is actively developing web applications in the Zope/Plone framework.

可以在在官方GraphViz的主页下载GraphViz(包含dot和其他工具)。在主页上还可以找到大量的文件和邮件列表中连接。

Perl的绑定 感谢Leon Brocard)和 Python绑定(感谢Manos Renieris)均可获取。此外,卡雷拉写了一个具有专业水准的dot的Python接口

在本文中的脚本 dot.py是相当简约。这是有意的。 我的Python Cookbook书中提供用点来绘制遗传图展示了提供了一个更为复杂的且带有额外例子python脚本。

作者:Michele Simionato受雇于Partecs(一个总部设在罗马的开源公司),他是使用Zope/Plone的框架积极开发Web应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值