Page Index Toggle Pages: [1] 2 3  Send TopicPrint
Very Hot Topic (More than 25 Replies) Autosnap diagram nodes if within certain distance? (Read 23246 times)
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Autosnap diagram nodes if within certain distance?
Oct 4th, 2013 at 9:36am
Print Post  
Hi,

Is it possible to, within a Diagram, autosnap nodes if they are within a certain amount of distance (WpfPoint) of each other?

I first want to try snapping them to the bottom of each other. I have a startnode that has a certain height (75) and a set position (Point start = new Point(270, 20)). So the position where I want the next node is Point destination = new Point(x, 95); 75 + 20. But I still want to be able to move the node around. Only if it comes within, let's say 10 WpfPoints, should it snap to that destination point. How can I do this?

Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #1 - Oct 4th, 2013 at 11:20am
Print Post  
Hi,

Set the AutoAlignNodes and AutoAlignDistance properties.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #2 - Oct 4th, 2013 at 2:30pm
Print Post  
That works, thanks!

I have another question:
I'm using the Factory to create a node in the diagram. The method for a ShapeNode requires 4 parameters of which the first 2 are the coordinates to where the node should be placed. I tried to do this dynamically by getting the width and height of the parent element. But when I run it the node doesn't appear. And when I show the width in a MessageBox I get a NaN value. What am I doing wrong?

Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #3 - Oct 4th, 2013 at 3:44pm
Print Post  
What do you mean by parent element? If you set that parent's NaN width as the new node's x position, it won't be seen anywhere indeed Smiley
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #4 - Oct 7th, 2013 at 8:36am
Print Post  
Ah ok. What I want is to place the node based on the width of the diagram. I tried to achieve that by calling the parent property but its width is NaN. Is there another way I can get the width?
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #5 - Oct 7th, 2013 at 9:05am
Print Post  
I think NaN is the default for FrameworkElement's Width and Height in WPF, meaning you don't want fixed size but one automatically calculated by parent panels. You could use the ActualWidth and ActualHeight properties instead, or diagram.Bounds.Width / diagram.Bounds.Height.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #6 - Oct 7th, 2013 at 10:02am
Print Post  
It works!
ActualWidth gives back 0 but the Bounds.Width returns the width that I was searching for.

Thanks Stoyan! Cheesy

Vincent
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #7 - Oct 7th, 2013 at 2:39pm
Print Post  
Hi Stoyan,

I've got another question about aligning nodes. In my current situation, the shapenodes align to each other by the outer border. For example, the rectangle and triangle are aligned by the dotted line as shown in the image below.
How can I make the shapenodes connect to each other based on the shape?



Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #8 - Oct 8th, 2013 at 7:02am
Print Post  
Hi,

There is no built-in support for aligning nodes by their geometries. You will have to implement that yourself, by overriding either UpdateModify in a custom node type, or AlignPointToGrid in a derived Diagram class. For example, this aligns the dragged node's top-middle point to a target node's interior point (X at center, Y at 2/3 height):

Code
Select All
protected override void UpdateModify(Point current, InteractionState ist)
{
	base.UpdateModify(current, ist);
	Align(current, ist);
}

protected override void CompleteModify(Point end, InteractionState ist)
{
	base.CompleteModify(end, ist);
	Align(end, ist);
}

private void Align(Point current, InteractionState ist)
{
	if (ist.AdjustmentHandle == 8 /* move */)
	{
		var nearbyNode = Parent.GetNearestNode(current, 60, this);
		if (nearbyNode != null)
		{
			var r1 = nearbyNode.Bounds;
			var targetPoint = new Point(r1.X + r1.Width / 2, r1.Bottom - r1.Height / 3);

			var r2 = this.Bounds;
			var pointToSnap = new Point(r2.X + r2.Width / 2, r2.Y);

			double dx = targetPoint.X - pointToSnap.X;
			double dy = targetPoint.Y - pointToSnap.Y;

			r2.Offset(dx, dy);
			SetBounds(r2, true, true);
		}
	}
} 



If you use only a few node types, your could keep potential pointToSnap / targetPoint lists for each pair of node types. Otherwise you could loop over points of both nodes' geometries, in sequences of 3, and check whether the current 3 points of the dragged node are at the same offset from the current 3 points of the target node; in such case, use the middle points of the sequences as snap / target points.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #9 - Oct 8th, 2013 at 11:15am
Print Post  
Ahh it works, thanks!
I noticed that it works node to node (makes sense because it scans for the nearest node). Is it also possible to snap the node to one part of the node or the other (based on which is closer)? For example, in the image below I want to be able to snap the yellow node to either the left or right side of the blue node.



Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #10 - Oct 8th, 2013 at 11:32am
Print Post  
It should be possible, you'll need to loop over all potential target points, check their distance to the source snap points, and finally snap between the nearest points:

Code
Select All
Point[] sourcePoints = ...;
Point[] targetPoints = ...;
double minDistance = double.MaxValue;
foreach (var s in sourcePoints)
{
    foreach (var t in targetPoints)
    {
        double d = Utilities.Distance(s, t);
        if (d < minDistance)
        {
            minDistance = d;
            targetPoint = t;
            snapPoint = s;
        }
    }
}

// proceed with alignment from snapPoint to targetPoint
 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #11 - Oct 9th, 2013 at 9:36am
Print Post  
Hi Stoyan,

Thanks!! It works prefectly Smiley

At the moment I'm a bit stuck at modifying the height of the node I'm snapping other nodes to. I assign my own shape to the node with ElementTemplate[] which has LineTemplates. Getting the shape to reform is no problem but I also want to update the Bounds. But doing that enlarges the whole shape. How can I modify only the height of the part where the node aligns like in the image below?



Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #12 - Oct 9th, 2013 at 9:43am
Print Post  
Hi Vincent,

You cannot use LineTemplates in that case, they specify coordinates as percent and can resize only proportionally to the node's dimensions. Instead, you could either draw the shape from a Draw override, or use Shape(CreatePathDelegate) or Shape(formula) constructors.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Vincent
Junior Member
**
Offline


I Love MindFusion!

Posts: 62
Joined: Oct 3rd, 2013
Re: Autosnap diagram nodes if within certain distance?
Reply #13 - Oct 9th, 2013 at 11:02am
Print Post  
Hi Stoyan,

Thanks for the tip Smiley
I've found an example of the Shape(outline) at the following website: http://www.mindfusion.eu/onlinehelp/flowchartnet/C_MindFusion_Diagramming_Shape_...

This is a piece of the example:

Code
Select All
    my = Height / 2;
    ah = Min(10, Height / 4);
    aw = Min(20, Width / 2);
 



What does Min() do?

Thanks in advance!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Autosnap diagram nodes if within certain distance?
Reply #14 - Oct 9th, 2013 at 11:40am
Print Post  
Hi,

The C shape could be defined like that:

Code
Select All
new Shape(@"
	LineTo(Width, 0);
	LineTo(Width, 20);
	LineTo(20, 20);
	LineTo(20, Height - 20);
	LineTo(Width, Height - 20);
	LineTo(Width, Height);
	LineTo(0, Height);
	LineTo(0, 0);
	", "C"); 



Min returns the smaller of its two arguments, as usual Smiley E.g. you might want to apply Min if you are letting users resize the shape, to make sure some elements don't start sticking outside when the node gets small. If you only allow moving these nodes and are setting their size from code, you can safely use fixed values such as the 20 above.

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