GraphViz-サブグラフを接続する方法は?


166

DOT言語でGraphVizは、依存関係図を表現しようとしています。コンテナー内にノードを持つことができ、ノードやコンテナーを他のノードやコンテナーに依存させることができる必要があります。

subgraphコンテナを表すために使用しています。ノードのリンクは問題なく機能しますが、サブグラフを接続する方法がわかりません。

以下のプログラムを考えると、矢印を使用cluster_1して接続できる必要がありますがcluster_2、クラスタを接続する代わりに、試行したすべてのノードが新しいノードを作成します。

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";
}

ここに画像の説明を入力してください


2
私は同じ問題を抱えていますが、サブグラフがノードのように機能する自然な例があります、graphviz.org / content / fdpclust
nlucaroni 2011年

1
@nlucaroniこの問題は解決されたのでしょうか。この例では、間違ったグラフが表示されます。エッジがサブグラフの中心を接続しています。例のように機能させる方法を知りませんか?
k102

1
@ k102、私は知っています。そのページをもう一度チェックしてください。それはあなたが使用する必要があると言いますfdp。リンクされた例と上の例は両方とも機能します(この例の最後の行はラベルではなくサブグラフ名を使用する必要があり、グラフの行の長さを含めるとよいでしょう)。それは少しタイトです)。
nlucaroni

1
@nlucaroni v2.28.0を使用してfdpサンプルからソースをコピー/貼り付けすると、線はエッジではなくサブグラフの中心に接続されます。OmniGraffleで.dotを開くと、それらは適切に接続されていますがneatodot両方ともクラスターに余分なノードを作成します。
Phrogz、2012年

回答:


190

DOTユーザーマニュアルは、クラスター間のエッジを持つクラスターを含むグラフの次の例を示しています。

重要:最初のcompound=trueステートメントは必須です。

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;
}

...ノードとクラスター間のエッジ:

ここに画像の説明を入力してください


14
ありがとう-うまくいきましたが、実際には醜いハックのように感じられます。私はよ期待して、私は私がいないノードを持つコンテナを持っているシナリオを持っていません。
Winston Smith

5
誰かが興味を持っている場合、リンク(エッジ)にラベルを付けていると、位置決めの問題が発生する可能性があります。エッジの頭または尾がクラスターの下に隠れている可能性がありますが、ラベルはまだ中間点に配置されています。つまり、一部のエッジラベルは、エッジ自体ではなくクラスターの上に浮いているように見えます。
Winston Smith

58
@WinstonSmith:古い質問ですが、同様の問題があり、クラスターごとに非表示のダミーノードを使用して解決しました。これは、クラスターが空の場合でもリンクできます。DUMMY_0 [shape=point style=invis]
DevSolar

2
垂直方向にのみ接続されているクラスターを使用すると、クラスター間エッジが矢印だけに縮小されることがわかりました。エッジのminlen = 1で修正しました。c-> g [ltail = cluster0、lhead = cluster1、minlen = 1];
Freenerd 2014年

3
例へのリンクは次のとおりです。graphviz.org / Documentation / dotguide.pdf(30ページ)。
Kirill Bulygin 2017

90

参照しやすいように、HighPerformanceMarkの回答で説明されているソリューションを元の質問に直接適用すると、次のようになります。

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];
}

宣言が不可欠です。それは出力を生成します:compound=truegraph

クラスターが接続されたグラフ

エッジをクラスター内の参照ノードに変更し、ltail属性とlhead属性を各エッジに追加し、クラスター名を指定し、グラフレベルの属性 'compound = true'を追加したことに注意してください。

内部にノードがないクラスターを接続したいという懸念に関して、私の解決策は、常にすべてのクラスターにノードを追加し、style = plaintextでレンダリングすることでした。このノードを使用して、クラスターにラベルを付けます(クラスターの組み込みの「label」属性の代わりに、空の文字列(Pythonではlabel='""')に設定する必要があります)。これは、クラスターを直接接続するエッジを追加しなくなったことを意味しますが、私の特定の状況で動作します。


24
注: 'graph [fontsize = 10 fontname = "Verdana" compound = true];' 重要です-あなたがltail / lheadへのリンクが機能しないことを見逃した場合
s.Daniel

1
@JonathanHartley、あなたの最後の段落に従って、そのノードをクラスターの真ん中に真ん中に置く方法はありますか?
パチェリエ14

また、クラスタの名前は大文字で始めるべきではありません
JCLL

7
@ s.Danielこれは単なるcompound = trueです。必須
Dr. MaxVölkel2016年

「アイテム1」->「アイテム3」をリンクするときにlheadとltailをリセットする代わりに、意味のあるコードでcluster_0とcluster_1をリンクするにはどうすればよいですか?私は、私cluster_0 -> cluster_1が出て、あなたが出力するように存在を作ります。cluster_0には多くの項目があり、cluster_1の他の多くの項目にリンクしている可能性があるため(多対多または1対多)。2つをリンクするだけでよいでしょう。
ミスリル

11

fdpファイルのレイアウトを使用していることを確認してください。neatoクラスタをサポートしていないと思います。


2
私も経験することを見出したneatoエンジンはクラスタをサポートしていません。これはバグか...である場合..私はよく分からない
ロス・ロジャース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.