Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different layout for children count greater than X #35

Open
alex-laycalvert opened this issue Mar 28, 2023 · 1 comment
Open

Different layout for children count greater than X #35

alex-laycalvert opened this issue Mar 28, 2023 · 1 comment

Comments

@alex-laycalvert
Copy link

Not sure if anyone is actively managing this but is there any known reference for having the layout change for any nodes that have a certain number of children?

I have all my nodes in a tree structure but for visual purposes, I want to have children nodes be displayed in columns of two as opposed to one long row. Not sure if anyone using this library has had similar interests/issues like this.

@alex-laycalvert
Copy link
Author

If anyone finds this later, I was able to achieve this layout by creating a modified array of my original nodes (my data is an array of nodes with a parentId) where anytime a parent had more than X children (2 in my case), each child would have their parentId changed to be the node that would be physically above them in the layout.

So if my data after the layout normally looks like this:

                p 
                |
  -------------------------
 |    |    |    |    |    |
c1  c2  c3  c4  c5  c6

And I want it to look like this:

      p
      |
c1 --- c2
      |
c3 --- c4
      |
c5 --- c6

I modify children c3-c6 to have a different parentId:

      p
      |
c1 --- c2
 |       |
c3     c4
 |       |
c5     c6

c1 and c2 are unaffected but I change c3 to have a parentId of c1, c4 changes to c2 and so on.

Then I just adjust some other values that are used by the lib I'm using to actually display these nodes so that the lines look how they do in the second ASCII masterpiece (how I want the data to look like).

So now my setup looks like:

const root = originalNodes[0] // or however you need to find the `root`
const modifiedNodes = structuredClone(originalNodes) // This was the easiest way to avoid modifying the original array even if probably slow
populateChildren(modifiedNodes)
const layout = flextree({ /* ... */ })
const tree = layout.hierarchy(root)
layout(tree)

// ...

The populateChildren function (this modified the given array):

export function populateChildren<T>(
    node: T,
    nodes: T[],
) {
    const children = nodes
            .filter((c) => c.parentId === node.id)
    const childIds = children.map((c) => c.id)

    // Arranges children into columns of two by assinging
    // a temporary `parentId`
    if (
        children.length > 2 && // or change `2` to whatever number you want
        !nodes.find((n) => childIds.includes(n.parentId))
    ) {
        children.forEach((c, i, arr) => {
            // `edgePosition` is used for actually displaying the nodes, not necessary to just arrange them in an array
            if (i % 2 === 0) {
                c.edgePosition = 'right'
            } else {
                c.edgePosition = 'left'
            }
            if (i <= 1) {
                return
            }
            c.parentId = arr[i - 2].id
        })
        children.splice(2, children.length - 2)
    }
    children.forEach((c) => populateChildren(c, nodes))
    node.children = children
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant