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

Node wrapping at certain indexes #242

Open
nlafleur opened this issue Sep 28, 2023 · 6 comments
Open

Node wrapping at certain indexes #242

nlafleur opened this issue Sep 28, 2023 · 6 comments
Labels

Comments

@nlafleur
Copy link

I am looking for a method to force "newlines" at certain nodes.
I want to create some kind of "step" method when clicking the nodes.
The steps are indicated at the top-left of the nodes.

Here is an example of my ideal outcome:
image

The only problem is that the nodes will be placed next to eachother whenever there is enough space for it.
This is my outcome right now:
image
I am trying to make a dynamic component, this happends when I select some big data:
image
I want to create a kind of "flex-direction" "column" type, so that the steps would be rendered below eachother.

I tried several methods, this is my current config:

const elkOptions = {
  "algorithm": "layered",
  "org.eclipse.elk.spacing.componentComponent": 100,
  "org.eclipse.layered.spacing.nodeNodeBetweenLayers": 40,
  "org.eclipse.elk.layered.considerModelOrder.components": "INSIDE_PORT_SIDE_GROUPS",
  
  "org.eclipse.elk.layered.wrapping.cutting.strategy": "MANUAL",
  // "org.eclipse.elk.layered.wrapping.cutting.cuts": [3, 4] < this doesn't work
}

Preferably I would even create groups and give the nodes the "parentNode" property, so that it the steps are more clear, but I cant seem to determine the width and height of this group dynamically.

Any other out of the box ideas are welcome.

ELK Version
0.8.2

@soerendomroes
Copy link
Member

Regarding the wrapping cutting strategy:

The cutting strategy works only for connected components, moreover, the manual mode is broken in 0.8.2 and a list of cuts required for the manual mode can only be added programmatically.

Regarding placement:

I suggest putting each of our groups in its own node.
This way you can just manually place the boxes under each other.
The box or rectangle packing algorithms "box" and "rectpacking" will however, similar to the separate connected component packing algorithm that you are currently using be selecting the layered algorithm, always use available width to pack other components in there.

You can however circumvent that by increasing the width of the dummy parent nodes such that two of them cannot fit in the same row and by setting the desired aspect ratio of the packing or for rectpacking the target width for the row accordingly.
Content alignment ensures that the inner graph is aligned according to your preferences.
With elkjs 0.9.0 you could also use the "in new row" constraint for rectpacking.

Another option would be to just place them yourself and use the fixed layout algorithm.

@nlafleur
Copy link
Author

Hi, thanks for your reply.

I tried using the "box" and "rectpacking" algorithms but these won't result in the way I want to (I am really looking for the tree-kind algorithms)
So I tried grouping the nodes by the following:

  1. creating group nodes like this:
{
  id: `group_${newStep}`,
  data: { label: `Step ${newStep}` },
  style: { backgroundColor: "rgba(255,255,255,0)" },
  type: "group"
}
  1. And setting the following properties for the nodes (excluding the group nodes):
{
  ...
  parentNode: `group_${stepId}`,
  expandParent: true
}

And this is how I create my elk js graph:

const graph = {
    id: "root",
    layoutOptions: options,
    children: nodes.map((node) => {
      return ({
        ...node,
        targetPosition: isHorizontal ? "left" : "top",
        sourcePosition: isHorizontal ? "right" : "bottom",
        animated: animated,
        width: DEFAULT_WIDTH,
        height: DEFAULT_HEIGHT
      })
    }),
    edges: edges.map((edge) => ({
      ...edge,
      animated: animated
    }))
  }

  return elk
    .layout(graph)
    .then((layoutedGraph) => ({
      nodes: layoutedGraph.children.map((node) => {
        return ({
          ...node,
          position: { x: node.x, y: node.y }
        })
      }),
      edges: layoutedGraph.edges
    }))
    .catch(console.error)

Steps:

  • Step1; looks fine, some padding problems but overall good:
    image

  • Step2; the second group starts at the same height as the first group for some reason, placement overal is fine if the group would start below the first group
    image

  • Step3; The third group also starts at the same x and y as the first and second group.
    image

!help!

