使用Dot/Graphviz在家族树可视化中的节点放置 [英] Node placement in family tree visualization with Dot/Graphviz

查看:102
本文介绍了使用Dot/Graphviz在家族树可视化中的节点放置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Dot/Graphviz从数据库生成族谱可视化.最初的结果看起来很有希望,但是有一个我还无法解决的布局问题.

I'm trying to generate family tree visualizations from a database using Dot/Graphviz. First results look promising, but there is one layout issue that I haven't been able to fix yet.

当我使用下面列出的代码时,它将产生

When I use the code listed below, it will produce

我对此非常满意.但是,只要我尝试在F4/M4/M5和F2/M2系列之间添加另一个节点(可以通过取消注释以下代码中的两行来完成),它将给我

I'm totally happy with this. But as soon as I try to add another node between families F4/M4/M5 and F2/M2, which can be done by uncommenting the two lines in the code below, it will give me

Male2现在被放置在远离Female2的位置,并且位于Female4和Male4之间.因此,家庭F2/M2和F4/M4/M5完全被撕裂了.我试图增加家庭连接的权重(值为100),以确保将家庭F2/M2和F4/M4/M5放在一起,但这是行不通的.到目前为止,更改节点或连接的顺序也无济于事.最好的解决方案是,如果可以将F4/M4/M5家族放在左边,将MaleX放在中央,将F2/M2家族放在右边.

Male2 is now placed far away from Female2 and between Female4 and Male4. So the families F2/M2 and F4/M4/M5 are completely torn apart. I tried to increase the weight for the family connections (value is 100) in order to make sure families F2/M2 and F4/M4/M5 are placed together, but this doesn't work. Also changing order of nodes or connections did not help so far. The best solution would be, if family F4/M4/M5 could be placed on the left, MaleX in the center and family F2/M2 on the right.

有人建议吗?我宁愿不更改代码中定义节点和连接的顺序,因为这是由脚本完成的,并且由数据库结构预先定义.

Does anyone have a suggestion? I would prefer to not change the order in which the nodes and connections are defined in the code, because this is done by a script and is kind of predefined by the database structure.

graph Test {

rankdir = BT;
splines = ortho;
center = true;

{
rank = same;
NodeFemale1 [label = Female1];
NodeMale1 [label = Male1];
ConnectionFemale1Male1 [shape = box, label = "", height = 0, width = 1, margin = 0, penwidth = 1];
NodeFemale1 -- ConnectionFemale1Male1 -- NodeMale1 [weight = 100, penwidth = 2];
}

ConnectionChildren11 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
ConnectionFemale1Male1 -- ConnectionChildren11 [penwidth = 2];

{
rank = same;
NodeFemale2 [label = Female2];
NodeMale2 [label = Male2];
ConnectionFemale2Male2 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
NodeFemale2 -- ConnectionFemale2Male2 -- NodeMale2 [weight = 100, penwidth = 2];
}

ConnectionChildren11 -- NodeMale2 [penwidth = 2];

ConnectionChildren22 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
ConnectionFemale2Male2 -- ConnectionChildren22 [penwidth = 2];

NodeMale3 [label = Male3];
ConnectionChildren22 -- NodeMale3 [weight = 10, penwidth = 2];

NodeFemale3 [label = Female3];
ConnectionChildren22 -- NodeFemale3 [penwidth = 2];

// NodeMaleX [label = MaleX];
// ConnectionChildren11 -- NodeMaleX [weight = 10, penwidth = 2];

{
rank = same;
NodeFemale4 [label = Female4];
NodeMale4 [label = Male4];
NodeMale5 [label = Male5];
ConnectionFemale4Male4 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
NodeFemale4 -- ConnectionFemale4Male4 -- NodeMale4 [weight = 100, penwidth = 2];
ConnectionMale4Male5 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
NodeMale4 -- ConnectionMale4Male5 -- NodeMale5 [weight = 100, penwidth = 2];
}

ConnectionChildren11 -- NodeFemale4 [penwidth = 2];

ConnectionChildren44 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
ConnectionFemale4Male4 -- ConnectionChildren44 [penwidth = 2];

NodeFemale6 [label = Female6];
ConnectionChildren44 -- NodeFemale6 [weight = 10, penwidth = 2];

NodeFemale7 [label = Female7];
ConnectionChildren44 -- NodeFemale7 [penwidth = 2];

ConnectionChildren45 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
ConnectionMale4Male5 -- ConnectionChildren45 [penwidth = 2];

NodeFemale8 [label = Female8];
ConnectionChildren45 -- NodeFemale8 [penwidth = 2];

}

推荐答案

我认为您可以不依靠subgraph来控制自己想要的方式.这在为您提供节点和边缘的脚本和数据库的上下文中可能有帮助,也可能没有帮助,但是我已经尝试过一些希望与您想要的内容接近的东西:

I don't think you can take control the way you want without resorting to subgraph. This may or may not be helpful in the context of your script and database that provides you with the nodes and edges but I have tried something that hopefully comes close to what you want:

