首页 > 解决方案 > 带有 Graphviz 的分层状态机

问题描述

我正在尝试在 Graphviz 的帮助下制作供应商机器的状态图。

我想要一个接近这个的结果。

它也由嵌套的状态机组成。这是我到目前为止在 Graphviz 中所做的。请在此处找到在线演示。

digraph vendorMachine {
compound=true

Entry[shape="point" label=""]

subgraph cluster_cancel {
    label = "Cancel"
    style = rounded

    C0 [label = <
        <table cellborder="0" style="rounded">
            <tr><td>C0</td></tr>
            <hr/>
            <tr><td></td></tr>
        </table>
    > margin=0 shape=none]
    
    C25 [label = <
        <table cellborder="0" style="rounded">
            <tr><td>C25</td></tr>
            <hr/>
            <tr><td></td></tr>
        </table>
    > margin=0 shape=none]

    C50 [label = <
        <table cellborder="0" style="rounded">
            <tr><td>C50</td></tr>
            <hr/>
            <tr><td></td></tr>
        </table>
    > margin=0 shape=none]
    
    C75 [label = <
        <table cellborder="0" style="rounded">
            <tr><td>C75</td></tr>
            <hr/>
            <tr><td></td></tr>
        </table>
    > margin=0 shape=none]
    
    subgraph cluster_DispenseC100Drink {
        label = "DispenseC100Drink"
        style = rounded
        
        C100 [label = <
            <table cellborder="0" style="rounded">
                <tr><td>C100</td></tr>
                <hr/>
                <tr><td></td></tr>
            </table>
        > margin=0 shape=none]
        
        subgraph cluster_DispenseC125Drink {
            label = "DispenseC125Drink"
            style = rounded
            
            C125 [label = <
                <table cellborder="0" style="rounded">
                    <tr><td>C125</td></tr>
                    <hr/>
                    <tr><td></td></tr>
                </table>
            > margin=0 shape=none]
            
            C150 [label = <
                <table cellborder="0" style="rounded">
                    <tr><td>C150</td></tr>
                    <hr/>
                    <tr><td></td></tr>
                </table>
            > margin=0 shape=none]
    
            C175 [label = <
                <table cellborder="0" style="rounded">
                    <tr><td>C175</td></tr>
                    <hr/>
                    <tr><td></td></tr>
                </table>
            > margin=0 shape=none]
            
            C200 [label = <
                <table cellborder="0" style="rounded">
                    <tr><td>C200</td></tr>
                    <hr/>
                    <tr><td></td></tr>
                </table>
            > margin=0 shape=none]
                }
            }
}

Entry -> C0
C0 -> C25[label=" Add\n$0.25 "]
C0 -> C50[label=" Add\n$0.50 "]

C25 -> C50[label=" Add\n$0.25 "]
C25 -> C75[label=" Add\n$0.50 "]

C50 -> C75[label=" Add\n$0.25 "]
C50 -> C100[label=" Add\n$0.50 "]

C100 -> C0[label=" Dispense\n $1.00 Drink " ltail="cluster_DispenseC100Drink"]

C75 -> C100[label=" Add\n$0.25 "]
C75 -> C125[label=" Add\n$0.50 "]

C100 -> C125[label=" Add\n$0.25 "]
C100 -> C150[label=" Add\n$0.50 "]

C125 -> C150[label=" Add\n$0.25 "]
C125 -> C175[label=" Add\n$0.50 "]

C125 -> C0[label=" Dispense\n $1.25 Drink "  ltail="cluster_DispenseC125Drink"]

C150 -> C175[label=" Add\n$0.25 "]
C150 -> C200[label=" Add\n$0.50 "]

C175 -> C200[label=" Add\n$0.25 "]

C200 -> C0[label=" Dispense\n $2.00 Drink "]

}

所以,我的查询是:

  1. 如何使这类似于提到的图像?
  2. 除了我的 Graphviz 代码之外,还有其他更好的方法吗?(这是我迄今为止所做的最好的方法)
  3. Graphviz 代码中缺少一个转换,如果我们通过Cancel事件,它应该进入状态C0(请查看附图)。我们如何使用 Graphviz 实现这一点?

