elkjs icon indicating copy to clipboard operation
elkjs copied to clipboard

Widths and heights getting reversed

Open chanpod opened this issue 1 year ago • 8 comments

Describe the bug I'm trying to generate an electrical SLD using the lib. So far it works great for most things but for some reason, with a particular setup, it's taking my widths and making it the height and then the width becomes some random value (I can't decipher how it's getting anyways). In the screen shot below, the top bit of JSON is the pre elk.layout call and the second bit is after it's put through the engine.

Expected behavior When I set widths and heights for nodes and children, it should be respected.

Screenshots image

ELK Version "elkjs": "^0.9.3",

Additional context

Structure pre engine. All ids are in our dev db so they aren't particularly sensitive. So I didn't obfuscate them here. This is the raw json dump.

It's important that the widths I set are respected. So it might just be a config issue? But seems like this is a bug so apologies if this is just a bad config.

I have attempted to just reverse the MINIMUM layout option for this scenario but it isn't consistent so that doesn't work :( And I shouldn't have to do that anyways haha. It threw me off for a while b/c I thought I kept getting the minimum wrong and it was (height, width) not (width, height).

{
    "id": "root",
    "layoutOptions": {
        "elk.algorithm": "layered",
        "elk.layered.spacing.edgeNodeBetweenLayers": "200",
        "elk.spacing.nodeNode": "100",
        "elk.edgeRouting": "ORTHOGONAL",
        "elk.direction": "DOWN",
        "elk.layered.nodePlacement.strategy": "BRANDES_KOEPF",
        "elk.layered.nodePlacement.favorStraightEdges": "true",
        "elk.spacing.edgeEdge": "50",
        "elk.edge.thickness": "30",
        "elk.hierarchyHandling": "INCLUDE_CHILDREN",
        "elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES"
    },
    "children": [
        {
            "id": "8849abdb-3a54-47e4-9110-4c36df7068e6",
            "width": 3005,
            "height": 400,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "V_TOP",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(3005, 400)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "SWITCHBOARD \"NOPOWER\"\n",
                    "width": 1335,
                    "height": 50
                }
            ],
            "children": [
                {
                    "id": "bc0d45f7-170b-4d03-908a-40764da00bda",
                    "width": 2805,
                    "height": 400,
                    "layoutOptions": {
                        "elk.nodeSize.constraints": "MINIMUM_SIZE",
                        "elk.nodeSize.minimum": "(2805, 400)",
                        "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                    },
                    "ports": [
                        {
                            "id": "a6ec6d93-7ce6-4e1a-8149-23e8f1ff77ec",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "24c5a2ea-c10d-498d-a78d-8f302a5f860f",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "f60f8303-6f2d-4b3d-b424-46074f1a66a6",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "6b69ad9c-4562-4c3a-a0ff-32d5a4d5b8e0",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        }
                    ],
                    "children": [
                        {
                            "id": "85a07b42-1a6e-4adf-a4d5-d2151671653d_0",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "85a07b42-1a6e-4adf-a4d5-d2151671653d_0_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        },
                        {
                            "id": "43979631-9369-4940-81c5-ee6ce9f2191b_0",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "43979631-9369-4940-81c5-ee6ce9f2191b_0_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        },
                        {
                            "id": "254db103-cb35-416c-9ecc-16082010d879_1",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "254db103-cb35-416c-9ecc-16082010d879_1_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        },
                        {
                            "id": "2f78ffc7-8e50-411d-8f0c-498b4ada0052_2",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "2f78ffc7-8e50-411d-8f0c-498b4ada0052_2_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        },
                        {
                            "id": "01000da7-5cd5-42b2-9c26-bc0ba982a2dc_0",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "01000da7-5cd5-42b2-9c26-bc0ba982a2dc_0_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "id": "aa9824c8-f40b-4a74-beba-c15c0aec895a",
            "width": 200,
            "height": 200,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "OUTSIDE",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(200, 200)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "\n",
                    "width": 0,
                    "height": 50
                }
            ]
        },
        {
            "id": "2eb79d27-b4ec-493c-848e-c9161f5ffd44",
            "width": 2020,
            "height": 400,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "V_TOP",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(2020, 400)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "SWITCHBOARD\n",
                    "width": 735,
                    "height": 50
                }
            ],
            "children": [
                {
                    "id": "e8480979-9440-4629-897f-6c90d02c5b06",
                    "width": 1820,
                    "height": 400,
                    "layoutOptions": {
                        "elk.nodeSize.constraints": "MINIMUM_SIZE",
                        "elk.nodeSize.minimum": "(1820, 400)",
                        "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                    },
                    "ports": [
                        {
                            "id": "e7ed03f3-07e7-4c55-9264-67fcfb84725f",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "2b188793-8e3c-43f2-83da-cd8ac7db882e",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "63426fd4-eabe-40fe-a54e-daf62bd46c93",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        },
                        {
                            "id": "cee90eb3-9e6a-425f-9f27-c83d5f8bde9e",
                            "width": 200,
                            "height": 0,
                            "layoutOptions": {
                                "elk.port.side": "SOUTH"
                            }
                        }
                    ],
                    "children": [
                        {
                            "id": "a46262b1-b88f-4798-8017-c58ee4d566c1_0",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "a46262b1-b88f-4798-8017-c58ee4d566c1_0_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        },
                        {
                            "id": "90097cf1-4eac-4dfc-a992-95cdfca9ad8a_0",
                            "width": 200,
                            "height": 400,
                            "layoutOptions": {
                                "elk.spacing.nodeNode": "0",
                                "elk.spacing.edgeNode": "0",
                                "elk.layered.spacing.edgeNodeBetweenLayers": "0",
                                "elk.spacing.portPort": "10",
                                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                                "elk.nodeSize.minimum": "(200, 400)",
                                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
                            },
                            "ports": [
                                {
                                    "id": "90097cf1-4eac-4dfc-a992-95cdfca9ad8a_0_0",
                                    "width": 0,
                                    "height": 0,
                                    "layoutOptions": {
                                        "elk.port.side": "SOUTH"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "id": "7a3820fe-b1d2-43e0-ac8e-021e51088033",
            "width": 130,
            "height": 100,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "OUTSIDE",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(130, 100)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "\n",
                    "width": 0,
                    "height": 50
                }
            ]
        },
        {
            "id": "3ae90a18-22e0-40c9-83fc-980d6e0e877f",
            "width": 130,
            "height": 100,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "OUTSIDE",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(130, 100)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "\n",
                    "width": 0,
                    "height": 50
                }
            ]
        },
        {
            "id": "bc9e204b-03fd-417e-99a0-b41695caa3e7",
            "width": 100,
            "height": 100,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "OUTSIDE",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(100, 100)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "\n",
                    "width": 0,
                    "height": 50
                }
            ]
        },
        {
            "id": "798a2491-d571-4e68-abf2-ef53858f449f",
            "width": 100,
            "height": 100,
            "layoutOptions": {
                "elk.spacing.nodeNode": "0",
                "elk.nodeLabels.placement": "OUTSIDE",
                "elk.layered.crossingMinimization.forceNodeModelOrder": "true",
                "elk.nodeSize.constraints": "MINIMUM_SIZE",
                "elk.nodeSize.minimum": "(100, 100)",
                "elk.padding": "[left=0, top=0, right=0, bottom=0]"
            },
            "labels": [
                {
                    "text": "M2\n",
                    "width": 145,
                    "height": 50
                }
            ]
        }
    ],
    "edges": [
        {
            "id": "2b1180b1-6a9c-469c-88f5-ac5a6a1a1798",
            "sources": [
                "85a07b42-1a6e-4adf-a4d5-d2151671653d_0_0"
            ],
            "targets": [
                "aa9824c8-f40b-4a74-beba-c15c0aec895a"
            ],
            "labels": [
                {
                    "text": "",
                    "width": 50,
                    "height": 0
                }
            ],
            "layoutOptions": {}
        },
        {
            "id": "51470108-c322-479b-9906-4916882034e6",
            "sources": [
                "a46262b1-b88f-4798-8017-c58ee4d566c1_0_0"
            ],
            "targets": [
                "7a3820fe-b1d2-43e0-ac8e-021e51088033"
            ],
            "labels": [
                {
                    "text": "",
                    "width": 50,
                    "height": 0
                }
            ],
            "layoutOptions": {}
        },
        {
            "id": "9bc754ea-81fc-4162-b422-d4f0a2c1bd17",
            "sources": [
                "90097cf1-4eac-4dfc-a992-95cdfca9ad8a_0_0"
            ],
            "targets": [
                "3ae90a18-22e0-40c9-83fc-980d6e0e877f"
            ],
            "labels": [
                {
                    "text": "",
                    "width": 50,
                    "height": 0
                }
            ],
            "layoutOptions": {}
        },
        {
            "id": "20ab19f8-e89c-4f49-9417-0654bfd50172",
            "sources": [
                "43979631-9369-4940-81c5-ee6ce9f2191b_0_0"
            ],
            "targets": [
                "bc9e204b-03fd-417e-99a0-b41695caa3e7"
            ],
            "labels": [
                {
                    "text": "3#8 AWG—1\" EMT—20'",
                    "width": 50,
                    "height": 720
                }
            ],
            "layoutOptions": {}
        },
        {
            "id": "37488e27-ba8a-4ee8-bd64-7e8e8482f29a",
            "sources": [
                "01000da7-5cd5-42b2-9c26-bc0ba982a2dc_0_0"
            ],
            "targets": [
                "798a2491-d571-4e68-abf2-ef53858f449f"
            ],
            "labels": [
                {
                    "text": "1#8 AWG—1\" EMT",
                    "width": 50,
                    "height": 560
                }
            ],
            "layoutOptions": {}
        }
    ]
}

chanpod avatar Dec 12 '24 13:12 chanpod

This looks like a duplicate of https://github.com/eclipse/elk/issues/1033 HierarchyHandling: includeChildren is sadly quite unstable

Eddykasp avatar Dec 12 '24 13:12 Eddykasp

This looks like a duplicate of eclipse/elk#1033 HierarchyHandling: includeChildren is sadly quite unstable

ah crap. Ok, that seems to have made it stop but now nothing is working :( Gonna have to figure out why nothing is routing to each other correctly now. And yeah, seems this is a duplicate. My bad!

chanpod avatar Dec 12 '24 14:12 chanpod

@Eddykasp Any reason why edges wouldn't generate sections since I removed that option? Seems it just straight up stopped working entirely :scream:

chanpod avatar Dec 12 '24 14:12 chanpod

The problem is that edges that cross hierarchies can only be routed correctly using the hierarchyHandling option. For hiearchy crossing edges without that option you need to split those edges up and connect them via ports at the edge boundaries.

Here is a minimal example.

Eddykasp avatar Dec 12 '24 15:12 Eddykasp

and by "crossing hierarchies" you mean having an edge point at the child of another node?

And to fix, I'd need to create an external port that other nodes point to, and then "internally" have the external port point at the "correct" port. I'm guessing by nature of how the layout algorithm works, given the internal ports are in a fixed position, it should rearrange the external ports (given they will have no width/height on them) to the apporpiate location?

image

chanpod avatar Dec 12 '24 16:12 chanpod

Yes exactly, the layout is performed recursively from the bottom up, so internal port positions would be determined first and then the outer layout needs to deal with whatever positions they have. This isn't as powerful as the includeHierarchy option as that would be able to perform crossing minimisation over multiple hierarchies but for many cases it can still work well. Hope this helps and if you need further advice, feel free to ask :)

Eddykasp avatar Dec 12 '24 17:12 Eddykasp

Awesome. Thanks for your prompt replies! I've been having one other big issue that hopefully I can resolve (or can find an existing ticket) on my own.

Should I keep this issue open or close it since it's a duplicate of the other.

chanpod avatar Dec 13 '24 17:12 chanpod

For anyone who comes here later. This is super hacky and a workaround, but it did work for me. Basically most of my scenarios my edges didn't cross the "hierarchy boundaries", so all I had to do is when it did, just flip my width and height values for the "elk.nodeSize.constraints": "MINIMUM_SIZE", "elk.nodeSize.minimum": minimum,

And my stuff worked fine. B/c for your nodes that don't have edges that cross the boundaries, it still works fine. This means you can keep HierarchyHandling: includeChildren which works great when it works.

chanpod avatar Dec 15 '24 01:12 chanpod