60

I'm currently working on a small genealogy experiment and would like to implement a simple family tree like in the picture below.

The best search results so far for this only yielded examples where a child can only have a parent node. But what I need is the ability to create links between entities (from father to mother) and links between nodes and other links (from child to the father-mother link). Currently I don't have a fixed data schema for this.

I've chosen d3.js for this because it looks like would be capable of doing the job. I just don't know how or even where to start. Tutorials about d3.js only cover standard charts like bar charts.

I hope someone can help me with this.

This is how the result should look like

  • 2
    a standard hierarchy table will do it.. what have you tried ? – Pogrindis Jul 06 '15 at 12:25
  • 3
    There are two problems here: creating and rendering the genealogy graph. D3.js is about rendering. You need a graph data structure to hold the data. – duffymo Jul 06 '15 at 12:25
  • @duffymo There is indeed a GraphDB behind this. As already mentioned I don't have a fixed JSON data schema for this to not scare away people with potential solutions. –  Jul 06 '15 at 12:27
  • Sounds like you need that schema. – duffymo Jul 06 '15 at 12:28
  • the schema as such is 90% of what you need, once you have a data structure its very easy to use with d3! – Pogrindis Jul 06 '15 at 12:31
  • Thanks for your comments guys. I will work that schema out, update the question (and also put a freaking bounty on this thing). Just thought I shouldn't restrict people to my schema. Any dynamic solution that looks like in the picture is *happily* welcome. –  Jul 06 '15 at 12:33
  • 1
    Hi @prc322 I'm not sure if you can directly help you here. But in my project (http://arda-maps.org/familytree/) I ran into the same trouble. First of all, yeah there is no out-of-the-box family tree layout available for D3. So I was searching a long time for a good alternative. But unfortunately there is none. Maybe the force layout is also a good way for you. I don't think it is the best for sure but at least it shows all the needed connections. Feel free to click on the Show All button to get an idea how it will look like with about 400 nodes. =) Hope it helps. – kwoxer Jul 07 '15 at 07:02
  • 1
    You could have a look at [dagre-d3](https://github.com/cpettitt/dagre-d3/wiki#demos). It's basically a library to draw DAG (directed acyclic graphs). So you should be able to use it to draw a family tree as well. [Here](http://cpettitt.github.io/project/dagre-d3/latest/demo/tcp-state-diagram.html) is an example of a dagre-d3 graph. – Baz Jul 08 '15 at 17:18
  • Why not this solution: http://stackoverflow.com/a/20810098/734687 – ChrLipp Jul 08 '15 at 17:46
  • @ChrLipp This is the answer. You can contact the author of this or make an answer to this thread and get the 500pts for yourself. Your decision. Anyways: thank you for this! –  Jul 08 '15 at 18:20
  • 2
    I contacted the original author. If he doesn't respond within 6 days I can still provide an answer, but I hope he does because he deserves it. Anyway: you are welcome! – ChrLipp Jul 09 '15 at 06:44
  • As a matter of fact D3 is a great option, however I doubt you will find a family tree otpion in it. However I found a library called Go.js that does it http://www.gojs.net/latest/samples/familyTree.html , go check their sample on gitHub, seems able to fit your needs – Jo Colina Jul 09 '15 at 11:50
  • @ChrLipp, this does not include siblings as the question illustrates...there are plenty of solutions that show standard pedigree that you've linked to here. However, the question here is about how to produce a more robust family tree. – matt Jul 09 '15 at 15:41
  • I would think a json hierarchy would do the job - however, I see some strange family relationships in that sample tree. It looks like siblings are having children, those children together are having children. That might be a challenge with the hierarchy and D3. – Mike Weber Jul 09 '15 at 16:03
  • @prc322 - did you ever come up with a solution for this? I'm trying to do the same thing - an interactive family tree such as familyecho. – meder omuraliev Nov 28 '15 at 21:24
  • @meder The Answer I marked as correct in here has pretty much everything I wanted. –  Nov 30 '15 at 09:17
  • @prc322 - How complex did your family tree get and did you have to extensively modify the code provided by Cyril? I'm doing an interactive family mapper so there will be infinite possibilities instead of just a static tree. – meder omuraliev Dec 02 '15 at 01:22
  • @meder Sounds like your problem is that Cyril didn't provide a module with an API but just static code working static data - which is totally okay. But you'd have to write that on your own. That's true. –  Dec 02 '15 at 15:08

7 Answers7

44

My approach is as under:

Lets take the example you have illustrated in the attached figure:

Jenny Of Oldstones is also a the child of Aegon V but the difference between this child and other children of Aegon V is that in this case I am not drawing the link between it.

This is done by setting the node as no_parent: true in the node JSON example:

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

In the code check the _elbow function_ this does the job of not drawing the line between it and its parent:

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

Next scenario is the link going between Node Aerys II and Rahella this node has its set of children.

  • I have created a node between them which is marked as hidden: true,
  • I make the display:none for such node. It appears that the children are coming from the line between node Aerys II and Rahella

JSON Example:

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

    }

