Avoiding nodes dosen't have the correct behaviour

here is how I create the elements on the document:

Document 
_document.Document = new GoDocument();
_document.Document.MaintainsPartID = true;
foreach(var anElement in _elements)
{

GoNode _N1 = new GoNode() { Location = new PointF(anElement.BoundingBox.X, anElement.BoundingBox.Y), Size = new
 SizeF(anElement.BoundingBox.Width, anElement.BoundingBox.Height) };
       _document.Document.Add(_N1);

       foreach(var aPort in anElement.ConnectionPoints)
       {
       	GoPort _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF((float)(anElement.BoundingBox.X + 
(aPort.Wpercent * anElement.BoundingBox.Width)), (float)(anElement.BoundingBox.Y + (aPort.Hpercent * anElement.BoundingBox.Height))) };
              _N1.Add(_p);
}
}

there the links

Northwoods.Go.GoLink _l = new Northwoods.Go.GoLink();
                                _l.Orthogonal = true;
                                _l.AvoidsNodes = true;
                                _l.FromPort = _source;
                                _l.ToPort = _dest;
                                _l.CalculateRoute();
                                _l.CalculateStroke();
                                _cdoc.Document.Add(_l);

                                _l.Orthogonal = true;                                
                                _l.AvoidsNodes = true;

                            Northwoods.Go.GoLink _l=(Northwoods.Go.GoLink) _cdoc.Document.FindPart(_l.PartId);
                            _l.CalculateRoute();
                            _l.CalculateStroke();
                            foreach (var aPoint in _l.CopyPointsArray())
                                ……
                        }

the result is strange because i have this issue:

I don’t know if i’m implementing something wrong. Thanks a lot

Sorry, I can’t tell from your code fragments what the whole story is here. Is that gray node in the middle N1? What are all those other fragments of lines?

The gray node in the middle looks like a candidate for GoGeneralNode, you should look at that.

Jake

Thanks Jake.

we map on goDiagram all element we have in the svg using their bundingbox (bbox) as GONode and then we render the link points on our svg.

So yes the grey one in the middle is _n1.

I guess we did not understand each other for you convenience find the attached a simple c#program reproducing the issue.

as you can see the link overlaps nodes. Looking for your reply.
Thanks for your support

M.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Northwoods.Go;


