Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Is it possible to customize the links? (Read 5512 times)
cds
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 10
Joined: Apr 7th, 2010
Is it possible to customize the links?
Apr 7th, 2010 at 4:44am
Print Post  
Hi

Just evaluating the Silvlight Diagramming product.

I need the ability for users to create a genogram (see: http://en.wikipedia.org/wiki/Genogram). In addition to custom nodes, I'd need custom links as well to represent different kins of relationships. Is this possible?

Thanks,

Craig
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Is it possible to customize the links?
Reply #1 - Apr 7th, 2010 at 8:58am
Print Post  
Hi,

This can be done only by overriding the link's UpdateVisuals method. For example this implements something like the "Distant-Hostile" link:

Code
Select All
public class MyLink : DiagramLink
{
	public MyLink() {}

	public MyLink(Diagram diagram) : base(diagram)
	{
	}

	protected override void UpdateVisuals()
	{
		base.UpdateVisuals();

		var canvas = Content as Canvas;
		if (canvas != null)
		{
			if (!canvas.Children.Contains(myPath))
				canvas.Children.Add(myPath);
			UpdatePath();
		}
	}

	private void UpdatePath()
	{
		var b = GetBounds();
		var p0 = ControlPoints[0];
		p0.X -= b.X; p0.Y -= b.Y;
		var p1 = ControlPoints[ControlPoints.Count - 1];
		p1.X -= b.X; p1.Y -= b.Y;

		double dx = p1.X - p0.X;
		double dy = p1.Y - p0.Y;

		var g = new PathGeometry();
		var f = new PathFigure
		{
			IsClosed = false,
			IsFilled = false,
			StartPoint = p0
		};

		double a = 0, r = 0, s = -1;
		CartesianToPolar(p0, p1, ref a, ref r);

		for (int i = 1; i < 10; ++i )
		{
			Point fp = p0;
			fp.X += i * dx / 10;
			fp.Y += i * dy / 10;
			PolarToCartesian(fp, a + s * 90, 20, ref fp);
			s *= -1;
			f.Segments.Add(new LineSegment { Point = fp });
		}

		g.Figures.Add(f);
		myPath.Data = g;
		myPath.Stroke = Brushes.Red;
	}

	static void PolarToCartesian(Point coordCenter, double a, double r, ref Point cartesian)
	{
		if (r == 0)
		{
			cartesian = coordCenter;
			return;
		}
		cartesian.X = coordCenter.X + Math.Cos(a * Math.PI / 180) * r;
		cartesian.Y = coordCenter.Y - Math.Sin(a * Math.PI / 180) * r;
	}

	static void CartesianToPolar(Point coordCenter, Point cartesian, ref double a, ref double r)
	{
		if (coordCenter == cartesian)
		{
			a = 0;
			r = 0;
			return;
		}
		double dx = cartesian.X - coordCenter.X;
		double dy = cartesian.Y - coordCenter.Y;
		r = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
		a = Math.Atan(-dy / dx) * 180 / Math.PI;
		if (dx < 0) a += 180;
	}

	private readonly Path myPath = new Path();
} 



You can let users draw that kind of links through a custom Behavior class:

Code
Select All
public class MyBehavior : LinkShapesBehavior
{
	public MyBehavior(Diagram diagram)
		: base(diagram)
	{
	}

	protected override DiagramLink CreateLink(DiagramNode origin, Point point)
	{
		var link = new MyLink(Diagram);
		link.Origin = origin;
		return link;
	}
} 



I hope that helps,
Stoyan
« Last Edit: May 31st, 2021 at 1:31pm by Slavcho »  
Back to top
 
IP Logged
 
cds
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 10
Joined: Apr 7th, 2010
Re: Is it possible to customize the links?
Reply #2 - Apr 8th, 2010 at 10:21am
Print Post  
Thanks Stoyan

This was very helpful.

Craig
  
Back to top
 
IP Logged
 
rajesh_patil74
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 220
Joined: Sep 3rd, 2009
Re: Is it possible to customize the links?
Reply #3 - Apr 8th, 2010 at 1:39pm
Print Post  
Hi Stoyo

Is it possible to add some small button for each line segment (when the line is horizontal and vertical only) and some handler for that button with which user can move the line vertically up/down or horizontally left/right.


-Rajesh
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Is it possible to customize the links?
Reply #4 - Apr 8th, 2010 at 2:45pm
Print Post  
Hi Rajesh,

You could add buttons to the link's Canvas as above, placing them according to the positions of segment points. Do you mean the segments positions should be changed by the buttons' Click handler?

Stoyan
  
Back to top
 
IP Logged
 
rajesh_patil74
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 220
Joined: Sep 3rd, 2009
Re: Is it possible to customize the links?
Reply #5 - Apr 9th, 2010 at 5:00am
Print Post  
Hi Stoyo

Ya. For each segement i want to add the button centrally on that segment and movement of that should be either vertical or horizontal.

The behavior expected in my post "Line Position Changer"
http://mindfusion.eu/Forum/YaBB.pl?board=diaglite_disc;action=display;num=126638...

The sample link provided over there doesn't do as expected. Can you provide a sample for same.
Not necessary it should be button. It can be path which looks like button and handler/attachment of mouse events for those paths.

Or, in other words, sample for changing the intermediate shape with custom paths gemoetry.

-Rajesh
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Is it possible to customize the links?
Reply #6 - Apr 9th, 2010 at 8:28am
Print Post  
Hi Rajesh,

Do you mean this custom behavior class does not work as expected?
http://mindfusion.eu/_samples/DragSegmentsBehavior.cs

Dragging a segment works fine for me.

However as mentioned in the original thread, inserting a new point when starting to drag the first or last segment is implemented only for horizontal left-to-right links in the sample code.

You will have to extend the StartDraw handler for the (segment == 0) and (segment == count - 1) cases to insert the point at correct positions for vertical and right-to-left links. E.g. instead of always setting p1.X += 10 for the first segment, you will have to check its current orientation and accordingly set X -= 10 or Y += 10 or Y -= 10.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
rajesh_patil74
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 220
Joined: Sep 3rd, 2009
Re: Is it possible to customize the links?
Reply #7 - Apr 9th, 2010 at 10:30am
Print Post  
Hi Stoyo

With code provided I did following thing.
I have two nodes horizontally placed and established a line between them with start and end points only.

Now dragging start and end point tries to move there position as expected. If i click some where in between the link and moves the mouse, two new points gets inserted and I can move those points horizontally.

This is not what I expect.

My expectation is as below -
I have two nodes horizonally placed and there is a link between these two points.

The points are linked vertically center at left and right edges of the nodes.
If I assume the link is between (100,50) and (300,50) points their central location is (150,50).

At this particular point ( 150,50) i need some small button which i can move vertically up or down to make the lines start end points either
1. (100,45) and (300,45) or
2. (100,40) and (300,40) or
3. (100,53) and (300, 53) etc.

And the center point for the line where the button will be shown will either
(150,45) or  (150,40) or (150,53).


I hope the requiement is clear now.

-Regards
Rajesh
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Is it possible to customize the links?
Reply #8 - Apr 14th, 2010 at 10:46am
Print Post  
Hi Rajesh,

This would be best to implement in a DiagramLink.UpdateDrag override, but to avoid subclassing you could do that in the behavior class too. Try modifying the sample behavior class from above as follows:

Code
Select All
// in OnMouseMove
if (Diagram.Interaction != null)
{
	Diagram.Interaction.Update(mousePosition);

	if (dragSegment == DragLinkSegment.Horizontal)
	{
		var dy = mousePosition.Y - startPoint.Y;
		for (int i = 0; i < modifiedLink.ControlPoints.Count; ++i)
		{
			var p = savedPoints[i];
			p.Y += dy;
			modifiedLink.ControlPoints[i] = p;
		}
		modifiedLink.UpdateFromPoints();
	}

	if (dragSegment == DragLinkSegment.Vertical)
	{ // similar for dx
	}

return;
}

// in StartDraw
int segment = 0;
modifiedLink = Diagram.GetLinkAt(point, 5, true, ref segment);
if (modifiedLink != null)
{
	var points = modifiedLink.ControlPoints;
	dragSegment = points[segment].Y == points[segment + 1].Y ?
		DragLinkSegment.Horizontal : DragLinkSegment.Vertical;
	startPoint = points[segment];
	savedPoints = new List<Point>(points);
	return new InteractionState(modifiedLink, Action.Modify, segment, modifiedLink.ControlPoints[segment]);
}

// new field definitions
private List<Point> savedPoints;
private DiagramLink modifiedLink; 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint