Affichage des articles dont le libellé est graphes. Afficher tous les articles
Affichage des articles dont le libellé est graphes. Afficher tous les articles

mercredi 14 avril 2010

graphviz : générer des graphes en ligne de commande


Description


L'outil en ligne de commande graphviz créé par ATT permet de générer des graphes orientés ou non, circulaires ou non à partir d'un fichier texte de description.
Voici quelques exemples permettant de générer des graphes hautement paramétrables.


Exemple d'un fichier de configuration


Un fichier de configuration simple comprend :
  • le type de graphe i.e. "graph" pour un graphe non-orienté.
  • le nom du projet i.e. "mcd" dans cet exemple.
  • des noeuds "node" définis par une forme "shape" et des objets à créer "voiture" et "marque".
  • chaque noeud est caractérisé par du texte décrit entre des crochets "[label="personne|insee\nnom\nprenom"]".
  • des liens ( non-orientés ici liant deux objets à la fois ( encore que ) comme "voiture -- "fabriquer" [label="1,1"]".
  • un titre, voir "label" et "fontsize" en fin de code.

à supposer que le fichier d'exemple ci-après se nomme mcd.xml,
pour générer une image nommée "mcd.png", il faut lancer en ligne de commande :
dot.exe -Tpng -omcd.png mcd.txt -Gcharset=latin1

graph mcd {
node [shape=box]; voiture; marque;
node [shape=record]; personne;
node [shape=ellipse,style=filled,color=lightgrey]; "posseder"; "fabriquer";

personne [label="personne|insee\nnom\nprenom"];

personne -- "posseder" [label="0,n"];
"posseder" -- voiture [label="1,1"];

voiture -- "fabriquer" [label="1,1"];
"fabriquer" -- marque [label="1,n"];

label = "\n\nMCD by NEATO";
fontsize=16;
}



Quelques fonctions avancées


Voici quelques paramètres et autres types de données permettant d'améliorer la lecture des graphes :
  • "#rankdir=LR ;" permet d'écrire les noeuds de gauche à droite.
  • "subgraph" permet de définir des sous-graphes avec des composants connexes.
  • "\n" dans des labels permet des sauts de ligne.
  • Les noeuds liés peuvent être chaînés linéairement : "sql0 -> sql1 -> sql2 -> sql3 -> sql4 -> sql5 ;".
  • Les noeuds liés peuvent être chaînés par destination : "sql4 -> { sql0 ; sql2 }".
  • définir des compartiments "boîte" dans les labels : "e0 [shape="record",label="e0|{0|0}"] ;".
  • le couplage de graphviz à un dictionnaire de données pour analyser un schéma ( utilisateur "scott" d'Oracle ) permet de visualiser graphiquement les tables. L'outil SchemaSpy génère le même genre de graphe et s'appuie sur graphviz ! ...


digraph wc_sql
{
#rankdir=LR ;
edge [color="tan",fontname="arial"] ;
node [color="white",fontname="arial",fontsize="10",shape="box",style="filled"] ;
bgcolor="white" ;
fontname="arial";
fontsize="10";

subgraph cluster_uml
{
color="whitesmoke"
style="filled" ;
label="SQL" ;

sql0 [label="étape\nSQL",color="orange",shape="ellipse"] ;
sql1 [label="vérifier\ntaille sources"] ;
sql2 [label="dropper le package généré \n(en cas de besoin)"] ;
sql3 [label="builder les packages"] ;
sql4 [label="vérifier\nvalidité",color="darkorange",shape="ellipse"] ;
sql5 [label="étape\njava",color="orange",shape="ellipse"] ;

sql0 -> sql1 -> sql2 -> sql3 -> sql4 -> sql5 ;

sql4 -> { sql0 ; sql2 } [ label="tant que pas OK" ,color="red",fontname="arial",fontsize="10" ] ;
sql1 -> sql0 [ label="tant que pas OK" ,color="red",fontname="arial",fontsize="10" ] ;
}
}


"Diagramme PERT"


digraph PERT {

rankdir="LR" ;

e0 [shape="record",label="e0|{0|0}"] ;
e1 [shape="record",label="e1|{5|5}"] ;
e2 [shape="record",label="e2|{7|17}"] ;
e3 [shape="record",label="e3|{13|13}"] ;
e4 [shape="record",label="e4|{16|17}"] ;
e5 [shape="record",label="e5|{23|24}"] ;
e6 [shape="record",label="e6|{0|3}"] ;
e7 [shape="record",label="e7|{3|6}"] ;
e8 [shape="record",label="e8|{4|7}"] ;
e9 [shape="record",label="e9|{8|13}"] ;
e10 [shape="record",label="e10|{4|15}"] ;
e11 [shape="record",label="e11|{13|13}"] ;
e12 [shape="record",label="e12|{15|15}"] ;
e13 [shape="record",label="e13|{24|24}"] ;

e1 -> e2 [label="j 2"] ;
e2 -> e4 [label="---"] ;
e3 -> e4 [label="k 3"] ;
e4 -> e5 [label="l 7"] ;
e5 -> e13 [label="---"] ;

e0 -> e6 [label="---"] ;
e6 -> e7 [label="a 3"] ;
e7 -> e8 [label="b 1"] ;
e7 -> e9 [label="c 5"] ;
e8 -> e10 [label="e 4"] ;
e8 -> e11 [label="d 6"] ;
e9 -> e11 [label="---"] ;
e10 -> e12 [label="---"] ;

e0 -> e1 [label="h 5"] ;
e1 -> e3 [label="i 8"] ;
e3 -> e11 [label="---"] ;
e11 -> e12 [label="f 2"] ;
e12 -> e13 [label="g 9"] ;

{
rank="same" ;
node [ fillcolor="red"] ;
e0 ; e1 ;
}

label = "\n\nPERT by DOT";
fontsize=16;
}











Autres exemples de graphes










































 

 

 

 

 

 

 

 

 





Programme java permettant de traiter tous les fichiers txt d'un même répertoire


import java.io.File;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Map.Entry;


public class TaiterFichiersDot
{
//-------------------------------------------
String dotPath = "\"C:\\Program Files\\ATT\\Graphviz\\bin\\dot\"" ;
String rep = "C:/_cmd/" ;
String repWin = "C:\\_cmd\\" ;
String format = "png" ;
String winShell = "c:\\WINNT\\system32\\cmd.exe /K " ;
SortedMap<String, String> smFichiers = new TreeMap<String, String>() ;
int nb = 0 ;
int nbOk = 0 ;
int nbKo = 0 ;
//-------------------------------------------
TaiterFichiersDot()
{
}
//-------------------------------------------
void faire()
{
lireRep(rep) ;
for(Entry<String, String> entry : smFichiers.entrySet())
{
{
String fic = entry.getValue() ;
executerCommandLine(fic) ;
}
}
}
//-------------------------------------------
String construireCommande( String _fichier )
{
return dotPath + " -T" + format + " -o" + repWin + "" + _fichier + "." + format + " " + repWin + "" + _fichier + " -Gcharset=latin1" ;
}
//-------------------------------------------
void lireRep( String _rep )
{
String [] s = new File(_rep).list();
int iMax = s.length ;
int i ;
String ff,match,matchLow ;
//
for ( i=0 ; i<iMax ; i++ )
{
ff = s[i].toLowerCase() ;
if ( ff.endsWith(".txt"))
{
match = s[i] ;
matchLow = match.toLowerCase() ;
smFichiers.put(matchLow,match) ;
nb++ ;
}
}
}
//-------------------------------------------
void afficherResume()
{
System.out.println("commandes OK : " + nbOk );
System.out.println("commandes KO : " + nbKo );
}
//-------------------------------------------
void executerCommandLine( String _fichier )
{
String chCmd = winShell + construireCommande(_fichier) ;
try
{
Runtime.getRuntime().exec(chCmd);
System.out.println("OK pour : "+chCmd);
nbOk++ ;
}
catch(Exception ie)
{
System.out.println("erreur : " + chCmd );
nbKo++ ;
}
}
//-------------------------------------------
public static void main(String[] args)
{
TaiterFichiersDot appli = new TaiterFichiersDot() ;
appli.faire() ;
appli.afficherResume() ;
}
//-------------------------------------------
}


Plus d'informations sur


  • Graphviz site ici.
  • Graphviz galleries ici.
  • Graphviz documentation ici.
  • Doxygen site ici.
  • SchemaSpy site ici.