@nlafleur nlafleur reopened this Sep 28, 2023
@soerendomroes
Copy link
Member

Can you please build your example graph in elklive or elklive json to be sure we are talking about the same issues?

As far as I understand it, you want something like this.

@nlafleur
Copy link
Author

Hi that is indeed almost what I am looking for!
Here is my "graph" output in the "elklive json" you linked above:
elklive json

Is there a way to convert your "this" example into a json example? I guess my grouping is all wrong

Thanks

@soerendomroes
Copy link
Member

You can use the converter. Note however that you need to use elkg as an intermediate representation in some cases.

@nlafleur
Copy link
Author

Maybe I should've mentioned that I am using the "ReactFlow" package to visualize the elkjs graph.

So maybe it is not a elkjs problem but a ReactFlow problem.
This is the "layoutedGraph" returned by the "elk.layout(graph)":

{
    "id": "root",
    "layoutOptions": {
        "elk.direction": "DOWN",
        "elk.animate": false,
        "aspectRatio": "0.1",
        "algorithm": "rectpacking"
    },
    "children": [
        {
            "id": "group1",
            "children": [
                {
                    "id": "n1",
                    "width": 30,
                    "height": 30,
                    "$H": 279,
                    "x": 22,
                    "y": 12
                },
                {
                    "id": "n2",
                    "width": 30,
                    "height": 30,
                    "$H": 281,
                    "x": 162,
                    "y": 92
                },
                {
                    "id": "n3",
                    "width": 30,
                    "height": 30,
                    "$H": 283,
                    "x": 212,
                    "y": 92
                },
                {
                    "id": "n4",
                    "width": 30,
                    "height": 30,
                    "$H": 285,
                    "x": 12,
                    "y": 92
                },
                {
                    "id": "n5",
                    "width": 30,
                    "height": 30,
                    "$H": 287,
                    "x": 62,
                    "y": 92
                },
                {
                    "id": "n6",
                    "width": 30,
                    "height": 30,
                    "$H": 289,
                    "x": 112,
                    "y": 92
                }
            ],
            "layoutOptions": {
                "nodeSize.constraints": "[MINIMUM_SIZE]",
                "elk.direction": "DOWN",
                "contentAlignment": "[V_TOP, H_LEFT]",
                "nodeSize.minimum": "(300.0,20.0)",
                "algorithm": "layered"
            },
            "edges": [
                {
                    "id": "e0",
                    "sources": [
                        "n1"
                    ],
                    "targets": [
                        "n2"
                    ],
                    "sections": [
                        {
                            "id": "e0_s0",
                            "startPoint": {
                                "x": 42,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 177,
                                "y": 92
                            },
                            "bendPoints": [
                                {
                                    "x": 42,
                                    "y": 62
                                },
                                {
                                    "x": 177,
                                    "y": 62
                                }
                            ],
                            "incomingShape": "n1",
                            "outgoingShape": "n2"
                        }
                    ],
                    "container": "group1"
                },
                {
                    "id": "e1",
                    "sources": [
                        "n1"
                    ],
                    "targets": [
                        "n3"
                    ],
                    "sections": [
                        {
                            "id": "e1_s0",
                            "startPoint": {
                                "x": 47,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 227,
                                "y": 92
                            },
                            "bendPoints": [
                                {
                                    "x": 47,
                                    "y": 52
                                },
                                {
                                    "x": 227,
                                    "y": 52
                                }
                            ],
                            "incomingShape": "n1",
                            "outgoingShape": "n3"
                        }
                    ],
                    "container": "group1"
                },
                {
                    "id": "e2",
                    "sources": [
                        "n1"
                    ],
                    "targets": [
                        "n4"
                    ],
                    "sections": [
                        {
                            "id": "e2_s0",
                            "startPoint": {
                                "x": 27,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 27,
                                "y": 92
                            },
                            "incomingShape": "n1",
                            "outgoingShape": "n4"
                        }
                    ],
                    "container": "group1"
                },
                {
                    "id": "e3",
                    "sources": [
                        "n1"
                    ],
                    "targets": [
                        "n5"
                    ],
                    "sections": [
                        {
                            "id": "e3_s0",
                            "startPoint": {
                                "x": 32,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 77,
                                "y": 92
                            },
                            "bendPoints": [
                                {
                                    "x": 32,
                                    "y": 82
                                },
                                {
                                    "x": 77,
                                    "y": 82
                                }
                            ],
                            "incomingShape": "n1",
                            "outgoingShape": "n5"
                        }
                    ],
                    "container": "group1"
                },
                {
                    "id": "e4",
                    "sources": [
                        "n1"
                    ],
                    "targets": [
                        "n6"
                    ],
                    "sections": [
                        {
                            "id": "e4_s0",
                            "startPoint": {
                                "x": 37,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 127,
                                "y": 92
                            },
                            "bendPoints": [
                                {
                                    "x": 37,
                                    "y": 72
                                },
                                {
                                    "x": 127,
                                    "y": 72
                                }
                            ],
                            "incomingShape": "n1",
                            "outgoingShape": "n6"
                        }
                    ],
                    "container": "group1"
                }
            ],
            "targetPosition": "top",
            "sourcePosition": "bottom",
            "animated": false,
            "$H": 277,
            "x": 15,
            "y": 15,
            "width": 300,
            "height": 134
        },
        {
            "id": "group2",
            "children": [
                {
                    "id": "n1_g512902",
                    "width": 30,
                    "height": 30,
                    "$H": 293,
                    "x": 12,
                    "y": 12
                },
                {
                    "id": "n2_g916742",
                    "width": 30,
                    "height": 30,
                    "$H": 295,
                    "x": 12,
                    "y": 62
                }
            ],
            "layoutOptions": {
                "nodeSize.constraints": "[MINIMUM_SIZE]",
                "elk.direction": "DOWN",
                "contentAlignment": "[V_TOP, H_LEFT]",
                "nodeSize.minimum": "(300.0,20.0)",
                "algorithm": "layered"
            },
            "edges": [
                {
                    "id": "e5",
                    "sources": [
                        "n1_g512902"
                    ],
                    "targets": [
                        "n2_g916742"
                    ],
                    "sections": [
                        {
                            "id": "e5_s0",
                            "startPoint": {
                                "x": 27,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 27,
                                "y": 62
                            },
                            "incomingShape": "n1_g512902",
                            "outgoingShape": "n2_g916742"
                        }
                    ],
                    "container": "group2"
                }
            ],
            "targetPosition": "top",
            "sourcePosition": "bottom",
            "animated": false,
            "$H": 291,
            "x": 15,
            "y": 164,
            "width": 300,
            "height": 104
        },
        {
            "id": "group3",
            "children": [
                {
                    "id": "n1_g992924",
                    "width": 30,
                    "height": 30,
                    "$H": 299,
                    "x": 12,
                    "y": 12
                },
                {
                    "id": "n2_g682435",
                    "width": 30,
                    "height": 30,
                    "$H": 301,
                    "x": 12,
                    "y": 62
                }
            ],
            "layoutOptions": {
                "nodeSize.constraints": "[MINIMUM_SIZE]",
                "elk.direction": "DOWN",
                "contentAlignment": "[V_TOP, H_LEFT]",
                "algorithm": "layered"
            },
            "edges": [
                {
                    "id": "e6",
                    "sources": [
                        "n1_g992924"
                    ],
                    "targets": [
                        "n2_g682435"
                    ],
                    "sections": [
                        {
                            "id": "e6_s0",
                            "startPoint": {
                                "x": 27,
                                "y": 42
                            },
                            "endPoint": {
                                "x": 27,
                                "y": 62
                            },
                            "incomingShape": "n1_g992924",
                            "outgoingShape": "n2_g682435"
                        }
                    ],
                    "container": "group3"
                }
            ],
            "targetPosition": "top",
            "sourcePosition": "bottom",
            "animated": false,
            "$H": 297,
            "x": 15,
            "y": 283,
            "width": 54,
            "height": 104
        }
    ],
    "edges": [],
    "$H": 13,
    "x": 0,
    "y": 0,
    "width": 330,
    "height": 402
}

But this is how my nodes are rendered: (only groups (first objects in children array) are rendered)
image

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

No branches or pull requests

2 participants