Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Beginning with ContainerNode (Read 3420 times)
fanderlf
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 12
Joined: May 5th, 2009
Beginning with ContainerNode
May 5th, 2009 at 2:25pm
Print Post  
Hello everybody,

I'm completely new to this FlowChart component. I'm currently evaluating if it is suitable for our new program.

As the table layout is not flexible enough for what we want to do, I choose to take a ContainerNode and place the shapes in there myself.

The Code I use is:

Code
Select All
ContainerNode con = new ContainerNode(dgCableHarness);
con.Bounds = new RectangleF(10, 10, 50, 50);

DiagramNode node;
node = new ShapeNode(dgCableHarness);
node.Bounds = new RectangleF(0, 1f, 2, 2);
con.Add(node);

node = new ShapeNode(dgCableHarness);
node.Bounds = new RectangleF(0, 3f, 2, 2);
con.Add(node);

node = new ShapeNode(dgCableHarness);



node.Bounds = new RectangleF(0, 5f, 2, 2);
con.Add(node);
con.ZBottom();



con.SubordinateGroup.Visible = true;



diagram.Nodes.Add(con); 



I've got a few question on that:

1. How can I define the position of the ShapeNodes inside the Container? Because if I set the X coordinate to 0 they don't appear on the left edge of the diagram, but a little bit in the middle? And is there any possibility to get them aligned in any way?
What I want to have is something that has inputs and outputs (where i = input/o = output). And I want to connect those inputs/outputs to other Containers having inputs and outputs.

Code
Select All
+-------+   +-------+
| Item1 |   | Item2 |
|-------|   |-------|
| i1 o1 | +-|-i1 o1 |
| i2 o2 | | | i2 o2 |
| i3 o3-|-+ | i3 o3 |
+-------+   +-------+
 



I tried that with one userdrawn shape and anchor points, but then I can't use all the logic behind Nodes and Links.

2. Why do my ShapeNodes disappear if the Container is not selected? If I select the container I see all nodes, if I deselect the Container the Nodes inside the Container disappear.
(View Behaviour is MindFusion.Diagramming.Behavior.LinkShapes)

The User is not allowed to draw Shapes/Containers himself. All DiagramItems are generated in the Code (will be Drag and Drop from something like a toolbox later). The User can only draw Links between Nodes.

I hope someone can point me in the right direction, because I didn't find an example fitting my needs.

Thanks for your help!!!

Greetings,
FanderlF
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Beginning with ContainerNode
Reply #1 - May 5th, 2009 at 2:56pm
Print Post  
Hi,

TableNodes might be more useful in this case. You can create some pretty compex table layouts using the ColumnSpan and RowSpan properties of cells. You can also define anchor points specific to a cell by setting Row.AnchorPattern where AnchorPoints have their Column property defined. Check the Entities example for some sample code showing this.

To align nodes to the left boundary of the diagram, set their position to Diagram.Bounds.Left.

The Z index of items cannot be changed before an item is added to the diagram, so the ZBottom call in your code does not have any effect; you should call Nodes.Add(con) before ZBottom(). You should also add the child ShapeNodes to the diagram.Nodes collection.

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


I love YaBB 1G - SP1!

Posts: 12
Joined: May 5th, 2009
Re: Beginning with ContainerNode
Reply #2 - May 12th, 2009 at 3:58pm
Print Post  
OK Smiley I managed to get the behaviour I want.

One thing I don't understand is:

What is the difference between DestinationAnchor and DestinationIndex?
In my eyes this should always be the same value (as long as the AnchorPattern is defined, which it is always in my case). How does it come that they aren't always the same?

I need this to check if the DestinationAnchor is currently connected. If so I delete the current connection and link it with the new origin.

I would have loved to use the AllowLinksRepeat Property to do that, but that only works on shapes and I assume a TableNode counts as one shape. That was the cause I was trying to use a ContainerNode or something else that just contains shapes and not anchors. I fear that I have to do a lot of stuff manual with anchors which would be integrated already if I would use Shapes.

Maybe I'll try it again by using Grouped Shape Nodes.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Beginning with ContainerNode
Reply #3 - May 12th, 2009 at 6:09pm
Print Post  
Well... there was a time when TableNodes did not have AnchorPattern property, while ShapeNodes had it. Then as now, DestinationIndex would mean an anchor point index if the link's destination is a ShapeNode, or a table row index if the destination is a TableNode. When we moved AnchorPattern to the base DiagramNode class, we had to add the new DestinationAchor property that would identify the anchor point, whatever the destination.

Disabling AllowLinksRepeat would not do what you describe anyway (moving the origin of the existing link), but would just show the stop mouse pointer and prevent dropping the link over that node. Perhaps you could implement that by handling LinkCreated and LinkModified, and changing the existing link Origin if you detect that a connection to the anchor point already exists. The CountLinks method here might help -
http://mindfusion.eu/Forum/YaBB.pl?board=fcnet_disc;action=display;num=124159240...
  
Back to top
 
IP Logged
 
