private fillCells()

in packages/ketcher-core/src/domain/entities/canvas-matrix/CanvasMatrix.ts [169:350]


  private fillCells() {
    // create matrix by initial matrix filling empty cells

    for (
      let rowNumber = 0;
      rowNumber < this.matrixConfig.initialMatrix.height;
      rowNumber++
    ) {
      for (
        let columnNumber = 0;
        columnNumber < this.initialMatrixWidth;
        columnNumber++
      ) {
        const initialMatrixCell = this.matrixConfig.initialMatrix.get(
          rowNumber,
          columnNumber,
        );

        if (!initialMatrixCell) {
          this.matrix.set(
            rowNumber,
            columnNumber,
            new Cell(null, [], columnNumber, rowNumber),
          );

          continue;
        }

        const cell = new Cell(
          initialMatrixCell.node,
          [],
          columnNumber,
          rowNumber,
          initialMatrixCell.monomer,
        );

        this.matrix.set(rowNumber, columnNumber, cell);

        if (initialMatrixCell.monomer) {
          this.monomerToCell.set(initialMatrixCell.monomer, cell);
        }
      }
    }

    const monomerToNode = this.chainsCollection.monomerToNode;
    const handledConnections = new Set<PolymerBond>();

    this.matrix.forEach((cell) => {
      const monomer = cell.monomer;

      monomer?.forEachBond((polymerBond) => {
        if (polymerBond instanceof MonomerToAtomBond) {
          return;
        }

        if (
          polymerBond.isSideChainConnection &&
          !handledConnections.has(polymerBond)
        ) {
          const anotherMonomer = polymerBond.getAnotherMonomer(
            monomer,
          ) as BaseMonomer;
          const connectedNode = monomerToNode.get(
            anotherMonomer,
          ) as SubChainNode;
          const connectedCell = this.monomerToCell.get(anotherMonomer);

          if (!connectedCell) {
            return;
          }

          const xDistance = connectedCell.x - cell.x;
          const yDistance = connectedCell.y - cell.y;
          const xDirection = xDistance > 0 ? 0 : 180;
          const yDirection = yDistance > 0 ? 90 : 270;
          let xDistanceAbsolute = Math.abs(xDistance);
          let yDistanceAbsolute = Math.abs(yDistance);
          const isVertical = xDistanceAbsolute === 0;

          // fill start cell by connection with direction
          let connection = new Connection(
            connectedNode,
            isVertical ? 90 : xDirection,
            isVertical,
            polymerBond,
            0,
            0,
          );

          cell.connections.push(connection);
          this.polymerBondToCells.set(polymerBond, [cell]);
          this.polymerBondToConnections.set(polymerBond, [connection]);

          let nextCellX = cell.x;
          let nextCellY = cell.y;

          // fill x cells by connection with direction
          while (xDistanceAbsolute > 1) {
            nextCellX += Math.sign(xDistance);
            const nextCellToHandle = this.matrix.get(
              nextCellY,
              nextCellX,
            ) as Cell;
            connection = new Connection(
              null,
              xDirection,
              isVertical,
              polymerBond,
              0,
              0,
            );
            nextCellToHandle.connections.push(connection);
            this.polymerBondToCells.get(polymerBond)?.push(nextCellToHandle);
            this.polymerBondToConnections.get(polymerBond)?.push(connection);

            xDistanceAbsolute--;
          }

          // fill y cells by connection with direction
          while (yDistanceAbsolute > 1) {
            nextCellY += Math.sign(yDistance);
            const nextCellToHandle = this.matrix.get(
              nextCellY,
              nextCellX,
            ) as Cell;
            connection = new Connection(
              null,
              yDirection,
              isVertical,
              polymerBond,
              0,
              0,
            );
            nextCellToHandle.connections.push(connection);
            this.polymerBondToCells.get(polymerBond)?.push(nextCellToHandle);
            this.polymerBondToConnections.get(polymerBond)?.push(connection);

            yDistanceAbsolute--;
          }

          // fill last cell by connection
          nextCellX += Math.sign(xDistance);
          nextCellY += Math.sign(yDistance);

          const lastCellToHandle = this.matrix.get(
            nextCellY,
            nextCellX,
          ) as Cell;
          connection = new Connection(
            connectedNode,
            isVertical
              ? yDirection
              : { x: xDistance === 0 ? 0 : xDirection, y: yDirection },
            isVertical,
            polymerBond,
            0,
            0,
          );
          lastCellToHandle.connections.push(connection);
          this.polymerBondToCells.get(polymerBond)?.push(lastCellToHandle);
          this.polymerBondToConnections.get(polymerBond)?.push(connection);

          handledConnections.add(polymerBond);
        }
      });
    });

    this.fillConnectionsOffset(180);
    this.fillRightConnectionsOffset();
    this.fillConnectionsOffset(0);
    this.fillConnectionsOffset(
      90,
      (connection: Connection, increaseValue: number | undefined): void => {
        if (isNumber(increaseValue)) {
          connection.yOffset = increaseValue;
        } else {
          connection.yOffset++;
        }
      },
      (connection: Connection): number => connection.yOffset,
    );
  }