Custom Tree Layout

I’m not sure how to approach this, so bear with me, please.

I’m trying to achieve a ‘dynamic’ tree layout that does not interfere with the user experience and lays out the nodes ‘locally’ without disrupting the entire tree. It’s still a tree layout, but with the ability to selectively layout individual nodes (and their children), pushing any nodes in the ‘neighborhood’ either down or to the right to make room for the new layout.

So, if the tree goes from left to right and there are existing nodes already in place, and the user repositions a node and its children into the middle of the tree, then invokes a context menu command to layout that node, the custom tree layout should push the surrounding nodes down just enough to make room for the newly laid out node and its children, leaving the other nodes where they are.

BEFORE: User is constructing the node by dragging and linking nodes to the ‘Files’ node…

AFTER: User drags the ‘Files’ node between the ‘Table’ and ‘Spreadsheet’ nodes and then invokes a custom ‘Layout’ command on the ‘Files’ node. The tree layout algorithm performs the localized tree layout (horizontal or vertical) and then pushes the ‘Spreadsheet’ node (and its children) down to make room.

Ideally, I’d like to have the sort of behavior that the Subgraph nodes provide when dragging nodes around inside them. The borders automatically adjust as the subnodes are being dragged.

Well, it seems to me that there are two separate issues:
(1) You intend for the user moving a node vertically to change the order of the node’s tree parent’s children.
(2) When a layout occurs, you do not want to move some nodes; but the circumstances aren’t clear to me.

I think (1) is easy to implement: define a custom TreeLayout.Comparer that sorts children based on the TreeVertex.Node.Bounds.Y position. (Don’t forget to set TreeLayout.Sorting.) If you also include the LayoutChange.NodeLocationChanged flag in the TreeLayout.Conditions property, the tree layout will occur continuously while the user is dragging. (I assume you have already set DraggingTool.Inclusions=“SubTree”.)

I don’t understand (2) well enough to guess what you might want.

OOPS: I thought this was a GoXam question. I’m sorry that this answer does not apply to GoDiagram.

Addendum (for clarification):

Let’s say there are already some nodes in the diagram and that a previous layout has been performed, so they are neatly arranged as a tree.

Then the user starts dragging more nodes from a palette into the middle of the diagram without performing a layout. They continue adding more nodes and linking them together in a random pattern in the middle of the diagram whereever there happens to be space. After a while the diagram becomes cluttered by the new nodes, so the user wants to ‘clean up’ the diagram, but does not want to rearrange the existing nodes because they are positioned correctly, and are ready for printing.

Using a context menu item, the user selects the first new node (the parent of the new set of nodes) and chooses a custom “layout subtree” command. This should arrange the children of the selected node as a tree (either left-to-right or top-to-bottom) without affecting any of the other nodes, except to make room for the new subtree.

Laying out a subtree is a matter of performing a GoLayoutTree with .Arrangement = GoLayoutTreeArrangement.FixedRoots on the nodes and links that are in the subtree. I don’t remember if there are any examples of this in the kit.

Are you saying that you want to change the order of the children of a node based on the current Y position of the child node? You can achieve that by setting the GoLayoutTree.Comparer property. However, it won’t be useful unless the parent and all of its children are actually laid out, which you do not seem to want to do.

I don’t understand how you want the nodes below the newly laid-out subtree to be moved. Do you just want to move them down by the amount needed to fit in the new subtree? If so, that’s easy to do after the subtree has been laid out and positioned where you want it.