web-dev-qa-db-fra.com

Graphviz sort un gâchis

J'essaie de visualiser les données suivantes au format dot en utilisant GraphViz:

digraph n {
  node [nodesep=2.0, fontsize=11];
  graph [ overlap=false];
  Edge[weight=0.2];
  A -> B [label="I/5"]
  A -> A [label="*/0"]
  A -> C [label="ii/2"]
  A -> H [label="vii/1"]
  B -> D [label="iii/1"]
  B -> E [label="IV/2"]
  B -> F [label="V/2"]
  B -> B [label="vi/2"]
  C -> F [label="V/2"]
  C -> H [label="vii/1"]
  D -> E [label="IV/2"]
  E -> D [label="iii/2"]
  E -> G [label="iv/1"]
  E -> F [label="V/3"]
  F -> B [label="I/4"]
  F -> B [label="vi/1"]
  F -> B [label="*/0"]
  G -> B [label="I/5"]
  H -> B [label="vi/1"]
}

Exécution de la commande suivante: neato -Tpng Chord_NFA.dot > Chord_NFA.png

me donne cette sortie:

Je voudrais qu'il s'adapte sur A4 et qu'aucun des bords ne se chevauche ou ne traverse un nœud. C'est possible (mathématiquement) car je l'ai fait moi-même avec un biro.

30
Rory

J'ai joué avec quelques-uns et j'ai obtenu ceci:

digraph n {
  node [nodesep=2.0, fontsize=11];
  graph [overlap = false];
  subgraph cluster_a {
    style=invisible;
    A; B; H;
  }
  subgraph cluster_b {
    style=invisible;
    D; E; G;
  }
  subgraph cluster_c {
    style=invisible;
    C; F;
  }
  A -> B [label="I/5"];
  A -> A [label="*/0"];
  A -> C [label="ii/2"];
  A -> H [label="vii/1"];
  B:w -> D [label="iii/1"];
  B:nw -> E [minlen=3 label="IV/2"];
  B -> F [minlen=2 label="V/2"];
  B -> B [label="vi/2"];
  C -> F [minlen=2 label="V/2"];
  C -> H [label="vii/1"];
  D -> E [label="IV/2"];
  D -> E [minlen=2 dir=back label="iii/2"];
  G -> E [minlen=2 dir=back label="iv/1"];
  F -> E [dir=back label="V/3"];
  B -> F [minlen=2 dir=back label="I/4"];
  B -> F [minlen=2 dir=back label="vi/1"];
  B -> F [minlen=2 dir=back label="*/0"];
  B -> G [dir=back label="I/5"];
  H -> B [label="vi/1"];
}

Compiler avec:

dot -Tpng -o Chord_NFA.png Chord_NFA.gv

La sortie est la suivante, sans aucun croisement de lignes:

graph

L'astuce est:

  1. Pour ajouter l'attribut minlen pour forcer une certaine séparation, donnant plus d'espacement pour le rendu sans chevauchements et croisements.

  2. Pour inverser la logique de certaines arêtes (en les rendant non inversées avec dir = back). De cette façon, dot voit toujours un graphique acyclique et peut ordonner les bords sans se confondre.

  3. En se concentrant d'abord sur certains sous-graphiques et en regroupant leurs nœuds en grappes pour leur donner une "protection" contre les interférences lors du rendu du reste du graphique.

26
Victor Stafusa

Voici quelques étapes dans une meilleure direction:

  • nodesep n'est pas un attribut de nœud - et il ne fait probablement pas ce que vous attendiez. Mais cela reste utile dans votre cas:

    ... cela affecte l'espacement entre les boucles sur un seul nœud, ou les multiedges entre une paire de nœuds.

  • Je ne pense pas que Edge le poids change quelque chose si vous le changez pour tous bords.
  • Activer splines est souvent une bonne idée.
  • L'ajout d'espace supplémentaire autour des nœuds peut être fait avec sep
  • overlap a plus de valeurs que vrai/faux - je trouve souvent scalexy utile.
  • Une fois que la distribution des nœuds est correcte, vous pouvez affiner les positions des étiquettes en utilisant une combinaison de headlabel/taillabel , labeldistance et labelangle (rouge dans l'exemple ci-dessous pour les faire ressortir).

Voici l'exemple modifié:

digraph n {
splines=true;
sep="+25,25";
overlap=scalexy;
nodesep=0.6;
node [fontsize=11];
//Edge[weight=0.2];

A -> B [label="I/5"]
A -> A [label="*/0"]
A -> C [label="ii/2"]
A -> H [label="vii/1"]
B -> D [label="iii/1"]
B -> E [label="IV/2"]
B -> F [headlabel="V/2", labeldistance=4, labelangle=-10, labelfontcolor=red]
B -> B [label="vi/2"]
C -> F [label="V/2"]
C -> H [label="vii/1"]
D -> E [label="IV/2"]
E -> D [label="iii/2"]
E -> G [label="iv/1"]
E -> F [headlabel="V/3", labeldistance=8, labelangle=-7, labelfontcolor=red]
F -> B [label="I/4"]
F -> B [label="vi/1"]
F -> B [label="*/0"]
G -> B [taillabel="I/5", labeldistance=4, labelangle=15, labelfontcolor=red]
H -> B [label="vi/1"]
}

graphviz output

37
marapet

En utilisant le moteur de points, j'ai obtenu la sortie suivante sans changer le fichier de points qui devrait tenir sur A4. Le rendu de Marapet permet une meilleure utilisation de l'espace.

dot engine output

8
ob1