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,
);
}