提前感谢您的建议和答案。

标签: graphvizdotstatechart

解决方案


“直” Graphviz(命令行)产生不同(和“更接近”)的结果。这是您的程序,只需进行一些调整:

digraph vendorMachine {
    compound=true
    graph [color=red]
    node [color=red]  // yuck style=filled fillcolor=yellow]
    edge [color=red]
    
    Entry[shape="point" label=""]

    subgraph cluster_cancel {
        label = "Cancel"
        style = rounded

    E2   [shape=rect label="" width=2 style=invis]
    E2:sw->C0  [label=cancel]


        C0 [label = <
            <table cellborder="0" style="rounded">
                <tr><td>C0</td></tr>
                <hr/>
                <tr><td></td></tr>
            </table>
        > margin=0 shape=none]
        
        C25 [label = <
            <table cellborder="0" style="rounded">
                <tr><td>C25</td></tr>
                <hr/>
                <tr><td></td></tr>
            </table>
        > margin=0 shape=none]

        C50 [label = <
            <table cellborder="0" style="rounded">
                <tr><td>C50</td></tr>
                <hr/>
                <tr><td></td></tr>
            </table>
        > margin=0 shape=none]
        
        C75 [label = <
            <table cellborder="0" style="rounded">
                <tr><td>C75</td></tr>
                <hr/>
                <tr><td></td></tr>
            </table>
        > margin=0 shape=none]
        
        subgraph cluster_DispenseC100Drink {
            label = "DispenseC100Drink"
            style = rounded
            
            C100 [label = <
                <table cellborder="0" style="rounded">
                    <tr><td>C100</td></tr>
                    <hr/>
                    <tr><td></td></tr>
                </table>
            > margin=0 shape=none]
            
            subgraph cluster_DispenseC125Drink {
                label = "DispenseC125Drink"
                style = rounded
                
                C125 [label = <
                    <table cellborder="0" style="rounded">
                        <tr><td>C125</td></tr>
                        <hr/>
                        <tr><td></td></tr>
                    </table>
                > margin=0 shape=none]
                
                C150 [label = <
                    <table cellborder="0" style="rounded">
                        <tr><td>C150</td></tr>
                        <hr/>
                        <tr><td></td></tr>
                    </table>
                > margin=0 shape=none]
        
                C175 [label = <
                    <table cellborder="0" style="rounded">
                        <tr><td>C175</td></tr>
                        <hr/>
                        <tr><td></td></tr>
                    </table>
                > margin=0 shape=none]
                
                C200 [label = <
                    <table cellborder="0" style="rounded">
                        <tr><td>C200</td></tr>
                        <hr/>
                        <tr><td></td></tr>
                    </table>
                > margin=0 shape=none]
                    }
                }
    }
    
    Entry -> C0
    C0 -> C25[label=" Add\n$0.25 "]
    C0 -> C50[label=" Add\n$0.50 "]
    
    C25 -> C50[label=" Add\n$0.25 "]
    C25 -> C75[label=" Add\n$0.50 "]
    
    C50 -> C75[label=" Add\n$0.25 "]
    C50 -> C100[label=" Add\n$0.50 "]
    
    C100 -> C0[label=" Dispense\n $1.00 Drink " ltail="cluster_DispenseC100Drink"]
    C75 -> C100[label=" Add\n$0.25 "]
    C75 -> C125[label=" Add\n$0.50 "]
    C100 -> C125[label=" Add\n$0.25 "]
    C100 -> C150[label=" Add\n$0.50 "]
    C125 -> C150[label=" Add\n$0.25 "]
    C125 -> C175[label=" Add\n$0.50 "]
    C125 -> C0[label=" Dispense\n $1.25 Drink "  ltail="cluster_DispenseC125Drink"]
    C150 -> C175[label=" Add\n$0.25 "]
    C150 -> C200[label=" Add\n$0.50 "]
    C175 -> C200[label=" Add\n$0.25 "]
    C200 -> C0[label=" Dispense\n $2.00 Drink "]
}

给予:
在此处输入图像描述


推荐阅读