GraphViz - Как подключить подграфы?

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

4 ответа

Решение

Руководство пользователя DOT дает следующий пример графика с кластерами с ребрами между кластерами

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

и ребра между узлами и кластерами.

Для удобства пользования решение, описанное в ответе 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=true в graph Декларация имеет жизненно важное значение. Это производит вывод:

граф со связанными кластерами

Обратите внимание, что я изменил ребра для ссылки на узлы в кластере, добавил атрибуты ltail и lhead для каждого ребра, указав имя кластера, и добавил атрибут уровня графа 'component =true'.

Что касается опасений, что кто-то может захотеть подключить кластер без узлов внутри него, мое решение состояло в том, чтобы всегда добавлять узел в каждый кластер с помощью style = plaintext. Используйте этот узел для маркировки кластера (вместо встроенного в кластер атрибута "label", который должен быть установлен в пустую строку (в Python, label='""'). Это означает, что я больше не добавляю ребра, которые соединяют кластеры напрямую, но это работает в моей конкретной ситуации.

Убедитесь, что вы используете fdp макет для файла. Я не думаю neato поддерживает кластеры.

Убедись в том, чтоcompound=trueв опциях орграфа (ссылка ):

      digraph {
  compound=true;

  subgraph cluster_a {
    label="Cluster A";
    node1; node3; node5; node7;
  }
  subgraph cluster_b {
    label="Cluster B";
    node2; node4; node6; node8;
  }

  node1 -> node2 [label="1"];
  node3 -> node4 [label="2" ltail="cluster_a"];
  
  node5 -> node6 [label="3" lhead="cluster_b"];
  node7 -> node8 [label="4" ltail="cluster_a" lhead="cluster_b"];
}

Другие вопросы по тегам