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
ฉันมีปัญหาเดียวกันพวกเขาก็ยังมีตัวอย่างที่เป็นธรรมชาติที่ subgraphs จะทำหน้าที่เหมือนโหนดgraphviz.org/content/fdpclust
nlucaroni

1
@ nlucaroni ฉันสงสัยว่าปัญหานี้จะได้รับการแก้ไข ตัวอย่างนี้ทำให้ฉันกราฟไม่ถูกต้อง: เชื่อมต่อกึ่งกลางของกราฟย่อย คุณไม่รู้วิธีทำให้มันใช้งานได้ในตัวอย่างหรือไม่
k102

1
@ k102 ฉันรู้ ลองดูหน้านั้นอีกครั้ง fdpมันบอกว่าคุณจำเป็นต้องใช้ ตัวอย่างที่เชื่อมโยงและรายการด้านบนทั้งสองทำงาน (บรรทัดสุดท้ายในตัวอย่างที่นี่จำเป็นต้องใช้ชื่อกราฟย่อยไม่ใช่ป้ายกำกับและอาจเป็นการดีที่จะรวมความยาวบรรทัดสำหรับกราฟ) มันค่อนข้างแน่นเหมือนเดิม)
nlucaroni

1
fdp@nlucaroni ใช้v2.28.0 และคัดลอก / วางแหล่งที่มาจากตัวอย่างบรรทัดที่เชื่อมต่อกับศูนย์กลางของกราฟย่อยไม่ใช่ไปที่ขอบ หากคุณเปิด. dot ใน OmniGraffle พวกเขาจะเชื่อมต่ออย่างถูกต้องในขณะที่neatoและdotทั้งสองสร้างโหนดฟุ่มเฟือยสำหรับคลัสเตอร์
Phrogz

คำตอบ:


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

3
นี่คือลิงค์ไปยังคู่มือพร้อมตัวอย่าง: graphviz.org/Documentation/dotguide.pdf (หน้า 30)
Kirill Bulygin

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=trueในgraphประกาศมีความสำคัญ ที่ผลิตผลลัพธ์:

กราฟกับกลุ่มที่เชื่อมต่อ

โปรดทราบว่าฉันเปลี่ยนขอบเป็นการอ้างอิงโหนดภายในคลัสเตอร์เพิ่มแอตทริบิวต์ ltail และ lhead ให้กับแต่ละขอบระบุชื่อคลัสเตอร์และเพิ่มแอตทริบิวต์ระดับกราฟ 'compound = true'

เกี่ยวกับความกังวลที่ว่าหนึ่งอาจต้องการที่จะเชื่อมต่อกับคลัสเตอร์โหนดภายในมันไม่มีวิธีการแก้ปัญหาของฉันได้รับการเสมอเพิ่มโหนดเพื่อทุกกลุ่มการแสดงผลที่มีสไตล์ = ธรรมดา ใช้โหนดนี้เพื่อทำป้ายชื่อคลัสเตอร์ (แทนแอตทริบิวต์ "label" ในตัวของคลัสเตอร์ซึ่งควรตั้งค่าเป็นสตริงว่าง (ใน Python, label='""') ซึ่งหมายความว่าฉันไม่ได้เพิ่มขอบที่เชื่อมต่อกลุ่มโดยตรงอีกต่อไป ทำงานในสถานการณ์เฉพาะของฉัน


24
หมายเหตุ: 'กราฟ [fontsize = 10 fontname = "Verdana" compound = true];' เป็นสิ่งสำคัญ - หากคุณพลาดการเชื่อมโยงไปยัง ltail / lhead จะไม่ทำงาน
s.Daniel

1
@JonathanHartley ตามวรรคสุดท้ายของคุณมีวิธีใดที่จะทำให้โหนดนั้นอยู่ตรงกลางของคลัสเตอร์หรือไม่
Pacerier

นอกจากนี้ชื่อของคลัสเตอร์ไม่ควรเริ่มต้นด้วยตัวพิมพ์ใหญ่
JCLL

7
@ s.Daniel มันเป็นแค่สารประกอบ = จริง ซึ่งเป็นสิ่งจำเป็น
ดร. แม็กซ์ Volkel

แทนที่จะรีเซ็ต lhead และ ltail เมื่อลิงก์ "รายการ 1" -> "รายการ 3" ฉันจะเชื่อมโยง cluster_0 และ cluster_1 ด้วยรหัสที่มีความหมายได้อย่างไร ฉันมีให้ทำcluster_0 -> cluster_1ตามที่คุณส่งออก เนื่องจากอาจมีหลายรายการใน cluster_0 ลิงก์ไปยังอีกหลายรายการใน cluster_1 (มากไปมากหรือหลายรายการ) มันเป็นการดีที่จะเชื่อมโยงสอง
มิ ธ ริล

11

ตรวจสอบให้แน่ใจว่าคุณใช้fdpเลย์เอาต์สำหรับไฟล์ ฉันไม่คิดว่าneatoสนับสนุนกลุ่ม


2
ฉันก็มีประสพการณ์พบว่าneatoเครื่องยนต์ไม่สนับสนุนกลุ่ม .. ฉันไม่แน่ใจว่านี้เป็นข้อผิดพลาดหรือไม่ ..
รอสส์โรเจอร์ส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.