In the code check the place where I make the rectangles, the code below hides the node:

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

Full code is in here: http://jsfiddle.net/cyril123/0vbtvoon/22/

In the example above, I have made the use of node names A/B/C... but you can change it as per you requirements. You will need to center the text.

I have added comments to the code to help you understand the flow. Just in case you are not clear on any point please comment I ll be happy to clarify.

Dave Alperovich
  • 31,680
  • 8
  • 71
  • 97
Cyril Cherian
  • 30,992
  • 7
  • 41
  • 50
  • If you watch the comments in the original question, then you will find that someone linked an answer I wanted to mark as correct. I've changed my mind: Your answer is the best answer since it does take some problems into account which others don't. Thank you! –  Jul 12 '15 at 18:28
  • 1
    @prc322 yes i had gone through those comments, before coding for this answer. – Cyril Cherian Jul 13 '15 at 00:57
  • @Cyril - brilliant answer. But what if you had to support multiple partners. For instance, what if in your example, say, "Q" had another partner named "Z" and they had a son. This would change how the structure would be, right? – meder omuraliev Dec 03 '15 at 22:31
  • @Cyril - I adjusted the structure and posted a question here: http://stackoverflow.com/questions/34077696/multiple-partners-in-a-familly-tree-in-d3-js – meder omuraliev Dec 03 '15 at 22:52
  • firstly thanks for this approach. Have you given any thoughts on if there is crossing (in reference to plants as in my case ) between more than a generation apart like among two parent one is from 1st generation and other from 3rd generation. Your approach works in some case when children are on appended after lower generation parent. But in some cases the upper generation parent get drawn on the lower x direction and the figure is out of place. any help is appreciated. – dhirajbasukala Sep 02 '16 at 11:03
  • I want image and click event for each person on it. can anyone help me through make it possible? – Mohit maru Feb 11 '17 at 06:25
  • Such a great answer, feeling awesome man. I was following the jsfiddle in the answer from last 3 days and bang on i cracked it. I am grateful to you :) – Codesingh May 24 '17 at 02:46
  • Hi, can you help me in implementing this thing in backend, i mean i am wanting to handle this thing in api so that when json data comes i can directly add it to the frontend code, voila. Thanks again for such a wizzo answer :) – Codesingh Jun 27 '17 at 06:48
  • can anyone please help me with my query? -https://stackoverflow.com/questions/64587495/how-can-i-connect-two-parent-node-into-one-child-node-in-d3-js-svg – thelonelyCoder Oct 29 '20 at 08:59
17

dTree is an open source library built on-top of D3 that creates family trees (or similar hierarchical graphs).

It handles the bothersome parts of generating the D3 graph manually and uses a simple json data format:

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

If you are interested in modifying it supports callback for node rendering and event handler. Finally the library is as of 2016 under development and pull requests are welcomed.

DISCLAIMER: I'm the author of dTree. I created the library after searching the web just like you did and not finding anything to my liking.

Erik
  • 171
  • 1
  • 3
8

The not-as-good news: The research I have done shows that there is no out-of-the-box d3 library that directly accomplishes this without some customization.

The good news: There have been some other people who have looked into this and have found some great starting points! I realize that this is not a complete solution to the entire task at hand, but it seems from your question that a large portion of your difficulty so far has been simply figuring out where to start (e.g. "Tutorials about d3.js only cover standard charts like bar charts."). In the absence of anything better, I will at least respond to that portion here.

