GraphViz - Làm thế nào để kết nối các sơ đồ con?


166

Trong DOTngôn ngữ cho GraphViz, tôi đang cố gắng biểu diễn một sơ đồ phụ thuộc. Tôi cần có khả năng có các nút bên trong một container và để có thể tạo các nút và / hoặc các container phụ thuộc vào các nút và / hoặc các container khác.

Tôi đang sử dụng subgraphđể đại diện cho container của tôi. Liên kết nút hoạt động tốt, nhưng tôi không thể tìm ra cách kết nối các sơ đồ con.

Đưa ra chương trình dưới đây, tôi cần có khả năng kết nối cluster_1cluster_2bằng một mũi tên, nhưng bất cứ điều gì tôi đã thử đều tạo các nút mới thay vì kết nối các cụm:

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

nhập mô tả hình ảnh ở đây


2
Tôi có cùng một vấn đề, nhưng họ có một ví dụ tự nhiên trong đó các sơ đồ con hoạt động như các nút, graphviz.org/content/fdpclust .
nlucaroni

1
@nlucaroni tôi tự hỏi nếu vấn đề này được giải quyết. ví dụ này cho tôi biểu đồ sai: các cạnh kết nối trung tâm của đồ thị con. Bạn không biết làm thế nào để nó hoạt động như trong ví dụ?
k102

1
@ k102, tôi có biết. Kiểm tra trang đó một lần nữa; Nó nói bạn cần sử dụng fdp. Ví dụ được liên kết và một ở trên cả hai đều hoạt động (dòng cuối cùng trong ví dụ ở đây cần sử dụng tên của sơ đồ con không phải là nhãn và có thể rất hay khi bao gồm độ dài dòng cho biểu đồ); nó hơi chặt như vậy).
nlucaroni

1
@nlucaroni Sử dụng fdpv2.28.0 và sao chép / dán nguồn từ ví dụ các đường kết nối với trung tâm của sơ đồ con, không phải với các cạnh. Nếu bạn mở .dot trong OmniGraffle, chúng được kết nối đúng cách, trong khi neatodotcả hai đều tạo các nút thừa cho cụm.
Phrogz

Câu trả lời:


190

Hướng dẫn sử dụng DOT đưa ra ví dụ sau về biểu đồ với các cụm có các cạnh giữa các cụm:

QUAN TRỌNG: compound=trueTuyên bố ban đầu là bắt buộc.

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

... và các cạnh giữa các nút và cụm:

nhập mô tả hình ảnh ở đây


14
Cảm ơn - nó hoạt động, nhưng nó thực sự cảm thấy như một hack xấu xí. Tôi hy vọng tôi không có một kịch bản trong đó tôi có một container không có nút.
Winston Smith

5
Trong trường hợp bất cứ ai quan tâm, điều này có thể gây ra vấn đề định vị nếu bạn có nhãn liên kết (cạnh). Mặc dù phần đầu hoặc phần đuôi của cạnh có thể bị ẩn bên dưới một cụm, nhãn vẫn được đặt ở điểm giữa, có nghĩa là một số nhãn cạnh dường như nổi trên một cụm thay vì được định vị bởi chính cạnh đó.
Winston Smith

58
@WinstonSmith: Câu hỏi cũ, nhưng tôi có một vấn đề tương tự và đã giải quyết nó bằng một nút giả vô hình trên mỗi cụm, có thể được liên kết đến ngay cả khi cụm trống. DUMMY_0 [shape=point style=invis]
DevSolar

2
Tôi thấy các cạnh liên cụm của mình bị thu gọn thành đầu mũi tên, khi sử dụng các cụm chỉ được kết nối theo chiều dọc. Tôi đã sửa nó với minlen = 1 trên các cạnh. c -> g [ltail = cluster0, lhead = cluster1, minlen = 1];
Freenerd

3
Đây là liên kết đến hướng dẫn sử dụng với ví dụ: graphviz.org/Documentation/dotguide.pdf (trang 30).
Kirill Bulygin

90

Để dễ tham khảo, giải pháp được mô tả trong câu trả lời của HighPerformanceMark, được áp dụng trực tiếp cho câu hỏi ban đầu, trông giống như sau:

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

Các compound=truetrong graphtuyên bố là rất quan trọng. Điều đó tạo ra đầu ra:

đồ thị với các cụm được kết nối

Lưu ý rằng tôi đã thay đổi các cạnh thành các nút tham chiếu trong cụm, thêm các thuộc tính ltail và lhead cho mỗi cạnh, chỉ định tên cụm và thêm thuộc tính mức đồ thị 'hợp chất = true'.

Liên quan đến lo lắng rằng người ta có thể muốn kết nối một cụm không có nút bên trong nó, giải pháp của tôi là luôn luôn thêm một nút vào mỗi cụm, được kết xuất với style = plaintext. Sử dụng nút này để gắn nhãn cho cụm (thay vì thuộc tính "nhãn" tích hợp của cụm, nên được đặt thành chuỗi trống (trong Python, label='""'). Điều này có nghĩa là tôi không còn thêm các cạnh kết nối trực tiếp với cụm, nhưng nó làm việc trong tình huống cụ thể của tôi.


24
Lưu ý: 'graph [Fontize = 10 fontname = "Verdana" hợp chất = true];' là điều cần thiết - nếu bạn bỏ lỡ việc liên kết đến ltail / lhead không hoạt động.
s.Daniel

1
@JonathanHartley, Theo đoạn cuối của bạn, có cách nào để tập trung vào nút đó ngay giữa cụm không?
Pacerier

cũng là tên của cụm không nên bắt đầu bằng chữ in hoa
JCLL

7
@ s.Daniel Nó chỉ là hợp chất = true; được yêu cầu
Tiến sĩ Max Völkel

Thay vì đặt lại lhead và ltail khi liên kết "Mục 1" -> "Mục 3", làm cách nào để liên kết cluster_0 và cluster_1 với mã có ý nghĩa? Tôi meam, làm cho cluster_0 -> cluster_1hiện tại như bạn đầu ra. Bởi vì có thể có nhiều mục trong cluster_0 liên kết đến nhiều mục khác trong cluster_1 (nhiều đến nhiều hoặc một với nhiều). Nó sẽ là tốt để chỉ liên kết hai.
Mithril

11

Hãy chắc chắn rằng bạn đang sử dụng fdpbố trí cho tập tin. Tôi không nghĩ rằng neatohỗ trợ các cụm.


2
Tôi cũng có kinh nghiệm thấy rằng neatođộng cơ không hỗ trợ các cụm .. Tôi không chắc đây có phải là lỗi hay không ..
Ross Rogers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.