namespace PIMS
{
    class Testcs
    {
        public void BuildDocument(ListView listView1)
        {
            GoDocument _d = new GoDocument();
            _d.MaintainsPartID = true;
            int _pStart = 0; int _pEnd = 0; GoNode _n = null; GoPort _p = null;
            _n = new GoNode() { Location = new PointF() { X = 1394, Y = 606 }, Size = new SizeF() { Height = 690, Width = 151 } };
            _d.Add(_n);
            // CDUIn
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1394, Y = 951 } };
            _n.Add(_p);
            // CDUOut
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1545, Y = 1066 } };
            _n.Add(_p);
            // CDUOut__AF__1
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1545, Y = 836 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 1114, Y = 923 }, Size = new SizeF() { Height = 56, Width = 159 } };
            _d.Add(_n);
            // SF_Flow1In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1114, Y = 951 } };
            _n.Add(_p);
            // SF_Flow1Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1273, Y = 951 } };
            _n.Add(_p);
            // SF_Flow1Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = (float)1193.5, Y = 979 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 1661, Y = 738 }, Size = new SizeF() { Height = 56, Width = 159 } };
            _d.Add(_n);
            // SF_Flow2In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1661, Y = 766 } };
            _n.Add(_p);
            // SF_Flow2Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1820, Y = 766 } };
            _n.Add(_p);
            // SF_Flow2Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = (float)1740.5, Y = 794 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 1661, Y = 1103 }, Size = new SizeF() { Height = 56, Width = 159 } };
            _d.Add(_n);
            // SF_Flow3In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1661, Y = 1131 } };
            _n.Add(_p);
            // SF_Flow3Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1820, Y = 1131 } };
            _n.Add(_p);
            // SF_Flow3Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = (float)1740.5, Y = 1159 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 672, Y = 921 }, Size = new SizeF() { Height = 60, Width = 60 } };
            _d.Add(_n);
            // SF_ReceiptPoint1Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 732, Y = 951 } };
            _n.Add(_p);
            _pStart = _p.PartID;
            _n = new GoNode() { Location = new PointF() { X = 2034, Y = 1365 }, Size = new SizeF() { Height = 111, Width = 142 } };
            _d.Add(_n);
            // SF_VolumeTank1In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2034, Y = (float)1420.5 } };
            _n.Add(_p);
            // SF_VolumeTank1Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2176, Y = (float)1420.5 } };
            _n.Add(_p);
            // SF_VolumeTank1Analyzer
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2105, Y = (float)1476 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 2407, Y = 659 }, Size = new SizeF() { Height = 198, Width = 50 } };
            _d.Add(_n);
            // SF_Node1In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = (float)2412.556, Y = (float)811.9109 } };
            _n.Add(_p);
            _pEnd = _p.PartID;
            // SF_Node1Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2457, Y = 725 } };
            _n.Add(_p);
            // SF_Node1Out__AF__1
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2457, Y = 791 } };
            _n.Add(_p);
            // SF_Node1In__AF__1
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2407, Y = 758 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 2304, Y = 1074 }, Size = new SizeF() { Height = 159, Width = 56 } };
            _d.Add(_n);
            // SF_Flow4In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2333, Y = 1232 } };
            _n.Add(_p);
            // SF_Flow4Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2331, Y = 1078 } };
            _n.Add(_p);
            // SF_Flow4Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2332, Y = 1233 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 2741, Y = 931 }, Size = new SizeF() { Height = 159, Width = 56 } };
            _d.Add(_n);
            // SF_Flow7In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2768, Y = 933 } };
            _n.Add(_p);
            // SF_Flow7Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2769, Y = 1089 } };
            _n.Add(_p);
            // SF_Flow7Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2741, Y = 1011 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 2129, Y = 210 }, Size = new SizeF() { Height = 57, Width = 160 } };
            _d.Add(_n);
            // SF_Flow8In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2129, Y = (float)238.5 } };
            _n.Add(_p);
            // SF_Flow8Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2289, Y = (float)238.5 } };
            _n.Add(_p);
            // SF_Flow8Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2209, Y = 267 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 1766, Y = 202 }, Size = new SizeF() { Height = 60, Width = 60 } };
            _d.Add(_n);
            // SF_ShipmentPoint2In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 1824, Y = 233 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 3284, Y = 1210 }, Size = new SizeF() { Height = 60, Width = 60 } };
            _d.Add(_n);
            // SF_ShipmentPoint3In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 3284, Y = 1240 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 1330, Y = 439 }, Size = new SizeF() { Height = 69, Width = 56 } };
            _d.Add(_n);
            _n = new GoNode() { Location = new PointF() { X = 558, Y = 175 }, Size = new SizeF() { Height = 182, Width = 293 } };
            _d.Add(_n);
            _n = new GoNode() { Location = new PointF() { X = 626, Y = 497 }, Size = new SizeF() { Height = 42, Width = 323 } };
            _d.Add(_n);
            _n = new GoNode() { Location = new PointF() { X = 3023, Y = 198 }, Size = new SizeF() { Height = 112, Width = 159 } };
            _d.Add(_n);
            // Tank_q32q_Verrsion_q32q_16In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 3023, Y = 254 } };
            _n.Add(_p);
            // Tank_q32q_Verrsion_q32q_16Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 3182, Y = 254 } };
            _n.Add(_p);
            // Tank_q32q_Verrsion_q32q_16Analyzer
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = (float)3102.5, Y = 310 } };
            _n.Add(_p);
            _n = new GoNode() { Location = new PointF() { X = 2719, Y = 606 }, Size = new SizeF() { Height = 56, Width = 159 } };
            _d.Add(_n);
            // SF_Flow10In
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2719, Y = 633 } };
            _n.Add(_p);
            // SF_Flow10Out
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2878, Y = 634 } };
            _n.Add(_p);
            // SF_Flow10Measurement
            _p = new GoPort() { Size = new SizeF(1, 1), Location = new PointF() { X = 2799, Y = 662 } };
            _n.Add(_p);

            // Add Link

            Northwoods.Go.GoLink _l = new Northwoods.Go.GoLink();
            _l.Orthogonal = true;
            _l.AvoidsNodes = true;
            _l.FromPort = (GoPort)_d.FindPart(_pStart);
            _l.ToPort = (GoPort)_d.FindPart(_pEnd);


            //_l.UpdateRoute();
            _l.CalculateRoute();
            _l.CalculateStroke();
            _d.Add(_l);

            _l.Orthogonal = true;
            _l.AvoidsNodes = true;
            //_l.UpdateRoute();
            //_l.CalculateStroke();

            int _pLink = _l.PartID;
            GoLink _lx = (GoLink)_d.FindPart(_pLink);
            //_l.UpdateRoute();
            _lx.CalculateRoute();
            _lx.CalculateStroke();
            listView1.Items.Clear();

            string _points = "";

            foreach (var aPoint in _l.CopyPointsArray())
            {
                ListViewItem I = new ListViewItem(((int)aPoint.X).ToString());
                I.SubItems.Add(((int)aPoint.Y).ToString());
                listView1.Items.Add(I);
            }
        }

    }
}

First, the default CalculateRoute just calls CalculateStroke.

public virtual void CalculateRoute() {
  CalculateStroke();
}

and AvoidsNodes can’t avoid any nodes if you call it before you add the link to the Document… where the other nodes are.

I added some background rectangles to your nodes so I could see where they are, and your code works.

with this link code:

        Northwoods.Go.GoLink _l = new Northwoods.Go.GoLink();
        _l.Orthogonal = true;
        _l.AvoidsNodes = true;
        _l.FromPort = (GoPort)_d.FindPart(_pStart);
        _l.ToPort = (GoPort)_d.FindPart(_pEnd);
        _d.Add(_l);
        _l.CalculateStroke();

and if I move the From or To node around after that, the AvoidsNodes routing continues.

my add Rectangle code (called for each GoNode)

    public void addbg(GoNode _n)
    {
        GoRectangle _r = new GoRectangle();
        _r.Bounds = _n.Bounds;
        _r.BrushColor = Color.Gray;
        _r.Selectable = false;
        _n.Add(_r);
    }

Thank you now it works.
we observed that without inserting the goRectangle the behavior didn’t change. We added the rectangle and it worked.

We ove to a new diagram with something less then 5000 symbols and 100 links and it takes around 30 seconds do you have any suggestion or strategy to improve the perfomances?

thanks again for your help!

Turn off UndoManager if you are using it until your load is done.

Do all the links at the end… you may already be doing that.

OK, understand, thanks.

We run parallel thread each of them using a proper GoDocument
Does the library support this scenario ?
We can do that?

Thanks

No. GoDiagram doesn’t support threaded operations.