自上而下的子图,左右内部子图

发布于 2024-12-09 20:57:13 字数 1406 浏览 1 评论 0 原文

我想让我的图表看起来像这样:

但我只能得到这个:

问题是,rankdir 子图中不起作用。 那么,如何模仿呢?

代码:

digraph G {
    node [shape = circle]
    0 [style = invis]

    0 -> "0A"

    subgraph clusterA {
        label=A
        "0A"
        "1A"
        "2A" -> "0A" [label=•]
    }

    subgraph clusterB {
        label=B
        "0B"
        "1B"
        "2B" -> "0B" [label=•]
    }

        subgraph clusterC {
        label=C
        "0C"
        "1C"
        "2C" -> "0C" [label=•]
    }

    subgraph clusterD {
        label=D
        "0D"
        "1D"
        "2D" -> "0D" [label=•]
    }

    subgraph clusterE {
        label=E
        "0E"
        "1E"
        "2E" -> "0E" [label=•]
    }

    subgraph clusterF {
        label=F
            {node [shape = doublecircle] "0F" "1F"}
        "2F" -> "0F" [label=•]
    }

    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
    "0C" -> "1D" [label=c]
    "1C" -> "2D" [label=c]
    "0D" -> "1E" [label=d]
    "1D" -> "2E" [label=d]
    "0E" -> "1F" [label=e]
    "1E" -> "2F" [label=e]
}

I'd like to have my graph looks like this:

But I can only get this:

The problem is, rankdir does not work in subgraph.
So, how to emulate it?

The code:

