Javascript 如何防止族树生成器中的重叠?

Javascript 如何防止族树生成器中的重叠?,javascript,charts,jsplumb,family-tree,genealogy,Javascript,Charts,Jsplumb,Family Tree,Genealogy,我正在创建一个交互式家谱生成器,不像更简单的版本,它是简单的系谱图/家谱树 矿山(基于familyecho.com)的要求是: 多个合作伙伴,而不是你通常看到的一个简单的双亲对一个孩子 多兄弟姐妹 伴侣不一定要有孩子 不一定要有一对父母,可以只有一个父亲/母亲 我遇到的问题是:我正在基于“当前”节点/族成员生成偏移量,当我超过第一代(例如,有两个父代)时,偏移量重叠 重叠以及伙伴未绘制在同一X轴上的示例: 这是我的问题所在。这里是我创建的一个演示父级/偏移问题的示例,尽管我确实需要解决重叠

我正在创建一个交互式家谱生成器,不像更简单的版本,它是简单的系谱图/家谱树

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

  • 多个合作伙伴,而不是你通常看到的一个简单的双亲对一个孩子
  • 多兄弟姐妹
  • 伴侣不一定要有孩子
  • 不一定要有一对父母,可以只有一个父亲/母亲
我遇到的问题是:我正在基于“当前”节点/族成员生成偏移量,当我超过第一代(例如,有两个父代)时,偏移量重叠

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

这是我的问题所在。这里是我创建的一个演示父级/偏移问题的示例,尽管我确实需要解决重叠问题,除了确保合作伙伴绘制在与其他合作伙伴相同的x轴上之外

我如何着手解决这一问题以及未来可能出现的重叠冲突?我是否需要某种重画功能,在检测时检测并调整每个块的偏移量?我试图使它无缝,所以有一个有限的重画完成

计算相对于“上下文”或当前节点的偏移量的示例:

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 );
                        }

我将给出一个复杂的答案,那是因为这种情况比你想象的要复杂。图形布局算法是一个活跃的研究领域。很容易尝试一种比一般算法更简单的算法,但当你做出不必要的、通常是隐藏的假设时,它会以惊人的方式失败

一般来说,遗传图不是平面图(参见维基百科)。虽然不常见,但所有的祖先关系都不是由独特的人来填补的。例如,当第二堂兄弟有孩子时,就会发生这种情况

另一种非平面情况可能发生在非一夫一妻制父母子女的情况下。最简单的例子是两男两女,每个人都有孩子(因此至少有四个孩子)。如果没有曲线,您甚至不能在一个列中布置四个父对

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

不过,你实际上问的问题要基本得多。您遇到了一些基本的困难,因为您需要使用图形的一部分。这是“自上而下”(在其中一条评论中)的完整版本。这只是许多算法中的一种

您正在绘制一个有向图,其中(至少)隐含了秩的概念。受试者为0级;父母排名第一;祖父母排名第二。(关于上述警告,排名并不总是唯一的。)这类图表的大部分区域都在祖先中。如果不先布置叶节点,就没有成功的希望。其思想是首先布置具有最高等级的节点,然后逐步合并等级较低的节点。深度优先遍历是最常用的方法


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

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

当我将您的示例图输入到Family Echo中时,我可以构建一个看起来很漂亮的树,它似乎就是您要寻找的,没有交叉

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


如果我在JavaScript方面有更多的专业知识,我会尝试构建一些代码来复制Family Echo正在做的事情,但我恐怕这不是我的窍门。

你必须调整你影响的节点上的所有分支,每个分支都必须重新计算其节点的位置,每个节点都必须在到达叶子的地方重新计算。一旦叶子被计算出来,你就必须在备份的过程中重新计算,所有这些都是递归的。它就像一棵真正的树,当你把树枝添加到树干上时。。。其他分支单独移动以留出一些空间,所有图纸都会自动重置,因此您必须想象。并在图表中模拟此过程。处理到达每个叶的每个分支,并重新计算直到重新计算修改的节点邻居。(比你开始的级别高一级)这不是一件容易的事,也不是一件容易的事。

对于重叠的爷爷/奶奶问题,你所要做的也许只是延长父母之间的距离?你是否尝试过从上到下而不是当前的自底向上的方法布置节点?您得到了重叠,因为(至少在JavaScript示例中)您是基于假设来定位父对象的