DOT 可以生成更结构化的图表吗?

Tam*_*nor 4 dot graphviz

我不太确定如何描述我的客户想要什么,所以我会让一张图片来说明大部分内容。我正在使用 DOT 来生成或多或少的物料清单问题的图表。(显示所有级别的传入批次和所有传出批次,这些批次是根据传入批次中的材料创建的。)我已经获得了创建包含适当结构化数据的图表的代码。例如,我生成这个GV文件:

digraph LotTrc {
  rankdir=LR;
  graph[label="Lot #AD626", labelloc=top, labeljust=left, fontsize=24];
   PO_AD626_0000003333[shape=triangle,color=greenyellow,style=filled,label=AD626];
   AJ_AD626_SJ00000099[shape=circle,color=red2,style=filled,label=AD626];
   PO_AD626_0000003333  -> AJ_AD626_SJ00000099;
   AJ_AD626_SJ00000103[shape=circle,color=red2,style=filled,label=AD626];
   PO_AD626_0000003333  -> AJ_AD626_SJ00000103;
   WO_AD627_RE00002230[shape=ellipse,color=lemonchiffon,style=filled,label=AD627];
   PO_AD626_0000003333  -> WO_AD627_RE00002230;
   SO_AD627_OZ00025429[shape=box,color=cyan3,style=filled,label=AD627];
   WO_AD627_RE00002230  -> SO_AD627_OZ00025429;
   SO_AD627_OZ00025434[shape=box,color=cyan3,style=filled,label=AD627];
   WO_AD627_RE00002230  -> SO_AD627_OZ00025434;
   SO_AD627_OZ00025439[shape=box,color=cyan3,style=filled,label=AD627];
   WO_AD627_RE00002230  -> SO_AD627_OZ00025439;
   SO_AD627_OZ00025444[shape=box,color=cyan3,style=filled,label=AD627];
   WO_AD627_RE00002230  -> SO_AD627_OZ00025444;
   WO_AD628_RE00002231[shape=ellipse,color=lemonchiffon,style=filled,label=AD628];
   PO_AD626_0000003333  -> WO_AD628_RE00002231;
   SO_AD628_OZ00025430[shape=box,color=cyan3,style=filled,label=AD628];
   WO_AD628_RE00002231  -> SO_AD628_OZ00025430;
   SO_AD628_OZ00025435[shape=box,color=cyan3,style=filled,label=AD628];
   WO_AD628_RE00002231  -> SO_AD628_OZ00025435;
   SO_AD628_OZ00025440[shape=box,color=cyan3,style=filled,label=AD628];
   WO_AD628_RE00002231  -> SO_AD628_OZ00025440;
   SO_AD628_OZ00025445[shape=box,color=cyan3,style=filled,label=AD628];
   WO_AD628_RE00002231  -> SO_AD628_OZ00025445;
   WO_AD629_RE00002232[shape=ellipse,color=lemonchiffon,style=filled,label=AD629];
   PO_AD626_0000003333  -> WO_AD629_RE00002232;
   SO_AD629_OZ00025431[shape=box,color=cyan3,style=filled,label=AD629];
   WO_AD629_RE00002232  -> SO_AD629_OZ00025431;
   SO_AD629_OZ00025436[shape=box,color=cyan3,style=filled,label=AD629];
   WO_AD629_RE00002232  -> SO_AD629_OZ00025436;
   SO_AD629_OZ00025441[shape=box,color=cyan3,style=filled,label=AD629];
   WO_AD629_RE00002232  -> SO_AD629_OZ00025441;
   SO_AD629_OZ00025446[shape=box,color=cyan3,style=filled,label=AD629];
   WO_AD629_RE00002232  -> SO_AD629_OZ00025446;
   WO_AD630_RE00002233[shape=ellipse,color=lemonchiffon,style=filled,label=AD630];
   PO_AD626_0000003333  -> WO_AD630_RE00002233;
   SO_AD630_OZ00025432[shape=box,color=cyan3,style=filled,label=AD630];
   WO_AD630_RE00002233  -> SO_AD630_OZ00025432;
   SO_AD630_OZ00025437[shape=box,color=cyan3,style=filled,label=AD630];
   WO_AD630_RE00002233  -> SO_AD630_OZ00025437;
   SO_AD630_OZ00025442[shape=box,color=cyan3,style=filled,label=AD630];
   WO_AD630_RE00002233  -> SO_AD630_OZ00025442;
   SO_AD630_OZ00025447[shape=box,color=cyan3,style=filled,label=AD630];
   WO_AD630_RE00002233  -> SO_AD630_OZ00025447;
   WO_AD631_RE00002234[shape=ellipse,color=lemonchiffon,style=filled,label=AD631];
   PO_AD626_0000003333  -> WO_AD631_RE00002234;
   SO_AD631_OZ00025433[shape=box,color=cyan3,style=filled,label=AD631];
   WO_AD631_RE00002234  -> SO_AD631_OZ00025433;
   SO_AD631_OZ00025438[shape=box,color=cyan3,style=filled,label=AD631];
   WO_AD631_RE00002234  -> SO_AD631_OZ00025438;
   SO_AD631_OZ00025443[shape=box,color=cyan3,style=filled,label=AD631];
   WO_AD631_RE00002234  -> SO_AD631_OZ00025443;
   SO_AD631_OZ00025448[shape=box,color=cyan3,style=filled,label=AD631];
   WO_AD631_RE00002234  -> SO_AD631_OZ00025448;

}
Run Code Online (Sandbox Code Playgroud)