digraph G {
    node [shape = circle]
    0 [style = invis]

    0 -> "0A"

    subgraph clusterA {
        label=A
        "0A"
        "1A"
        "2A" -> "0A" [label=•]
    }

    subgraph clusterB {
        label=B
        "0B"
        "1B"
        "2B" -> "0B" [label=•]
    }

        subgraph clusterC {
        label=C
        "0C"
        "1C"
        "2C" -> "0C" [label=•]
    }

    subgraph clusterD {
        label=D
        "0D"
        "1D"
        "2D" -> "0D" [label=•]
    }

    subgraph clusterE {
        label=E
        "0E"
        "1E"
        "2E" -> "0E" [label=•]
    }

    subgraph clusterF {
        label=F
            {node [shape = doublecircle] "0F" "1F"}
        "2F" -> "0F" [label=•]
    }

    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
    "0C" -> "1D" [label=c]
    "1C" -> "2D" [label=c]
    "0D" -> "1E" [label=d]
    "1D" -> "2E" [label=d]
    "0E" -> "1F" [label=e]
    "1E" -> "2F" [label=e]
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柠檬 2024-12-16 20:57:13

复制特定的图形布局通常可以通过以下方式实现:

  • 不可见的节点和边
  • 等级约束

以下是我复制图形的方法 - 或至少是它的一部分:

digraph g {
    rankdir="LR";
    node[shape = circle, fontsize=14];
    fontsize=18;
    labeljust="l";

    edge[style=invis, fontsize=12];

    { rank=same;
        0 [style = invis];
        01 [style = invis];
        02 [style=invis];
        0 -> 01 -> 02;
    }

    subgraph clusterA {
        "0A" -> "1A" -> "2A";
        "2A" -> "0A" [label=".", constraint=false, style=solid];
        label="A";
    }

    subgraph clusterB {
        "0B" -> "1B" -> "2B";
        "2B" -> "0B" [label=".", constraint=false, style=solid];
        label="B";
    }

    subgraph clusterC {
        "0C" -> "1C" -> "2C";
        "2C" -> "0C" [label=".", constraint=false, style=solid];
        label="C";
    }

    0 -> "0A"[style=solid];
    01 -> "0B"[style=invis];
    02 -> "0C"[style=invis];

    // edges between clusters
    edge[constraint=false, style=solid];
    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
}

这个解决方案不是很直观。要实现这一点,需要注意以下几点:

  • 我选择了 rankdir="LR",它的边缘比 TB 更好,尽管它与图形的方向并不真正对应
  • < strong>不可见节点和边用于顶级节点(0、01、02),以使簇左对齐。
  • (不可见的)顶部节点被强制为相同的等级,并通过不可见的边链接 - 这将确保链接到每个节点的簇以正确的顺序出现。

结果是:

Reproducing particular graph layouts usually can be achieved with:

  • Invisible nodes and edges
  • rank constraints

Here's how I reproduced your graph - or at least a part of it:

digraph g {
    rankdir="LR";
    node[shape = circle, fontsize=14];
    fontsize=18;
    labeljust="l";

    edge[style=invis, fontsize=12];

    { rank=same;
        0 [style = invis];
        01 [style = invis];
        02 [style=invis];
        0 -> 01 -> 02;
    }

    subgraph clusterA {
        "0A" -> "1A" -> "2A";
        "2A" -> "0A" [label=".", constraint=false, style=solid];
        label="A";
    }

    subgraph clusterB {
        "0B" -> "1B" -> "2B";
        "2B" -> "0B" [label=".", constraint=false, style=solid];
        label="B";
    }

    subgraph clusterC {
        "0C" -> "1C" -> "2C";
        "2C" -> "0C" [label=".", constraint=false, style=solid];
        label="C";
    }

    0 -> "0A"[style=solid];
    01 -> "0B"[style=invis];
    02 -> "0C"[style=invis];

    // edges between clusters
    edge[constraint=false, style=solid];
    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
}

This solution is not very intuitive. A couple of points to achieve this:

  • I chose rankdir="LR" which resulted in nicer edges than TB, though it does not really correspond with the direction of the graph
  • Invisible nodes and edges are use for the top rank nodes (0, 01, 02) in order to have the clusters align left.
  • The (invisible) top nodes are forced to the same rank and are linked by invisible edges - this will ensure that the clusters linked to each node appear in the correct order.

The result is:

graphviz output

野心澎湃 2024-12-16 20:57:13

看起来rank=same可能是一个更干净的解决方案。查看在 Graphviz 中将集群置于相同等级

您还可以使用“constraint=false”和不可见边来仔细控制节点等级。这与上面的答案基本相同。

digraph G {
    newrank=true; // rank without respect to cluster
    rankdir="LR"; 
    node [shape = circle]
    
    subgraph clusterA {
        a0 -> a1 -> a2 [style = invis] // set node order in cluster
        a2 -> a0 [constraint=false] //don't use this edge for ranking
    }

    subgraph clusterB {
        b0 -> b1 -> b2 [style = invis]
        b2 -> b0  [constraint=false]
    }
    
    a0 -> b1 [constraint=false]
    a1 -> b2 [constraint=false]
    
}

输入图像描述这里

It looks like rank=same might be a cleaner solution. Take a look at Placing clusters on the same rank in Graphviz.

You can also use 'constraint=false' and invisible edges to carefully control node rank. This is basically the same answer as the above.

digraph G {
    newrank=true; // rank without respect to cluster
    rankdir="LR"; 
    node [shape = circle]
    
    subgraph clusterA {
        a0 -> a1 -> a2 [style = invis] // set node order in cluster
        a2 -> a0 [constraint=false] //don't use this edge for ranking
    }

    subgraph clusterB {
        b0 -> b1 -> b2 [style = invis]
        b2 -> b0  [constraint=false]
    }
    
    a0 -> b1 [constraint=false]
    a1 -> b2 [constraint=false]
    
}

enter image description here

混浊又暗下来 2024-12-16 20:57:13

使用group更新@marapet的答案

digraph g {
rankdir="LR";
node[shape = circle, fontsize=14];
fontsize=18;
labeljust="l";

edge[style=invis, fontsize=12];

{ rank=same;
    0 [group=a style = invis];
    01 [style = invis];
    02 [group=b style=invis];
    0 -> 01 -> 02;
}

subgraph clusterA {
    "0A" [group=a]
    "0A" -> "1A" -> "2A";
    "2A" -> "0A" [label=".", constraint=false, style=solid];
    label="A";
}

subgraph clusterB {
    "0B" -> "1B" -> "2B";
    "2B" -> "0B" [label=".", constraint=false, style=solid];
    label="B";
}

subgraph clusterC {
    "0C" [group=b]
    "1C" [group=b]
    "0C" -> "1C" -> "2C";
    "2C" -> "0C" [label=".", constraint=false, style=solid];
    label="C";
}

0 -> "0A"[style=solid];
01 -> "0B"[style=invis];
02 -> "0C"[style=invis];

// edges between clusters
edge[constraint=false, style=solid];
"0A" -> "1B" [label=a]
"1A" -> "2B" [label=a]
"0B" -> "1C" [label=b]
"1B" -> "2C" [label=b]
}

An update on @marapet's answer using group

digraph g {
rankdir="LR";
node[shape = circle, fontsize=14];
fontsize=18;
labeljust="l";

edge[style=invis, fontsize=12];

{ rank=same;
    0 [group=a style = invis];
    01 [style = invis];
    02 [group=b style=invis];
    0 -> 01 -> 02;
}

subgraph clusterA {
    "0A" [group=a]
    "0A" -> "1A" -> "2A";
    "2A" -> "0A" [label=".", constraint=false, style=solid];
    label="A";
}

subgraph clusterB {
    "0B" -> "1B" -> "2B";
    "2B" -> "0B" [label=".", constraint=false, style=solid];
    label="B";
}

subgraph clusterC {
    "0C" [group=b]
    "1C" [group=b]
    "0C" -> "1C" -> "2C";
    "2C" -> "0C" [label=".", constraint=false, style=solid];
    label="C";
}

0 -> "0A"[style=solid];
01 -> "0B"[style=invis];
02 -> "0C"[style=invis];

// edges between clusters
edge[constraint=false, style=solid];
"0A" -> "1B" [label=a]
"1A" -> "2B" [label=a]
"0B" -> "1C" [label=b]
"1B" -> "2C" [label=b]
}
≈。彩虹 2024-12-16 20:57:13

使用constraint = false应该让子图中的节点变成你想要的方式
http://www.graphviz.org/doc/info/attrs.html #d:constraint

subgraph clusterB {
    label=B
    "0B"
    "1B"
    "2B" -> "0B" [constraint=false label=•]
}

之后,您会发现您的子图没有按照您想要的方式彼此对齐。像这样的事情可以解决这个问题。

"0A" -> "0B" -> "0C" -> "0D" -> "0E" [weight=999 style=invis];

Using constraint=false should get the nodes in your subgraphs to turn out the way you want
http://www.graphviz.org/doc/info/attrs.html#d:constraint

subgraph clusterB {
    label=B
    "0B"
    "1B"
    "2B" -> "0B" [constraint=false label=•]
}

After that you'll find that your subgraphs don't line up with each other the way you want. Something like this could resolve that.

"0A" -> "0B" -> "0C" -> "0D" -> "0E" [weight=999 style=invis];
深爱不及久伴 2024-12-16 20:57:13

rankdir 不能直接在子图中工作,但是如果您添加另一组大括号(无论它叫什么),rankdir 就可以工作。见下文。然后,显然您需要更多技巧来恢复您所追求的对齐和排序。

digraph G {
    node [shape = circle]
    0 [style = invis]

    0 -> "0A"

    subgraph clusterA {
        label=A
        {
            rank=same
            "0A"
            "1A"
            "2A" -> "0A" [label=•]
        }
    }

    subgraph clusterB {
        label=B
        {
            rank=same
            "0B"
            "1B"
            "2B" -> "0B" [label=•]
        }
    }

    subgraph clusterC {
        label=C
        {
            rank=same
            "0C"
            "1C"
            "2C" -> "0C" [label=•]
        }
    }

    subgraph clusterD {
        label=D
        {
            rank=same
            "0D"
            "1D"
            "2D" -> "0D" [label=•]
        }
    }

    subgraph clusterE {
        label=E
        {
            rank=same
            "0E"
            "1E"
            "2E" -> "0E" [label=•]
        }
    }

    subgraph clusterF {
        label=F
        {
            rank=same
            {node [shape = doublecircle] "0F" "1F"}
            "2F" -> "0F" [label=•]
        }
    }

    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
    "0C" -> "1D" [label=c]
    "1C" -> "2D" [label=c]
    "0D" -> "1E" [label=d]
    "1D" -> "2E" [label=d]
    "0E" -> "1F" [label=e]
    "1E" -> "2F" [label=e]
}

输入图片此处描述

rankdir doesn't work directly in the subgraph, but if you add another set of curly braces - whatever that's called - rankdir works. See below. Then, obviously you need more tricks to restore the alignment and ordering you're after.

digraph G {
    node [shape = circle]
    0 [style = invis]

    0 -> "0A"

    subgraph clusterA {
        label=A
        {
            rank=same
            "0A"
            "1A"
            "2A" -> "0A" [label=•]
        }
    }

    subgraph clusterB {
        label=B
        {
            rank=same
            "0B"
            "1B"
            "2B" -> "0B" [label=•]
        }
    }

    subgraph clusterC {
        label=C
        {
            rank=same
            "0C"
            "1C"
            "2C" -> "0C" [label=•]
        }
    }

    subgraph clusterD {
        label=D
        {
            rank=same
            "0D"
            "1D"
            "2D" -> "0D" [label=•]
        }
    }

    subgraph clusterE {
        label=E
        {
            rank=same
            "0E"
            "1E"
            "2E" -> "0E" [label=•]
        }
    }

    subgraph clusterF {
        label=F
        {
            rank=same
            {node [shape = doublecircle] "0F" "1F"}
            "2F" -> "0F" [label=•]
        }
    }

    "0A" -> "1B" [label=a]
    "1A" -> "2B" [label=a]
    "0B" -> "1C" [label=b]
    "1B" -> "2C" [label=b]
    "0C" -> "1D" [label=c]
    "1C" -> "2D" [label=c]
    "0D" -> "1E" [label=d]
    "1D" -> "2E" [label=d]
    "0E" -> "1F" [label=e]
    "1E" -> "2F" [label=e]
}

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文