web-dev-qa-db-fra.com

GraphViz - Comment connecter des sous-graphes?

Dans le langage DOT pour GraphViz, j'essaie de représenter un diagramme de dépendance. Je dois pouvoir avoir des nœuds à l'intérieur d'un conteneur et pouvoir créer des nœuds et/ou des conteneurs dépendants d'autres nœuds et/ou conteneurs.

J'utilise subgraph pour représenter mes conteneurs. Node la liaison fonctionne très bien, mais je ne vois pas comment connecter des sous-graphes.

Étant donné le programme ci-dessous, je dois pouvoir connecter cluster_1 et cluster_2 avec une flèche, mais tout ce que j'ai essayé crée de nouveaux noeuds au lieu de connecter les clusters:

digraph G {

    graph [fontsize=10 fontname="Verdana"];
    node [shape=record fontsize=10 fontname="Verdana"];

    subgraph cluster_0 {
        node [style=filled];
        "Item 1" "Item 2";
        label = "Container A";
        color=blue;
    }

    subgraph cluster_1 {
        node [style=filled];
        "Item 3" "Item 4";
        label = "Container B";
        color=blue;
    }

    subgraph cluster_2 {
        node [style=filled];
        "Item 5" "Item 6";
        label = "Container C";
        color=blue;
    }

    // Renders fine
    "Item 1" -> "Item 2";
    "Item 2" -> "Item 3";

    // Both of these create new nodes
    cluster_1 -> cluster_2;
    "Container A" -> "Container C";
}

enter image description here

149
Winston Smith

Le manuel d'utilisation du DOT donne l'exemple suivant d'un graphe avec des grappes avec des bords entre les grappes

digraph G {
  compound=true;
  subgraph cluster0 {
    a -> b;
    a -> c;
    b -> d;
    c -> d;
  }
  subgraph cluster1 {
    e -> g;
    e -> f;
  }
  b -> f [lhead=cluster1];
  d -> e;
  c -> g [ltail=cluster0,lhead=cluster1];
  c -> e [ltail=cluster0];
  d -> h;
}

et des bords entre les nœuds et les clusters.

enter image description here

160

Pour plus de facilité, la solution décrite dans la réponse de HighPerformanceMark, appliquée directement à la question initiale, ressemble à ceci:

digraph G {

    graph [fontsize=10 fontname="Verdana" compound=true];
    node [shape=record fontsize=10 fontname="Verdana"];

    subgraph cluster_0 {
        node [style=filled];
        "Item 1" "Item 2";
        label = "Container A";
        color=blue;
    }

    subgraph cluster_1 {
        node [style=filled];
        "Item 3" "Item 4";
        label = "Container B";
        color=blue;
    }

    subgraph cluster_2 {
        node [style=filled];
        "Item 5" "Item 6";
        label = "Container C";
        color=blue;
    }

    // Edges between nodes render fine
    "Item 1" -> "Item 2";
    "Item 2" -> "Item 3";

    // Edges that directly connect one cluster to another
    "Item 1" -> "Item 3" [ltail=cluster_0 lhead=cluster_1];
    "Item 1" -> "Item 5" [ltail=cluster_0 lhead=cluster_2];
}

Le compound=true dans la déclaration graph est essentielle. Cela produit une sortie:

graph with connected clusters

Notez que j'ai modifié les bords pour référencer les nœuds au sein du cluster, ajouté les attributs ltail et lhead à chaque bord, en spécifiant le nom du cluster, et ajouté l'attribut de niveau graphique 'compound = true'.

En ce qui concerne l’inquiétude de vouloir connecter un cluster ne contenant aucun nœud, ma solution consiste à toujours ajouter un nœud à chaque cluster, rendu avec style = texte brut. Utilisez ce nœud pour étiqueter le cluster (au lieu de l'attribut "label" intégré du cluster, qui doit être défini sur la chaîne vide (en Python, label='""'). Cela signifie que je n’ajoute plus d’arêtes reliant directement des clusters, mais cela fonctionne dans mon cas particulier.

82
Jonathan Hartley

Assurez-vous que vous utilisez fdp layout pour le fichier. Je ne pense pas que neato supporte les clusters.

10
mihajlv