dagrejs / dagre-d3

A D3-based renderer for Dagre
MIT License
2.85k stars 587 forks source link

Fix the positions of some nodes/edges during rendering #64

Open abegong opened 10 years ago

abegong commented 10 years ago

Is it possible to specify the position of some (but not all) nodes at fixed coordinates?

Ideally, I'm imagining this kind of input:

g = new dagreD3.Digraph()

g.addNode({label : 'node at the origin', x : 0, y : 0})
g.addNode({label : 'node at 100, 100', x : 100, y : 100})
g.addNode({label : 'put me wherever'})
g.addNode({label : 'me too'})

//add a bunch of edges
...

renderer.run(g, d3.select("#mycanvas svg g"));
dantomosoiu commented 10 years ago

Is there a plan for this ? I think it would be a useful addition and it might possibly help with https://github.com/cpettitt/dagre-d3/issues/31#issuecomment-46829207 as well.

I think the problem in general with re-rendering is that nodes' positions varies wildly, so in medium or large graphs it's hard to follow what happens. In some cases, even when adding/removing a single leaf node.

cpettitt commented 10 years ago

I can imagine how we could specify relative ordering between nodes so that they don't shift relative to each other. In fact, the layout code can already do this, but IIRC there is no user interface to specify this.

Pinning the coordinates for nodes is more complicated. The Sugiyama algorithm doesn't start setting coordinates until the last phase, after ranking and positioning has been done.

dantomosoiu commented 10 years ago

I think that even just fixing the relative ordering would definitely help, sure.

dantomosoiu commented 10 years ago

I can imagine how we could specify relative ordering between nodes so that they don't shift relative to each other. In fact, the layout code can already do this, but IIRC there is no user interface to specify this.

I'm thinking of editing the code to make this happen, but I'm not sure where to start. Could you please point me in the right direction ?

Thanks

cpettitt commented 10 years ago

Sure. In sweepDown and sweepUp of the order phase we set up an undefined constraint graph, called cg. Later we initialize it in sortLayer. You could instead initialize it before calling into sweepDown and sweepUp with constraints on the nodes of which you want to fix order. The constraint graph has nodes with the same ids as the layout graph and the edges specify a "right of" constraint. So, if I had 1 -> 2 -> 3 the constraints would put 3 to the right of 1 and 2, and 2 to the right of 1 thereby fixing the order.

gitsome commented 7 years ago

screen shot 2016-12-28 at 10 36 14 am I am also interested in the ability to ensure nodes (not edges) are always positioned relative of other nodes within each layer. In the screenshot above I would like all the longer orange paths to be next to each other but there is one orange path that is split off from the other two (note my orientation is left to right).

It seems the current version is a little different than what was mentioned above. I see "sweepLayerGraphs" in the order/index.js file and have made some attempts to sort by a custom property with no luck. Any other guidance you can give here in terms of where to make the change? Thanks!

gitsome commented 7 years ago

screen shot 2016-12-28 at 12 16 12 pm Okay, I got something that seems to be working. I need to get the tests running, then write some tests and then I'll put up a PR.

gitsome commented 7 years ago

I had to make changes to dagre not dagre d3. I noticed this isn't being maintained so I have made changes in a fork of dagre and then have a fork of dagre-d3 to pull in the forked npm dependency. https://github.com/gitsome/dagre-d3