【问题标题】:Positionating and arrow direction in GraphVizGraphViz 中的定位和箭头方向
【发布时间】:2017-11-02 17:29:25
【问题描述】:

我正在尝试使用 GraphViz 将一些非常旧的文档迁移到我们的内部 wiki。

我不习惯 Dot 语言,需要一些帮助

参见以下示例:

我进行了很多实验,但到目前为止我得出的最好的结果是:

digraph CentralPmr {  
  fontname="Helvetica";
  shape=box;
  node[shape=box];
  graph [splines=ortho]

  sg  [label="TTD storage group for\nthe logged values"]
  vc  [label="Value catalogue"]
  tc1 [label="Time catalogoue (1)"]
  tc2 [label="Time catalogoue (2)"]
  sv_ [shape=point,width=0.01,height=0.01];
  sv  [label=""]
  ie  [shape=none, label="Initiating event"]
  c1  [shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log."]
  c2  [shape=none, label="Time catalogue defining\nat what time around the\ninitiating event values\nshould be collected."]
  sgf [shape=record, label="{<f0> 1|2|3|4|..}|{ | | | | }"]

  sg  -> sv_ [penwidth=4, dir=none];
  sv_ -> sv -> tc2 [penwidth=4]
  sv  -> sgf:f0 [penwidth=4]
  {vc, tc1}  -> sg
  c1  -> sv [style=dashed, arrowhead="open"];

  {rank=min;  ie} 
  {rank=same; sg c1}
  {rank=same; vc sgf}
  {rank=max;  rc2}
}

它不必与来源完全相同,但我希望它易于理解。

问题是:

  1. 如何在“Value catalogue”和“Time catalogue (1)”之间放置文字?
  2. [编辑]如何强制箭头“用于 PMR 冻结值的 TTD 存储组”从侧面而不是从上方?它是内存区域的虚拟化,箭头指向特定的内存柱。在其他图像中,它可以指向内存区域中的其他内存柱(例如 2、3、4..)。
  3. 是否可以从“启动事件”创建曲折线?
  4. 如何在底部放置说明不同类型线条的图例?
  5. [编辑]如何在“用于 PMR 冻结值的 TTD 存储组”上方、下方和右侧添加 cmets?
  6. [编辑] 如何使“PMR 冻结值的 TTD 存储组”更宽?

【问题讨论】:

    标签: graph graphviz dot directed-graph


    【解决方案1】:

    这是在我的第一个答案之上,以某种方式编辑该答案会造成太多混乱。我已尝试考虑您的所有需求,并且仅在您放弃 splines=ortho 要求时才有效(我相信)。请参考我的第一个答案下方的 cmets。我们开始:

    digraph CentralPmr {  
        fontname="Helvetica";
        shape=box;
        node[shape=box];
        // graph [splines=ortho]
    
        sg  [label="TTD storage group for\nthe logged values", width = 2.5]
        sv[ label="", width = 2]
        ie [ shape=none, label="Initiating event", fontsize = 18 ]
        c1 [ shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log." ]
    
        sgf[shape=box, margin=0, label=<
        <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
            <TR>
                <TD BORDER="0" COLSPAN="2">TTD storage group for<BR/>PMR freezed values</TD>
            </TR>
            <TR>
                <TD PORT="f1">1</TD>
                <TD BORDER="0" ROWSPAN="6">The set of<BR/>values is<BR/>stored in<BR/>the TTD<BR/>storage<BR/>group</TD>
            </TR>
            <TR>
                <TD>2</TD>
            </TR>
                    <TR>
                <TD>3</TD>
            </TR>
                    <TR>
                <TD>4</TD>
            </TR>
                    <TR>
                <TD>-</TD>
            </TR>
            <TR>
                <TD>-</TD>
            </TR>
            <TR>
                <TD BORDER="0" COLSPAN="2">Up to nine freezing areas<BR/>for defined central PMR</TD>
            </TR>
        </TABLE>>]; 
    
        TTD [shape=none, margin=0, label=<
        <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="12">
            <TR>
                <TD PORT="f1">Value catalogue</TD>
            </TR>
            <TR>
                <TD BORDER="0"></TD>
            </TR>
            <TR>
                <TD PORT="f2">Time catalogue (1)</TD>
            </TR>
            <TR>
                <TD BORDER="0">Time catalogue defining<BR/>at what time around the<BR/>initiating event values<BR/>should be collected</TD>
            </TR>
            <TR>
                <TD PORT="f3">Time catalogue (2)</TD>
            </TR>
        </TABLE>>]; 
    
    
        connector_1[ shape = point height = 0 width = 0 margin = 0 ]
        ie -> connector_1[ style = dotted, arrowhead = none ];
        { rank = same; connector_1 c1 }
        connector_1 -> c1[ style = invis, minlen = 4 ];
        c1 -> sv[ style = dashed, arrowhead = open ];
        connector_2[ shape = point height = 0 width = 0 margin = 0 ]
        connector_1 -> connector_2[ style = dotted ];
        { rank = same; sg connector_2 sv }
        sg -> connector_2[ minlen = 3, penwidth = 4, arrowhead = none ];
        connector_2 -> sv[ minlen = 3, penwidth = 4 ];
    
        sg:sw -> TTD:f1:nw[ weight = 5 ];
        sg:w -> TTD:f2:w;
        sv:sw -> TTD:f3:e[ penwidth = 4 ];
        sv:sw -> sgf:f1:w[ penwidth = 4 ];
    
        node[ shape = plaintext ];
        leg2[ label = "Data flow" ];
        leg4[ label = "Reference" ];
        leg6[ label = "Comment" ];
    
        node [ shape = point height = 0 width = 0 margin = 0 ];
        leg1 leg3 leg5
    
        TTD:sw -> leg1[ style = invis ];
    
        { rank = same; leg1 leg2 leg3 leg4 leg5 leg6 }
        edge[ minlen = 2 ];
        leg1 -> leg2[ penwidth = 4 ];
        leg3 -> leg4[ style = dotted ];
        leg5 -> leg6[ style = dashed, arrowhead = open ];
    }
    

    产量

    【讨论】:

    • 我非常感谢你放下的工作。它看起来很棒,比我预期的要好得多。现在我想我已经拥有了将其余文档数字化所需的东西。非常感谢。
    • 祝你好运,随时乐于提供帮助!
    • 如果你有更多的东西,你可能会喜欢一些处理工具。使用 m4 作为预处理器可以帮助我保持源文件小而干净。看看here.
    • 我已将我的 m4 文件和命令添加到上面的 github 链接中,以防你想看看它是如何工作的。
    【解决方案2】:

    不确定我是否完全理解您想要什么,但低于我的看法。这只是第一次尝试,可以做更多的微调。我可能会使用类似 HTML 的节点,其中文本和“框”需要更接近,特别是对于原始图中的“用于 PMR 冻结值的 TTD 存储组”。

    我对您的问题的回答是:

    如何在“价值目录”和“时间目录(1)”之间放置文字?

    --- 见下文。我把它放在两个时间目录之间,就像原始图表一样,但很容易移动。

    如何强制记录的箭头从侧面而不是从上方?

    --- 见下文。如果这是您的问题,您也可以使用 rankdir = LR; 更改方向。

    是否可以从“启动事件”创建锯齿线?

    --- 有很多方法,但需要付出很多努力(比如创建自定义形状)。据我所知,没有什么“开箱即用”。

    如何在底部放置图例?

    我不太明白,但总的来说,当我们谈论节点时,答案应该是类似 HTML 的标签。

    她就是我所做的:

    digraph CentralPmr 
    {  
        fontname="Helvetica";
        shape=box;
        node[shape=box];
        graph [splines=ortho]
    
        sg  [label="TTD storage group for\nthe logged values"]
        vc  [label="Value catalogue"]
        tc1 [label="Time catalogoue (1)"]
        tc2 [label="Time catalogoue (2)"]
        sv_ [shape=point,width=0.01,height=0.01];
        sv  [label="", width = 2]
        ie  [shape=none, label="Initiating event"]
        c1  [shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log."]
        c2  [shape=none, label="Time catalogue defining\nat what time around the\ninitiating event values\nshould be collected."]
        sgf [shape=record, label="{<f0> 1|2|3|4|..}|{ | | | | }"]
    
        connector_1[ shape = point height = 0 width = 0 margin = 0 ]
        ie -> connector_1[ style = dotted, arrowhead = none ];
        { rank = same; connector_1 c1 }
        connector_1 -> c1[ style = invis ];
        c1 -> sv[ style = dashed, arrowhead = open ];
        connector_2[ shape = point height = 0 width = 0 margin = 0 ]
        connector_1 -> connector_2[ style = dotted ];
        { rank = same; sg connector_2 sv }
        sg -> connector_2[ minlen = 3, penwidth = 4, arrowhead = none ];
        connector_2 -> sv[ minlen = 3, penwidth = 4 ];
    
        vc -> tc1 -> c2 -> tc2[ style = invis, weight = 10 ];
        sg -> vc;
        sg -> tc1;
        sv -> tc2[ penwidth = 4 ];
        sv -> sgf;
    }
    

    产量

    【讨论】:

    • 哦,非常感谢。与我的尝试相比有了很大的进步。 *我在第二个问题中有些不清楚,我希望我现在已经说得更清楚了。 * 是否可以使“价值目录”、“时间目录1/2”和评论更接近? * 缺少“用于 PMR 冻结值的 TTD 存储组”周围的文本(已将其添加到原始问题中) * 对于图例,我的意思是在不同行的含义底部进行解释。
    • 恐怕我承诺过头了。要么我得到正确的文本框,但无法控制边缘,或者相反。毕竟,如果你看看 graphviz 应该做什么,这并不奇怪。我会做更多的工作,稍后在此处将其发布为 github 链接,但这不是一个完美的解决方案。
    • 您会考虑放弃splines = ortho 布局吗?让生活变得如此轻松......
    • 我知道完美的解决方案是不可能的。但是 spline=ortho 并不是那么重要,所以如果它更容易删除它。如果需要,您还可以将结构向右移动。
    • 看我的第二个答案