private adjustNodePositions()

in web/frontend/src/app/pages/flow/components/flow/flow.component.ts [296:381]


  private adjustNodePositions(positions: NodePositions) {
    const allNodeNames = Object.keys(positions);

    const nodesOutOfView = {};
    const nodesOverlappedWithGraphIndex = [];
    const nodesAtTheCenter = [];
    const stickyNodes = {};

    const {width, height} = this.hostElement.nativeElement.querySelector('canvas').closest('div').getBoundingClientRect();
    const canvasSidesRatio = width && height ? + (width / height).toFixed(2) : 0;
    
    allNodeNames.forEach(nodeName => {
      // nodes out of view
      nodesOutOfView[nodeName] = {x: false, y: false};
      if (!this.canvasSidesRatio || canvasSidesRatio !== this.canvasSidesRatio) {
        const coordinateY = Math.abs(positions[nodeName].y);
        if (coordinateY >= (nodeName === this.graphIndexName ? 430 : 530) && canvasSidesRatio > this.canvasSidesRatio) {
          nodesOutOfView[nodeName].y = true;
        }
        const coordinateX = Math.abs(positions[nodeName].x);
        if (coordinateX >= (nodeName === this.graphIndexName ? 600 : 700) && canvasSidesRatio < this.canvasSidesRatio) {
          nodesOutOfView[nodeName].x = true;
        }
      }

      // nodes overlapping with index node
      if (this.graphIndexName) {
        const params = {
          positions,
          nodeName,
          targetNodeName: this.graphIndexName,
          targetIsIndexNode: true,
        }
        if (filterNodesWithCloseCoordinate({...params, coordinate: 'x'}) && 
          filterNodesWithCloseCoordinate({...params, coordinate: 'y'}) && nodeName !== this.graphIndexName) {
            nodesOverlappedWithGraphIndex.push(nodeName);
        }
      }

      // nodes at the center (default view)
      if (!this.flowFilter.nodes.length && !this.flowFilter.rpsVal && !this.graphIndexName) {
        if (Math.abs(positions[nodeName].x) < 100 && Math.abs(positions[nodeName].y) < 100) {
          nodesAtTheCenter.push(nodeName);
        }
      }

      // sticky nodes
      const closeNode = Object.keys(stickyNodes).find(targetNodeName => {
        const params = {
          positions,
          nodeName,
          targetNodeName,
        }
        return (filterNodesWithCloseCoordinate({...params, coordinate: 'x'}) && 
              filterNodesWithCloseCoordinate({...params, coordinate: 'y'}));
      })
      if (closeNode) {
        stickyNodes[closeNode] = (!stickyNodes[closeNode] || !stickyNodes[closeNode].length) ? 
          [nodeName] : [...stickyNodes[closeNode], nodeName]
      } else {
        stickyNodes[nodeName] = [];
      }
    })

    if (!Object.keys(nodesOutOfView).length && !nodesOverlappedWithGraphIndex.length && 
      this.defaultViewNodesSeparated && !Object.keys(stickyNodes).length) {
        return null;
    }

    if (!!Object.keys(nodesOutOfView).length) {
      positions = this.setNodesIntoView(nodesOutOfView, positions);
    }

    if (!!nodesOverlappedWithGraphIndex.length) {
      positions = this.fixIndexNodeOverlapping(positions, nodesOverlappedWithGraphIndex);
    }

    if (!this.defaultViewNodesSeparated) {
      positions = this.setDefaultPositions(positions, nodesAtTheCenter);
    } else if (!!Object.keys(stickyNodes).length) {
      positions = this.separateStickyNodes(positions, stickyNodes);
    }

    this.canvasSidesRatio = canvasSidesRatio;
    return positions;
  }