_placeBranchNodes(parentId, parentLevel) {
    const childRef = this.hierarchical.childrenReference[parentId];

    // if this is not a parent, cancel the placing. This can happen with multiple parents to one child.
    if (childRef === undefined) {
      return;
    }

    // get a list of childNodes
    const childNodes = [];
    for (let i = 0; i < childRef.length; i++) {
      childNodes.push(this.body.nodes[childRef[i]]);
    }

    // use the positions to order the nodes.
    this.direction.sort(childNodes);

    // position the childNodes
    for (let i = 0; i < childNodes.length; i++) {
      const childNode = childNodes[i];
      const childNodeLevel = this.hierarchical.levels[childNode.id];
      // check if the child node is below the parent node and if it has already been positioned.
      if (
        childNodeLevel > parentLevel &&
        this.positionedNodes[childNode.id] === undefined
      ) {
        // get the amount of space required for this node. If parent the width is based on the amount of children.
        const spacing = this.options.hierarchical.nodeSpacing;
        let pos;

        // we get the X or Y values we need and store them in pos and previousPos.
        // The get and set make sure we get X or Y
        if (i === 0) {
          pos = this.direction.getPosition(this.body.nodes[parentId]);
        } else {
          pos = this.direction.getPosition(childNodes[i - 1]) + spacing;
        }
        this.direction.setPosition(childNode, pos, childNodeLevel);
        this._validatePositionAndContinue(childNode, childNodeLevel, pos);
      } else {
        return;
      }
    }

    // center the parent nodes.
    const center = this._getCenterPosition(childNodes);
    this.direction.setPosition(this.body.nodes[parentId], center, parentLevel);
  }
This is a recursively called function to enumerate the branches from the largest hubs and place the nodes
on a X position that ensures there will be no overlap.
@param {Node.id} parentId
@param {number} parentLevel
@private