Graphviz分层显示子图树

问题描述 投票:0回答:1

我有一个程序,可自动生成graphviz .dot文件,其内容是子图树。当我观察此文件的呈现方式时,树似乎已“展平”,无法很好地显示层次结构。我想知道如何解决此问题,并正确渲染此树。

过去,我使用fdp布局程序来呈现此图。它能够显示树的层次结构,但是作为子图的节点的内容不是很可读。我想使用点布局程序,因为它可以更好地对子图的节点进行分层,并且据说是分层图的理想选择。

[请参阅下面的图像,以获得显示不良渲染树的示例图。

enter image description here

生成此图形的代码是:

digraph G {
compound=true
subgraph cluster_649 {label = EPISODE649count3
subgraph cluster_STATE650 {
label = State_1;
EPISODE649HEIGHT643[label="HEIGHT",shape=oval,color=blue];
EPISODE649LEN642[label="LEN",shape=oval,color=blue];
EPISODE649Y641[label="Y",shape=oval,color=blue];
EPISODE649X640[label="X",shape=oval,color=blue];
EPISODE649BLOCK639[label="BLOCK",shape=oval,color=blue];
EPISODE649HEIGHT638[label="HEIGHT",shape=oval,color=blue];
EPISODE649LEN637[label="LEN",shape=oval,color=blue];
EPISODE649Y636[label="Y",shape=oval,color=blue];
EPISODE649X635[label="X",shape=oval,color=blue];
EPISODE649TRIANGLE634[label="TRIANGLE",shape=oval,color=blue];
EPISODE649ON645[label="ON",shape=oval,color=blue];
EPISODE649ON555[label="ON",shape=oval,color=blue];
EPISODE649CLEAR647[label="CLEAR",shape=oval,color=blue];
EPISODE649CLEAR557[label="CLEAR",shape=oval,color=blue];
EPISODE649CLEAR558[label="CLEAR",shape=oval,color=blue];
EPISODE649ON556[label="ON",shape=oval,color=blue];
EPISODE649BLOCK545[label="BLOCK",shape=oval,color=blue];
EPISODE649X546[label="X",shape=oval,color=blue];
EPISODE649Y547[label="Y",shape=oval,color=blue];
EPISODE649LEN548[label="LEN",shape=oval,color=blue];
EPISODE649HEIGHT549[label="HEIGHT",shape=oval,color=blue];
EPISODE649BLOCK550[label="BLOCK",shape=oval,color=blue];
EPISODE649X551[label="X",shape=oval,color=blue];
EPISODE649Y552[label="Y",shape=oval,color=blue];
EPISODE649LEN553[label="LEN",shape=oval,color=blue];
EPISODE649HEIGHT554[label="HEIGHT",shape=oval,color=blue];
EPISODE649BLOCK639 -> EPISODE649HEIGHT643;
EPISODE649BLOCK639 -> EPISODE649LEN642;
EPISODE649BLOCK639 -> EPISODE649Y641;
EPISODE649BLOCK639 -> EPISODE649X640;
EPISODE649TRIANGLE634 -> EPISODE649HEIGHT638;
EPISODE649TRIANGLE634 -> EPISODE649LEN637;
EPISODE649TRIANGLE634 -> EPISODE649Y636;
EPISODE649TRIANGLE634 -> EPISODE649X635;
EPISODE649ON645 -> EPISODE649HEIGHT643;
EPISODE649ON645 -> EPISODE649LEN642;
EPISODE649ON645 -> EPISODE649Y641;
EPISODE649ON645 -> EPISODE649X640;
EPISODE649ON645 -> EPISODE649BLOCK639;
EPISODE649ON645 -> EPISODE649HEIGHT638;
EPISODE649ON645 -> EPISODE649LEN637;
EPISODE649ON645 -> EPISODE649Y636;
EPISODE649ON645 -> EPISODE649X635;
EPISODE649ON645 -> EPISODE649TRIANGLE634;
EPISODE649ON555 -> EPISODE649ON645;
EPISODE649ON555 -> EPISODE649ON556;
EPISODE649CLEAR647 -> EPISODE649HEIGHT638;
EPISODE649CLEAR647 -> EPISODE649LEN637;
EPISODE649CLEAR647 -> EPISODE649Y636;
EPISODE649CLEAR647 -> EPISODE649X635;
EPISODE649CLEAR647 -> EPISODE649TRIANGLE634;
EPISODE649CLEAR557 -> EPISODE649CLEAR647;
EPISODE649CLEAR557 -> EPISODE649CLEAR558;
EPISODE649CLEAR558 -> EPISODE649BLOCK545;
EPISODE649CLEAR558 -> EPISODE649X546;
EPISODE649CLEAR558 -> EPISODE649Y547;
EPISODE649CLEAR558 -> EPISODE649LEN548;
EPISODE649CLEAR558 -> EPISODE649HEIGHT549;
EPISODE649ON556 -> EPISODE649BLOCK545;
EPISODE649ON556 -> EPISODE649X546;
EPISODE649ON556 -> EPISODE649Y547;
EPISODE649ON556 -> EPISODE649LEN548;
EPISODE649ON556 -> EPISODE649HEIGHT549;
EPISODE649ON556 -> EPISODE649BLOCK550;
EPISODE649ON556 -> EPISODE649X551;
EPISODE649ON556 -> EPISODE649Y552;
EPISODE649ON556 -> EPISODE649LEN553;
EPISODE649ON556 -> EPISODE649HEIGHT554;
EPISODE649BLOCK545 -> EPISODE649X546;
EPISODE649BLOCK545 -> EPISODE649Y547;
EPISODE649BLOCK545 -> EPISODE649LEN548;
EPISODE649BLOCK545 -> EPISODE649HEIGHT549;
EPISODE649BLOCK550 -> EPISODE649X551;
EPISODE649BLOCK550 -> EPISODE649Y552;
EPISODE649BLOCK550 -> EPISODE649LEN553;
EPISODE649BLOCK550 -> EPISODE649HEIGHT554;
}
649[shape=point style=invis]
}
subgraph cluster_559 {label = EPISODE559count1
subgraph cluster_STATE651 {
label = State_1;
EPISODE559CLEAR557[label="CLEAR",shape=oval,color=blue];
EPISODE559CLEAR558[label="CLEAR",shape=oval,color=blue];
EPISODE559ON555[label="ON",shape=oval,color=blue];
EPISODE559ON556[label="ON",shape=oval,color=blue];
EPISODE559BLOCK545[label="BLOCK",shape=oval,color=blue];
EPISODE559X546[label="X",shape=oval,color=blue];
EPISODE559Y547[label="Y",shape=oval,color=blue];
EPISODE559LEN548[label="LEN",shape=oval,color=blue];
EPISODE559HEIGHT549[label="HEIGHT",shape=oval,color=blue];
EPISODE559BLOCK550[label="BLOCK",shape=oval,color=blue];
EPISODE559X551[label="X",shape=oval,color=blue];
EPISODE559Y552[label="Y",shape=oval,color=blue];
EPISODE559LEN553[label="LEN",shape=oval,color=blue];
EPISODE559HEIGHT554[label="HEIGHT",shape=oval,color=blue];
EPISODE559CLEAR557 -> EPISODE559CLEAR558;
EPISODE559CLEAR558 -> EPISODE559BLOCK545;
EPISODE559CLEAR558 -> EPISODE559X546;
EPISODE559CLEAR558 -> EPISODE559Y547;
EPISODE559CLEAR558 -> EPISODE559LEN548;
EPISODE559CLEAR558 -> EPISODE559HEIGHT549;
EPISODE559ON555 -> EPISODE559ON556;
EPISODE559ON556 -> EPISODE559BLOCK545;
EPISODE559ON556 -> EPISODE559X546;
EPISODE559ON556 -> EPISODE559Y547;
EPISODE559ON556 -> EPISODE559LEN548;
EPISODE559ON556 -> EPISODE559HEIGHT549;
EPISODE559ON556 -> EPISODE559BLOCK550;
EPISODE559ON556 -> EPISODE559X551;
EPISODE559ON556 -> EPISODE559Y552;
EPISODE559ON556 -> EPISODE559LEN553;
EPISODE559ON556 -> EPISODE559HEIGHT554;
EPISODE559BLOCK545 -> EPISODE559X546;
EPISODE559BLOCK545 -> EPISODE559Y547;
EPISODE559BLOCK545 -> EPISODE559LEN548;
EPISODE559BLOCK545 -> EPISODE559HEIGHT549;
EPISODE559BLOCK550 -> EPISODE559X551;
EPISODE559BLOCK550 -> EPISODE559Y552;
EPISODE559BLOCK550 -> EPISODE559LEN553;
EPISODE559BLOCK550 -> EPISODE559HEIGHT554;
}
559[shape=point style=invis]
}
649 -> 559 [ltail=cluster_649 lhead=cluster_559];
subgraph cluster_625 {label = EPISODE625count1
subgraph cluster_STATE652 {
label = State_1;
EPISODE625CLEAR623[label="CLEAR",shape=oval,color=blue];
EPISODE625CLEAR624[label="CLEAR",shape=oval,color=blue];
EPISODE625ON621[label="ON",shape=oval,color=blue];
EPISODE625ON622[label="ON",shape=oval,color=blue];
EPISODE625BLOCK611[label="BLOCK",shape=oval,color=blue];
EPISODE625X612[label="X",shape=oval,color=blue];
EPISODE625Y613[label="Y",shape=oval,color=blue];
EPISODE625LEN614[label="LEN",shape=oval,color=blue];
EPISODE625HEIGHT615[label="HEIGHT",shape=oval,color=blue];
EPISODE625BLOCK616[label="BLOCK",shape=oval,color=blue];
EPISODE625X617[label="X",shape=oval,color=blue];
EPISODE625Y618[label="Y",shape=oval,color=blue];
EPISODE625LEN619[label="LEN",shape=oval,color=blue];
EPISODE625HEIGHT620[label="HEIGHT",shape=oval,color=blue];
EPISODE625CLEAR623 -> EPISODE625CLEAR624;
EPISODE625CLEAR624 -> EPISODE625BLOCK611;
EPISODE625CLEAR624 -> EPISODE625X612;
EPISODE625CLEAR624 -> EPISODE625Y613;
EPISODE625CLEAR624 -> EPISODE625LEN614;
EPISODE625CLEAR624 -> EPISODE625HEIGHT615;
EPISODE625ON621 -> EPISODE625ON622;
EPISODE625ON622 -> EPISODE625BLOCK611;
EPISODE625ON622 -> EPISODE625X612;
EPISODE625ON622 -> EPISODE625Y613;
EPISODE625ON622 -> EPISODE625LEN614;
EPISODE625ON622 -> EPISODE625HEIGHT615;
EPISODE625ON622 -> EPISODE625BLOCK616;
EPISODE625ON622 -> EPISODE625X617;
EPISODE625ON622 -> EPISODE625Y618;
EPISODE625ON622 -> EPISODE625LEN619;
EPISODE625ON622 -> EPISODE625HEIGHT620;
EPISODE625BLOCK611 -> EPISODE625X612;
EPISODE625BLOCK611 -> EPISODE625Y613;
EPISODE625BLOCK611 -> EPISODE625LEN614;
EPISODE625BLOCK611 -> EPISODE625HEIGHT615;
EPISODE625BLOCK616 -> EPISODE625X617;
EPISODE625BLOCK616 -> EPISODE625Y618;
EPISODE625BLOCK616 -> EPISODE625LEN619;
EPISODE625BLOCK616 -> EPISODE625HEIGHT620;
}
625[shape=point style=invis]
}
649 -> 625 [ltail=cluster_649 lhead=cluster_625];
subgraph cluster_648 {label = EPISODE648count1
subgraph cluster_STATE653 {
label = State_1;
EPISODE648CLEAR646[label="CLEAR",shape=oval,color=blue];
EPISODE648CLEAR647[label="CLEAR",shape=oval,color=blue];
EPISODE648ON644[label="ON",shape=oval,color=blue];
EPISODE648ON645[label="ON",shape=oval,color=blue];
EPISODE648TRIANGLE634[label="TRIANGLE",shape=oval,color=blue];
EPISODE648X635[label="X",shape=oval,color=blue];
EPISODE648Y636[label="Y",shape=oval,color=blue];
EPISODE648LEN637[label="LEN",shape=oval,color=blue];
EPISODE648HEIGHT638[label="HEIGHT",shape=oval,color=blue];
EPISODE648BLOCK639[label="BLOCK",shape=oval,color=blue];
EPISODE648X640[label="X",shape=oval,color=blue];
EPISODE648Y641[label="Y",shape=oval,color=blue];
EPISODE648LEN642[label="LEN",shape=oval,color=blue];
EPISODE648HEIGHT643[label="HEIGHT",shape=oval,color=blue];
EPISODE648CLEAR646 -> EPISODE648CLEAR647;
EPISODE648CLEAR647 -> EPISODE648TRIANGLE634;
EPISODE648CLEAR647 -> EPISODE648X635;
EPISODE648CLEAR647 -> EPISODE648Y636;
EPISODE648CLEAR647 -> EPISODE648LEN637;
EPISODE648CLEAR647 -> EPISODE648HEIGHT638;
EPISODE648ON644 -> EPISODE648ON645;
EPISODE648ON645 -> EPISODE648TRIANGLE634;
EPISODE648ON645 -> EPISODE648X635;
EPISODE648ON645 -> EPISODE648Y636;
EPISODE648ON645 -> EPISODE648LEN637;
EPISODE648ON645 -> EPISODE648HEIGHT638;
EPISODE648ON645 -> EPISODE648BLOCK639;
EPISODE648ON645 -> EPISODE648X640;
EPISODE648ON645 -> EPISODE648Y641;
EPISODE648ON645 -> EPISODE648LEN642;
EPISODE648ON645 -> EPISODE648HEIGHT643;
EPISODE648TRIANGLE634 -> EPISODE648X635;
EPISODE648TRIANGLE634 -> EPISODE648Y636;
EPISODE648TRIANGLE634 -> EPISODE648LEN637;
EPISODE648TRIANGLE634 -> EPISODE648HEIGHT638;
EPISODE648BLOCK639 -> EPISODE648X640;
EPISODE648BLOCK639 -> EPISODE648Y641;
EPISODE648BLOCK639 -> EPISODE648LEN642;
EPISODE648BLOCK639 -> EPISODE648HEIGHT643;
}
648[shape=point style=invis]
}
649 -> 648 [ltail=cluster_649 lhead=cluster_648];
}

观察到,为了在群集之间绘制边缘,我在每个群集中创建了不可见节点,例如:625[shape=point style=invis],并且如果两个群集之间存在父/子关系,则连接两个不可见节点,例如:[ C0]

感谢您的帮助!

graphviz dot
1个回答
0
投票

您的不可见节点是一个好主意,但是您被dot的(未写的?)规则所吸引,该规则要求所有节点都应处于同一等级,除非有命令“强制”一个新等级。如果将“ invisible”更改为“ dotted”,您将看到这些节点发生了什么。我试图找到一种简单的方法来使dot与这些额外的节点很好地协作,但是失败了。最终,我使用了一些现有节点来实现我认为的目标。我将这些边缘保持可见,因此您可以轻松看到我的更改。我还添加了外围设备和边距属性。该程序的简化版本:

649 -> 625 [ltail=cluster_649 lhead=cluster_625];

digraph G { compound = true // a dummy cluster to pad the left side subgraph cluster_dummy{ label="" ; peripheries=0;node[style=invis]; {rank=same _a; _b } } peripheries=0 subgraph cluster_649 { label = EPISODE649count3 subgraph cluster_STATE650 { graph [ margin=30] label = State_1; // unmodified nodes go here } } subgraph cluster_559 { label = EPISODE559count1 subgraph cluster_STATE651 { graph [ margin=30] label = State_1; // unmodified nodes go here } } subgraph cluster_625 { label = EPISODE625count1 subgraph cluster_STATE652 { graph [ margin=30] label = State_1; // unmodified nodes go here } } subgraph cluster_648 { label = EPISODE648count1 subgraph cluster_STATE653 { graph [ margin=30] label = State_1; // unmodified nodes go here } } EPISODE649HEIGHT638 -> EPISODE559ON555 [weight=0 style=dotted] EPISODE649HEIGHT638 -> EPISODE625ON621 [weight=0 style=dotted] EPISODE649HEIGHT638 -> EPISODE648ON644 [weight=0 style=dotted] }

© www.soinside.com 2019 - 2024. All rights reserved.