Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) Links overlapping on their way to destination (Read 6327 times)
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Links overlapping on their way to destination
May 17th, 2011 at 6:58am
Print Post  
Hello,

Lets say I have a row of Nodes ( nodes with the same Center.Y ).
When I want to draw connections from these nodes to other far nodes, the links will be overlapped on the way.

Here is an example to better explain the situation:


A is connected to C,  B is connected to C.
The link part between B and C is actually 2 links overlapped, apparently.

Lets say I have a List<ShapeNode> that I need to apply a fix for that issue on it.
What would be the optimal way to fix this?

By the way Stoyo, I'm using your distribute functions so two connections originating/ending at the same point is not an issue.


Many thanks in advance
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #1 - May 17th, 2011 at 7:44am
Print Post  
Hi,

The distribute method should pull links apart at the C end. Do you also need to keep the links horizontal and avoid overlapping in that case?

Stoyan
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #2 - May 17th, 2011 at 8:15am
Print Post  
It's true that they'll get pulled apart at C in that case.

But what if it it's like this:


The 2 links have different end points and they overlap on the way.
Can that be avoided?

Thanks Smiley
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #3 - May 17th, 2011 at 8:49am
Print Post  
An easy solution is to divide the nodes height by as many links as there are between these nodes, and put only one link at the same Y. However this will waste some space if there are short links that can share the same Y without overlapping. I'll check with our developers if there's a way to distribute them more compactly and let you know later today.
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #4 - May 17th, 2011 at 9:20am
Print Post  
Thanks a lot, appreciated.
Dividing height by # of connections seems like a good idea. I'll try it out.
Waiting for you reply.

Thanks again,
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #5 - May 17th, 2011 at 11:00am
Print Post  
The DistributeLinks method below should distribute the links reusing as much vertical positions as possible. It assumes all nodes from the collection have the same height and are aligned vertically, and that links' end points have already been placed at the closer sides of the connected nodes. You will have to add a reference to mindfusion.graphs assembly and namespace to use the IntervalGraph class.

Code
Select All
void DistributeLinks(DiagramNodeCollection nodes)
{
	Dictionary<DiagramLink, int> linkLevels = new Dictionary<DiagramLink, int>();
	int levels = GetLinkLevels(nodes, linkLevels);

	float top = nodes[0].Bounds.Top;
	float levelDist = nodes[0].Bounds.Height / (levels + 1);
	foreach (DiagramLink link in linkLevels.Keys)
	{
		int level = linkLevels[link];
		float y = top + (level + 1) * levelDist;
		for (int i = 0; i < link.ControlPoints.Count; ++i)
		{
			PointF point = link.ControlPoints[i];
			point.Y = y;
			link.ControlPoints[i] = point;
		}
		link.UpdateFromPoints();
	}
	diagram.Invalidate();
}

int GetLinkLevels(DiagramNodeCollection nodes, Dictionary<DiagramLink, int> linkLevels)
{
	List<DiagramLink> unassignedLinks = new List<DiagramLink>();
	foreach (DiagramLink link in diagram.Links)
	{
		if (nodes.Contains(link.Origin) && nodes.Contains(link.Destination))
			unassignedLinks.Add(link);
	}

	int currentLevel = 0;

	while (unassignedLinks.Count > 0)
	{
		IntervalGraph graph = GraphFromLinks(unassignedLinks);
		graph.SetItemIndices();

		List<Vertex> independentSet = graph.MaxWeightedIndependentSet();
		List<DiagramLink> nonOverlapping = new List<DiagramLink>();
		foreach (Vertex vertex in independentSet)
		{
			DiagramLink link = unassignedLinks[vertex.index];
			linkLevels[link] = currentLevel;
			nonOverlapping.Add(link);
		}
		foreach (DiagramLink link in nonOverlapping)
			unassignedLinks.Remove(link);
		currentLevel++;
	}

	return currentLevel;
}

IntervalGraph GraphFromLinks(List<DiagramLink> links)
{
	List<Interval> linkIntervals = new List<Interval>();
	foreach (DiagramLink link in links)
	{
		PointF p1 = link.ControlPoints[0];
		PointF p2 = link.ControlPoints[link.ControlPoints.Count - 1];
		linkIntervals.Add(
			new Interval(Math.Min(p1.X, p2.X), Math.Max(p1.X, p2.X)));
	}
	return new IntervalGraph(linkIntervals);
} 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #6 - May 17th, 2011 at 1:07pm
Print Post  
That code is pretty neat and it works well when they're the same height,aligned vertically and connections are made between the nodes in the collection.

But in some cases, i have a row of nodes which are the same height and aligned vertically. But there are no connections between them. They're connected to nodes outside of the collection with varying sizes.

To be exact:


Thanks for trying though, I'm keeping the code you posted as I would need it later on.

Sorry that I didn't explain the full picture from the beginning Smiley
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #7 - May 17th, 2011 at 1:38pm
Print Post  
If that should sort both links that are internal for the specified nodes and also external ones going to other nodes, you could adapt the same method with only a few modifications:

- GetLinkLevels should add to unassignedLinks if the nodes collection contain either link.Origin or link.Destination.

- GraphFromLinks should set some fixed interval coordinates for the external part of the links, either on the left or right of all other nodes depending on where the other link end is located.

