使用Dot/Graphviz在家族树可视化中的节点放置 [英] Node placement in family tree visualization with 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屋!