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

Edge label positioning with multiple edges #195

Closed
ghost opened this issue Jan 13, 2016 · 10 comments
Closed

Edge label positioning with multiple edges #195

ghost opened this issue Jan 13, 2016 · 10 comments

Comments

@ghost
Copy link

ghost commented Jan 13, 2016

I've been working with Dagre for a while now and it really is an awesome library. Unfortunately one of our use cases is not displayed correctly. When creating a graph with multiple edges between the same two nodes the edge label positioning floats off:

transition_label_width

Each label should be attached to one of the four edges, but the distance only grows with each edge. I tried using various of the API options such as changing the label width and offset. But things did not get better:

transition_label_width2

Is there some way to fix this? A workaround is fine as well. If I somehow can get an approximately location of the edge I can change the label position. Any help would be appriciated!

@ghost
Copy link
Author

ghost commented Jan 14, 2016

The issue will be further discussed here:
dagrejs/dagre-d3#205

@ghost ghost closed this as completed Jan 14, 2016
@jonmcgill
Copy link

This is impossibly old. I know this. But I can't figure out how to configure dagre to recognize multiple edges between the two same nodes.

g.setEdge('n1', 'n2', { label: 'e1' });
g.setEdge('n1', 'n2', { label: 'e2' });

Always outputs just 1 edge with label e2

Can anyone point me in the right direction?

@GordonSmith
Copy link

@jonmcgill from memory I think you have to provide a unique ID for both edges...

@jonmcgill
Copy link

@GordonSmith Yeah, I tried that. It gets written over as well.

g.setEdge('n1', 'n2', { id: 'e1' });
g.setEdge('n1', 'n2', { id: 'e2' });

I still only get 1 edge with id e2

@GordonSmith
Copy link

Have you set multigraph: true?

@GordonSmith
Copy link

To add multiple edges between the same two nodes in dagre, you need to create a multigraph using the dagre.graphlib.Graph constructor. A multigraph is a type of graph that allows multiple edges between the same pair of nodes. To create a multigraph in dagre, you need to pass an options object to the constructor with the multigraph property set to true. For example:

var g = new dagre.graphlib.Graph({ multigraph: true });

Once you have created a multigraph, you can add multiple edges between the same pair of nodes using the addEdge method. This method works the same way as in a regular graph, but it allows you to add multiple edges between the same pair of nodes. For example:

var g = new dagre.graphlib.Graph({ multigraph: true });

// Add some nodes to the graph
g.setNode("A", { label: "Node A" });
g.setNode("B", { label: "Node B" });

// Add two edges from node A to node B
g.addEdge(null, "A", "B", { label: "Edge 1" });
g.addEdge(null, "A", "B", { label: "Edge 2" });

In this example, we create a new multigraph using the dagre.graphlib.Graph constructor and pass an options object with the multigraph property set to true. We then add two nodes to the graph using the setNode method, and add two edges from node A to node B using the addEdge method. Because we created a multigraph, we are able to add multiple edges between the same pair of nodes.

@jonmcgill
Copy link

I do have { multigraph: true} set but addEdge does not appear to be a method on the returned graph instance. setEdge is the only thing available. Is your example above an older version?

@jonmcgill
Copy link

Looks like #320 is duplicate of mine ☹️

@GordonSmith
Copy link

FWIW this is my boilerplate code (you are correct about the setEdge and addEdge):

    const digraph = new graphlib.Graph({ multigraph: true, compound: true, directed: options.digraph !== false })
        .setGraph(options)
        .setDefaultNodeLabel(function () { return {}; })
        .setDefaultEdgeLabel(function () { return {}; })
        ;
    subgraphs.forEach(sp => {
        digraph.setNode(sp.id, sp);
    });
    nodes.forEach(vp => {
        digraph.setNode(vp.id, vp);
    });
    links.forEach(ep => {
        digraph.setEdge(ep.source.id, ep.target.id, ep, ep.id);
    });
    hierarchy.forEach(h => {
        digraph.setParent(h.child, h.parent);
    });
    layout(digraph, { debugTiming: false } as GraphLabel);
    const deltaX = (-digraph.graph().width / 2) || 0;
    const deltaY = -digraph.graph().height / 2;
    digraph. Nodes().forEach(function (u) {
        const vp = digraph.node(u) as any;
        vp.x += deltaX;
        vp.y += deltaY;
    });
    digraph. Edges().forEach(function (e) {
        const ep = digraph.edge(e) as any;
        ep.points = ep.points.map(p => [p.x + deltaX, p.y + deltaY]);
    });

    return { subgraphs, nodes, links };

@jonmcgill
Copy link

There was a fourth argument to setEdge for a uid ...

That did the trick, many many thanks 🙏

This issue was closed.
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

2 participants