First, in the response to this related stackoverflow post from a few years back, inanutshellus provides some great d3 tools that are available and could be of use here. With some light customization/extension, they should be able to get you where you're going relatively quickly. For posterity, inanutshellus's answer is reproduced here:

There are some options, but I believe each would require a bit of work. It would help if there were one single standard for representing a family tree in JSON. I've recently noticed that geni.com has a quite in-depth API for this. Perhaps coding against their API would be a good idea for reusability...

-- Pedigree tree --

The Pedigree Tree might be sufficient for your needs. You'd make in-law's linkable, where if you clicked on their name the graph would redraw so you could see their lineage.

-- Bracket Layout Tree --

Similar to the Pedigree Tree, but bidirectional, this Bracket Layout Tree lets you handle a "here are my parents, grandparents, children, grandchildren" type view. Like the Pedigree Tree, you'd make individuals linkable to re-center the bracket on that node.

-- Force-Based Layout --

There are some interesting force-based layouts that seem promising. Take a look at this example of a force-based layout with smart labels. An adjustment to the algorithm for how the "force" is determined could make this into a very lovely tree, with older generations above or below newer ones.

-- Cluster Dendogram (why it fails) --

The d3.js layouts I've seen that would lend themselves best to family trees assume a single node is the parent, whereas you need to represent the parent as the combination of (visually a "T" between) two nodes: one node that is a member of your tree, and one floating node that represents the in-law. Adjusting a cluster dendogram to do this should be feasible but not without significant modification.

If you--or anyone else for that matter--tackle this, let me know. I'd like to see (and benefit from) the work and may be able to contribute to it if feasible.

In terms of concrete implementation, mj8591 asked this question regarding a similar family tree with a different problem. However, luckily for you that question includes a fiddle (all the js code) that has most or all the components that you need, and the response from mdml includes another fiddle that adds some more granular "clickability" to each node.

Again, it's nothing automagic but hopefully these resources are enough to get you a great start!

Community
  • 1
  • 1
matt
  • 668
  • 6
  • 15
4

I tried dtree and liked it. However, when you add several generations, the horizontal display can make the overall display very large and unwieldy. Instead, I used the Reingold–Tilford Tree. One disadvantage of this tree is each node can have only one parent: spouses cannot be displayed alongside each other: To get past this limitation, I tweaked the JSON to combine spouses into one entity (ex: "husband - wife" ) just before sending it to the tree.

Community
  • 1
  • 1
Vivek Kodira
  • 2,261
  • 4
  • 26
  • 48
1

Answering 3 years after the question.

There is now a Pedigree Tree graph from Mike

enter image description here

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

Then there is this d3.tree - A Family Tree https://bl.ocks.org/mell0kat/5cb91a2048384560dfa8f041fd9a0295

You can also try the D3 Tidy Tree again from Mike https://beta.observablehq.com/@mbostock/d3-tidy-tree

kiranvj
  • 22,650
  • 5
  • 51
  • 69
  • The problem with your example is that each child only has 1 parent. That can easily be done with D3 (or google org chart even easier) but the issue is that it cannot show 2 parents. – Lau Frie Jul 13 '20 at 14:21
1

You can use dTree (Based on D3) to achieve your requirement.

enter image description here

Demo: https://treehouse.gartner.io/ErikGartner/58e58be650453b6d49d7

Reference Link: https://github.com/ErikGartner/dTree

Jerry Chong
  • 3,606
  • 1
  • 27
  • 29
0

I don't know if this is of any help to you, because you said that you were going to use d3.js but there is another tool that you might want to look into using called jsplumb. It seems perfect for this kind of project: home page. They also have some decent tutorials. There is one more like docs, and another more interactive.

Like I said, if it's not too late to switch technologies, this might be worth trying. It's all html, css, and javascript, so it shouldn't be a harsh transition.

Web_Designer
  • 64,966
  • 87
  • 197
  • 254
  • 2
    Suggesting a change in tools is not an answer – Dave Alperovich Jul 12 '15 at 18:14
  • 1
    Of course it can be of use to suggest another tool, if the solution might be much easier be solved using another tool. Strictly speaking the high voted answer "dTree" is another tool as well. Build upon d3, but still another tool... Also, the question is asked in a way, that d3 just "seems" to be the best tool for the job out of "research" – Adrian Jul 20 '19 at 11:47