Search code examples
c#winformsgraph-theorymsagl

How to draw a node in some given coordinates


Can`t draw node with specified coordinates on gViewer.

Try to use code from this question Change Node position in MSAGL , but it doesn`t work.

        Form form = new ();
        GViewer viewer = new ();
        Graph graph = new ("graph");
        graph.AddNode("test");
        Microsoft.Msagl.Core.Geometry.Point position = new(100, 100);
        graph.FindGeometryNode("test").Center = position;//exception in this line
        viewer.NeedToCalculateLayout = false; 
        viewer.Graph = graph;
        form.SuspendLayout();
        viewer.Dock = System.Windows.Forms.DockStyle.Fill;
        form.Controls.Add(viewer);
        form.ShowDialog();

It throws NullReferenceException.

Message:

        "Object reference not set to an instance of an object." 

Stack:

MsaglTestApplication.dll!MsaglTestApplication.Program.Main() Line 23 C#


Solution

  • Find detailed example how to fix this problem on winforms. Was test this code it`s worked. On github: https://github.com/microsoft/automatic-graph-layout/blob/master/GraphLayout/Samples/PopulateGViewerWithPrecalculatedDrawingGraph/Program.cs

    Update:

    Here is code of answer:

            private static void SetNodeBoundary(Microsoft.Msagl.Drawing.Node drawingNode) {
            var font = new System.Drawing.Font(drawingNode.Label.FontName, (float)drawingNode.Label.FontSize);
            StringMeasure.MeasureWithFont(drawingNode.LabelText, font, out double width, out double height);
            drawingNode.Label.GeometryLabel = new Microsoft.Msagl.Core.Layout.Label();
            drawingNode.Label.GeometryLabel.Width = width;
            drawingNode.Label.GeometryLabel.Height = width;
            drawingNode.Label.Width = width;
            drawingNode.Label.Height = height;
            int r = drawingNode.Attr.LabelMargin;
            drawingNode.GeometryNode.BoundaryCurve = CurveFactory.CreateRectangleWithRoundedCorners(width + r * 2, height + r * 2, r, r, new Point());
        }
        static void Main(string[] args)
        {
            var gviewer = new GViewer();
            var form = TestFormForGViewer.FormStuff.CreateOrAttachForm(gviewer, null);
            gviewer.NeedToCalculateLayout = false;
            var drawingGraph = new Microsoft.Msagl.Drawing.Graph();
            var a = drawingGraph.AddNode("a");
            var b = drawingGraph.AddNode("b");
            drawingGraph.AddEdge("a", "b");
            var geometryGraph = drawingGraph.CreateGeometryGraph();
            SetNodeBoundary(a);
            SetNodeBoundary(b);
            a.GeometryNode.Center = new Point(0, 50);
            b.GeometryNode.Center = new Point(50, -500);
            var router = new Microsoft.Msagl.Routing.SplineRouter(geometryGraph, new EdgeRoutingSettings());
            router.Run();
            geometryGraph.UpdateBoundingBox();
            gviewer.Graph = drawingGraph;
            Application.Run(form);
        }