5

私はこのGraphvizグラフを持っています:

digraph
{
   rankdir="LR";
   overlap = true;
   Node[shape=record, height="0.4", width="0.4"];
   Edge[dir=none];

   A B C D E F G H I 

   A -> B -> C
   D -> E -> F
   G -> H -> I

   Edge[constraint=false]

   A -> D -> G

   subgraph clusterX
   {
      A
      B
   }

   subgraph clusterY
   {
      E
      H
      F
      I
   }
}

次の出力が生成されます。

Graphviz の出力

ノードが次のように配置されるように、A と D の間のエッジの長さが最小化されることを期待していました。

A B C
D E F
G H I

それよりも

D E F
G H I
A B C

サブグラフ定義を削除すると、これは期待どおりに機能します。

サブグラフが導入されると、Graphviz が ABC を一番下に配置するのはなぜですか?

4

1 に答える 1

8

特にこの例では、属性でエッジが定義されているため、これは実際にはエッジの長さを最小化することではありませんconstraint=false

これは完全な答えではありませんが、次の 2 点のどこかにあると思います。

  • グラフ内のノードの出現順序は重要です
  • に変更rankdirするとLR、予測できない (または少なくとも予測が難しい) 動作が含まれます。また、おそらくまだバグが 1 つまたは 2 つ含まれています ( rankdir を検索)。

私はできる限り十分に説明し、graphviz を理解できるように努めますが、グラフビズ メーリング リストの Emden R. Gansner のこの返信と、Stephen North の次の回答をすぐに読みたいと思うかもしれません。知っているので、その一部を引用します...


ノードの出現順序が重要なのはなぜですか? デフォルトでは、トップダウン グラフでは、エッジと制約によってレイアウトが改善されない限り、最初に言及されたノードが次のノードの左側に表示されます。

したがって、クラスター と がないrankdir=LR場合、グラフは次のようになります (驚くことではありません)。

A D G
B E H
C F I

ここまでは順調ですね。しかし、rankdir=LR適用されるとどうなるでしょうか。

ERG は次のように書いています。

ドットは、通常の TB レイアウトで rankdir=LR を処理し、次にレイアウトを反時計回りに 90 度回転します (そして、もちろん、ノードの回転、エッジの方向などを処理します)。したがって、サブグラフ 1 は、予想どおり TB レイアウトでサブグラフ 2 の左側に配置され、回転後はそれよりも低くなります。サブグラフ 1 を一番上にしたい場合は、グラフの 2 番目にリストします。

したがって、それが正しい場合、クラスターなしで、ノードは次のように表示されます。

G H I
D E F
A B C

実際には、次のように表示されます。

A B C
D E F
G H I

なんで?スティーブン・ノースはこう答えました。

ある時点で
、グラフが回転していても上から下をデフォルトにすべきであると判断したため、フラット エッジを内部で反転するコードがあります。

したがって、グラフは TB にレイアウトされ、反時計回りに回転し、平らなエッジが反転されます。

A D G     G H I     A B C
B E H --> D E F --> D E F
C F I     A B C     G H I

これは単純なグラフでは非常にうまく機能しますが、クラスターが関係する場合は少し異なるようです。通常、( のように) クラスタ内でエッジも反転されますが、平坦なエッジの反転が思ったように機能しないclusterY場合があります。あなたの例はそれらのケースの1つです。

これらのエッジの反転にエラーまたは制限があるのはなぜですか? を使用すると、同じグラフが通常正しく表示されるためrankdir=TBです。


幸いなことに、多くの場合、回避策は簡単です。たとえば、ノードの表示順序を使用してレイアウトに影響を与えることができます。

digraph
{
   rankdir="LR";
   node[shape=record, height="0.4", width="0.4"];
   edge[dir=none];

   E; // E is first node to appear
   A -> B -> C;
   D -> E -> F;
   G -> H -> I;

   edge[constraint=false]
   A -> D -> G;

   subgraph clusterX { A; B; }
   subgraph clusterY { E; F; H; I; }
}
于 2012-03-06T22:21:11.657 に答える