Creating a new DiagramLayout class

Hi,

I have been trying to create a new Layout class, derived from DiagramLayout . The only override I have it for the DoLayout() method. I’m calling the base.DoLayout() first.

My problem is that it only seems to be effective on loaded diagrams (ie, from a model.Load()), not when adding Nodes. I’m using the “InitialOnly” Condition. Nodes and Links creation is done through a button event, and I do use Start/Commit, after which I call LayoutDiagram() (because it’s the only other time I want to do the layout).

What really puzzles me is that the DoLayout() method is called, it seems to be properly modifying Locations, but these modifications to the nodes and links locations are not displayed on-screen. If I save the resulting diagram, locations will be “0 0”. In fact, if I do check these locations in the LayoutCompleted event, Locations are indeed “0 0”.

It looks as if some method overrides/reverts modifications I’ve just done.

What am I missing?

B.

So you are saying that your DoLayout method is being called, you are assigning Locations to all of the Nodes, and yet the value of Node.Location remains at 0,0?

Are you two-way binding the Node.Location attached property in your node DataTemplate to a property on your data?

[QUOTE=walter]So you are saying that your DoLayout method is being called, you are assigning Locations to all of the Nodes, and yet the value of Node.Location remains at 0,0?

Are you two-way binding the Node.Location attached property in your node DataTemplate to a property on your data?
[/quote]

Indeed, since I want to be able to load/save these locations.

And I do see the Data.Location values being updated to the values of Node.Location, in DoLayout, so I assume that’s all working well.

I’m not following you. Are you saying that layout appears to work correctly with the nodes created originally by …Model.Load, but not for those nodes that you have added in that button event?

And your custom DoLayout method is correctly assigning non-origin locations for all of the new nodes?

Do those new nodes show up at 0,0 even though in the debugger you can see that the Node.Location is somewhere else, and even though in the debugger you can see that your new node data has that (not-origin) location? That’s very odd.

[QUOTE=walter]I’m not following you. Are you saying that layout appears to work correctly with the nodes created originally by …Model.Load, but not for those nodes that you have added in that button event?

And your custom DoLayout method is correctly assigning non-origin locations for all of the new nodes?

Do those new nodes show up at 0,0 even though in the debugger you can see that the Node.Location is somewhere else, and even though in the debugger you can see that your new node data has that (not-origin) location? That’s very odd.
[/quote]

Yes. That’s what I’m saying. The layout is working correctly when the nodes are created by Model.Load, but not when the nodes are created from a button event (and manually calling LayoutDiagram).

While in DoLayout, I change the Node.Location, and I can see (from the debugger) that the NodeData.Location gets instantly updated accordingly, to a non-origin location.

I did some more tries, and I got it working as I wish by not calling the base DoLayout method. I’m not sure about this though, is this supposed to do something besides assigning proper Locations? I’m thinking about the Conditions handling, in particular…

If you’re assigning the Position or Location of all the nodes that you want, then there’s no need to call the base method.

That base method, DiagramLayout.DoLayout, is pretty simple. I tried changing the implementation of our layouts to call base.DoLayout() first, just to see if there was any change in behavior. There wasn’t.

But that’s in version 1.1 beta. Which version are you using?

I’m also using 1.1. (WPF, assembly 1.1.0.3)

But I did notice some changes in behavior:

  • the Condition is not considered if the base method is skipped. (ie, I’m using InitialOnly, but the DoLayout is called on every event, not just on Model.Load)

  • ValidLayout is always false following manual DoLayout call (when base method not called)

DoLayout is supposed to set ValidLayout to true if it thinks it’s done. (See the documentation for IDiagramLayout.DoLayout.)

I’ll investigate any issues with DiagramLayout.Conditions.

I don’t think there is anything to investigate… Once I added the ValidLayout=true when done in DoLayout, it all started to work fine…

Thanks for the help!

B.

Ah, good, because I did start investigating, and I was coming to the same conclusion – that it was working correctly.

I’ve improved the documentation for DoLayout.

We have changed the implementation of the LayoutManager in version 1.1 to always set ValidLayout = true after calling DoLayout.