Is there any way to prevent sorting when auto-aligning objects in TreeLayout?

Hello, I have a question about how to align objects.
This may be impractical, but if possible, I would greatly appreciate it if you could tell me how to do it.

Current situation

I am using go.TreeLayout for layout to enjoy the following benefits

  • When I move the parent object, the child objects move with it.
  • When I add a child object, the object is automatically created at the organized x,y coordinates.

Problem

  • Even if objects are sorted for user visibility, text editing, adding child objects, etc., can cause the objects to be re-aligned and re-sorted using the default keys.
    Even if objects are sorted for user visibility, they are re-aligned and sorted with the default key due to text editing, addition of child objects, etc. (Even if the user manually sorts the objects, it is useless.)

What we tried

To solve this, we tried the following

  • Used the comparer option
    I added my own option nodeId as a key for sorting.
    Edit the nodeId with a custom function each time the object’s position changes.
go.TreeLayout, {
  comparer: function (v1, v2) {
    var key1 = v1.data.nodeId
    var key2 = v2.data.nodeId
    if (key1 < key2) return -1
    if (key1 > key2) return 1
    return 0
  }
}

However, this one does not seem to be called when editing text or adding child objects.
So the problem could not be solved.

  • Using Layout.isOngoing
    This would not automatically align when editing text or adding objects, but
    The result of the user’s rearrangement is preserved.
    However, when the saved data is reopened, it is still aligned.
    Also, the linkData lines are no longer a clean TreeLayout. (as in child4 in the attached image).
    image

What I would like to discuss

As a request, I would like to do some sorting, but I don’t need to sort.
Is there any way to determine the location of an object and align it, rather than by some key?
Like the auto-alignment of icons on the Windows desktop, so that they are aligned to the most different location.

I think your comparer function isn’t correct. The arguments are instances of TreeVertex, not Node. Try something like:

  comparer: function (v1, v2) {
    var key1 = v1.node ? v1.node.data.nodeId : 0;
    var key2 = v2.node ? v2.node.data.nodeId : 0;
    if (key1 < key2) return -1
    if (key1 > key2) return 1
    return 0
  }

Thank you for pointing out the error.
Unfortunately, however, this function was not called from the beginning.
we were unable to resolve the issue.
(I have not reached the phase where I can determine if this function is in error or not)

I determined this from the fact that the string specified in console.log is not displayed when editing text or adding objects.
Below is the code I used.
For ease of confirmation, I have keyed the text of the object.

go.Diagram,
'eml1',
{
  'clickCreatingTool.archetypeNodeData': {}
  'undoManager.isEnabled': true,
  allowDragOut: true, { 'clickCreatingTool.archetypeNodeData': {}.
  maxScale: 3,
  minScale: 0.1,
  hoverDelay: 0,
  'draggingTool.dragsTree': true,
  Layout $(go.TreeLayout, {)
    comparer: function (v1, v2) {
      console.log('comparer fnc')
      var key1 = v1.node ? v1.node.data.text : 0
      var key2 = v2.node ? v2.node.data.text : 0
      if (key1 < key2) return -1
      if (key1 > key2) return 1
      return 0
    },
  }),
}

Tree structures are by default assumed to have links going from the parent to each child. If your screenshot shows arrowheads at the “to” end of links, then they are going in the wrong logical direction. You could set Diagram.isTreePathToChildren to false so that all links are assumed to go from children to their parent.

Sorry my initial question was not clear.
What I was trying to solve was

  • When a user changes the position of an object (fig: before)
  • Currently, the objects are rearranged in the order they were created (fig: actual result).
  • The desired result is without rearrange the order, but only to align position of the objects (fig: desired result).

The desired result is that the order is not rearranged, only aligned.
Is this possible?

before:
image

desired result:
image

actual result:
image

Oh, OK. Sort by current y location.

  comparer: function (v1, v2) {
    var y1 = v1.node ? v1.node.location.y : 0;
    var y2 = v2.node ? v2.node.location.y : 0;
    if (y1 < y2) return -1
    if (y1 > y2) return 1
    return 0
  }

Hmmm, the initial layout might operate on nodes that do not have real locations yet – i.e. (NaN, NaN). So you might want to depend on some data property if isNaN(location.y).

1 Like

Thank you!
I will take care of this for NaN by putting in alternate values.
However, even if I plant a console.log as follows, the functions in the comparator are not executed when editing text or creating new objects.

diagram = $(
  go.Diagram,
  'elm',
  {
    'clickCreatingTool.archetypeNodeData': {},
    'undoManager.isEnabled': true,
    allowDragOut: true,
    maxScale: 3,
    minScale: 0.1,
    hoverDelay: 0,
    'draggingTool.dragsTree': true,
    layout: $(go.TreeLayout, {
      comparer: function (v1, v2) {
        console.log('run comparer')
        var y1 = v1.node ? v1.node.location.y : 0
        var y2 = v2.node ? v2.node.location.y : 0
        if (y1 < y2) return -1
        if (y1 > y2) return 1
        return 0
      },
    }),
  }
)

Do I need to set any flags separately to execute the comparer function?

If you read the documentation for TreeLayout.comparer:

you will see that you need to set TreeLayout.sorting to either go.TreeLayout.SortingAscending or go.TreeLayout.SortingDescending.

1 Like

Problem solved!
I guess my understanding of the documentation was not good enough. (I mistakenly thought that the default value was set with no sort set).
Thank you for addressing this issue!