microsoft / automatic-graph-layout

A set of tools for graph layout and viewing
Other
1.35k stars 302 forks source link

Pan and zoom to specific node via code #309

Open voidray opened 2 years ago

voidray commented 2 years ago

I'm trying to pan and zoom to a specific node. For the zoom the issue is that when setting the ZoomF value, it is still 1 after the line with the assignment and nothing happens: graphViewer.ZoomF = 2;

Regarding panning to a node I'm not sure how to calculate the values for the Pan() method. First I'm getting the position of the node: var node = graphViewer.Graph.FindNode(id);

Then using than node.Pos value I need somehow get the offset for the Pan() method. If I understand it correctly the Pan() method expects the difference, not the absolute position. The current offset when panning seems to be available in graphViewer.Transform.Offset. Without any zooming and panning the X value is 0 and the Y value seems to be the height of the graphViewer control.

Does the zoom level also have to be taken into account? Can the Pan offset be calculated using Transform.Offset and the node position?

Similar question, but without an answer: Zoom and pan programatically? https://github.com/microsoft/automatic-graph-layout/issues/227

levnach commented 2 years ago

I am not sure why ZoomF does not work in your situation. Have you debugged it? Anyway, you can use function void ShowBBox(Core.Geometry.Rectangle bb) of GViewer. You need to figure 'bb', the rectangle you want to zoom in. It could be in a form node.BoundingBox.Pad('some margin')

voidray commented 2 years ago

Thanks a lot. The focusing works with the following code:

graphViewer.ShowBBox(new Microsoft.Msagl.Core.Geometry.Rectangle { 
                            Center = node.Pos,
                            Width = 1200,
                            Height = 1200
                        });

Regarding ZoomF: Yes, I debugged this part. When I step over this line, the value remains the same. Regarding the ShowBBox suggestion: Was this meant as an alternative to setting ZoomF in combination with Pan(), or would Pan() also be a typical way to achieve this?

Is there any documentation on those methods? Because for example the part with node.BoundingBox.Pad() I didn't figure out what you mean - the method doesn't return anything, so is it changed the node margin?

levnach commented 2 years ago

All these methods in the end set GViewer.Transform, and later this matrix is used to define the graphics transformation. Maybe you might see why ZoomF does not change if you step into it with the debugger... My suggestion was a mistake, but the following should work: var b = node.BoundingBox; b.Pad(someValue);

graphViewer.ShowBBox(b);

voidray commented 2 years ago

The reason why the zoom level was not set was that the line was before the graph was assigned to the graph control. The ZoomF setter returns in that case.

The issue I still have is that the zoom level cannot be applied in a generic way, because it depends on how may nodes are currently displayed. Is there a way to make sure the nodes always have the same size. For example if there are only one or two nodes they fill the whole control.