- DistributeLinks should set Y only for 2 points of the segment of an external link that is adjacent to a node from the collection.
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #8 - May 17th, 2011 at 2:00pm
Print Post  
I hate to ask this but can you please show me the changes of your 2nd and 3rd point?
I'm not sure what to do exacty in GraphFromLinks and DistributeLinks.
???
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #9 - May 18th, 2011 at 8:24am
Print Post  
I was implementing the solution you suggested ( dividing the height by the number of connections ) and it looks like this:


I'm still not sure how to modify the functions you gave me, if you can shed some light on the matter I'd appreciate it.

Thanks,
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #10 - May 18th, 2011 at 8:48am
Print Post  
This will also sort external links, assuming they come from the left or right sides of the specified nodes, and already have more than one segment:
Code
Select All
void DistributeLinks(DiagramNodeCollection nodes)
{
	Dictionary<DiagramLink, int> linkLevels = new Dictionary<DiagramLink, int>();
	int levels = GetLinkLevels(nodes, linkLevels);

	float top = nodes[0].Bounds.Top;
	float levelDist = nodes[0].Bounds.Height / (levels + 1);
	foreach (DiagramLink link in linkLevels.Keys)
	{
		int level = linkLevels[link];
		float y = top + (level + 1) * levelDist;
		int i1 = 0, i2 = 0;
		if (nodes.Contains(link.Origin) && nodes.Contains(link.Destination))
		{
			i1 = 0;
			i2 = link.ControlPoints.Count;
		}
		else if (nodes.Contains(link.Origin))
		{
			i1 = 0;
			i2 = 2;
		}
		else if (nodes.Contains(link.Destination))
		{
			i1 = link.ControlPoints.Count - 2;
			i2 = link.ControlPoints.Count;
		}
		for (int i = i1; i < i2; ++i)
		{
			PointF point = link.ControlPoints[i];
			point.Y = y;
			link.ControlPoints[i] = point;
		}
		link.UpdateFromPoints();
	}
	diagram.Invalidate();
}

int GetLinkLevels(DiagramNodeCollection nodes, Dictionary<DiagramLink, int> linkLevels)
{
	List<DiagramLink> unassignedLinks = new List<DiagramLink>();
	foreach (DiagramLink link in diagram.Links)
	{
		if (nodes.Contains(link.Origin) || nodes.Contains(link.Destination))
			unassignedLinks.Add(link);
	}

	int currentLevel = 0;

	while (unassignedLinks.Count > 0)
	{
		IntervalGraph graph = GraphFromLinks(unassignedLinks, nodes);
		graph.SetItemIndices();

		List<Vertex> independentSet = graph.MaxWeightedIndependentSet();
		List<DiagramLink> nonOverlapping = new List<DiagramLink>();
		foreach (Vertex vertex in independentSet)
		{
			DiagramLink link = unassignedLinks[vertex.index];
			linkLevels[link] = currentLevel;
			nonOverlapping.Add(link);
		}
		foreach (DiagramLink link in nonOverlapping)
			unassignedLinks.Remove(link);
		currentLevel++;
	}

	return currentLevel;
}

IntervalGraph GraphFromLinks(List<DiagramLink> links, DiagramNodeCollection nodes)
{
	List<Interval> linkIntervals = new List<Interval>();
	foreach (DiagramLink link in links)
	{
		int last = link.ControlPoints.Count - 1;
		if (nodes.Contains(link.Origin) && nodes.Contains(link.Destination))
		{
			PointF p1 = link.ControlPoints[0];
			PointF p2 = link.ControlPoints[last];
			linkIntervals.Add(
				new Interval(Math.Min(p1.X, p2.X), Math.Max(p1.X, p2.X)));
		}
		else if (nodes.Contains(link.Origin))
		{
			PointF p1 = link.ControlPoints[0];
			PointF p2 = link.ControlPoints[1];
			linkIntervals.Add(
				new Interval(Math.Min(p1.X, p2.X), Math.Max(p1.X, p2.X)));
		}
		else if (nodes.Contains(link.Destination))
		{
			PointF p1 = link.ControlPoints[last];
			PointF p2 = link.ControlPoints[last - 1];
			linkIntervals.Add(
				new Interval(Math.Min(p1.X, p2.X), Math.Max(p1.X, p2.X)));
		}
	}
	return new IntervalGraph(linkIntervals);
} 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #11 - May 18th, 2011 at 9:13am
Print Post  
Alright Stoyo, thanks.

I tried your code out and here is the output:


You can compare it to the previous output I posted.

Both screenshots are taken after offsetting link control points to be inside the containers.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #12 - May 18th, 2011 at 9:41am
Print Post  
and?
  
Back to top
 
IP Logged
 
lenix
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 31
Joined: Apr 6th, 2011
Re: Links overlapping on their way to destination
Reply #13 - May 18th, 2011 at 12:36pm
Print Post  
Nothing, just wanted to show results.
By the way, I'm using the diagramming components to draw schematics of Telecom Equipment and I'm going to post screenshots on this forum after the work is done. The tool is actually a custom tool for ArcGIS.
It's a big project and I'm pretty sure that it'll show many of the capabilities of MindFusion.Digramming components.

Thanks for all the help Stoyo, your time is much appreciated.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Links overlapping on their way to destination
Reply #14 - May 18th, 2011 at 1:01pm
Print Post  
Ok. There's room for some improvement if you feel like coding it Smiley

- since you are pulling the arrowheads towards the node interior, you could create larger intervals that add the arrowheads size to the left and right. This should avoid overlappings where links meet at the same X position.

- you could sort the levels based on the Y positions of external links' opposite nodes, this should decrease the crossings visible on the left side.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint