Graphviz(xdot):如何制作递归节点?

6
I希望你能在Java中撰写一个图形库,并需要一种工具来可视化某些图形。我发现Graph-viz是一个很好的方法,虽然有些错误。
在我的模型中,图形节点边缘组成。每个节点都有一定数量的端口(输入/输出/输入输出),并且边缘将这些端口连接在一起。一些特殊节点被称为GraphNode,并嵌入一个图形。这些GraphNode端口映射到内部节点的一些端口
我想提供几种表示形式。其中第一种是我满意的:http://i.stack.imgur.com/ujU71.png 输入端口用绿色表示,输出端口用红色表示,输入输出端口用蓝色表示。
在这个表述中,GraphNodes没有被展开,只显示为简单的Nodes。在第二个版本中,我想创建一个类似于以下图片的东西:http://i.stack.imgur.com/Cx624.png 问题是我无法创建一个具有固定区域的子图(集群)(似乎不可能)。我尝试的另一种解决方案是将图形嵌入到节点中。然而,在HTML标签的<td> </td>部分插入一些代码不会评估该代码。
digraph graph0
{

    node1
    [
        label =
        <
            <table border="0" cellspacing="0">
                <tr>
                    <td cellpadding="0">
                        <table border="0" cellspacing="0">
                            <tr>
                                <td bgcolor="palegreen" border="1" port="port2">port2</td>
                                <td bgcolor="palegreen" border="1" port="port3">port3</td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td cellpadding="0">
                        <table border="0" cellspacing="0">
                            <tr>
                                <td cellpadding="0">
                                    <table border="0" cellspacing="0">
                                        <tr>
                                            <td bgcolor="skyblue" border="1" port="port5">port5</td>
                                        </tr>
                                    </table>
                                </td>
                                <td bgcolor="peachpuff" border="1">

                                    subgraph clusterTest
                                    {
                                        nodeTest
                                    }

                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td cellpadding="0">
                        <table border="0" cellspacing="0">
                            <tr>
                                <td bgcolor="lightpink" border="1" port="port4">port4</td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        >
        style = "invisible"
    ]

}

前面的代码创建了以下图形:http://i.stack.imgur.com/E9jQ1.png

最终,我能想到的最好解决方案如下: http://i.stack.imgur.com/VzS5g.png

但是我不满意它,因为 GraphNodes Ports 有时放置在奇怪的位置。

请问您知道我如何达到目标图形布局吗?如果需要,请索取任何其他信息。


编辑:我仍然没有找到任何解决方案。解决此问题的一种方法是能够固定包含群集内给定节点的位置,但似乎“dot”布局不支持此功能。有任何想法吗?

1个回答

1
使用有向图可以指定节点位置(相对于彼此的位置)。这可用于强制某些元素出现在其他元素之上。同时,其他节点可以被强制出现在同一级别上(在此示例中为端口101和102)。 虚假嵌套:该图不使用嵌套的明文/半HTML节点,因为我认为这不是可能的(不是功能)。我不确定是否有任何Graphviz库支持它们,但可能值得研究其他库。我从未甚至使用过来自Java或Python的dot,否则我会提出建议。

nesting


digraph { nodesep = 0.2 ranksep = 0.8 pad = 0.1 node [ 形状=正方形 ] node [ 样式=填充 ] edge [ 箭头类型=无 ]
//rankdir = LR
component_starter [ 标签 = < port02 port03 port06 S port07 port08 port04 port05 > 样式 = "隐形" ]
subgraph cluster_container { 标签="带组件的I/O设备" 颜色=橙色
//margin = 0
edge [ style="invis"]
//edge [ len="0.5" minlen="1" ]
node [ height="0.5" width="2" fixedsize=true ];
node [ shape=rectangle style=filled ]
{ 
node [ color=palegreen ];
    { rank = same port101 -> port102 }
}
{
node [ color=skyblue];
    port103 port104 }
{
node [ height="1.5" width="2" fixedsize=true ];
node [ color=peachpuff];
    //notaport
}
{
node [ height="0.5" width="4" fixedsize=true ];
node [ color=lightpink];
    output
}

//--

//subgraph  cluster_inner {
    //label="abstractions"
    //color="black"
    //style="invis"
    component_a [ label = <
        <table border="0" cellspacing="0"><tr>
            <td border="1" bgcolor="white"   > </td>
            <td border="1" bgcolor="palegreen" port="port2">port2</td>
            <td border="1" bgcolor="palegreen" port="port3">port3</td>
        </tr><tr>
            <td border="1" bgcolor="skyblue"   port="port6">port6</td>
            <td border="1" bgcolor="peachpuff" rowspan="3" colspan="2">A</td>
        </tr><tr>
            <td border="1" bgcolor="skyblue"   port="port7">port7</td>
        </tr><tr>
            <td border="1" bgcolor="skyblue"   port="port8">port8</td>
        </tr><tr>
           <td border="1" bgcolor="lightpink" colspan="1" port="port4">port4</td>
           <td border="1" bgcolor="lightpink" colspan="2" port="port5">port5</td>
        </tr></table> > style = "invisible" ]

    component_b [ label = <
        <table border="0" cellspacing="0"><tr>
            <td border="1" bgcolor="white"   > </td>
            <td border="1" bgcolor="palegreen" port="port22">port22</td>
            <td border="1" bgcolor="palegreen" port="port23">port23</td>
        </tr><tr>
            <td border="1" bgcolor="skyblue"   port="port25">port25</td>
            <td border="1" bgcolor="peachpuff" colspan="2"> B </td>
        </tr><tr>
        <td border="1" bgcolor="lightpink" colspan="3" port="port24">port24</td>
        </tr></table> > style = "invisible" ]

//-

    component_c [ label = <
        <table border="0" cellspacing="0"><tr>
            <td border="1" bgcolor="white"   > </td>
            <td border="1" bgcolor="palegreen" port="port32">port32</td>
            <td border="1" bgcolor="palegreen" port="port33">port33</td>
        </tr><tr>
            <td border="1" bgcolor="skyblue"   port="port35">port35</td>
            <td border="1" bgcolor="peachpuff" colspan="2"> C </td>
        </tr><tr>
         <td border="1" bgcolor="lightpink" colspan="3" port="port34">port34</td>
        </tr></table> > style = "invisible" ]
//}


port101 -> port103
port102 -> component_a 
port102 -> component_b
port103 -> port104

component_a -> output;
component_b -> output;
component_c -> output;

edge [ style="" arrowhead="normal" color="#444444"]
component_a:port4 -> output;

component_c:port34 -> component_a:port3;
component_a:port5 -> component_b:port22;

port101 -> component_c:port33

//-

{ rank = same

    edge [ dir=back ]
    port104 -> component_a:port8
}

}

component_starter;
component_starter:port5 -> port101;

}