graph Test 
{
/* layout / format */
    rankdir = BT;               // bottoms to top
    splines = ortho;            // edges orthogonal
    center = true;              // page center
    edge [ penwidth = 2 ];      // edge thickness
    node [ width = 1.1 ];       // conistent node size

/* node and edge definitions as produced by the script (?) */
    NodeFemale1 [label = Female1];
    NodeMale1 [label = Male1];
    ConnectionFemale1Male1 [shape = box, label = "", height = 0, width = 1, margin = 0, penwidth = 1];
    // 1 NodeFemale1 -- ConnectionFemale1Male1 -- NodeMale1 [weight = 100, penwidth = 2];
    ConnectionChildren11 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 2 ConnectionFemale1Male1 -- ConnectionChildren11 [penwidth = 2];
    NodeFemale2 [label = Female2];
    NodeMale2 [label = Male2];
    ConnectionFemale2Male2 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 3 NodeFemale2 -- ConnectionFemale2Male2 -- NodeMale2 [weight = 100, penwidth = 2];
    // 4 ConnectionChildren11 -- NodeMale2 [penwidth = 2];
    ConnectionChildren22 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 5 ConnectionFemale2Male2 -- ConnectionChildren22 [penwidth = 2];
    NodeMale3 [label = Male3];
    // 6 ConnectionChildren22 -- NodeMale3 [weight = 10, penwidth = 2];
    NodeFemale3 [label = Female3];
    // 7 ConnectionChildren22 -- NodeFemale3 [penwidth = 2];
    NodeMaleX [label = MaleX];
    // 8 ConnectionChildren11 -- NodeMaleX [weight = 10, penwidth = 2];
    NodeFemale4 [label = Female4];
    NodeMale4 [label = Male4];
    NodeMale5 [label = Male5];
    ConnectionFemale4Male4 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 9 NodeFemale4 -- ConnectionFemale4Male4 -- NodeMale4 [weight = 100, penwidth = 2];
    ConnectionMale4Male5 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 10 NodeMale4 -- ConnectionMale4Male5 -- NodeMale5 [weight = 100, penwidth = 2];
    // 11 ConnectionChildren11 -- NodeFemale4 [penwidth = 2];
    ConnectionChildren44 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 12 ConnectionFemale4Male4 -- ConnectionChildren44 [penwidth = 2];
    NodeFemale6 [label = Female6];
    // 13 ConnectionChildren44 -- NodeFemale6 [weight = 10, penwidth = 2];
    NodeFemale7 [label = Female7];
    // 14 ConnectionChildren44 -- NodeFemale7 [penwidth = 2];
    ConnectionChildren45 [shape = box, label = "", height = 0, width = 0, margin = 0, penwidth = 1];
    // 15 ConnectionMale4Male5 -- ConnectionChildren45 [penwidth = 2];
    NodeFemale8 [label = Female8];
    // 16 ConnectionChildren45 -- NodeFemale8 [penwidth = 2];

/* family / generation subgraphs */
    subgraph cluster0
    {
        style = filled;
        fillcolor = lightgrey;
        color = white;
        { rank = same; NodeFemale1; ConnectionFemale1Male1; NodeMale1 }
        NodeFemale1 -- ConnectionFemale1Male1 -- NodeMale1;
    }

    ConnectionFemale1Male1 -- ConnectionChildren11;

    subgraph cluster1
    {
        { rank = same; NodeMale2; ConnectionFemale2Male2; NodeFemale2 }
        NodeFemale2 -- ConnectionFemale2Male2 -- NodeMale2;
    }

    ConnectionChildren11 -- NodeMale2;

    subgraph cluster2
    {
        NodeMaleX;
    }

    ConnectionChildren11 -- NodeMaleX;

    subgraph cluster3
    {
        { rank = same; NodeFemale4; NodeMale4; NodeMale5; ConnectionFemale4Male4; ConnectionMale4Male5 }
        NodeFemale4 -- ConnectionFemale4Male4 -- NodeMale4 -- ConnectionMale4Male5 -- NodeMale5;
    }

    ConnectionChildren11 -- NodeFemale4;

    subgraph cluster4
    {
        color = white;
        { rank = same; NodeMale3; NodeFemale3 }
    }

    ConnectionFemale2Male2 --ConnectionChildren22;
    ConnectionChildren22 -- { NodeMale3 NodeFemale3 };

    subgraph cluster5
    {
        color = white;
        { rank = same; NodeFemale6; NodeFemale7 }
    }

    ConnectionFemale4Male4 --ConnectionChildren44;
    ConnectionChildren44 -- { NodeFemale6 NodeFemale7 };

    subgraph cluster6
    {
        color = white;
        NodeFemale8;
    }

    ConnectionMale4Male5 --ConnectionChildren45;
    ConnectionChildren45 -- NodeFemale8;
}

集群可以自定义,如父母级别所示.如果您只设置color = white,它们将变为不可见",如孙子代所示.

The clusters can be customized, as demonstrated on the parents level. If you just set color = white they become "invisible", as shown in the grandchildren generation.

这篇关于使用Dot/Graphviz在家族树可视化中的节点放置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