你如何在 d3.js 中创建家谱?

IT技术 javascript d3.js charts family-tree genealogy
2021-01-18 21:22:05

我目前正在进行一个小型家谱实验,并希望实现一个简单的家谱,如下图所示。

迄今为止最好的搜索结果只产生了一个子节点只能有一个父节点的例子。但我需要的是能够在实体之间(从父亲到母亲)以及节点和其他链接(从孩子到父母链接)之间创建链接。目前我没有固定的数据模式。

为此选择了d3.js因为它看起来能够胜任这项工作我只是不知道如何开始,甚至不知道从哪里开始。有关 d3.js 的教程仅涵盖条形图等标准图表。

我希望有人能帮我解决这个问题。

结果应该是这样的

6个回答

我的方法如下:

让我们以您在附图中说明的示例为例:

Jenny Of Oldstones也是Aegon V的孩子,但这个孩子与 Aegon V 的其他孩子之间的区别在于,在这种情况下,我没有画出它之间的联系。

这是通过在节点 JSON 示例中将节点设置为no_parent: true来完成的:

//Here Q will not have a parent
 {
            name: "Q",
            id: 16,
            no_parent: true
 }

在代码中检查_elbowfunction_ 这做了不画它和它的父之间的线的工作:

if (d.target.no_parent) {
    return "M0,0L0,0";
}

下一个场景是节点Aerys II 和 Rahella之间的链接该节点有其子节点集。

  • 我在它们之间创建了一个节点,标记为 hidden: true,
  • display:none为这样的节点制作了看起来孩子们来自节点Aerys II 和 Rahella之间的线

JSON 示例:

//this node will not be displayed
{ name: "",
    id: 2,
    no_parent: true,
    hidden: true,
    children: [....]

    }

在代码中检查我制作矩形的地方,下面的代码隐藏了节点:

    .attr("display", function (d) {
    if (d.hidden) {
        return "none"
    } else {
        return ""
    };
})

完整代码在这里:http : //jsfiddle.net/cyril123/0vbtvoon/22/

在上面的示例中,我使用了节点名称 A/B/C...但您可以根据需要更改它。您需要将文本居中。

我在代码中添加了注释以帮助您理解流程。以防万一您有任何不清楚的地方,请发表评论,我很乐意澄清。

如果您查看原始问题中的评论,那么您会发现有人链接了我想标记为正确的答案。我改变了主意:你的答案是最好的答案,因为它确实考虑了一些其他人没有考虑的问题。谢谢!
2021-03-24 21:22:05
@prc322 是的,在为此答案编码之前,我已经阅读了这些评论。
2021-03-30 21:22:05
@Cyril - 精彩的回答。但是,如果您必须支持多个合作伙伴呢?例如,如果在您的示例中,假设“Q”有另一个名为“Z”的合作伙伴,并且他们有一个儿子。这会改变结构的方式,对吧?
2021-03-31 21:22:05
@Cyril - 我调整了结构并在这里发布了一个问题:stackoverflow.com/questions/34077696/...
2021-04-08 21:22:05
首先感谢这种方法。你有没有想过是否有超过一代人之间的杂交(在我的情况下参考植物),比如两个亲本来自第一代,另一个来自第三代。在某些情况下,当孩子在低代父母之后附加时,您的方法有效。但在某些情况下,上一代父代被绘制在较低的 x 方向上,并且图形不合适。任何帮助表示赞赏。
2021-04-09 21:22:05

dTree是一个建立在 D3 之上的开源库,用于创建家谱(或类似的分层图)。

它处理手动生成 D3 图的麻烦部分,并使用简单的 json 数据格式:

[{
  name: "Father",
  marriages: [{
    spouse: {
      name: "Mother",
    },
    children: [{
      name: "Child",
    }]
  }]
}]

如果您有兴趣修改它,它支持节点渲染和事件处理程序的回调。最后,该库截至 2016 年正在开发中,欢迎请求请求。

免责声明:我是 dTree 的作者。我像你一样在网上搜索后创建了这个库,但没有找到我喜欢的任何东西。

