带有子图的 graphviz 三级布局

graphviz three ranks layout with subgraphs

我正在尝试以自动生成的流程图的形式定位元素。 一般来说,inputs(绿色)应该在最左边,outputs(红色)在最右边,其余的根据布局放在中间。 为此,我使用 rank=sourcerank=sink。 在标准图表中它工作得很好。

但是,当我开始嵌套图形时,rank=source 似乎不起作用。我希望 <> 的三个输入(电、开关、room_temperature)放在最左边(因为它发生在子图中)和子图 + 状态(棕色圆圈)和输入之间的蓝色框和输出。

有没有办法指定 "rank=center"(或类似的东西?)

我已经检查了 documentation 但没有找到正确的属性(以及在何处指定它们)。

digraph MyGraph {
    node [fontsize=8  margin=".1,.01" width=.5 height=.5 shape=box]
    edge [fontsize=8]
    rankdir=LR;
    ranksep = .25;
    nodesep= .5;

subgraph cluster_4386357488 {
    label = " <<GrowLamp>>"
    style=solid
    {rank=source;
        4386357544 [label="electricity" style=filled fillcolor="#b5fed9"]
        4386357712 [label="room_temperature" style=filled fillcolor="#b5fed9"]
        4386357768 [label="switch" style=filled fillcolor="#b5fed9"]
    }
    {
        4386357880 [label="off" style=filled fillcolor="#e2cbc1" shape=doublecircle]
        4386357936 [label="on" style=filled fillcolor="#e2cbc1" shape=circle]
        4386357656 [label="on_time" style=filled fillcolor="#d2ceef"]
    }
    {rank=sink;
        4386357600 [label="light" style=filled fillcolor="#fcc5b3"]
        4386357824 [label="temperature" style=filled fillcolor="#fcc5b3"]
    }
    4386357880 -> 4386357936
    4386357936 -> 4386357880
    {
        subgraph cluster_4386357992 {
            label = "<<Adder>>"
            style=dashed
            {rank=source;
                4386358048 [label="heat_in" style=filled fillcolor="#b5fed9"]
                4386358104 [label="room_temp_in" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358216 [label="state" style=filled fillcolor="#e2cbc1" shape=doublecircle]
            }
            {rank=sink;
                4386358160 [label="temperature" style=filled fillcolor="#fcc5b3"]
            }
            4386358216 -> 4386358160 [style="dashed"]
        }


        subgraph cluster_4386358328 {
            label = "<<HeatElement>>"
            style=solid
            {rank=source;
                4386358384 [label="electricity" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358496 [label="on" style=filled fillcolor="#e2cbc1" shape=doublecircle]
            }
            {rank=sink;
                4386358440 [label="heat" style=filled fillcolor="#fcc5b3"]
            }
            4386358496 -> 4386358440 [style="dashed"]
        }


        subgraph cluster_4386358608 {
            label = "<<LightElement>>"
            style=solid
            {rank=source;
                4386358664 [label="electricity" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358776 [label="off" style=filled fillcolor="#e2cbc1" shape=doublecircle]
                4386358832 [label="on" style=filled fillcolor="#e2cbc1" shape=circle]
            }
            {rank=sink;
                4386358720 [label="light" style=filled fillcolor="#fcc5b3"]
            }
            4386358776 -> 4386358832
            4386358832 -> 4386358776
            4386358776 -> 4386358720 [style="dashed"]
            4386358832 -> 4386358720 [style="dashed"]
        }

        4386358160 -> 4386357824
        4386357712 -> 4386358104
        4386358440 -> 4386358048
        4386358720 -> 4386357600
        4386357936 -> 4386358384 [style="dashed"]
        4386357936 -> 4386358664 [style="dashed"]
        4386357936 -> 4386357656 [style="dashed"]
    }

}

希望的解决方案: 这是我想要结束的。请注意绿色框在各自子图中的左侧,而红色框在右侧。之间应该有其余的元素,由 graphviz 定位。

您可以通过添加不可见边将三个输入连接到图表的其余部分来获得您想要的布局,以便 graphviz 布局算法可以正确计算它们的排名。您可以通过将 style=invis 添加到边缘格式来使任何边缘不可见。

digraph MyGraph {
    node [fontsize=8  margin=".1,.01" width=.5 height=.5 shape=box]
    edge [fontsize=8]
    rankdir=LR;
    ranksep = .25;
    nodesep= .5;

subgraph cluster_4386357488 {
    label = " <<GrowLamp>>"
    style=solid
    {rank=source;
        4386357544 [label="electricity" style=filled fillcolor="#b5fed9"]
        4386357712 [label="room_temperature" style=filled fillcolor="#b5fed9"]
        4386357768 [label="switch" style=filled fillcolor="#b5fed9"]
    }
    {
        4386357880 [label="off" style=filled fillcolor="#e2cbc1" shape=doublecircle]
        4386357936 [label="on" style=filled fillcolor="#e2cbc1" shape=circle]
        4386357656 [label="on_time" style=filled fillcolor="#d2ceef"]
    }
    {rank=sink;
        4386357600 [label="light" style=filled fillcolor="#fcc5b3"]
        4386357824 [label="temperature" style=filled fillcolor="#fcc5b3"]
    }
    4386357880 -> 4386357936
    4386357936 -> 4386357880
    #invisible edges added to achieve correct layout
    4386357544 -> 4386357880 [style="invis"]
    4386357712 -> 4386357880 [style="invis"]
    4386357768 -> 4386357880 [style="invis"]

    {
        subgraph cluster_4386357992 {
            label = "<<Adder>>"
            style=dashed
            {rank=source;
                4386358048 [label="heat_in" style=filled fillcolor="#b5fed9"]
                4386358104 [label="room_temp_in" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358216 [label="state" style=filled fillcolor="#e2cbc1" shape=doublecircle]
            }
            {rank=sink;
                4386358160 [label="temperature" style=filled fillcolor="#fcc5b3"]
            }
            4386358216 -> 4386358160 [style="dashed"]
        }


        subgraph cluster_4386358328 {
            label = "<<HeatElement>>"
            style=solid
            {rank=source;
                4386358384 [label="electricity" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358496 [label="on" style=filled fillcolor="#e2cbc1" shape=doublecircle]
            }
            {rank=sink;
                4386358440 [label="heat" style=filled fillcolor="#fcc5b3"]
            }
            4386358496 -> 4386358440 [style="dashed"]
        }


        subgraph cluster_4386358608 {
            label = "<<LightElement>>"
            style=solid
            {rank=source;
                4386358664 [label="electricity" style=filled fillcolor="#b5fed9"]
            }
            {
                4386358776 [label="off" style=filled fillcolor="#e2cbc1" shape=doublecircle]
                4386358832 [label="on" style=filled fillcolor="#e2cbc1" shape=circle]
            }
            {rank=sink;
                4386358720 [label="light" style=filled fillcolor="#fcc5b3"]
            }
            4386358776 -> 4386358832
            4386358832 -> 4386358776
            4386358776 -> 4386358720 [style="dashed"]
            4386358832 -> 4386358720 [style="dashed"]
        }

        4386358160 -> 4386357824
        4386357712 -> 4386358104
        4386358440 -> 4386358048
        4386358720 -> 4386357600
        4386357936 -> 4386358384 [style="dashed"]
        4386357936 -> 4386358664 [style="dashed"]
        4386357936 -> 4386357656 [style="dashed"]
    }

}
}

使用 dot.exe 2.38 版,您应该得到如下图表: