kieler / elkjs

ELK's layout algorithms for JavaScript
Other
1.81k stars 97 forks source link

Layout configurations not applying #283

Closed manansoni77 closed 5 months ago

manansoni77 commented 5 months ago

Hi, I am using the elkjs library for the first time to create a graph. I am using the layered algorithms and trying to apply some additional configurations to it, but the configurations are not working, i.e they are not having any effect on the graph.

const elkOptions = {
        // 'elk.algorithm': 'mrtree',
        'elk.layered.spacing.nodeNodeBetweenLayers': '100',
        'elk.spacing.nodeNode': '80',
        // new options
        'elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX',
        'elk.layered.crossingMinimization.semiInteractive': 'True',
        'elk.separateConnectedComponents': 'False',
        'elk.contentAlignment': 'V_TOP'
};
const graph = {
    id: 'root',
    layoutOptions: options,
    children: nodes.map((node) => ({
        ...node,
        // Adjust the target and source handle positions based on the layout
        // direction.
        targetPosition: isHorizontal ? Position.Left : Position.Top,
        sourcePosition: isHorizontal ? Position.Right : Position.Bottom,

        // Hardcode a width and height for elk to use when layouting.
        width: 150,
        height: 50
    })),
    edges: edges
};
elk.layout(graph)

Without new options image

With new options image

Both are exactly the same, which leads me to believe that layout options are not working.

Please help regarding how to apply configurations correctly.

soerendomroes commented 5 months ago

This may be a typo: you declare elkOptions but use options in your graph. I am not sure whether you should use true and false instead of True and False.

Have you tried creating a graph in elklive?

At least to my understanding, only elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX could actually affect your graph. semiInteractive needs positions of elements (which might not be there), you only have one connected component, and I am not sure whether contentAlignment would work as you want it on the root and whether you need an additional horizontal option for it to work.

soerendomroes commented 5 months ago

And for elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX' the drawings seem to be slightly different.

What exactly are you trying to achieve for your drawing?

manansoni77 commented 5 months ago

Hey @soerendomroes

The elkOptions typo is not the problem, it's just snippets of the whole code so it is like that. As for what I'm trying to achieve is something like this (below)

image

Also, i tried a few examples from elk demonstrators, and this was the one I was trying to reproduce when I ran into the issue of elkOptions not having any effect. It is not exactly like my goal, but atleast it had all the nodes and edges clearly seperated and not overlapping.

soerendomroes commented 5 months ago

Overlaps should not be created by ELK if you configure the node sizes as they actually are.

Maybe something similar to this might work for you. I used network simplex for node placement and straightness priority for edges that should be straight. Additionally you might want to use explizit ports with fixed positions.

What framework are you using? In the last year, we had similar overlap problems from people that used reactflow for their diagrams.

manansoni77 commented 5 months ago

I am using svelte-flow framework.

I'll try the demonstration you have suggested.

manansoni77 commented 5 months ago

Hey @soerendomroes , I tried applying the properties like those here

I tried various combinations and different ways to apply them as described below, but they made no difference.

Either of these changes are not having any affect on the output graph. image

soerendomroes commented 5 months ago

Well, the drawing looks different. Maybe I did not fully understand what you are interested in. How does your desired output look like?

The priority.straightness is applied like this to a json graph. More documentation can be found here. Since it applies to edges, you can set it on individual edges. If it applied to parents, you would add the property to the root node as it is the case for e.g. cycleBreaking.strategy.