dagrejs / dagre

Directed graph layout for JavaScript
MIT License
4.68k stars 601 forks source link

Unable to draw an edge from a child to parent compound graph #238

Open thenylify opened 6 years ago

thenylify commented 6 years ago

Hi all,

I am currently using Dagre for one of my data visualisation project, it is a compound graph which requires a node to contain a nested node, I'm unable to draw edges from child nodes to parent nodes, I get the following error:

Uncaught TypeError: Cannot set property ‘rank’ of undefined.

Please also see the below code:

g.setNode('a', {label: 'A'}); g.setNode('b', {label: 'B'}); g.setNode('c', {label: 'C'}); g.setNode('d', {label: 'D'});

g.setNode('top_group', {label: 'Top Group', clusterLabelPos: 'bottom', style: 'fill: #ffd47f'}); g.setNode('bottom_group', {label: 'Group', clusterLabelPos: 'top', style: 'fill: #d3d7e8'});

// Set the parents to define which nodes belong to which cluster g.setParent('a', 'top_group'); g.setParent('b', 'bottom_group'); g.setParent('c', 'bottom_group'); g.setParent('d', 'bottom_group');

// Draw edges g.setEdge('a', 'b'); g.setEdge('b', 'c'); g.setEdge('b', 'd');

// Set edge from child to parent g.setEdge('a', 'bottom_group'); // THIS LINE CAUSES THE ABOVE ERROR

The way how we create a parent is the same as how we create a child node, so the library should allow us to draw an edge from a child node to a parent node.

Can someone please advice?

This is really urgent so can someone please help.

Much appreciated, Thanks, Michael

GordonSmith commented 6 years ago

Just curios why your trying to set and edge usingsetParentand not setEdge?

// Set edge from child to parent
g.setEdge('a', 'bottom_group'); // THIS LINE CAUSES THE ABOVE ERROR

(not saying it will work, just asking?)

thenylify commented 6 years ago

@GordonSmith thanks for the reply. It was a typo in my question, it’s setEdge, and it’s still having the same error.

koosvanderkolk commented 6 years ago

Could you please provide a jsfiddle (or equivalent?)

thenylify commented 6 years ago

@koosvanderkolk Hay, thank you so much for the reply! I have created a JSFiddle for this, but you can refer to this demo repo - https://github.com/dagrejs/dagre-d3/blob/master/demo/clusters.html, you can simply pull this down and run the "Cluster" demo, please add a line "g.setEdge('b', 'bottom_group'); // Try to draw an edge from child "b" to parent "bottom_group"." to line 78 in the clusters.html, after you done this you should see the error "Unable to draw an edge from a child to parent".

In the meantime, I will create a JSFiddle to make this easier to debug for other helpers.

Thanks so much man, appreciate this!

koosvanderkolk commented 6 years ago

If the error indeed reads "Unable to draw an edge from a child to parent" then I am afraid this isn't just possible with this library.

But maybe with your jsfiddle people can come up with a nice workaround :-).

thenylify commented 6 years ago

@koosvanderkolk Okay, no problem. Thanks anyway. Here is the JSFiddle if you're interested: http://jsfiddle.net/thenylify/Lbjm54ob/8/

Thank you.

alimahmoodyar commented 5 years ago

No solutions?

gordonwoodhull commented 5 years ago

I don't think this is supported by this library. You could use graphviz via Viz.js

ChanDaoH commented 4 years ago

Any workaround ?

yangxiaoqiao2016 commented 4 years ago

Any workaround ?

rewweRrr commented 4 years ago

Fix here: https://github.com/dagrejs/dagre/pull/293 Workaround: https://www.npmjs.com/package/dagre-cluster-fix Workaround for cytoscape-dagre : https://www.npmjs.com/package/cytoscape-dagre-cluster-fix

LeonsCd commented 2 years ago
if (isNode(element)) {
      const { data,id } = element
      if(id!=="0"){
        const {parentId} = data
        if(parentId===0||parentId){
          g.setParent(id, parentId+"");
        }
      }
      g.setNode(element.id, {
        width: element.__rf?.width,
        height: element.__rf?.height,
      });
    } else {
      g.setEdge(element.source, element.target);
    }

I used setEdge before but i got the graph drawn by the nodes of the second level is evenly spaced, so I think they are caused by no parent-child relationship So you see that code i added the setParent I hope they can divide the space equally in their own area but i failed Uncaught TypeError: Cannot set properties of undefined (setting 'rank') i don't know what to use