Skip to content

Commit

Permalink
Handling matrices in removing columns
Browse files Browse the repository at this point in the history
  • Loading branch information
swistak35 committed Jul 8, 2019
1 parent 0ff15f9 commit 36beb1a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/DependencyGraph/AddressMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ export class AddressMapping {
}, this.matrixMapping.values()[Symbol.iterator]())
}

public* numericMatricesInColumns(sheet: number, startColumn: number): IterableIterator<MatrixVertex> {
public* numericMatricesInColumns(sheet: number, startColumn: number, endColumn: number = startColumn): IterableIterator<MatrixVertex> {
yield* filterWith((mtx) => {
return mtx.spansThroughSheetColumn(sheet, startColumn) && !mtx.isFormula()
return mtx.spansThroughSheetColumn(sheet, startColumn, endColumn) && !mtx.isFormula()
}, this.matrixMapping.values()[Symbol.iterator]())
}
}
9 changes: 9 additions & 0 deletions src/DependencyGraph/DependencyGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ export class DependencyGraph {
this.graph.removeNode(vertex)
}
}

for (let matrix of this.addressMapping!.numericMatricesInColumns(sheet, columnStart, columnEnd)) {
const numberOfColumns = columnEnd - columnStart + 1
if (matrix.width === numberOfColumns) {
this.graph.removeNode(matrix)
} else {
matrix.removeColumns(sheet, columnStart, columnEnd)
}
}
}

public addRows(sheet: number, rowStart: number, numberOfRows: number) {
Expand Down
12 changes: 10 additions & 2 deletions src/DependencyGraph/Vertex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ export class MatrixVertex {
(startRow < this.cellAddress.row + this.height)
}

public spansThroughSheetColumn(sheet: number, col: number): boolean {
public spansThroughSheetColumn(sheet: number, col: number, columnEnd: number = col): boolean {
return (this.cellAddress.sheet === sheet) &&
(this.cellAddress.col <= col) &&
(this.cellAddress.col <= columnEnd) &&
(col < this.cellAddress.col + this.width)
}

Expand All @@ -118,6 +118,14 @@ export class MatrixVertex {
this.matrix.removeRows(start, end)
}
}

public removeColumns(sheet: number, leftColumn: number, rightColumn: number): void {
if (this.matrix instanceof Matrix) {
const start = Math.max(leftColumn, this.getAddress().col) - this.getAddress().col
const end = Math.min(rightColumn, this.getAddress().col + this.width - 1) - this.getAddress().col
this.matrix.removeColumns(start, end)
}
}
}

/**
Expand Down
13 changes: 12 additions & 1 deletion src/Matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function checkMatrixSize(ast: Ast, formulaAddress: SimpleCellAddress): Ma
export interface IMatrix {
width(): number
height(): number
get(col: number, row: number): number
get(col: number, row: number): number,
}

export class NotComputedMatrix implements IMatrix {
Expand Down Expand Up @@ -176,6 +176,17 @@ export class Matrix implements IMatrix {
this.size.height -= numberOfRows
}

public removeColumns(leftmostColumn: number, rightmostColumn: number) {
if (this.outOfBound(leftmostColumn, 0) || this.outOfBound(rightmostColumn, 0)) {
throw Error("Matrix index out of bound")
}
const numberOfColumns = rightmostColumn - leftmostColumn + 1
for (const row of this.matrix) {
row.splice(leftmostColumn, numberOfColumns)
}
this.size.width -= numberOfColumns
}

public zeroArrays(count: number, size: number) {
const result = []
for (let i=0; i<count; ++i) {
Expand Down
40 changes: 40 additions & 0 deletions test/removing-columns.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {Config, HandsOnEngine} from "../src";
import {ErrorType, CellError, SimpleCellAddress, simpleCellAddress} from "../src/Cell";
import './testConfig.ts'
import {EmptyCellVertex, FormulaCellVertex, MatrixVertex, RangeVertex} from "../src/DependencyGraph";

describe('Removing columns - matrices', () => {
it('should not remove column within formula matrix', () => {
Expand All @@ -10,6 +12,44 @@ describe('Removing columns - matrices', () => {

expect(() => engine.removeColumns(0, 2, 2)).toThrowError("It is not possible to remove column within matrix")
})

it('should remove column from numeric matrix', () => {
const config = new Config({matrixDetection: true, matrixDetectionThreshold: 1})
const engine = HandsOnEngine.buildFromArray([
['1', '2', '3'],
['1', '2', '3'],
], config)

engine.removeColumns(0, 1, 1)

const matrix = engine.addressMapping!.fetchCell(simpleCellAddress(0, 0, 0)) as MatrixVertex
expect(matrix).toBeInstanceOf(MatrixVertex)
expect(matrix.width).toBe(2)
})

it('should remove columns when partial overlap', () => {
const config = new Config({matrixDetection: true, matrixDetectionThreshold: 1})
const engine = HandsOnEngine.buildFromArray([
['1', '2'],
['3', '4'],
], config)

engine.removeColumns(0, 1, 3)
const matrix = engine.addressMapping!.fetchCell(simpleCellAddress(0, 0, 0)) as MatrixVertex
expect(matrix).toBeInstanceOf(MatrixVertex)
expect(matrix.width).toBe(1)
})

it('should remove MatrixVertex completely from graph', () => {
const config = new Config({matrixDetection: true, matrixDetectionThreshold: 1})
const engine = HandsOnEngine.buildFromArray([
['1', '2'],
['3', '4'],
], config)

engine.removeColumns(0, 0, 1)
expect(engine.graph.nodes.size).toBe(1)
})
});

describe('Removing columns - graph', function () {
Expand Down

0 comments on commit 36beb1a

Please sign in to comment.