fanderlf
YaBB Newbies
*
Offline


I love YaBB 1G - SP1!

Posts: 12
Joined: May 5th, 2009
Re: Beginning with ContainerNode
Reply #4 - May 13th, 2009 at 8:08am
Print Post  
Ah OK... The Anchor Pattern is defined for every Row in the Table Node. That is where the DestinationIndex is coming from. It defines the Index of the Row in the TableNode. And together with DestinationAnchor I can find the AnchorPoint like:
((TableNode)link.Destination).Rows[e.Link.DestinationIndex].AnchorPattern.Points[e.Link.DestinationAnchor]

I do the check like this at the moment (in linkmodified I use the same code):

Code
Select All
private void dgCableHarness_LinkCreated(object sender, LinkEventArgs e)
{
  if (e.Link != null)
  {
    if (e.Link.Origin == null)
      return;

    if (e.Link.Destination == null)
      return;

    foreach (DiagramLink link in e.Link.Destination.IncomingLinks)
    {
      if (link != e.Link)
        if (link.DestinationIndex == e.Link.DestinationIndex &&
          link.DestinationAnchor == e.Link.DestinationAnchor)
            dgCableHarness.Links.Remove(link);
    }
  }
} 



The Problem now is that e.Link.Destination.IncomingLinks has now links in its Collection though there are some Sad

If I do this:

Code
Select All
private void dgCableHarness_LinkCreated(object sender, LinkEventArgs e)
{
  if (e.Link != null)
  {
    if (e.Link.Origin == null)
      return;

    if (e.Link.Destination == null)
      return;

    foreach (DiagramLink link in e.Link.Destination.GetAllLinks())
    {
      if(link.Destination == e.Link.Destination)
        if (link != e.Link)
          if (link.DestinationIndex == e.Link.DestinationIndex &&
            link.DestinationAnchor == e.Link.DestinationAnchor)
              dgCableHarness.Links.Remove(link);
    }
  }
} 



Everything works as intended, but why doesn't the first one work?

Just additional:
I added the following Loop to the LinkCreated EventHandler to prevent two links from starting from the same anchor:

Code
Select All
foreach (DiagramLink link in e.Link.Origin.GetAllLinks())
{
  if (link.Origin == e.Link.Origin)
    if (link != e.Link)
      (link.OriginIndex == e.Link.OriginIndex &&
        link.OriginAnchor == e.Link.OriginAnchor)
          dgCableHarness.Links.Remove(link);
} 



Another question I have is:

If I create a Link all this stuff works fine, but if I move the starting Point of a Link I can place it anywhere on the TableNode and it doesn't snap to the anchors.
If I drop it outside a Node it is reset to the original Position (desired behaviour).
AllowUnanchoredLinks is false and AllowUnconnectedLinks is false, too.

Edit: e.Link.ReassignAnchorPoints(); solved the problem
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Beginning with ContainerNode
Reply #5 - May 13th, 2009 at 9:56am
Print Post  
The control makes a difference between links connected to a row, and links connected to the whole node. The former are contained in the IncomingLinks collection of the respective TableNode.Row object; the latter in the TableNode's collection. GetAllLinks() returns all of them, regardless whether connected to a row or the table.

You might set the SnapToAnchor property to CreateOrModify.

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


I love YaBB 1G - SP1!

Posts: 12
Joined: May 5th, 2009
Re: Beginning with ContainerNode
Reply #6 - May 14th, 2009 at 12:49pm
Print Post  
Just me again Cheesy

Why does that work:

Code
Select All
DiagramLink link = Diagram.Factory.CreateDiagramLink(startIdentifier.TableNode, startIdentifier.Anchor, endIdentifier.TableNode, endIdentifier.Anchor);

link.OriginIndex = startIdentifier.Index;
link.DestinationIndex = endIdentifier.Index;

Diagram.Links.Add(link); 



While that does not:

Code
Select All
DiagramLink link = new DiagramLink(Diagram);
link.Origin = startIdentifier.TableNode;
link.OriginIndex = startIdentifier.Index;
link.OriginAnchor = startIdentifier.Anchor;


link.Destination = endIdentifier.TableNode;
link.DestinationIndex = endIdentifier.Index;
link.DestinationAnchor = endIdentifier.Anchor;

Diagram.Links.Add(link); 



In the second example I get a NullReferenceException when trying to set link.DestinationIndex/link.OriginIndex

If I understood everything right the Node identifies the Node the link is connected to. The Index represents the row the link should connect to. And the Anchor is the Index of the AnchorPoint in this row.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Beginning with ContainerNode
Reply #7 - May 14th, 2009 at 1:46pm
Print Post  
These setters might expect that both the Origin and Destination have been set, so that they update the links end points. What happens if you use the DiagramLink(parent, origin, destination) constructor, or set both Origin and Destination before setting the indices?

You should not call Links.Add or Nodes.Add when using the Factory methods as in the first sample. CreateDiagramLink automatically adds the link to Diagram.Links, and Links.Add() will add it for a second time.

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