Hi Stoyo,
Thanks for your reply. I've slightly modified your code that I found here in another post as shown below:
private void UntangleLink(DiagramLink NewLink)
{
try
{
if (NewLink.Origin == NewLink.Destination)
{
//it's self referential
NewLink.Style = LinkStyle.Polyline;
NewLink.Route();
return;
}
//get all common links between start and end state
DiagramLinkCollection commonLinks = GetCommonLinks(NewLink.Origin, NewLink.Destination);
if (commonLinks.Count > 1)
{
//get the start and end point of the calling link
Point pt1 = NewLink.ControlPoints[0];
Point pt2 = NewLink.ControlPoints[NewLink.ControlPoints.Count - 1];
//loop thru all the common links
for (int c = 0; c < commonLinks.Count; ++c)
{
DiagramLink link = commonLinks[c];
link.Style = LinkStyle.Bezier;
//reset to one segment
link.SegmentCount = 1;
//get new control points
Point cp1 = new Point(pt1.X + 1 * (pt2.X - pt1.X) / 3, pt1.Y + 1 * (pt2.Y - pt1.Y) / 3);
Point cp2 = new Point(pt1.X + 2 * (pt2.X - pt1.X) / 3, pt1.Y + 2 * (pt2.Y - pt1.Y) / 3);
float angle = 0, radius = 0;
CartesianToPolar(pt1, pt2, ref angle, ref radius);
int pairOffset = (c / 2 + 1) * 10;
//if (commonLinks.Count % 2 == 0)
//{
PolarToCartesian(cp1, c % 2 == 0 ? angle - 90 : angle + 90, pairOffset, ref cp1);
PolarToCartesian(cp2, c % 2 == 0 ? angle - 90 : angle + 90, pairOffset, ref cp2);
if (link.ControlPoints[0] == pt1)
{
link.ControlPoints[1] = cp1;
link.ControlPoints[2] = cp2;
}
else
{
link.ControlPoints[1] = cp2;
link.ControlPoints[2] = cp1;
}
link.UpdateFromPoints();
//}
}
}
}
catch (Exception exc)
{
AUISL.Utilities.LogException(exc);
}
}
DiagramLinkCollection GetCommonLinks(DiagramNode node1, DiagramNode node2)
{
DiagramLinkCollection commonLinks = new DiagramLinkCollection();
foreach (DiagramLink link in node1.OutgoingLinks)
if (link.Destination == node2)
commonLinks.Add(link);
foreach (DiagramLink link in node1.IncomingLinks)
if (link.Origin == node2)
commonLinks.Add(link);
return commonLinks;
}
void PolarToCartesian(Point coordCenter, float a, float r, ref Point cartesian)
{
if (r == 0)
{
cartesian = coordCenter;
return;
}
cartesian.X = (float)(coordCenter.X + Math.Cos(a * Math.PI / 180) * r);
cartesian.Y = (float)(coordCenter.Y - Math.Sin(a * Math.PI / 180) * r);
}
void CartesianToPolar(Point coordCenter, Point cartesian, ref float a, ref float r)
{
if (coordCenter == cartesian)
{
a = 0;
r = 0;
return;
}
double dx = cartesian.X - coordCenter.X;
double dy = cartesian.Y - coordCenter.Y;
r = (float)(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)));
a = (float)(Math.Atan(-dy / dx) * 180 / Math.PI);
if (dx < 0) a += 180;
}
After Annealing I run UntangleLink for every link in the diagram.
If you set up the scenario I described you'll see that this is a pretty graceful solution. �But the self-referencing links still overlap.
I guess I can just write code that separates the links but makes sure they're outside the Node.
Any other ideas?
Thanks for your help,
JR