Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Positioning arrows in a box (Read 6778 times)
Carlos Ramos
Guest


Positioning arrows in a box
Jul 31st, 2006 at 2:45pm
Print Post  
I.


Is there a way to separate diferent arrows in the same box. When creating arrows within two boxes in both ways, they are drawed in the same position, and i whould like to see them separated.


Thanks.

Carlos Ramos
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: Positioning arrows in a box
Reply #1 - Jul 31st, 2006 at 4:05pm
Print Post  
Hi,

Use the Bezier arrow style; it will let you draw arc-like arrows that do not overlap each other.

If you want to use straight arrows, define more anchor points at the box sides and connect the arrows to these points.

HTH
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: Positioning arrows in a box
Reply #2 - Jul 31st, 2006 at 4:09pm
Print Post  
You might also handle the ArrowCreated event, so that when a user draws a second arrow between the same boxes, you can automatically distribute the arrows in the area between the boxes. Do that by changing the arrows Style to Bezier and setting the middle control points positions, or by setting the arrows OriginAnchor and  DestAnchor properties.

- glavcho
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: Positioning arrows in a box
Reply #3 - Jul 31st, 2006 at 4:49pm
Print Post  
Here's how that could be done with Beziers:

Code
Select All
private void fc_ArrowCreated(object sender, MindFusion.FlowChartX.ArrowEventArgs e)
{
    ArrowCollection commonArrows = getCommonArrows(e.Arrow.Origin, e.Arrow.Destination);

    PointF pt1 = e.Arrow.ControlPoints[0];
    PointF pt2 = e.Arrow.ControlPoints[e.Arrow.ControlPoints.Count - 1];

    if (commonArrows.Count > 1)
    {
        for (int c = 0; c < commonArrows.Count; ++c)
        {
            Arrow arrow = commonArrows[c];
            arrow.Style = ArrowStyle.Bezier;
            arrow.SegmentCount = 1;

            PointF cp1 = new PointF(pt1.X + 1 * (pt2.X - pt1.X) / 3, pt1.Y + 1 * (pt2.Y - pt1.Y) / 3);
            PointF cp2 = new PointF(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) * 5;
            if (commonArrows.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 (arrow.ControlPoints[0] == pt1)
                {
                    arrow.ControlPoints[1] = cp1;
                    arrow.ControlPoints[2] = cp2;
                }
                else
                {
                    arrow.ControlPoints[1] = cp2;
                    arrow.ControlPoints[2] = cp1;
                }

                arrow.UpdateFromPoints();
            }
        }
    }
}

ArrowCollection getCommonArrows(Node box1, Node box2)
{
    ArrowCollection commonArrows = new ArrowCollection();

    foreach (Arrow arrow in box1.OutgoingArrows)
        if (arrow.Destination == box2)
            commonArrows.Add(arrow);

    foreach (Arrow arrow in box1.IncomingArrows)
        if (arrow.Origin == box2)
            commonArrows.Add(arrow);

    return commonArrows;
}

void polarToCartesian(PointF coordCenter, float a, float r, ref PointF 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(PointF coordCenter, PointF cartesian, ref float a, ref float r)
{
    if (coordCenter == cartesian)
    {
        a = 0;
        r = 0;
        return;
    }

    float dx = cartesian.X - coordCenter.X;
    float 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;
}
 



Now if anyone can think up a nice property name, we might add this a standard feature in the next version of the control Grin
« Last Edit: May 31st, 2021 at 1:17pm by Slavcho »  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: Positioning arrows in a box
Reply #4 - Jul 31st, 2006 at 5:18pm
Print Post  
now I see that can be optimized by moving the "if (%2)" clause out of the loop - we don't need to enter the loop at all for a new arrow when the number of common arrows is odd. In that case the new arrow would lie at the center between the other ones anyway.
  
Back to top
 
IP Logged
 
Carlos Ramos
Guest


Re: Positioning arrows in a box
Reply #5 - Aug 1st, 2006 at 7:21am
Print Post  
Thanks. It helps a lot.
  
Back to top
 
IP Logged
 
Dunkelelb
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 19
Joined: Apr 24th, 2007
Re: Positioning arrows in a box
Reply #6 - Apr 27th, 2007 at 8:43am
Print Post  
you should it also implementing to the automatic layout:)
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Positioning arrows in a box
Reply #7 - Apr 27th, 2007 at 8:57am
Print Post  
I'll add this to the wish-list we keep for Flowchart.NET, though our developers won't be able to implement it very soon  Undecided
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint