Strange Behavior with SubGraphs

Hi,

I’m experiencing strange behavior from SubGraph that I cannot track down. I was hoping you might have some guidance for me.

When I drag a node (GoBoxNode in this example) out of a SubGraph using the key and dragging, the position and/or border of the subgraph changes, depending on where I drop the node on the GoView. Two possible behaviors occur:

  1. If the last node is being dragged out of the SubGraph and I drop the node to the left of the top-left corner (position) of the SubGraph, the empty SubGraph jumps to the node’s new position on the GoView.

  2. If a node other than the last node is dragged out, the SubGraph’s border is redrawn (stretched) to include the node’s new position on the GoView.

I can’t seem to identify how the SubGraph’s position and/or border is being modified. I’ve overriden every method I can think of (that makes sense to me to override in this instance) but no luck.

Do you know what might be causing this problem? If so, how would I fix it.

Thanks a lot.

R. Houston

Can you reproduce it with an unmodified version of SubGraphApp?

Hi Jake,

Yes, I can reproduce behavior #1 - dragging the last node out of the subgraph causes the empty subgraph to warp to a new position - in the unmodified SubGraphApp. Steps to recreate:

  1. Launch SubGraphApp and rubberband select all of the nodes and links shown when app launches.
  2. Click button to make a new custom subgraph.
  3. Move the subgraph with its nodes and links to the far right hand side of the goview.
  4. Rubberband select all nodes and links inside subgraph.
  5. Shift drag them to the far left hand side of the goview and release mouse.

When the mouse button is released the nodes and links are dropped and the empty subgraph warps to the position of the drop.

I’m thinking that the SubGraph still considers the dragged out nodes (and links) to still be its children and the subgraph is trying to recompute its new border/bounds based on this. It seems to me that something in the reparenting process (perhaps the call to the AddCollection method iinside DoDragging?) is responsible for this behavior but I’m just not sure. I can’t figure it out.

Do you have any ideas?

Thanks a lot.

R. Houston

That appears to be a “misfeature” of the implementation of that sample’s SubGraphDraggingTool.DoDragging. You need to move the calls to base.DoDragging to be just before the return statements – after the calls to AddCollection.

Basically, the base.DoDragging implementation actually completes the move, causing the nodes to be moved within the subgraph. When there’s only one child node in a subgraph, the whole subgraph just goes whereever that one node goes. Then when that node is reparented, either to another subgraph or to be a top-level object, the subgraph is emptied but remains where it is.

By actually doing the move after reparenting the selected node(s), the original parent subgraph will only be resized due to its emptiness.

public override void DoDragging(GoInputState evttype) { if (this.CurrentObject == null) return; if (MustBeMoving() && this.Selection.Primary != null) { this.View.DragsRealtime = false; GoSubGraph sg = FindSubGraph(this.LastInput.DocPoint, this.Selection.Primary); if (sg != null) { // adding to a subgraph? if (evttype == GoInputState.Continue) { if (myTargetSubGraph != sg && this.Selection.Primary.Parent != sg) { UnhighlightSubGraph(); myTargetSubGraph = sg; HighlightSubGraph(Color.Red); } } else if (evttype == GoInputState.Finish) { if (this.Selection.Primary.Parent != sg) { // collapsed? gotta expand first bool expandfirst = !sg.IsExpanded; if (expandfirst) sg.Expand(); // reparent to that subgraph sg.AddCollection(this.EffectiveSelection, true); this.View.Selection.Clear(); this.View.Selection.AddRange(this.EffectiveSelection); if (expandfirst) sg.Collapse(); base.DoDragging(evttype); return; // DoDragging already done } } } else { // adding at top-level UnhighlightSubGraph(); // no dynamic feedback, while evttype == GoInputState.Continue if (evttype == GoInputState.Finish) { // reparent to top-level, the default layer this.View.Document.Layers.Default.AddCollection(this.EffectiveSelection, true); this.View.Selection.Clear(); this.View.Selection.AddRange(this.EffectiveSelection); } base.DoDragging(evttype); return; // DoDragging already done } } else { this.View.DragsRealtime = myOriginalDragsRealtime; UnhighlightSubGraph(); } base.DoDragging(evttype); }

Thank you Walter,

Once the change is made I now have the opposite problem: the SubGraph resizes itself when items are dragged into the SubGraph.

Depending on where an item is on the screen when dragged into the SubGraph the SubGraph may resize quite substantially, using a lot of screen real estate in order to encompass the node dragged in. The items must be moved inside the subgraph in order to correct this problem. You can see this behavior in the SubGraphApp with the changed base.dodragging. Is there any way around this without reverting back to the way it was?

Thank you.

R. Houston

I don’t understand the situation you are talking about. Each subgraph is supposed to surround all of the nodes that are its children.

If you drag in a selection consisting of several nodes and links (or just of a single large node), they will all be added to the subgraph at their dropped positions, so that subgraph may need to be expanded to include the bounds of all of those newly added nodes and links.

Hi Walter,

When I bring nodes to a non-empty subgraph (by selecting/dragging/dropping) I would expect the size of the subgraph to not change. If I understand what you’re saying in your last post I think you’re saying the same thing.

What I found after making the change to DoDragging (i.e., moving the base.dodragging call) is that now the subgraph does resize after bringing new node(s) to the non-empty subgraph. The new size of the subgraph includes the origination position of the selected node(s). I may not be saying this clearly but you can recreate the behavior in the SubGraphApp (modified with the change to DoDragging that you recommended in a previous post). Steps to recreate behavior in modified SubGraph App:

  1. Modifiy DoDragging in the SubGraphApp per your instructions (in a previous post)
  2. Launch SugGraph App and select all nodes/links.
  3. Click button to make a new custom subgraph
  4. Move the subgraph with its nodes/links to the right hand side of the screen
  5. Now double-click the goview background near the left-hand edge of the goview. A new node is created at the point where you double-clicked.
  6. Select and drag/drop the new node into the subgraph. The subgraph will expand it’s size to include the node’s origination position, or rather, the point at which you double-clicked (the background) to create the new node. I would like to prevent the subgraph from resizing itself in this manner. Instead, what I would prefer is that the subgraph not resize when new nodes are added to a non-empty subgraph.

From what you stated in your last post I’m optimistic that I should be able to achieve what I want. I’m just not sure how to achieve it. Try the example as I’ve described it above and see what you think.

Let me know.

Thank you.

R. Houston

When I follow the steps you list, I get the behavior I expected, not what you describe. Here’s what I get:

The subgraph labeled “5” did get a bit bigger when I dropped the “6” node into it, because I did so near the subgraph’s left edge.

Obviously, the subgraph did not extend its bounds to include where the “6” node had originated from, way off to the left.

I found what was different,

I forgot to add the other mods to DoDragging - Namely the ones you recommended in another thread/post in which you said to add the following two lines to DoDragging, after AddCollection (I added them to my code but not to the example code):

this.View.Selection.Clear();
this.View.Selection.AddRange(this.EffectiveSelection);

Once I update DoDragging with that coding change as well, I get the expected behavior. Sorry for the confusion.

Thank you again.

R. Houston