Está en la página 1de 4

PRCTICO Graphviz

Visualizacin de grficos con Graphviz

KIT DEL DIBUJANTE


El empleo de herramientas de dibujo para crear grficos y diagramas de forma manual puede resultar lento y complicado. La caja de herramientas Graphviz ofrece un camino ms rpido. Basndose en un breve texto con la informacin para el grfico, Graphviz genera rpidamente un dibujo claro. POR TIM SCHRMANN.
rahpviz es una aplicacin muy til si necesitamos un mtodo automatizado de generacin de grficos (vase el cuadro Terminologa). Los usuarios de ordenador suelen ir dando tumbos cuando se trata de este tema, desde los diagramas E / R para visualizar esquemas de bases de datos hasta las estructuras jerrquicas de rbol que representan las acciones de una organizacin o una cadena de mando. Normalmente, la informacin se sita en cajas cuadradas que deben estar colocadas cuidadosamente, sin superponerse a otras, antes de dibujar cualquier flecha de conexin. En este tipo de desafos destaca Graphviz: el usuario slo tiene que especificar las relaciones entre elementos, y la herramienta devuelve, de forma autom-

tica, un dibujo atractivo. No es preciso buscar un editor de grficos en el que poder especificar las relaciones, ya que, en su lugar, Graphviz lee una descripcin de texto del grfico en un lenguaje de marcas especial (LaTeX emplea un mtodo parecido, aunque ambos sistemas no tienen nada que ver salvo esto). Graphviz se incluye en todas las distribuciones populares de Linux desde hace aos. Instalar el paquete es simple: slo con un click en nuestro gestor de paquetes favorito. Tambin podemos bajar la ltima versin del cdigo fuente desde su pgina de inicio [1], y seguir el mtodo estndar para construir e instalar:
:configure; make; make install

Sea cual sea la forma elegida, deberamos tener una coleccin de herramientas en el disco duro cuando acabemos.

No te Olvides de Escribir
Antes de comprobar las aptitudes de las herramientas de Graphviz, necesitaremos una descripcin del grfico que queremos crear. Para

Listado 1: ejemplo1.dot
01 digraph G { 02 /* El padre tiene un hijo y una hija: */ 03 padre -> hijo; 04 padre -> hija; 05 }

46

Nmero 29

WWW.LINUX- MAGAZINE.ES

Graphviz PRCTICO

Alerta Roja
Si la descripcin no indica lo contrario, dot crear nodos ovalados con una etiqueta con su nombre. Vamos a cambiar esto en el ejemplo aadiendo el nombre y apellido del padre y empleando rectngulos rellenos de rojo. El lenguaje dot tiene un nmero de atributos que nos ayudan a implementar los cambios. Para modificar uno concreto, como el color de la etiqueta, le cambiamos su valor:
Figura 1: La descripcin del Listado 1 crea este grfico dirigido.

color = red label = John Smith

ello, debemos escribir un archivo de texto en el lenguaje dot, muy sencillo de aprender. Como ejemplo, el Listado 1 implementa un grfico simple y directo. La descripcin comienza por definir un grfico llamado G con tres nodos: padre, hijo e hija. Al contrario que en otros lenguajes de programacin, no es necesario declararlos de forma explcita. Podemos utilizarlos directamente. La flecha especifica cules estn conectados, y los bucles estn permitidos. El siguiente apuntara a s mismo:
padre - > padre

Deberemos separar con comas los atributos y aadirlos al nombre del nodo con corchetes. En el caso del padre, la sintaxis sera como sigue:
padre [shape = box,U style = filled, color = red,U label = John Smith];

Figura 2: Basta con un par de instrucciones de Graphviz para ponerle color rojo al nodo del padre.

El rbol genealgico se muestra en el Listado 2, y podemos ver los resultados tras pasar la descripcin por dot en la Figura 2.

Uno para Todos


