存在集群时的 GraphViz 水平顺序

标签 graphviz dot

好吧,我知道在 GraphViz 中排序节点的问题已经接近死亡,但我还没有看到有人解决排序集群的问题。我尝试了书中的所有技巧:

  • 文件中节点的顺序是从左到右。如果我不添加集群,dot 只会做正确的事情并以正确的顺序显示它们,而无需任何提示。但是,当添加集群时,点会打乱(随机化?)顺序。
  • 我添加了不可见的边来尝试强制子集群之间的顺序;但似乎一旦子集群被放置在一个集群中,dot 就会决定一些特定的顺序,并且会毫不犹豫地让边缘遍布 map 以保留它。
  • 由于节点顺序和不可见边使我失败,我转向尝试强制节点的位置。这再次失败,因为只有 dot 进行聚类,并且它忽略了输入位置。甚至通过 fdp 运行未经修改的 dot 输出(带有生成的位置)也会导致崩溃,所以我也放弃了这个方向。

  • 这是一个 example dot file产生下面的图像。绿线是我添加的“不可见”边缘,试图强制点从左到右对所有内容进行排序,但未成功。如果这成功了,绿线将从 anchor 向左穿过节点,然后向右移动,而不会交叉。例如,每个 be.0 将在其同级 be.1 的左侧,对于 tg-s 也是如此)。如您所见, dot 打乱了子簇的顺序(将 .1 兄弟放在 .0 的左侧)。就好像它是故意这样做的,由于一些限制,不管任何边缘。我找不到任何方法来说服它不这样做。这非常令人沮丧,因为生成的图表非常适合我的需求。
    Badly ordered dot clusters
    (来源:ben-kiki.org)
    所以。有没有任何 有什么方法可以强制 dot 遵守集群内集群的某些顺序?
    编辑:进一步研究这一点,似乎集群的默认顺序与节点的顺序相反。也就是说,通常(在 TB 图中),首先出现在文本中的节点将倾向于出现在文本中稍后出现的节点的左侧;但似乎首先出现在文本中的子簇往往会出现在文本中稍后出现的子簇的右侧。现在,如果这是一个硬性规定,生活会很棒;然而, dot 有时(但不经常)仍然坚持重新排列子簇,不管产生的任何交叉边缘,似乎“只是因为”。所以问题仍然存在。

    最佳答案

    有点晚了,但这里有一些其他人的想法:
    (示例数据有点大,无法使用)

    无论如何你有没有试过:

  • edge[constraint=false] 在一些黑/红线上(constraint=false 可能会
    虽然有些奇怪的长边路由)
  • 和/或绿线上的 edge[weight=1000](更难做对),
  • 您可能还想投入更多的脚手架
  • 你不能跨集群排名=相同,所以如果需要它必须在脚手架节点上

  • 这是一个简单的例子,它成功地改变了包括集群在内的一半节点的顺序
    digraph G {
        subgraph cluster_sa{
        edge[weight=1000]
        subgraph cluster_s1a{ s1a1->s1a2 }
        subgraph cluster_s2a{ s2a1->s2a2 }
        subgraph cluster_s1a_{ s1a1_->s1a2_ }
        subgraph cluster_s2a_{ s2a1_->s2a2_ }
        s1a2->s1a1_
        s2a2->s2a1_
        }
    {
        edge[constraint=false]
        subgraph cluster_ta{
        subgraph cluster_t1a{ t1a1->t1a2 }
        subgraph cluster_t2a{ t2a1->t2a2 }
        subgraph cluster_t1a_{ t1a1_->t1a2_ }
        subgraph cluster_t2a_{ t2a1_->t2a2_ }
        t1a2->t1a1_
        t2a2->t2a1_
        }
        edge[tailport=s headport=s]
        s1a2_->t1a1
        s2a2_->t2a1
    }
    edge[color=green]
    node[color=green]
    {rank=same s1a0->s2a0->t2a0->t1a0}
    s1a0->s1a1
    s2a0->s2a1
    t1a0->t1a2_
    t2a0->t2a2_
    
    t1a2_->t1a1_->t1a2->t1a1
    t2a2_->t2a1_->t2a2->t2a1
    }
    

    在 viz-js.com 上呈现

    bending

    有时,以相反的顺序连接节点也可能很有用(例如 t2a2_->t2a1_[dir=back] 而不是上面的实际上会更好,因为绿色箭头可以被删除,给出一个直的黑色箭头)但我不认为这对你的情况会有帮助

    关于存在集群时的 GraphViz 水平顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11942033/

    相关文章:

    Graphviz 允许边缘节点重叠

    graphviz - 有没有办法使用 graphviz 中的 fdp 布局在同一集群中的节点之间与不同集群中的节点之间拥有不同的边缘样条?

    graphviz - 如何引导边缘脱离右侧的菱形?

    graphviz - 如何控制 graphviz 中的节点放置(即避免边缘交叉)

    dot - 在 dot graphviz 中从左到右订购框

    python - 在python中将点转换为png

    graphviz - 使用 GraphViz 绘制扩展形式的游戏

    graphviz - 为什么 fillcolor 不能与 graphviz 一起使用?

    python - 如何从 Python 将 "dot"作为命令运行?