如何防止家谱生成器中出现重叠?

How can I prevent overlapping in a family tree generator?

我正在创建一个交互式家谱创建器,不像更简单的版本是简单的家谱 charts/trees。

我的要求(基于familyecho.com)是:

我遇到的问题是:我正在根据 "current" node/family 成员生成偏移量,当我经过第一个时一代说,2 parents,它重叠。

重叠和伙伴未绘制在同一 X 轴上的示例:

这是我创建的 actual app and main js file where I'm having the issue. And here is a simplified jsfiddle,它演示了 parent/offset 问题,尽管我确实必须解决这个 一般 的重叠问题,此外还需要确保合作伙伴与其他合作伙伴绘制在相同的 x 轴上。

我该如何着手解决这个问题以及未来可能发生的重叠冲突?我是否需要某种重绘功能来检测 collisions 并在检测时调整每个块的偏移量?我正在尝试使其无缝,因此完成的重绘数量有限。

计算相对于"context"或当前节点偏移的例子:

var offset = getCurrentNodeOffset();

                        if ( relationship == RELATIONSHIPS.PARTNER ) {
                            var t = offset.top; // same level
                            var l = offset.left + ( blockWidth + 25 );
                        } else {
                            var t = offset.top - (blockHeight + 123 ); // higher
                            var l = offset.left - ( blockWidth - 25 );
                        }

我要给出一个复杂的答案,那是因为这种情况比你想象的要复杂得多。图布局算法是一个活跃的研究领域。很容易尝试 simpler-than-general 算法,然后当您做出毫无根据且通常是隐藏的假设时,它会以惊人的方式失败。

一般来说,基因遗传图是不是平面的(参见维基百科上的Planar Graphs)。尽管不常见,但肯定会发生并非所有祖先关系都由独特的人填补。例如,当第二代表亲有 children 时,就会发生这种情况。

另一种non-planar情况可能发生在children的情况下non-monogamousparents。最简单的例子是两个男人和两个女人,每个配对 children(因此至少有四个)。如果没有曲线,您甚至无法将四对 parent 排成一排。

这些只是示例。我相信您在研究算法时会发现更多。这里真正的教训是显式建模 class 您的算法能够布局的关系,并在算法中包含验证代码以检测数据何时不满足这些要求。

不过,您实际上要问的问题要基本得多。您遇到了基本困难,因为您需要使用 depth-first traversal of the graph. This is the (easiest) full version of what it means to lay out "from the top down" (in one of the comments). This is only one of many algorithms for tree traversal.

您正在布置一个具有(至少)隐含等级概念的有向图。主题排名 0; parent排名第一; grandparents 排在第 2 位。(关于上面的警告,排名并不总是唯一的。)此类图表的大部分区域都在祖先中。如果不先把叶子节点布局好,就没有成功的希望。这个想法是首先布置排名最高的节点,逐渐合并 lower-ranked 个节点。 Depth-first 遍历是最常用的方法。

我会将其视为 graph-rewriting 算法。基本数据结构是渲染子图和底层祖先图的混合体。渲染的子图是 (1) 整个图的子树,具有 (1a) 一组后代,其所有祖先都被渲染,以及 (2) 渲染数据的集合:节点和线的位置等。初始状态混合的是整个图,没有渲染的子图。最终状态是渲染的整个图。该算法的每一步都将混合图的叶边界处的一组元素转换为(更大的)渲染子图,从而减少混合图中的元素数量。最后只有一个元素,即整个渲染图。

既然您已经在使用 Family Echo,我建议您看看他们是如何制作在线家谱图的,因为他们似乎已经解决了您的问题。

当我将您的示例图表输入 Family Echo 时,我可以构建一个看起来很漂亮的树,这似乎是您正在寻找的没有交叉的树。

虽然他们是用 html 和 css 创建图表,但您可以将人员一一添加到他们的图表中,然后根据左侧和右侧检查框的放置位置每个元素的顶部像素位置。

如果我在 JavaScript 方面有更多专业知识,我会尝试编写一些代码来复制 Family Echo 正在做的一些事情,但恐怕那不是我的魔力。

你必须调整你影响的节点的所有分支,每个分支都必须重新计算其节点的位置,并且每个节点都必须在本地重新计算达到 leaves.You 计算一旦叶子将不得不重新计算一直到备份,所有这些都是递归的。就像一棵真正的树,当你在树干上添加物理分支时......其他分支单独移动留下一些space,所有的工作表都会自动重置,所以你必须想象。并在你的图表中模拟这个过程。处理每个分支到达每个叶子,并重新计算以重新计算修改后的节点邻居。 (比你开始的级别高)这不是一件容易的事,也不是一件容易的事。