Cambiar la forma de todos los nodos en un grfico grande puede parecer mucho trabajo. El lenguaje de etiquetado dot emplea dos palabras clave (node y edge) para facilitar la tarea. Al cambiar sus atributos, cambian los de todos los elementos del grfico. Por ejemplo, el siguiente texto:
digraph G ( node [shape = box]; ... )

Un punto y coma opcional termina cada lnea. Como puede verse a partir de la llave, la sintaxis se model en esto como el lenguaje C, que tambin es la inspiracin para el sistema de comentarios al cdigo, que emplea /* para abrir y */ para cerrar.

Lo siguiente es insertar esta lnea en algn lugar en el grfico, bajo las llaves. El mtodo recomendado es definir primero la apariencia de los nodos antes de ir a definir los extremos. Si nos ha funcionado con los nodos, podemos esperar con seguridad que funcionar para los extremos. El usuario tambin puede cambiar su color, su estilo de lnea o aadirle etiquetas. Una vez ms, todo lo que debemos hacer es aadir pares de valores en corchetes al *borde en cuestin, como en el ejemplo que sigue:
padre -> hija [style = bold,U label = primognita,U color = blue];

Empleo de Dot
Para convertir esta descripcin en un dibujo, necesitamos usar la herramienta dot. Es confuso, pero el programa comparte nombre con el lenguaje de etiquetado. El siguiente comando crea un archivo PNG (Figura 1):
dot -Tpng ejemplo1.dotU -o ejemplo1.png

asigna un marco rectangular a todos los nodos (a menos que el nodo individual contenga rdenes que indiquen lo contrario). La instruccin edge hace lo mismo para los extremos. Por ejemplo el cdigo:
digraph G ( node [shape = box]; ... )

Alternativas
Los programas de Graphviz esperan una breve descripcin del grfico, que convertirn automticamente en un dibujo. Esto deja al usuario pocas opciones para influir en el tipo de resultados que obtienen. Si aprecias los beneficios que puede aportarte un lenguaje descriptivo, pero prefieres tener ms control granular sobre la posicin y forma de cada uno de los elementos individuales del grfico, podras preferir uno de los competidores de Graphviz: Asymptote [2] y GLE [3], en particular, merecen especial atencin. Podemos acceder a ambos desde LaTeX. Los lenguajes basados en XML, como SVG [4], siguen un mtodo parecido; sin embargo, hay muy poco software en esta lnea por ahora.

Listado 2: ejemplo2.dot
01 digraph G { 02 padre [shape = box, style = filled, color = red, label =John Smith]; 03 hija [label =Petra]; 04 hijo[label = Patrick]; 05 padre -> hijo; 06 padre -> hija [style = bold, label = first-born, color = blue]; 07 }

Adems de esto, dot soporta PostScript (parmetro -Tps), JPG, Gif, Fig, SVG y un buen nmero de otros formatos ms o menos exticos. La salida PDF directa no est implementada todava, pero podemos usar la herramienta GhostScript ps2pdf como solucin provisional. No hay que olvidarse especificar el -o junto al nombre de archivo. De este modo la herramienta enviar el archivo final directamente a la consola. Lo mismo se aplica al parmetro T; sin l, dot slo enviar la descripcin de texto del dibujo.

WWW.LINUX- MAGAZINE.ES

Nmero 29

47

PRCTICO Graphviz

Figura 5: Los slots del Listado 5 soportan el tipo de nodos que necesitas visualizar, como funciones hash o agrupaciones. Figura 3: La descripcin del Listado 3 remarca el subgrfico con los hijos.

No Dirigidos
Los grficos dirigidos son la especialidad de dot; si necesitamos grficos no dirigidos, podemos usar otra herramienta de la coleccin: neato. De nuevo, el programa espera descripciones en dot; sin embargo, slo soporta la palabra clave graph, en lugar de digraph. Los extremos dirigidos se convierten en no dirigidos empleando . El Listado 6 muestra un ejemplo. Las Figuras 6a y 6b prsentan los diagramas creados por dot y neato. Las herramientas dot y neato emplean diferentes algoritmos de dibujo. Mientras que dot organiza los nodos jerrquicamente, neato reemplaza los extremos por tentculos virtuales, y emplea gravedad simulada para calcular la distancia correcta entre nodos, creando as una composicin simtrica. Las herramientas twopi y circo tambin son dignas de atencin. Organizan los nodos en patrones cir-

Divisible
Los subgrficos son tambin muy tiles. Pueden utilizarse para agrupar nodos que deberan estar juntos. El Listado 3 es un ejemplo. En este caso, hemos introducido un subgrfico que contiene al hijo y la hija. Para indicarle a dot que subraye el grupo en el resultado final, debemos colocar el prefijo cluster delante del nombre. Los dems atributos pertenecen al subgrfico; en este caso, definen el color y la etiqueta. La Figura 3 muestra el resultado.

Figura 4: El pequeo diagrama UML definido en el Listado 4.

node [shape = record]

Clases
Hasta ahora, slo se han puesto etiquetas simples a los nodos. Sin embargo, la clase de diagramas UML a la que me refera antes necesita nodos con mltiples subdivisiones. Para realizar este trabajo en dot, primero tendrs que cambiar el marco a un modo espacial: record.

A partir de este punto del cdigo, dot crear una etiqueta especial para el nodo, aadiendo lneas verticales para subdividirlo en secciones mltiples:
empleado [label =U {Empleado|+ salario :U int\l+ nombre : string\l |U tarea() : void\l} ]

Listado 3: ejemplo3.dot
01 digraph G { 02 subgraph cluster_children { 03 style = filled; 04 color = lightgrey; 05 label = Hijos; 06 07 hija [label =Petra]; 08 hijo [label = Patrick]; 09 } 10 11 padre [label = John Smith]; 12 13 14 15 padre -> hija; padre -> hijo; }

El tag \l justifica el texto, y las llaves introducen barras verticales. Esto nos da una representacin ms o menos perfecta de la clase UML; todo lo que necesitamos ahora son etiquetas para los extremos. En UML, las cardinalidades pueden colocarse en ambos extremos de un borde. Para esto, podemos emplear los atributos headlabel y taillabel:
edge [headlabel = 1,U taillabel = 1..* ]

Listado 4: Diagrama UML


01 digraph G { 02 node [shape = record] /* se dibujan las lneas verticales de la etiqueta */ 03 edge [arrowhead = none, headlabel = 1, taillabel = 1..* ] 04 /* las llaves significan: dibuja una lnea horizontal, y no una barra vertical (gira la caja 90 grados)*/ 05 empleado [label = {Empleado|+ salario : int\l+ name : string\l | + work() : void\l} ] 06 corporacion [label = {Corporacion| | + pagarsalario() : void\l} ] empleado -> corporacion 07 }

Para un ejemplo de una pequea descripcin de un diagrama UML, fijmonos en el Listado 4. La Figura 4 muestra el diagrama resultante.

Slots
Un record, o registro, puede hacer mucho ms que esto. El usuario puede emplear divisiones en el nodo para controlar los enlaces a mltiples nodos subsiguientes. El Listado 5 y la Figura 5 ensean cmo funciona. Los parntesis angulados (< >) marcan puntos especiales, conocidos como slots, a partir de los cuales las flechas del diagrama empiezan o terminan.

48

Nmero 29

WWW.LINUX- MAGAZINE.ES

Graphviz PRCTICO

necesitamos, siempre podremos crear un programa C para acceder a las funciones de la librera Graphviz. Esta librera tiene algunas muy prcticas para compilar archivos Figura 6a: El grfico no dirigido del Listado 6, renderizado por dot. basados en texto en formato dot y proyectar los culares; para ms detalles de los algoritresultados sobre una estructura de datos mos que hacen esto, puede ojearse la designada explcitamente para este propsito. documentacin de Graphviz [5]. Tambin podemos manipular grficos en memoria y mostrar los resultados. El proTuberas y Filtros grama que aparece en el Listado 7 ofrece un Con una ayudita de tuberas y filtros, la herrabreve ejemplo: Compila un texto con mienta de lnea de comandos dot tambin comandos dot, dibuja un grfico con una puede emplearse para programar, o integrado pequea ayuda del algoritmo dot y muestra en otros programas en Linux. Para ello, debeel resultado en pantalla. De hecho, el remos preparar primero la descripcin del grmismo dot est construido de un modo fico en un bfer de texto, pasarlo a dot y utilisimilar. zar el resultado. Un guin shell podra funcioExisten unos cuantos programas de ejemnar de esta forma, por ejemplo: plo en el directorio dot.demo que viene con el paquete del cdigo fuente. La pgina web de echo *digraph G (padre -> hijo;U Graphviz incluye referencias exhaustivas para padre -> hija;}* | U API. Si empleamos API para nuestro trabajo dot -Tpng > ejemplo7.png de desarrollo, ntese que las libreras aparecen bajo licencia Common Public. Aqu vemos que la salida de dot est, simpleConclusiones mente, redireccionada a un archivo; por supuesto, ste podra ser otro guin shell o Una vez que nos hayamos acostumbrado cdigo, para procesamiento posterior. a los trminos del lenguaje de descripEl editor grfico, dotty, funciona del mismo modo. No es particularmente cmodo, pero permitir crear grficos con un click de ratn. Si todas estas opciones no ofrecen lo que

cin de grficos, dot, apreciaremos las herramientas del paquete Graphviz. Es difcil encontrar un mtodo ms rpido de crear grficos. Gracias a las tuberas y filtros, dot y compaa son fciles de integrar con otras secuencias y guiones de shell. Adems, si el paquete no termina de gustarnos, siempre podemos buscar en el cuadro Alternativas para I algunos similares.

Listado 7: API en C con Graphviz


01 #include <gvc.h> 02 03 04 05 06 07 08 09 10 11 12 context = gvContext(); fp = fopen(ejemplo.dot, r); graph = agread(fp); /* Compila grfico */ gvLayout(context, graph, dot); /*Crear capa con el algoritmo de dot */ 13 gvRender(context, graph, png, stdout); /* Muestra grfico en pantalla en formato PNG */ 14 15 16 /* Limpia */ gvFreeLayout(context, graph); agclose(graph); gvFreeContext(context); } int main() { GVC_t *context; graph_t *graph; FILE *fp;

Listado 5: Uniones Complejas


01 digraph G 02 03 04 05 06 07 08 09 10 11 padre:center -> son: left; padre:center -> hija:right; } { node [shape = record]; /* Los Puertos se muestran con corchetes */ padre [ label =<left> | <center> Padre | <right>]; hijo [ label =<left> | <center> Hijo | <right>]; hija [ label =<left> | <center> Hija | <right>]; Figura 6b: El grfico no dirigido del Listado 6, renderizado por neato.

17 18

Listado 6: Grficos no Dirigidos


01 graph G { 02 03 04 05 06 07 08 server cliente_smith server cliente_miller; server cliente_turner; server cliente_meier; } server [label = Servidor principal Leo];

RECURSOS
[1] Pgina de Graphviz: http:// www. graphviz. org [2] Pgina de Asymptote: http:// asymptote. sourceforge. net [3] Pgina de GLE: http://www. gle-graphics. org [4] Especificaciones del formato SVG: http:// www. w3. org/ Graphics/ SVG/ [5] Informacin sobre los algoritmos usados por Graphviz: http://www. graphviz. org/Documentation.php

WWW.LINUX- MAGAZINE.ES

Nmero 29

49