Graphviz学习(二)——有关Graphviz的概述

           (一)、总的架构

             今天我们讲一下Graphviz的概述,从前一章我们明白,Graphviz不只是一个解释器那么简单,它还包含着包括C接口在内的诸多接口,事实上,Graphviz可以根据用户的需求,在运行的各个环节进行定制和嵌入,下面这张概念图,是我对Graphviz机制的了解:

                                

            在这里,我们会一一解释,并且讨论几个关键的地方:C接口、布局计算与渲染。

            首先看一看输入,Graphviz的输入包括三个:脚本输入(DOT)、编程语言输入(C语言、Python语言甚至是Java语言、PHP)、图形界面输入。事实上,无论是那一种输入,到最后都会调用C接口输入。

            然后就是C语言接口,也就是我们上一章所说的C语言接口的例子,着一个环节主要将输入变成Graphviz可以识别的内部格式,也就是用于描述图的数据结构,包括Agraph_t、Agnode_t、Agedge等等。

            产生内部格式后,程序应该交给Graphviz预定义的布局引擎进行计算,这个过程将会计算出图的各个元素的集合信息,例如节点的位置、大小、形状;边的形状(Graphviz使用贝塞尔曲线显示边)等等。同时,用户还可以自己定制自己的布局引擎。

            下一步就是将内部格式转换为可以被用户所了解的格式,也就是渲染环节,这一环节使用的机制称为渲染引擎,经过渲染,可以将信息转换为DOT格式(就是脚本,可以用于存储、调试)、图片(有很多、我就不说了)。用户也可以定制自己的渲染引擎,以生成其它格式,或者向用户程序生成图像。

            在Graphviz的C接口,也就是GVC中,封装了其中的三个模块:数据结构以及操作、布局引擎、渲染引擎。每一个模块都可以单独使用,使之嵌入到应用程序之中,并且布局引擎以及渲染引擎可以由用户定制,执行用户自己指定的行为。例如,我们将使用布局引擎嵌入至应用程序之中,应用程序可以使用布局引擎的计算结果,去指导应用程序的绘图;可以定制自己的渲染模块,使输出格式更为多样。

 

            (二)、关于数据结构

               1. 在gvc(Graphviz的C语言封装)中、最重要的数据结构莫过于这三个:Agraph_t、Agnode_t、Agedge_t。这三个数据分别代表图(子图)、节点、边。gvc中所有操作可以说是围绕这三个元素进行的,也可以分为两类:结构操作、属性操作。

                通过结构操作,用户可以完成对图的结构的构建,如agedge(graph,node1,node2,name,flag),会生成一个图graph中的边,边的两端为node1与node2,标识(不是label)为name。这些操作都可以导致图结构的变动。

                通过属性操作,用户可以完成对图中元素属性的改动,Graphviz提供了大量的属性,用户甚至可以定义自己的属性,因此具有良好的自由度和重用性。值得一提的是,Graphviz的属性只接受字符串形式,也就是说,我们提取和指定属性时,即使属性是数值型或其他不是字符串的类型,也要转换为字符串,Graphviz会通过内部的转换机制,将字符串转换为相应的类型;同时,属性必需先初始化,再提取和指定,没有初始化的情况下,Graphviz会使用内部预定义的默认值,比如字体的颜色属性fontcolor默认是黑色、字体名称fontname默认时Times-Roman、字体大小fontsize默认时14。

                2.经过布局计算,计算结果将会储存至数据结构自身的其他字段当中之中,由于Graphviz向用户隐藏了数据结构的具体细节,用户只能通过特定的接口,而不是直接通过结构的定义,去访问布局计算的结果;访问计算结果的接口定义在头文件include/graphviz/types.h中,形式为ElemType_ResultField(ElemHandle),ElemType_为元素的类型前缀,图的前缀为GD_,节点的前缀为ND_,边的前缀为ED_;如果我要访问某一个节点的形状,可以使用宏ND_shape(instance)->name,类型为char*。

                3.关于内存问题,以下几个部分的内存,是需要程序员自己管理的,以防止内存溢出:一是GVC的句柄GVC_t,再GVC使用之前要使用gvContext()产生,再使用完毕后要使用gvFreeContext(gv)进行回收;二是,数据结构,例如图Agraph_t,使用完毕后也要使用agclose(g),来回收,只要不是顶层的元素,例如子图、节点、边、属性句柄,他们在创建的时候就已经被顶层数据结构所标记,因此回收时不需要显式的回收,因为顶层回收时会自动回收,但是,如果中途就不使用这一个元素了,就要显式的回收,例如Agnode_t使用agdelnode回收;三是,布局结果需要显式回收,一般使用gvFreeLayout(gv,g)进行回收。

 

            (三)、关于脚本语言

            再Graphviz之中,使用的最多的莫过于脚本语言,相比C接口,脚本语言跟加便捷易懂,也不需要使用太多的精力去学习。一般说,C接口主要用于对Graphviz进行扩展以及嵌入到一些应用程序之中。

            可以使用dot程序生成带有汉字信息的图片,需要注意两点,否则生成的图片中汉字会被显示为乱码:一是文件应该使用UTF-8编码保存(再Windows的要注意了,不是默认的ANSI编码);二是、字体应该指定为支持汉字的字体,如宋体SimSun,一般最好使用一些大多数平台共用的字体例如Times字体。

            

转载于:https://my.oschina.net/goodmoon/blog/757220

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值