BenPortner / js_family_tree

An interactive family tree visualization using d3-dag
GNU General Public License v3.0
70 stars 30 forks source link

Sort visible nodes at each hierarchy layer #4

Open djBirdman opened 2 years ago

djBirdman commented 2 years ago

The use of d3-dag, unions and collapsible node works really nicely.

I'm new to d3 / d3-dag, so am wondering how to ensure the following:

NB: first thing I did was change y_sep to -50 instead of 50, to get the children sorting eldest-to-youngest (reading top to bottom) instead of the other way around.

BenPortner commented 2 years ago

Hi @djBirdman,

thanks for using js_family_tree. The proposals you make to improve the ordering of the nodes seem promising. Unfortunately, I did not have time to play around with the settings yet to achieve this. In fact, I would be thankful for your help! Under the hood, js_family_tree uses d3-dag's sugiyama layout to position nodes. You can find it's documentation here. The behavior you are describing should be achievable by manipulating the decross and coord properties with appropriate operators. Unfortunately, I cannot help you beyond this point, because this is also how far my knowledge of d3-dag goes ;) Keep me updated if you make any progress here. Maybe we can crack this nut together.

Thanks. Ben

djBirdman commented 2 years ago

Looking at the sugiyama docs, my understanding is that you're already using the correct coord accessor, and while decross can change the order of the layer, it's doing so to decross the graph edges and not to specifically order each layer. I noticed that d3-hierarchy has nodes.sort() that might be the right thing, but d3-dag does not.

What I have done is to work out the order and manually update the x-position of the nodes. First I added unionyear in the union data; then within update() iterate over all visible nodes to work out a sort order based on both birthyear and unionyear and record the current node x-positions; I then re-order the x-positions using the calculated order. For partners that union into the family, I use their partner's sort order. For children I also take into account their parent's order, and by iterating top-down this sorting works for all descendants.

This works for my purpose, but realise it's a bit of a rough hack: I'm happy to share my additions if you're OK with the way I've done it. Will try and tidy it up a bit, comment etc. and also throw a bit more test data at it over the weekend.

BenPortner commented 2 years ago

Hi @djBirdman, Thank you for looking into this! I am glad to hear that you managed to achieve the desired behavior and would be very interested in seeing the associated code :) Is it on your GitHub fork? Thanks! Ben