感谢分享!如果可以选择水平或垂直渲染树,那就太好了!
2021-03-24 21:22:05
谢谢,正是我要找的。
2021-04-01 21:22:05
这太棒了,感谢分享,我只是在尝试创建自己的家谱,这非常有帮助
2021-04-09 21:22:05

不太好的消息:我所做的研究表明,没有开箱即用的 d3 库可以直接实现这一点,而无需进行一些自定义。

消息:已经有谁已经研究过这和发现了一些很好的出发点,其他一些人!我意识到这不是手头整个任务的完整解决方案,但从您的问题看来,到目前为止您的大部分困难只是弄清楚从哪里开始(例如“关于 d3.js 的教程仅涵盖标准像条形图这样的图表。”)。在没有更好的情况下,我至少会在这里回应那部分。

首先,为了响应几年前这篇相关的 stackoverflow 帖子,inanutshellus 提供了一些很棒的 d3 工具,这些工具可以在这里使用。通过一些轻量级的定制/扩展,它们应该能够让您相对较快地到达目的地。对于后人,inanutshellus 的回答在此转载:

有一些选择,但我相信每个都需要一些工作。如果有一个单一的标准来表示 JSON 中的家谱,那将会有所帮助。我最近注意到 geni.com 有一个非常深入的 API。也许针对他们的 API 进行编码对于可重用性来说是一个好主意......

-- 谱系树 --

谱系树 可能足以满足您的需求。您可以将姻亲的链接设为可链接,如果您点击他们的名字,图表将重新绘制,以便您可以看到他们的血统。

-- 支架布局树 --

类似于谱系树,但是是双向的,这个Bracket Layout Tree 允许您处理“这是我的父母、祖父母、孩子、孙子”类型的视图。与谱系树一样,您可以使个人可链接以将括号重新居中在该节点上。

-- 基于力的布局 --

有一些有趣的基于力的布局看起来很有希望。看看这个带有智能标签的基于力的布局示例对如何确定“力”的算法进行调整可以使其成为一棵非常可爱的树,老一代在新一代之上或之下。

-- 聚类树状图(失败的原因)-

我见过的最适合家谱的 d3.js 布局假设单个节点是父节点,而您需要将父节点表示为两个节点之间的组合(视觉上是“T”):一个节点是你的树的一个成员,一个代表姻亲的浮动节点。调整集群树状图来做到这一点应该是可行的,但并非没有重大修改。

如果你——或者其他任何人——解决了这个问题,请告诉我。我希望看到(并从中受益)这项工作,并且在可行的情况下可能会做出贡献。

在具体实现上,mj8591针对一个相似的家谱,不同的问题问了这个问题。但是,幸运的是,该问题包含一个具有您需要的大部分或所有组件的小提琴(所有 js 代码),并且来自 mdml响应包括另一个为每个节点添加一些更细粒度的“可点击性”的小提琴。

同样,这不是自动的,但希望这些资源足以让您有一个良好的开端!

我试过dtree并喜欢它。但是,当您添加几代时,横向显示会使整体显示非常大且笨拙。相反,我使用了Reingold-Tilford 树这棵树的一个缺点是每个节点只能有一个父节点:配偶不能并排显示:为了克服这个限制,我在发送之前调整了 JSON 以将配偶合并为一个实体(例如:“丈夫 - 妻子”)它到树上。

3年后回答问题。

现在有一个来自 Mike 的谱系树图

在此处输入图片说明

https://bl.ocks.org/mell0kat/5cb91a2048384560dfa8f041fd9a0295

然后是这个 d3.tree - 家谱 https://bl.ocks.org/mell0kat/5cb91a2048384560dfa8f041fd9a0295

您也可以从 Mike https://beta.observablehq.com/@mbostock/d3-tidy-tree再次尝试 D3 Tidy Tree

你的例子的问题是每个孩子只有 1 个父母。这可以通过 D3(或 google org chart 更容易)轻松完成,但问题是它无法显示 2 个父母。
2021-03-23 21:22:05