上述点文件已压缩。使用base64 -d nesting.bz2.base64 |bzcat查看它。
QlpoOTFBWSZTWd/epEIABCzfgHAwWAP/3zgkmAq/7//6UASZm8a7VNrQBQQlSDUaYjTINGjIyZAG
ho0aNMgkUZJpEIzUw0TTEzQBoAIwCTUiFT1NppDymGk0Pap6gMmCaAAcwAAAAAAAAAAFSRJoGp6B
TyNTyhABoD1DQ0aephLyAcTAhMSQiKogMBLsVaZBYIwUHIGFISYVKCMVkRgLypG2mhHPb5z0hBap
yN3HCL2iJVDYvXI6SykmzPN9LCaex+63c7jyTnk18c2KgvDZq6Kkz+WWf4DU4KoQsCQJ1gKpAcwC
mp5nGnmlI8wBNtgDi+Hmf0/g/v4PoNaZVrhy5cdWCavJkutPC0t50kljBJLHXrbQUjJMPPDCUKwN
NHO8aaiqKTus3tLEpprCW8Gzr68DtvyteHrqa7JJ9J46R4muUMuU39kJYPEgwJWwCSqsgMteezTo
ta1rr3va1sccdW/32OJUROFkmUzqeyHn+g96EccgEY5SfJixh2aJgQC0JVmWAtrdagoOkDZAViKA
qUpGZ1dXNJikmmsRZmAO16Kq9osW7KzzPZPS9IeLIqXo0cOoNwatry3Mi792YMRvA3oiKxe84ac7
EMGmdrabTaG0qqDpAMJJn5IeAbvMNiSJW8og7y+Ik+CExJBhLDZlKFSFKMBgIIMai57J5pLmgl5R
Qm261e797RF6qhy82NQypLEa8ktUVAL2R1hxThWC3pVB0jBThRxVLfHHJeZHv+pMEkxZ3P6KP+ho
QWyC9gtIM2cxJK2pIiiIooOPlxE0kkspJPijcgrHRHw6XvMpwy5ldiqlUpWzvymgxr78zAXh4vSW
L3jya8Hqc6ekwhhDROybThDBnIdmdlN6ClO8bo7ucxNqSVjHNGd8F8ocW2qmT0bJRujojA9MJqnC
TPg09tZlJ5d/am7W8E6GeU3TkyVC0N5nTgeXXn7Sj1UWijm1Q07OKeXiyPbENRSNcNzrnkyxkNeu
RgS5GWEXKkpTdIy8NenUhVYpqkbUCushe+cQ15oMcRIrb4GZscDDVmLk3LF7Txk6yFvmky8aoiK5
T+3pVRjVVVUtLRVFFI0q1lrpHlGqNnHKOVIKkktUYAuq2L1bekwQeG68LX3tK64kVNRw2tDb7rLn
acBl0J61Ld57HXXHKpXLjoqAo5yyRvQ/YxLdufjNCSaEk4mmYLcZp1ybI1BqDTum20PSm2cId4pU
Zx00pZzOJZwnSHjAqXNkWCM4s/+LuSKcKEhv71IhAA==

我把这个交给你了,因为我现在得走了。如果有问题(细节)我可以添加到答案,请告诉我... - Ярослав Рахматуллин
你好!感谢你的回答,很抱歉我之前没能测试它。然而,我无法让它运行起来。看起来 Python 在检索属性 'width' 时出现了问题。你使用哪个版本的 Xdot 来可视化它(我的是0.4)?还是其他软件?不管怎样,你的回答对我来说看起来很完美! - Bastien Pasdeloup
我直接使用Graphviz进行了渲染。dot - Graphviz版本2.26.3。 - Ярослав Рахматуллин
是的,我刚刚测试了一下,它完美地工作了!看起来Xdot无法处理固定大小的元素。谢谢大家! - Bastien Pasdeloup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接