recursion - Graphviz (xdot) : How to make recursive nodes?

标签 recursion graph graphviz dot

我目前正在用 Java 编写一个图形库,我想要一个工具来可视化一些图形。我发现了 Graph-viz,它恰好是一种很好的(尽管有缺陷)做到这一点的方法。

在我的模型中,节点组成。每个节点都有一定数量的端口 (I/O/IO),并且边缘将这些端口连接在一起。一些特殊的节点称为GraphNodes并嵌入Graph。这些GraphNode端口映射到内部节点的一些端口

我想提供几个代表。其中我满意的第一个如下: /image/ujU71.png

输入端口以绿色表示,输出端口以红色表示,输入输出端口以蓝色表示。

在此表示中,图形节点未展开,并且仅显示为简单的节点。在第二个版本中,我想创建如下图所示的内容:/image/Cx624.png

问题是我无法设法创建具有固定区域的子图(簇)(似乎不可能)。我尝试的另一个解决方案是将图嵌入到节点中。但是,将一些代码插入 <td> </td> HTML 标签的一部分不会评估代码:

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"
    ]

}

前面的代码创建了以下图表:/image/E9jQ1.png

最后,我能想到的最佳解决方案如下:/image/VzS5g.png

但是我对此并不满意,因为GraphNodes端口有时会放置在奇怪的位置。

你知道我怎样才能达到目标图形布局吗?如果需要,请询问任何其他信息。

<小时/>

编辑:我仍然没有找到任何解决方案。处理这个问题的一种方法是能够修复包含集群内给定节点的位置,但对于“点”布局似乎不可能。有什么想法吗?

最佳答案

使用有向图,可以指定节点的位置(相对于彼此)。这可以用来强制某些元素出现在其他元素之上。而其他节点可以强制出现在同一级别(本例中为端口 101 和 102)

假嵌套:该图不使用嵌套的纯文本/半html节点,因为我认为这是不可能的(不是功能)。我不确定是否有任何 graphviz 库也支持它们,但可能值得研究其他库。我什至从未使用过 Java 或 Python 中的点,否则我会提出建议。

<小时/>

nesting

<小时/>

有向图{ 节点间隔 = 0.2 排名间隔 = 0.8 垫= 0.1 节点 [ 形状=正方形 ] 节点[style=填充] 边缘[箭头=无]

//rankdir = LR

组件启动器 [ 标签 = < 端口02 端口03 端口06 S 端口07 端口08 端口04 端口05 > style=“隐形”]

子图 cluster_container { label="带组件的 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==

关于recursion - Graphviz (xdot) : How to make recursive nodes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17363535/

相关文章:

haskell - 我的Haskell代码中的堆栈溢出

python-3.x - 基于Python中的值对无向图的节点进行排序

java - Dijkstra 算法只有一行文件没有正确处理

graphviz - 如何添加“不相关的”边缘

c - 在 C 中使用递归函数时避免使用全局变量

c++ - 在检查 array[i] == i 时返回 bool 的递归算法(必须是 O(log n))

c++ - 如何在显示多个属性的 graphviz 中打印图形

graphviz - 使用点语言在 Graphviz 中压缩有向图

algorithm - 当主定理不适用时如何解决递归关系

python - NetworkX:如何为现有的 G.edges() 添加权重?