I want to order the lanes inside a Pool

I have this doLayout logic taken from gojs forums (not sure about the source)

im adding that in this way (line 102)
image

All i want to maintain the order of the lanes,
example, i have parendId: “l1” and parentId:“l2”

but due to the logic written in the do layout its repositioning itself based on the positions, so we can hardcode if parentId===“l1” then set it first and for l2 set it 2nd order,
Note: I tried to change the order by pushing elements to the array, but it doesnt seem to work.

Do layout is a part of CustomSwimlaneLayout class

  doLayout(coll: go.Group): void {
    const diagram = coll.diagram;
    const isVertical = coll?.containingGroup?.data?.isVertical;
    const minLaneWidth = coll?.data?.metaData?.minLaneWidth ?? 0;

    const modelData = diagram.model.modelData as ISwimlaneModelData;
    this._layoutCompletedListener(diagram);
    let { positionInfo, lanesRankMap, lanes, maxWidth, maxHeight } = {
      positionInfo: null,
      lanesRankMap: {},
      lanes: [],
      maxWidth: minLaneWidth,
      maxHeight: 0,
      ...(modelData ?? {}),
    };
    let maxX = 0;
    if (!positionInfo) {
      this._addTempLinks(diagram);
      positionInfo = {};
      const flowInfo = getFlowInfo(diagram);
      const startNode = diagram.nodes
        .filter((node) => isStartNode(node))
        .first();
      let start = startNode.key as string;
      const end = diagram.nodes.filter((node) => isEndNode(node)).first()
        .key as string;
      if (coll?.containingGroup?.data?.skipNodeIndexRetain) {
        start = startNode.findNodesOutOf().first().key as string;
      }
      const traversalInfo = traverseGraph(flowInfo, start);
      const endTraversalInfo = traversalInfo[end];

      /** Sort by longest path to shortest path from start to end nodes. */
      const orderedTraversal = orderBy(
        endTraversalInfo.info,
        "distance",
        "desc"
      );

      const otherTraversals: INodeTraversalInfo[] = [];
      for (const infoNode in traversalInfo) {
        if (infoNode !== end) {
          otherTraversals.push(...traversalInfo[infoNode].info);
        }
      }

      const traversals = [
        ...orderedTraversal,
        /** Other nodes traversals from start, need this as some circular linking nodes will not be part of end node traversal list. */
        ...orderBy(otherTraversals, "distance", "desc"),
      ];

      const nodesCount = diagram.nodes.filter(
        (node) =>
          node.category !== CanvasShapesCategory.SWIMLANE &&
          node.category !== CanvasShapesCategory.POOL
      ).count;

      const visitedNodesMap = {};

      /** To stroke collection of nodes in x index. */
      const positionsMap: {
        nodeIds: string[];
        lanesMap: { [laneId: string]: boolean };
      }[] = [];

      for (const traversal of traversals) {
        if (Object.keys(visitedNodesMap).length === nodesCount - 1) {
          break;
        }
        for (const [index, nodeId] of traversal.path.entries()) {
          if (Object.keys(visitedNodesMap).length === nodesCount - 1) {
            break;
          }
          const node = diagram.findNodeForKey(nodeId);
          const { width, height } = node.actualBounds;
          if (maxWidth < width) {
            maxWidth = width;
          }
          if (maxHeight < height) {
            maxHeight = height;
          }
          if (!visitedNodesMap[nodeId] && nodeId !== end && node) {
            visitedNodesMap[nodeId] = true;
            const parentId = node.data.parentID;
            if (parentId) {
              if (!lanesRankMap[parentId]) {
                const keysLength = Object.keys(lanesRankMap).length;
                diagram.findNodeForKey(parentId).data.rank = keysLength + 1;
                lanesRankMap[parentId] = {
                  rank: keysLength,
                  xIndexInfo: {},
                  maxY: 0,
                };
                lanes.push(parentId);
              }
              const y = lanesRankMap[parentId].xIndexInfo[index]?.length ?? 0;
              positionInfo[nodeId] = {
                x: isVertical ? y : index,
                y: isVertical ? index : y,
              };
              if (!positionsMap[index]) {
                positionsMap[index] = {
                  nodeIds: [],
                  lanesMap: {},
                };
              }
              positionsMap[index].nodeIds.push(nodeId);
              positionsMap[index].lanesMap[parentId] = true;
              if (maxX < index) {
                maxX = index;
              }
              if (!lanesRankMap[parentId].xIndexInfo[index]) {
                lanesRankMap[parentId].xIndexInfo[index] = [];
              }
              lanesRankMap[parentId].xIndexInfo[index].push(nodeId);
              if (lanesRankMap[parentId].maxY < y) {
                lanesRankMap[parentId].maxY = y;
              }
            }
          }
        }
      }

      /** To adjust nodes to left if there is space availabel to move left without effecting the links.  */
      if (!coll?.containingGroup?.data?.skipNodeIndexRetain) {
        let positionIndex = 0;
        while (
          positionIndex !== positionsMap.length - 1 &&
          positionsMap.length
        ) {
          if (!positionsMap[positionIndex]) {
            positionsMap[positionIndex] = {
              nodeIds: [],
              lanesMap: {},
            };
          }
          const nodeIds = positionsMap[positionIndex]?.nodeIds ?? [];
          if (nodeIds.length === 1) {
            const currentNodeId = nodeIds[0];
            const currentNode = diagram.findNodeForKey(currentNodeId);
            const fromNodes = currentNode.findNodesInto();
            const parentId = currentNode.data.parentID;
            const fromNodeParentId = fromNodes.first()?.data?.parentID;
            /** Checks if no of nodes in current index is only one and
             * current node and its parent node are not in same lane and
             * current node lane space is empty to move one step left */
            const previousIndex = positionIndex - 1;
            if (
              fromNodes.count === 1 &&
              parentId !== fromNodeParentId &&
              !lanesRankMap[parentId].xIndexInfo[previousIndex]?.length &&
              !positionsMap[previousIndex]?.lanesMap?.[parentId]
            ) {
              positionsMap[previousIndex].nodeIds.push(currentNodeId);
              positionsMap[previousIndex].lanesMap[parentId] = true;
              positionsMap.splice(positionIndex, 1);
              positionIndex--;
            }
          }
          positionIndex++;
        }

        /** Updates position info based on shifted positions. */
        for (const [index, { nodeIds }] of positionsMap.entries()) {
          nodeIds.forEach((nodeId) => {
            if (isVertical) {
              positionInfo[nodeId].y = index;
            } else {
              positionInfo[nodeId].x = index;
            }
          });
        }

        /** To keep end node at the end.  */
        positionInfo[end] = {
          y: isVertical ? positionsMap.length : 0,
          x: isVertical ? 0 : positionsMap.length,
        };
      }

      modelData.positionInfo = positionInfo;
      modelData.lanesRankMap = lanesRankMap;
      modelData.lanes = lanes;
      modelData.maxHeight = maxHeight;
      modelData.maxWidth = maxWidth;
    }

    this._updateLaneMembers(coll, modelData);
  }

if you wanna know the data, then somewhat looks like this

p1 is pool, l1 and l2 are the lanes
{
nodeId:“p1”,
parentId:nul,
…data
}
{
nodeId:“l1”,
parentId:“p1”,
…data
}
{
nodeId:“l2”,
parentId:“p1”,
…data
}
…other nodes in similar way

In Swim Lanes “lanes” are Groups that are contained by “pool” groups. The order of those lane groups is controlled by the pool group’s Group.layout, which is an instance of PoolLayout that extends GridLayout. Note how the PoolLayout constructor sets GridLayout.comparer. Replace that with your own comparison function.