Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Arrows lieing over each other (Read 4825 times)
mbuechler
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 39
Joined: Oct 21st, 2009
Arrows lieing over each other
Nov 11th, 2009 at 10:57am
Print Post  
hi.

I use the LayeredLayout Engine in my flowchart. the problem I have is, that when there are two boxes connected by 2 arrows (one from box A to B and one from B to A) these arrows are lieing over each other. In my app it is neccesary that you can select each arrow... is it possible to set a property which avoid this overlieing arrows.
I hope its clear what i mean Wink

thank for all help.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Arrows lieing over each other
Reply #1 - Nov 11th, 2009 at 12:34pm
Print Post  
Hi,

There is no built-in property to do that. You might call this method to split the links (assuming vertical layout):

Code
Select All
void SplitLinksIgnoreDirection(float padding)
{
	// find repeating links
	Dictionary<int, List<DiagramLink>> repeatingLinks = new Dictionary<int, List<DiagramLink>>();
	foreach (DiagramLink link in diagram.Links)
	{
		int z1 = Math.Min(link.Origin.ZIndex, link.Destination.ZIndex);
		int z2 = Math.Max(link.Origin.ZIndex, link.Destination.ZIndex);
		int key = diagram.Items.Count * z1 + z2;
		if (!repeatingLinks.ContainsKey(key))
			repeatingLinks[key] = new List<DiagramLink>();
		repeatingLinks[key].Add(link);
	}

	// pull them apart
	foreach (KeyValuePair<int, List<DiagramLink>> linkList in repeatingLinks)
	{
		int c = 0, numLinks = linkList.Value.Count;
		if (numLinks < 2)
			continue;
		foreach (DiagramLink link in linkList.Value)
		{
			for (int p = 0; p < link.ControlPoints.Count; ++p)
			{
				PointF point = link.ControlPoints[p];
				point.X += padding * c - padding * (numLinks - 1) / 2;
				link.ControlPoints[p] = point;
				link.UpdateFromPoints();
			}
			c++;
		}
	}
}
 



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


I love YaBB 1G - SP1!

Posts: 39
Joined: Oct 21st, 2009
Re: Arrows lieing over each other
Reply #2 - Nov 11th, 2009 at 1:22pm
Print Post  
Thanks for this...
can you tell me what i have to change when i use horizontal layout? the user can change this in the app...

another point: when I move one of the boxes where the splitaction was performed for, the arrows are lieing over each other again. is there a way to prevent this? Or do I only have to call this function after moving an object on the flowchart?
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Arrows lieing over each other
Reply #3 - Nov 11th, 2009 at 2:14pm
Print Post  
For horizontal layouts add to point.Y, and disable the Dynamic property of links to prevent them from returning to the middle of the node borders.

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


I love YaBB 1G - SP1!

Posts: 39
Joined: Oct 21st, 2009
Re: Arrows lieing over each other
Reply #4 - Nov 16th, 2009 at 9:12am
Print Post  
thanks. the function works good.
the only change i made was the decision when to move it along the x or the y axis.
i calculate the delta X and delta Y of first and last point in ControlPointcollection.
if deltaX > deltaY -> move vertical
if deltaX < deltaY -> move horizontal.
so i dont have to look at the orientation of my layout engine and the seperation of the arrows also work if someone pull the states on the flowchart.

maybe you can tell me another thing: if there is a transition which has its beginning and its end on the same box, the transition isn't visible after applieing layered layout engine.
does someone has a solution for this?
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Arrows lieing over each other
Reply #5 - Nov 16th, 2009 at 11:09am
Print Post  
You could run this code for self-loop links after applying the layout:

Code
Select All
if (link.Origin == link.Destination)
{
	RectangleF r = link.Origin.Bounds;
	PointF p = new PointF(r.X + 10, r.Y);
	link.Style = LinkStyle.Bezier;
	link.SegmentCount = 1;
	link.ControlPoints.Clear();
	link.ControlPoints.Add(p);
	link.ControlPoints.Add(new PointF(p.X - 8, p.Y - 12));
	link.ControlPoints.Add(new PointF(p.X + 10, p.Y - 12));
	link.ControlPoints.Add(new PointF(p.X + 2, p.Y));
	link.UpdateFromPoints();
}
 



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


I love YaBB 1G - SP1!

Posts: 39
Joined: Oct 21st, 2009
Re: Arrows lieing over each other
Reply #6 - Nov 17th, 2009 at 9:02am
Print Post  
thank you very much. you helped my very much....
  
Back to top
 
IP Logged
 
nejelski
YaBB Newbies
*
Offline



Posts: 5
Joined: Mar 24th, 2010
Re: Arrows lieing over each other
Reply #7 - Apr 8th, 2010 at 9:31pm
Print Post  
Hi Stoyo,
Do you have a C++ version of "SplitLinksIgnoreDirection" function that splits arrow items?
Or may be there is a new way to split overlaying arrows between the same box items?

I use FlowChartPro ActiveX with MFC wrappers.

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Arrows lieing over each other
Reply #8 - Apr 9th, 2010 at 9:20am
Print Post  
Hi,

For FlowchartX with MFC it should look like

Code
Select All
void SplitLinksIgnoreDirection(FlowChart& diagram, int padding)
{
	// find repeating links
	std::map<int, std::vector<LPDISPATCH> > repeatingLinks;
	for (int i = 0; i < diagram.GetArrows().GetCount(); ++i)
	{
		ArrowItem link = diagram.GetArrows().GetItem(i);
		int z1 = min(link.GetOriginBox().GetZIndex(), link.GetDestinationBox().GetZIndex());
		int z2 = max(link.GetOriginBox().GetZIndex(), link.GetDestinationBox().GetZIndex());
		int key = (diagram.GetArrows().GetCount() + diagram.GetBoxes().GetCount()) * z1 + z2;
		repeatingLinks[key].push_back(link.m_lpDispatch);
	}

	// pull them apart
	for (std::map<int, std::vector<LPDISPATCH> >::iterator mi = repeatingLinks.begin();
		mi != repeatingLinks.end(); ++mi)
	{
		size_t c = 0, numLinks = mi->second.size();
		if (numLinks < 2)
			continue;
		for (size_t l = 0; l < mi->second.size(); ++l)
		{
			ArrowItem link; link.AttachDispatch(mi->second[l], FALSE);
			for (int p = 0; p < link.GetCtrlPtCount(); ++p)
			{
				int x = link.GetCtrlPtX(p);
				x += padding * c - padding * (numLinks - 1) / 2;
				link.SetCtrlPtX(p, x);
				link.Update();
			}
			c++;
		}
	}
} 



This code assumes the links are initially vertical and connected to the center of node sides.

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



Posts: 5
Joined: Mar 24th, 2010
Re: Arrows lieing over each other
Reply #9 - Apr 9th, 2010 at 5:20pm
Print Post  
Works great!
Great function to start with.
I will take care of the rest.
I am Very impressed with FAST technical support!
Good job!
Thanks a lot.

Just in case : for  those who would use it too. Add the following lines before function declaration to get rid of different errors:

#include <map>
#include <vector>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint