Este documento introduce a la sintaxis de los archivos .dot para dibujar grafos con la herramienta graphviz
Para instalar graphviz en Lihuen, basta con poner como root en un terminal
#apt-get install graphviz graphviz-dev graphviz-doc
y aceptar.
Esto instala entre otras cosas, la aplicación dot que nos permitirá convertir un archivo .dot a un archivo .ps (PostScript) o .png (Portable Network Graphic) con el dibujo del grafo y las páginas del manual con el detalle de la sintaxis para dot.
Los archivos .dot tienen la siguiente sintaxis.
/*Esto es un comentario*/ graph nombre_del_grafo { "idNodo1"; "idNodo2"; /*estos son identificadores de nodos*/ "idNodo3"; "idNodo1" -- "idNodo2"; "idNodo1" -- "idNodo3"; /*estas son relaciones entre nodos*/ "idNodo3" -- "idNodo1"; }
Para compilar el siguiente código escribimos en la terminal
$dot ejemplo1.dot -o ejemplo1.png -Tpng -Gcharset=utf8
Donde ejemplo.dot es el archivo que contiene el código, ejemplo1.png es el archivo con el grafico generado y -Tpng para que el tipo del archivo de salida sea png (Cambiar por -Tps para ps o -Tjpg para jpg, etc.). Así, se genera el siguiente gráfico:
Con esto generamos un grafo no dirigido con 3 nodos. Es posible mostrar una etiqueta para un nodo en lugar de su id. Por ejemplo:
graph nombre_del_grafo { "idNodo1" [label="Nodo"]; "idNodo2" [label="Nodo"]; "idNodo3" [label="Nodo"]; "idNodo1" -- "idNodo2"; "idNodo1" -- "idNodo3"; "idNodo3" -- "idNodo1"; }
Compilando de vuelta con dot
$ dot ejemplo2.dot -o ejemplo2.png -Tpng -Gcharset=utf8
obtenemos el siguiente gráfico
Además de modificar el nombre que va a mostrar el nodo, podemos modificar algunas otras de sus propiedades como su forma, color, fuente, tamaño, etc. Por ejemplo el siguiente código:
graph nombre_del_grafo { "idNodo1" [label="Nodo", fillcolor="lightblue", style="filled", shape="triangle"]; "idNodo2" [label="Nodo", fillcolor="darkolivegreen4", style="filled", fontname="Courier"]; "idNodo3" [label="Nodo", fillcolor="mistyrose2", style="filled", shape="parallelogram"]; "idNodo1" -- "idNodo2"; "idNodo1" -- "idNodo3"; "idNodo3" -- "idNodo1"; }
Genera el gráfico
En este caso sólo se modifican las propiedades para cada nodo, para que todos los nodos tengan una determinada propiedad por ejemplo label="Nodo", se usa la instrucción node [atribs]. Estas propiedades son específicas para todos los nodos, pero pueden ser redefinidas para un nodo en particular
graph nombre_del_grafo { node [label="Nodo", style="filled"] /*Propiedades globales para todos los nodos*/ "idNodo1" [fillcolor="lightblue", shape="triangle"]; "idNodo2" [fillcolor="darkolivegreen4", fontname="Courier"]; "idNodo3" [label="Nodo Importante", fillcolor="mistyrose2", shape="parallelogram"]; /*Acá se redefine la etiqueta label*/ "idNodo1" -- "idNodo2"; "idNodo1" -- "idNodo3"; "idNodo3" -- "idNodo1"; }
Note la etiqueta del nodo que redefine la propiedad label...
Las aristas pueden tener diferentes trazos y colores y al igual que las propiedades de los nodos pueden modificar local o globalmente usando la instrucción edge [atribs].
graph nombre_del_grafo { edge [label="Arista", style="dashed", color="blue"]; /*propiedades globales*/ "idNodo1" [label="Nodo", fillcolor="lightblue", style="filled", shape="triangle"]; "idNodo2" [label="Nodo", fillcolor="darkolivegreen4", style="filled", fontname="Courier"]; "idNodo3" [label="Nodo", fillcolor="mistyrose2", style="filled", shape="parallelogram"]; "idNodo1" -- "idNodo2" [label="Arista Importante"]; "idNodo1" -- "idNodo3" [style="solid", color="red" ];/*propiedades sobreescritas*/ "idNodo3" -- "idNodo1"; }
Note las propiedades sobreescritas
<graph> ::= [ 'strict' ] ('graph' | 'digraph') [ ID ] '{' <stmt_list> '}' <stmt_list> ::= [ <stmt> [ ';' ] [ <stmt_list> ] ] <stmt> ::= <node_stmt> | <edge_stmt> | <attr_stmt> | ID '=' ID | <subgraph> <attr_stmt> ::= ('graph' | 'node' | 'edge') <attr_list> <attr_list> ::= '[' [ <a_list> ] ']' [ <attr_list> ] <a_list> ::= ID [ '=' ID ] [ ',' ] [ <a_list> ] <edge_stmt> ::= ('node_id' | 'subgraph') <edgeRHS> [ <attr_list> ] <edgeRHS> ::= <edgeop> (<node_id> | <subgraph>) [ <edgeRHS> ] <node_stmt> ::= <node_id> [ <attr_list> ] <node_id> ::= ID [ <port> ] <port> ::= ':' ID [ ':' <compass_pt> ] | ':' <compass_pt> <subgraph> ::= [ <subgraph> [ ID ] ] '{' <stmt_list> '}' <compass_pt> ::= ('n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw')