Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram? (Read 1810 times)
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Mar 24th, 2023 at 2:49pm
Print Post  
Hi!

I'm working on a VirtualizingDiagram, where data items that are displayed as nodes/links are assigned to the NodesSource and LinksSource properties. The one parent container contains all other diagram elements. I'm trying to use OrthogonalRouter after manually positioning the nodes in the container just like in this question. For Diagram, I could use the second parameter of type DiagramItemCollection for OrthogonalRouter.Arrange() as it was said there. But the only option for VirtualizingDiagram is:

Code
Select All
Arrange(VirtualizingDiagram diagram); 



Can you please advise how to make OrthogonalRouter work to arrange links inside the container node in this case?

Thanks,
Kostya
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #1 - Mar 27th, 2023 at 10:20am
Print Post  
Hi Kostya,

Unfortunately OrthogonalRouter won't work even with the full diagram Arrange overload. The control does not store control point positions for virtual links at this time, but expect LinkRealized event handler to set them.

Our developer has added Arrange(virtual_diag, items) overload here anyway, but it will help only for layout classes that set straight links -
https://mindfusion.eu/_beta/wpfdiag391.zip

We'll have in mind extending virtual links for next larger release. Until then, you could try working around like this:

- copy container and its child items to a hidden diagram
- call containerCopy.Arrange there
- copy link points back to your data objects
- assign them to ControlPoints in LinkRealized handler.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #2 - Mar 27th, 2023 at 12:46pm
Print Post  
Hi Slavcho,

Thank you for your reply and the suggested workaround! I will try to do it.

Could you please tell me what's the ETA for this next larger release, when would such an improvement be expected?

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


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #3 - Mar 28th, 2023 at 3:27pm
Print Post  
Hi Kostya,

We should be releasing version 4 of the diagram at some point in autumn, with virtualization improvements included.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #4 - Mar 29th, 2023 at 9:02am
Print Post  
Hi Slavcho,

Thanks, got it.

Let me also ask you to clarify the workaround steps you described?

Quote:
1) copy container and its child items to a hidden diagram
2) call containerCopy.Arrange there
3) copy link points back to your data objects
4) assign them to ControlPoints in LinkRealized handler.


#1 How to make a correct copy of the container and its child items into a temporary, hidden diagram? That is, in fact, create a Diagram based on the existing VirtualizingDiagram.

#4 The VirtualizingDiagram.LinkRealized Event
Quote:
Raised when an actual DiagramLink instance is created to represent a data item from LinksSource.


Does this mean that when adding a new link, it will be necessary to do all these steps to get updated ControlPoints (after Arrange()) and then assign them in the LinkRealized event raised?

Thanks,
Kostya
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #5 - Mar 29th, 2023 at 7:41pm
Print Post  
Hi Kostya,

Here's some helper methods to make copying between diagrams easier -

https://mindfusion.eu/_temp/wpfdiag_copy.zip

Code
Select All
var containerRect = ...;
diagram.RealizeItems(containerRect);

var copyItems = new DiagramItemCollection();
foreach (var item in diagram.Items)
	if (containerRect.IntersectsWith(item.GetBounds()))
		copyItems.Add(item);

var tempDiagram = new Diagram();
tempDiagram.PasteSelection(
	diagram.CopySelection(copyItems, false, true),
	null, new Vector(0, 0));

foreach (var item in tempDiagram.Items)
{
	var container = item as ContainerNode;
	if (container != null &&
		containerRect.IntersectsWith(item.GetBounds()))
	{
		container.Arrange(...);
	}
} 



Quote:
Does this mean that when adding a new link, it will be necessary to do all these steps to get updated ControlPoints (after Arrange()) and then assign them in the LinkRealized event raised?


If you mean link just drawn by user, it will already have the actual DiagramLink object created in current viewport. You could route it or call arrange, but it will indeed lose points if scrolled out of viewport and back again, unless you restore points from LinkRealized.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #6 - Mar 31st, 2023 at 9:40am
Print Post  
Hi Slavcho,

Thanks for the code! I see that in the new set of attached assemblies the addition that you described earlier is missing, namely

Code
Select All
Arrange(virtual_diag, items) overload 



Is it supposed to update the location of the diagram nodes by analogy with links, restoring it in the NodeRealized handler from previously saved data?

Also, the problem now is that in some cases the container loses its child nodes. For example:

  1. On the first RealizeItems(containerRect) call.
  2. When resizing the application window.


I have noticed that this happens when BindingMode="TwoWay" is set for the diagram, which is required. That is, the container.Arrange() code works once, and when the container loses its child nodes for some reason, it no longer works. Is this behavior expected and can it be fixed?

Quote:
If you mean link just drawn by user, it will already have the actual DiagramLink object created in current viewport. You could route it or call arrange, but it will indeed lose points if scrolled out of viewport and back again, unless you restore points from LinkRealized.

Understood.

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


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #7 - Apr 3rd, 2023 at 7:20am
Print Post  
Hi Kostya,

Quote:
I see that in the new set of attached assemblies the addition that you described earlier is missing


It's defined in base class and I can see this in VS source browser in Layout (from metadata) tab when referencing those assemblies -

Code
Select All
public virtual bool Arrange(VirtualizingDiagram diagram, IEnumerable<object> items);
public virtual bool Arrange(VirtualizingDiagram diagram);
public virtual bool Arrange(Diagram diagram, DiagramItemCollection items);
public virtual bool Arrange(Diagram diagram); 



but it won't be doing anything useful with OrthogonalRouter specifically until our developers add some support for virtual link points.

That overload at least arranges virtual nodes too, so you should be able to directly apply it with classes that set straight links (e.g. SpringLayout). For layouts that set more than one link segment, you will still have to copy the points through a temporary actual diagram as in code above.

Quote:
Also, the problem now is that in some cases the container loses its child nodes


Our developer will check. You could try ensuring child nodes are placed inside container from NodeRealized event too.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #8 - Apr 3rd, 2023 at 10:46am
Print Post  
Hi Slavcho,

Sorry, I actually meant ContainerNode.Arrange() for VirtualizingDiagram. I arrange the elements of the temporary/hidden diagram container, as you wrote, to restore the link points after that. But I also have to arrange the nodes of the visible VirtualizingDiagram control by calling Arrange() on the container only, not on the entire diagram. This just doesn't work (because of the layout type? I tried different types though.)

Code
Select All
containerNode.Arrange(layout); 



And if it's done like that, the arrangement occurs. But even when specifying a set of elements as a second parameter, it causes the nodes to lose their container, hmm.

Code
Select All
layout.Arrange(this, GetNonContainerItems()); 



Am I arranging the elements of the VirtualizingDiagram container somehow incorrectly, have I missed something? Although, for normal Diagram it works.

Quote:
Our developer will check. You could try ensuring child nodes are placed inside container from NodeRealized event too.


Thanks, but maybe it's something obvious that's actually happening on Arrange(), as I wrote above.

Thanks,
Kostya

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


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #9 - Apr 4th, 2023 at 4:33pm
Print Post  
Hi Kostya,

Quote:
containerNode.Arrange(layout);


Do you mean calling this on an already realized ContainerNode you know is currently visible? If calling Arrange from NodeRalized event, are you sure the child data items have their actual nodes created too?  Maybe best attach a test project showing the problem.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #10 - Apr 4th, 2023 at 8:35pm
Print Post  
Hi Slavcho,

To be honest, I doubt I'm doing it right at all. I would appreciate it if you could take a look at the test project, thanks! So, I created it based on one of the VirtualizingDiagram usage examples (Virtualization_ArrangeContainer_20230404.rar, attached).

The code is in the DoArrange() method of the VirtualizingDiagramEx control. If I understood it correctly, right after
Code
Select All
container.Arrange(layout); 


I'm iterating over the diagram links and copying the hidden diagram link's ControlPoints into the property of the data object (I assign them to the links ControlPoints in the LinkRealized handler).

The problem is that I also have to arrange the nodes. My guess is that it should be
Code
Select All
layout.Arrange(this, GetNonContainerItems()); 


to exclude the container. Or Arrange the container items, like container.Arrange(). All this leads to the fact that the container loses its nodes.

The attached image (arrange_container.png) shows what I'm trying to get. So that links don't overlap nodes. And of course, it's desirable that this happens not by clicking a button, as in the example, but when loading data, adding a new node, etc. Obviously, it's not what I get.

Thanks,
Kostya
  

arrange_container.png ( 5 KB | 42 Downloads )
arrange_container.png
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Offline


tech.support

Posts: 3154
Joined: Oct 19th, 2005
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #11 - Apr 6th, 2023 at 7:23am
Print Post  
Hi Kostya,

Try also copying nodes' layout coordinates to realized nodes and their data items for time being -

Code
Select All
container.Arrange(layout);
container.UpdateBounds(true); // make space for the right link too

...

for (int i = 0; i < copyItems.Count; i++)
{
	var link = copyItems[i] as DiagramLink;
	if (link != null)
	{
		var tempLink = (DiagramLink)tempDiagram.Items[i];
		var linkData = (LinkData)link.DataContext;
		linkData.ControlPoints = tempLink.ControlPoints;
		link.ControlPoints.Clear();
		link.ControlPoints.AddRange(tempLink.ControlPoints);
		link.UpdateFromPoints();
	}
	var node = copyItems[i] as DiagramNode;
	if (node != null)
	{
		var tempNode = (DiagramNode)tempDiagram.Items[i];
		var nodeData = (NodeData)node.DataContext;
		nodeData.Width = tempNode.Bounds.Width;
		nodeData.Height = tempNode.Bounds.Height;
		nodeData.X = tempNode.Bounds.X;
		nodeData.Y = tempNode.Bounds.Y;
		node.SetBounds(tempNode.Bounds, false, false);
	}
}

public class NodeData : INotifyPropertyChanged
{
...
	private double width;
	public double Width
	{
		get { return width; }
		set
		{
			if (width != value)
			{
				width = value;
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Width"));
			}
		}
	}

	private double height;
	public double Height
	{
		get { return height; }
		set
		{
			if (height != value)
			{
				height = value;
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Height"));
			}
		}
	}
... 



We plan overhauling the virtualizing diagram for v4 (like bringing virtualization into base Diagram and leaving current VrtDiag API only for data-binding purposes), so our developers don't want to invest much time in layout details right now...

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
Kostya
Junior Member
**
Offline


I Love MindFusion!

Posts: 59
Joined: Aug 5th, 2014
Re: How to make OrthogonalRouter work in case of using ContainerNode in VirtualizingDiagram?
Reply #12 - Apr 6th, 2023 at 4:59pm
Print Post  
Hi Slavcho,

Thank you very much! This helped a lot and now I'm applying this to my main project. If I understood your words correctly, then the best thing would be to wait for the release of a new version so that all these things work without workarounds.

Thanks again
Kostya
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint