Introduction

Background

This article is about using the dot tool from the Graphviz package to automatically generate UML diagrams on the fly. We'll take a look at modelling packages, classes, attributes, methods and associations which already covers a fair subset of the class diagrams in UML.

Of course, the information given in this article is only of limited use in situations where you are manually entering the graph description, but the information is highly useful when you're writing a tool which analyzes program structure. So read on if you're writing a piece of software like UMLGraph.

Getting Started

What you need

First of all, you need to have the Graphviz package installed on your computer, head over to the Graphviz website to download a version for your operating system. Windows users can find binary installers there, Linux users should simply use their package manager since graphviz is a common piece of software. For other Unices, you should download and compile the source code.

There aren't many other prerequisites, but it helps if you've got a good example scenario to start with. In this article I'll be using a somewhat contrived and artificial example, but I hope it gets the point through. You might also want to make sure you have the Bitstream Vera family of fonts installed as I will be using these throughout the article.

The so-called "problem"

The example will be based on a small portion of an animal inspired domain. We'll model a simple Animal superclass which will have two subclasses: Dog and Cat. Animal will have some attributes and methods and both Dog and Cat will add another method to the mix.

We'll model an association between Dog and Cat which resembles an arch-enemy relation. This relation will be of an N:M multiplicity. Besides this, the Animal class will be in the default package, while both Dog and Cat are placed in a package called "animal.impl".

So, fire up a text editor and let's type away.

Graphing Basics

General properties

Let's start off by writing the boilerplate for the dot tool:

digraph G {
fontname = "Bitstream Vera Sans"
fontsize = 8 node [
fontname = "Bitstream Vera Sans"
fontsize = 8
shape = "record"
] edge [
fontname = "Bitstream Vera Sans"
fontsize = 8
]

Don't worry if you don't get this immediately. The first line tells dot we want to draw a directed graph, or digraph for short. A directed graph is a graph in which all edges point from one node to another node, each edge has a start and end node.

The second and third lines set the font properties for the graph, as you can see the next few lines set the font properties for the default nodes and edges as well. There's one line of interest which isn't covered yet, it's the one defining the shape property for nodes.

We set the shape to record because the record shape allows a node to be separated using bars. As we'll see later on, this is the perfect way to model an UML class diagram.

Modelling the Animal class

Let's model the Animal class, which will have a public "name" and "age" property and a public method called "die()". As I stated earlier, this example is somewhat artificial, but it works. I modelled the Animal class like this:

        Animal [
label = "{Animal|+ name : string\l+ age : int\l|+ die() : void\l}"
]

If you're not familiar with the dot syntax, it will look awkward to you. But let's look at what this class looks like after using dot:

The basic Animal class example generated by dot.

Seeing this should give you an idea about how the dot syntax works.

Why the Animal class looks like this

The label property we've set for the Animal node does a few things:

  • The opening and closing curly braces "{" and "}" indicate that we want to create a "record" shape with multiple dividers.
  • The pipe characters "|" indicate the dividers, we use one to separate the class name from the attributes and another one to separate the methods from the attributes.
  • Putting the "\l" characters after a line of text indicates the line should be aligned to the left side of the shape and that a new line of text should start.

Trying it for yourself

To generate the Animal example yourself, copy and paste the following code in a file called "class.dot":

digraph G {
fontname = "Bitstream Vera Sans"
fontsize = 8 node [
fontname = "Bitstream Vera Sans"
fontsize = 8
shape = "record"
] edge [
fontname = "Bitstream Vera Sans"
fontsize = 8
] Animal [
label = "{Animal|+ name : string\l+ age : int\l|+ die() : void\l}"
]
}

Now, open a terminal in the directory you've created this file and call the dot tool like this:

dot -T png -o class.png class.dot

This will generate a PNG file with the Animal class model in it. For the rest of the article, I will assume that you can add closing braces yourself, so I won't give you the full code for each example anymore.

Futher Modelling

Creating the Dog and Cat classes

The Dog and Cat classes are actually quite simple once you've seen the Animal class. Add the following lines after the Animal class and before the closing curly brace:

        Dog [
label = "{Dog||+ bark() : void\l}"
] Cat [
label = "{Cat||+ meow() : void\l}"
]

If you run dot on the resulting file, you'll see the three classes without any associations or relations between them:

The three classes: Animal, Dog and Cat.

Modelling the subclass relation

Dog and Cat should be subclasses of Animal. Let's add two lines originating from Dog and Cat and ending at the Animal class with an empty arrowhead, UML's way of expresing a subclass relation. Enter the following lines after the Cat declaration, but before the ending curly brace:

        edge [
arrowhead = "empty"
] Dog -> Animal
Cat -> Animal

You can see the arrowhead being set to "empty" in the second line. The lines with "->" in them describe the directed relations. Dog points to Animal, Cat points to Animal: both subclass relationships are defined in those lines. Using dot, the UML diagram now looks like this:

The three classes and the subclass relations are now modelled.

Modelling the "arch-enemy" association

Let's add the N:M relationship between Dog and Cat. I used the following lines in my dot file, enter these after the subclass relation lines but before the closing curly brace:

        edge [
arrowhead = "none" headlabel = "0..*"
taillabel = "0..*"
] Dog -> Cat

The second line disables the arrowhead, necessary because association do not exhibit a graphival direction. The "headlabel" and "taillabel" values describe the texts shown at the beginning and end of the edge. In the case of a N:M relation, both of these labels should read "0..*". The last line adds an edge between the Dog and Cat class. After running dot, the result is this:

The arch-enemy association between Dog and Cat is now modelled.

Modelling the package

Adding the package to the mix is a bit more complicated, you'll need to add two lines before the declaration of the Dog class:

        subgraph clusterAnimalImpl {
label = "Package animal.impl"

Add a closing brace "}" just below the Cat class declaration.

The first line tells dot that the coming nodes are to be clustered together in a box. The second line describes the label of the box. The name of the subgraph is very important: only subgraphs having a name starting with "cluster" are drawn together inside a box.

Conclusion

The end result

The resulting dot file should look like this:

digraph G {
fontname = "Bitstream Vera Sans"
fontsize = 8 node [
fontname = "Bitstream Vera Sans"
fontsize = 8
shape = "record"
] edge [
fontname = "Bitstream Vera Sans"
fontsize = 8
] Animal [
label = "{Animal|+ name : string\l+ age : int\l|+ die() : void\l}"
] subgraph clusterAnimalImpl {
label = "Package animal.impl" Dog [
label = "{Dog||+ bark() : void\l}"
] Cat [
label = "{Cat||+ meow() : void\l}"
]
} edge [
arrowhead = "empty"
] Dog -> Animal
Cat -> Animal edge [
arrowhead = "none" headlabel = "0..*"
taillabel = "0..*"
] Dog -> Cat
}

Running this file through dot gives the following UML diagram:

The end result of our dot modelling work.

Further ideas

I hope this article provided a good starting point for drawing UML diagrams automatically using dot. See the UMLGraph website for more ideas on implementing extensions to the basic ideas. I hope you found this information useful.

About this article

This article was added to the site on the 1st of April 2006.

UML Diagrams Using Graphviz Dot的更多相关文章

  1. How to generate UML Diagrams from Java code in Eclipse

    UML diagrams compliment inline documentation ( javadoc ) and allow to better explore / understand a ...

  2. 将 Graphviz .dot 文件转换为其他格式的图像

    参考: Graphviz: How to go from .dot to a graph? 将 Graphviz .dot 文件转换为其他格式的图像 在Linux系统下,使用以下命令: dot -Tp ...

  3. UML类图(Unified Modeling Language Class Diagrams)

    统一建模语言(UML) |  类图 什么是UML? UML是一种用于可视化描述系统,具有广泛用途的建模语言.作为一种标准化的图形语言,在软件工业中被用于软件系统部件的具体化,可视化,结构化描述以及撰写 ...

  4. 使用DOT语言和Graphviz绘图(翻译)

    Casa Taloyum About Me Blog Archives 使用DOT语言和Graphviz绘图(翻译) Date Wed 26 November 2014 Tags graphviz / ...

  5. Tools - UML

    ProcessOn - 在线绘图工具 ProcessOn 支持流程图.思维导图.原型图.UML.网络拓扑图等: 主流的UML图列都支持,可以作为方便快捷的UML工具: PlantUML - 多系统多编 ...

  6. Linux命令之dot - 绘制DOT语言脚本描述的图形

    本文链接:http://codingstandards.iteye.com/blog/840055 用途说明 Graphviz (Graph Visualization Software的缩写)是一个 ...

  7. 【实践】源代码分析工具Doxygen+Graphviz

    拿到一个新项目或者一个开源框架,看源代码的方式不是先进行单步调试!最好的方式是先画出整个项目或者开源框架的类.协作.已经方法调用图,能够帮助你更快的理解框架或者项目的设计. 打包下载地址:http:/ ...

  8. 转:深入浅出UML类图(具体到代码层次)

    深入浅出UML类图 作者:刘伟 ,发布于:2012-11-23,来源:CSDN   在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML ...

  9. 深入浅出UML类图(一)

    在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML Distilled: A Brief Guide to the Standard O ...

随机推荐

  1. 【Java 线程的深入研究4】ThreadPoolExecutor运转机制详解

    hreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调 ...

  2. MySQL索引覆盖

    什么是“索引覆盖”? 简单来的说,就是让查询的字段(包括where子句中的字段),都是索引字段.索引覆盖的好处是什么?好处是极大的.极大的.极大的提高查询的效率!重要的说三遍! 特别说明: 1.whe ...

  3. jQuery中return false,e.preventDefault(),e.stopPropagation()的区别

    e.stopPropagation()阻止事件冒泡 <head> <title></title> <script src="Scripts/jQue ...

  4. POJ 3211 Washing Clothes 背包题解

    本题是背包问题,可是须要转化成背包的. 由于是两个人洗衣服,那么就是说一个人仅仅须要洗一半就能够了,由于不能两个人同一时候洗一件衣服,所以就成了01背包问题了. 思路: 1 计算洗完同一颜色的衣服须要 ...

  5. js 自函数

    函数基本概念: 函数声明:function box(){} 函数表达式:var box = function(){}; 匿名函数:function(){} 属于函数表达式 匿名函数的作用:如果将匿名函 ...

  6. 用MathType怎么编辑带圈数字序号

    在用MathType编辑公式时,涉及到的数学公式与符号这些都能编辑出来,只要你能够细心一点找到它们相应的模板,不管是在word公式编辑器MathType工具栏模板中,还是在插入符号之后的面板中都可以. ...

  7. OpenCV学习:实现简单的图像叠加

    本实例使用简单的线性叠加方法来实现两幅图像的叠加,主要使用的知识如下: 1)线性融合 2)addWeighted函数 //! computes weighted sum of two arrays ( ...

  8. Leetcode: Best Time to Buy and Sell Stock I, II

    思路: 1. 算法导论讲 divide and conquer 时, 讲到过这个例子. 书中的做法是先让 price 数组减去一个值, 然后求解最大连续子数组的和. 分治算法的复杂度为 o(nlogn ...

  9. python2.0_day21_web聊天室一

    bbs系统项目中我们用到的ajax不多,但是在聊天室里用到的全是ajax,所以本项目的主要内容就是:前端使用ajax传输json格式的数据是本节的重点以及 前端函数的的使用.http协议的特点是:短链 ...

  10. python2.0 s12 day8 _ socketserver学习

    Socket 概念 一个socket就是一个点对点的链接.当今,大多数的通信都是基于Internet Protocl,因此大多数的网络Socket都是Internet Protocl(互联网)的通信( ...