Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) DiagramView coordinates (Read 7905 times)
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
DiagramView coordinates
Aug 27th, 2010 at 1:01pm
Print Post  
Hi,

Is there a way to use the coordinates of the objects used on a DiagramView in pixels, having the top-left corner as 0,0?

So even if a diagram goes beyond the visible area, the coordinates just keep counting up (not bound to the visible area, and regardless of the position on screen).

I am reading a workflow graph from a different application which used basic X,Y coordinates like this, but I am having a hard time converting that to the DiagramView.

Thanks,
Bas

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramView coordinates
Reply #1 - Aug 27th, 2010 at 2:31pm
Print Post  
Hi,

Do you mean you need the objects' coordinates to change dynamically based on the DiagramView scroll position? That's not supported.

You can use the ClientToDoc and DocToClient methods of DiagramView to convert between pixels and diagram coordinates. E.g. ClientToDoc(new Point(0,0)) will return the diagram point that's currently at the view's top-left corner.

Stoyan
  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #2 - Aug 28th, 2010 at 9:29am
Print Post  
Thanks for the quick reply.

If I do the following:

Code
Select All
PointF Coords = DiagramView.ClientToDoc(new Point(0, 0));
SizeF Size = new SizeF(20, 15);

Diagram.Items.Add(Diagram.Factory.CreateShapeNode(Coords, Size));
 



The shapenode is always drawn at 0,0 relative of the visible area. What I am trying to do, is that if 0,0 is outside the visible area, the shapenode would still be drawn at the absolute 0,0 of the diagram.


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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramView coordinates
Reply #3 - Aug 29th, 2010 at 9:15am
Print Post  
If you want a specific node to follow the scroll position, so that it's always at the top-left of the view, you can update node.Bounds in response to the ScrollChanged event. If that's not what you need, please email to support@mindfusion.eu some drawing that shows your requirements.

Stoyan
  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #4 - Aug 29th, 2010 at 10:46am
Print Post  
I dont think I got the message across Wink

Ill just try to explain using some screenshots, perhaps this will help someone else in the future.

Ok, now I took some sample code from another topic of the forum:

Code
Select All
  private void DiagramView_DragDrop(object sender, DragEventArgs e)

  {


// compute the correct xy coordinates for the new shape


Point ClientPoint = DiagramView.PointToClient(new Point(e.X, e.Y));


PointF DiagramPoint = DiagramView.ClientToDoc(ClientPoint);

 



My first issue:

In this case if I drop an object at the top left corner, the actual coordinates of the DiagramPoint.X and DiagramPoint.Y are -186,-68 and not 0,0.

If you take a look at the second screenshot (the workflow of the external application I try to load) the diagram at the topleft is 0,0.

So I would like to have the same diagram coords as the source diagram. Being: topleft coords at 0,0.

I also notice that the DiagramPoint.X and .Y values change depending on the actual position on the screen. So they are different if the window is maximized for example.

I am looking for an absolute 0,0 at the topleft corner.


My second issue:

If I scroll the diagram all the way to the right, and create a new ShapeNode at, lets say, 10,10, the node appears immediately in the current viewable area, and not all the way on the left.


Screenshots:

Mindfusion diagramming


Source diagram (external application)


As you can see in the image above, there is one node outside of the visible area. It is at X 1172. And the value of X is that number regardless of the node being inside of the visible area or not.

I hope this makes sense now.

Thanks,
Bas
« Last Edit: Aug 29th, 2010 at 12:32pm by Bass »  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramView coordinates
Reply #5 - Aug 29th, 2010 at 5:52pm
Print Post  
Hi,

There are two problems from what I understand.

First the diagram origin is set to negative coordinates, and that's legal as far as the control is concerned. The Diagram.Bounds property lets you define a coordinate system that starts at a position different than (0,0). Even if you haven't set it explicitly, it might change if AutoResize is set to AllDirections, or if you call ResizeToFitItems. If it's the former, change the property value to RightAndBottom. If it's the latter, restore the Top and Left values of Bounds to 0,0 after calling the resize method.

The second issue where the coordinates depend on the window position could happen if you don't pass screen coordinates to the PointToClient method, or if you call PointToClient on a different control rather than the DiagramView. Could you verify if you are consistently getting a value close to 0,0 for ClientPoint when the window is at different positions and the mouse is at the top-left corner?

Stoyan
  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #6 - Aug 30th, 2010 at 6:46am
Print Post  
Just came in the office and checked your suggestions.

Regarding the first issue; I checked the AutoResize property and it is set to the default value of "RightAndDown". Diagram.Bounds and its X and Y properties are set to 0,0.

I dont make a call to ResizeFitToItems, or any other resizing/fitting/zooming methods.


Regarding issue number two:

To show how it behaves, I used the DiagramView.MouseMove event to put the EventArgs.X and .Y properties on screen:

Code
Select All
private void DiagramView_MouseMove(object sender, MouseEventArgs e)
{
Point ClientPoint = DiagramView.PointToClient(new Point(e.X, e.Y));
PointF DiagramPoint = DiagramView.ClientToDoc(ClientPoint);

textBox1.Text = DiagramPoint.X.ToString();
textBox2.Text = DiagramPoint.Y.ToString();
}
 





By just changing the window from maximized to a smaller width and height I get totally different coordinates for the same location in the diagram:



My only guess at this point is that the event handler is somehow incorrect?

  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #7 - Aug 30th, 2010 at 7:35am
Print Post  
Just FYI, If I create a totally new Windows Forms application, just drop the Diagram, and DiagramView components, and write the same event handler as my previous post, I get the exact same results.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramView coordinates
Reply #8 - Aug 30th, 2010 at 9:01am
Print Post  
The coordinates received by MouseMove are local for the control, so you don't have to convert them using the PointToClient method. PointToClient is useful in drag-and-drop events, which receive screen coordinates as arguments. So from the MouseMove handler you should only call ClientToDoc(MouseEventArgs.Location) to get the diagram coordinates of the mouse position.
  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #9 - Aug 30th, 2010 at 1:41pm
Print Post  
Yeah I also just figured that out Grin

Just by doing a
Code
Select All
ShapeNode Activity = new ShapeNode(DiagramView.Diagram);
Activity.Bounds = new RectangleF(Node.Style.X, Node.Style.Y, Node.Style.Width, Node.Style.Height);
 



Works quite well (Node being an internal object to store custom properties). Thats what you get for copy/pasting a method.. Undecided

One more question: when a link is created to connect two ShapeNodes together, how can you influence the way ControlPoints are created in that link?

For example, I create a link by calling CreateDiagramLink. This gives me already 6 ControlPoints in that link. I am only interested to have the first one and last one in that collection (the one connected to the handles on the source and target ShapeNodes).

I am now removing the unwanted ControlPoints manually, but is there a better way?


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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramView coordinates
Reply #10 - Aug 30th, 2010 at 1:56pm
Print Post  
Nice 8)

Set Diagram.LinkSegments = 1 and Diagram.RouteLinks = false and all links will have a single line segment between the two end points. You can enable these features only for specific links via the AutoRoute and SegmentCount properties of DiagramLink.

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



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #11 - Aug 30th, 2010 at 5:58pm
Print Post  
Diagram.LinkSegments was already on 1, but I set Diagram.RouteLinks back to False.

However, doing that deletes actual segments of the link, rather than only removing the control points. So my links look quite chopped up with parts of them missing.

Code
Select All
DiagramLink Edge = DiagramView.Diagram.Factory.CreateDiagramLink(GetShapeByNodeId(SourceNode), SourceHandle, GetShapeByNodeId(DestinationNode), DestinationHandle);

// keep only first and last control point
DiagramLink Edge = DiagramView.Diagram.Factory.CreateDiagramLink(GetShapeByNodeId(SourceNode), SourceHandle, GetShapeByNodeId(DestinationNode), DestinationHandle);

// keep only first and last control point
Edge.AutoRoute = false;

while (Edge.ControlPoints.Count > 2)
{
Edge.ControlPoints.RemoveAt(1);
Edge.UpdateFromPoints();
}

Edge.SegmentCount = 1;
 



Which works (resulting in chopped Links), as long AutoRoute is false. To get everything connected again I set AutoRoute back to true. If set to true, it starts throwing this exception:

Code
Select All
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
   at System.Collections.CollectionBase.System.Collections.IList.get_Item(Int32 index)
   at MindFusion.Diagramming.PointCollection.get_Item(Int32 index)
   at MindFusion.Diagramming.DiagramLink.xd4b19570e431d503()
   at MindFusion.Diagramming.DiagramLink.xa6ae8efa17e3530e(IGraphics x41347a961b838962, Pen x9c79b5ad7b769b12, Brush xe7ebe10fa44d8d49, Pen xfe39089439ac4f68, Boolean x2f9dabff87b2168b, Boolean x86c500fe5a9b7707)
   at MindFusion.Diagramming.DiagramLink.DrawShadow(IGraphics graphics, RenderOptions options)
   at MindFusion.Diagramming.Diagram.x826b585edd6a93e2(IGraphics x41347a961b838962, RectangleF xa6236fc5cd405c4e, Boolean x979174172ae18db3)
   at MindFusion.Diagramming.Diagram.Draw(IGraphics graphics, RenderOptions options, RectangleF clipRect, Boolean noModifiedItems)
   at MindFusion.Diagramming.WinForms.DiagramView.x45babdc9db40342f(IGraphics x41347a961b838962, RectangleF xd1cff1e8f8666dbe, Boolean x8de543c74cdd4f6e)
   at MindFusion.Diagramming.WinForms.DiagramView.OnPaint(PaintEventArgs pe)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 



How can I reconnect the two control points?

All I want is to keep the first and last control points, add some of my own in between and have all points connected.
  
Back to top
 
IP Logged
 
Bass
YaBB Newbies
*
Offline



Posts: 31
Joined: Aug 27th, 2010
Re: DiagramView coordinates
Reply #12 - Aug 30th, 2010 at 7:12pm
Print Post  
I noticed that increasing DiagramLink.SegmentCount also creates control points in the DiagramLink.ControlPoints collection.

So instead of creating control points by manipulating the collection, I change SegmentCount and just change the X and Y properties of the created control points:

Code
Select All
DiagramLink Edge = new DiagramLink(DiagramView.Diagram, GetShapeByNodeId(SourceNode),  GetShapeByNodeId(DestinationNode));

Edge.OriginAnchor = SourceHandle;
Edge.DestinationAnchor = DestinationHandle;

Edge.SegmentCount = Convert.ToInt16(EdgePoints.Count - 1);

// add control points as defined in the workflow diagram
for (int n = 0; n < EdgePoints.Count; n++)
{
if ((n > 0) & (n < EdgePoints.Count - 1))
{
PointF Point = new PointF(EdgePoints[n].X, EdgePoints[n].Y);
Edge.ControlPoints.SetAt(n, Point);

Edge.UpdateFromPoints();
}
}

DiagramView.Diagram.Links.Add(Edge);
 



Works perfectly! This solved my last issue.

Thanks for your help and patience Stoyo.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint