dagre
dagre copied to clipboard
Maintain the structure when dynamically add nodes
Hey there, I'm working on a project where I will append nodes dynamically when I click on the existing nodes. But it comes out that Dagre will do some "optimizations" for me, liking switching the position of the existing nodes.
I found a similar stack overflow questions here, but it was to old, and the dagre.layout().orderIters(-1)
method does not work. Is there some ways to work around this? I really like Dagre and don't want to switch to other libraries.
In general this is a hard problem because you (probably) do want some optimization, but you want stability more. The two goals conflict.
There are also some changes that must change the positions of existing nodes, for example if an edge insertion causes a new rank to be added between existing nodes.
So is this possible? Are there any other libraries that provide "stable" algorithms?
Thanks.
Found a solution. You have to replace these lines: https://github.com/cpettitt/dagre/blob/master/lib/order/index.js#L40-L50 with best = _.cloneDeep(util.buildLayerMatrix(g));
Looks like that basically disables crossing minimization, correct?
I wonder if it would make sense to add an option to dagre.layout()
to disable this step. So that you could e.g. do full layout with crossing minimization on the initial graph, then more stable layouts for incremental changes.
(That is, if someone takes up maintainership of this library.)
It seems that it does. I've got an idea from a comment in this fiddle: http://jsfiddle.net/gke2dann/1/ , mentioned in the Stackoverflow question from the first message in this thread.
I've tried to add an option, but g
object is some internal representation of a graph (I think from graphlib package) and does not carry options like ranksep
and others. So I didn't find an easy way to pass an option to that function.
Seemes like at some point it was possible to configure this, but later this was removed. Didn't find anything in the commits history, though.
I was looking at the options which are passed to dagre.layout()
in the second parameter. However, I haven't looked very closely and I don't know if this would work.
It's probably not worth worrying about until we find a new maintainer. AFAIK dagre is unique and it's not likely someone else will implement a similar library in JavaScript.
(I built a similar library in C++ a while back, and I rely on dagre for some of my projects, so I guess I'd be a natural fit. However, the list of open issues is intimidating and I'm not sure I want to take this on.)
@graymur if you replace those lines then is the idea that you can call layout(), then addNode(), then layout() on the same dagre graph and get some level of stability when adding nodes?