Rendering a dynamically created family graph with no overlapping using a depth first search?

前端 未结 5 1821
深忆病人
深忆病人 2021-01-31 07:42

I want to generate this:

With this data structure (ids are random, btw not sequential):

var tree = [
    { \"id\": 1, \"name\": \"Me\", \"dob\":         


        
5条回答
  •  无人及你
    2021-01-31 08:14

    As you show it, your tree data will not allow you to draw the diagram. You are in fact missing some information there:

    • tree should really be an object (dictionary) mapping the id to the person's data. Otherwise, it is costly to go from the id, as given in children for instance, back to the child's data.
    • there is duplicate information since children are associated with both parent. This actually lead to incorrect data in the example you sent ('daugher1' is a child of 'wife', but a parent of 'me', and 'mary' is presumably mother of 'jeff'; jessie is a partner of robert; so are raymond and betty)

    In my attempt (https://jsfiddle.net/61q2ym7q/), I am therefore converting your tree to a graph, and then doing various stages of computation to achieve a layout.

    This is inspired by the Sugiyama algorithm, but simplified, since that algorithm is very tricky to implement. Still, the various stages are:

    • organize nodes into layers, using depth-first search. We do this in two steps by making sure that parents are always on a layer above their parent, and then trying to shorten the links when there is more than one layer between child and parent. This is the part where I am not using the exact Sugiyama algorithm, which uses a complex notion of cut points.

    • then sort the nodes into each layer to minimize crossing of edges. I use the barycenter method for this

    • finally, while preserving the order above, assign a specific x coordinate for each node, again using the barycenter method

    There are lots of things that can be improved in this code (efficiency, by merging some of the loops for instance) and also in the final layout. But I tried to keep it simpler to make it easier to follow...

提交回复
热议问题