它产生这个图表:在此输入图像描述

但我的客户真正想要的是看起来更像这样的东西,边缘是直线,根据需要使用 90 度角。(请注意,这是通用的,并非基于上面的示例。)

在此输入图像描述

有没有办法使用 DOT 来生产类似的东西?

Dan*_*any 6

您可以尝试样条=ortho图属性。它以 90 度角进行非常笔直的连接。

但我不会推荐它。控制它们几乎是不可能的,端口规范通常不适用于它们,而且正交样条可能会消耗一些边缘标签。

可能的解决方案是使用具有point形状的虚拟节点(此形状很方便,因为它默认删除节点标签)和width=0。在需要 90 度转弯的地方使用这些虚拟节点。您必须将它们与子图中的主节点分组,并添加等级=same属性以强制这些节点保持在同一级别。

您可能还需要向某些边缘添加重量以防止它们弯曲(重量较高的边缘往往是直的)。

例子

我已经使用上述技术实现了示例图的一部分,代码和图像如下:

digraph {
    rankdir=LR
    ranksep=1
    nodesep=0.5

    LOT1 [shape=rect]
    LOT2 [shape=rect]
    LOT3 [shape=rect]
    LOT4 [shape=rect]
    LOT5 [shape=rect]

    {rank=same
        PO
        dot1 [shape=point width=0]
        dot2 [shape=point width=0]
        PO -> dot1 -> dot2 [arrowhead=none]
    }
    dot1 -> WO1 [weight=20]
    {
        rank=same
        WO1
        dot21  [shape=point width=0]
        dot22  [shape=point width=0]
        WO1 -> dot21 -> dot22 [arrowhead=none]
    }
    dot21 -> LOT1 [weight=20]
    dot22 -> LOT2 [weight=20]
    {
        rank=same
        dot31 [shape=point width=0]
        dot32 [shape=point width=0]
        dot33 [shape=point width=0]
        dot31 -> dot32 -> dot33 [arrowhead=none]
    }
        dot2 -> WO2 [weight=20]
    {
        WO2
        rank=same
        dot23 [shape=point width=0]
        dot24 [shape=point width=0]
        dot25 [shape=point width=0]
        WO2 -> dot23 -> dot24 -> dot25 [arrowhead=none]
    }
    dot23 -> LOT3 [weight=20]
    dot24 -> LOT4 [weight=20]
    dot25 -> LOT5 [weight=20]
    dot31 -> SO1
    dot33 -> SO2
    LOT1 -> dot32
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述