microsoft / automatic-graph-layout

A set of tools for graph layout and viewing
Other
1.36k stars 304 forks source link

Edge routing collapse on node move #144

Closed lafrank closed 6 years ago

lafrank commented 6 years ago

When two nodes have multiple edges in between them, they are drawn as separate lines when performing a layout calculation. That is perfect so far. However, when I move a node away, these edges collapse visually into a single line in between the two nodes. How can I prevent this to happen, or how can I trigger rerouting of edges - without recalculating layout -the same way it happens with layout calculation.

levnach commented 6 years ago

Try holding a Shift key when you drag a node.

lafrank commented 6 years ago

Wow, that's it ! Cool, thank you.

lafrank commented 6 years ago

Just one more question. How can I achieve rerouting to happen from code ?

lafrank commented 6 years ago

Reopening this case as I can't find the way to achieve this functionality from code. So my question is : how is it possible to trigger re-routing only when a node drag ended, like if the node was ragged while holding the shift key ?

levnach commented 6 years ago

Please have a look at function GeometryGraphEditor. RunSplineRouterAndPutLabels(). It does the job of rerouting the edges.

lafrank commented 6 years ago

Thank you, that helps.

However, it is not easy - if not impossible - to get this done from user code without modifying MSAGL, library which is not very nice. Most of the required members are not public.

To start with, I can't even catch the OnDragEnd event as it is consumed by GraphViewerGDI without publishing it. So first I need to make this event available for subscription by consumers.

It is also unclear for me, why the GraphViewGDI class is not explicitly implementing the IViewer interface, but rather casts itself as IView in certain calls :

image

image

I highly appreciate your help and admire the mathematics behind - read some of your publications in this topic - but the code itself is very confusing and hard to follow.

levnach commented 6 years ago

I am afraid you need to modify the code of MSAGL to reach this effect. From my experience, the viewers that edit entities are extremely complex and confusing.

lafrank commented 6 years ago

Thanks Lev, I will manage it this way coping with complexity...

One more question, if you still had some patience... Is there a way to influence the placement distance of a node from another node, or at least modify the node size ? The below illustrates a part of the graph my application currently produces: image The bigger picture is: image

As you can see,, some anomalies stem fromt the fact that the gray - label only - nodes were placed too far from its neighbor node by MDS algorithm with current settings.

What I would like to achive instead is something like below:

image

How is it possible ?

Many thanks in advance.

levnach commented 6 years ago

The simplest way is to change the font size of the "center nodes", something like that
graph.FindNode("47").Label.FontSize *= 3; If it does not look good you can get control over the node size and rendering as in NodesWithImages sample.

lafrank commented 6 years ago

Thank you, but no success with changing text sizes unfortunately. Although I don't understand MDS in depth, the layout generated doesn't make sense in my view :

image

Why things like this happen ? image

levnach commented 6 years ago

MDS attempts to position the nodes that have similar set of neighbors close by. The edge directions are ignored. If your graph represents some process and has directed edges then Sugiyama scheme is a better option. But the picture above does not look right, the labels on large nodes are too small. It could be a bug.

lafrank commented 6 years ago

What the graph represents is a computer network with the blue nodes being routers. They have their labels cleared for posting due to company privacy considerations, sorry for causing confusion with this.

The problem is that the grey, text-only nodes - visible on the top-left corner - have only one node connected to them, and still are placed very far from their single connected node.

Just as you explained MDS, my goal would be the same, having single edge interconnected nodes as close to each other as possible. And wondering why this is not happening ?

If you look at the below once again, you can see exactly what my issue is : image

Edge diretions are not important to me at this stage.

levnach commented 6 years ago

Can you try another layout, the one that is used in FastIncrementalLayoutWithGdi? It might work better for you.

lafrank commented 6 years ago

Sure, I will soon, and send an update...

On Oct 10, 2017 20:49, "Lev Nachmanson" notifications@github.com wrote:

Can you try another layout, the one that is used in FastIncrementalLayoutWithGdi? It might work better for you.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/Microsoft/automatic-graph-layout/issues/144#issuecomment-335570922, or mute the thread https://github.com/notifications/unsubscribe-auth/AO-XZMbXvTdzRGju2MDJBJykbdnALDxKks5sq7wsgaJpZM4Pi980 .

lafrank commented 6 years ago

I was experimenting a lot with clusters, but was not able to achieve a good-looking graph layout unfortunately. Are clusters only working with IncrementalLayout or also with MDS ?

Anyhow, I took another direction in development.

Once a graph is calculated, user can edit the layout and save it to msagl file. Whenever I do some augmenting of the graph and need to perform layout again, I want to restore the positions of pre-existing nodes from the saved msagl file.

I have no issue doing that with nodes, but can't find the way to update edges. In fact, I wouldn't even need to update edges if I could perform rerouting only, like if Graph.RerouteAllEdges() were existing.

Could you please help me with this ? Below is my code for the above, quite short :

image

Thank you !

lafrank commented 6 years ago

I also tried

gViewer1.LayoutEditor.geomGraphEditor.RunSplineRouterAndPutLabels();

but this does not have any visible effect.

lafrank commented 6 years ago

I am closing this issue as most of my concerns are addressed in pull request #150

Thanks @levnach once again for your help so far.