From 0e1a4c9b328e8454248d58646ca6eddf37233984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 18 May 2023 12:17:53 +0200 Subject: [PATCH] fix(types): improve typings and allow typed arrays as inputs --- src/BasicContourDrawer.ts | 12 +++--- src/ContourBuilder.ts | 9 +++-- src/ShapeContourDrawer.ts | 4 +- src/calculateContour.ts | 31 +++++++--------- src/index.ts | 77 ++++++++++++++------------------------- tsconfig.json | 5 +-- 6 files changed, 57 insertions(+), 81 deletions(-) diff --git a/src/BasicContourDrawer.ts b/src/BasicContourDrawer.ts index ad227bb..905de11 100644 --- a/src/BasicContourDrawer.ts +++ b/src/BasicContourDrawer.ts @@ -7,13 +7,13 @@ export class BasicContourDrawer { private contour: BasicContour[]; private swapAxes: boolean; - constructor(levels: number[], swapAxes: boolean) { - this.contour = new Array(levels.length); - for (let i = 0; i < levels.length; i++) { - this.contour[i] = { - zValue: levels[i], + constructor(levels: Readonly, swapAxes: boolean) { + this.contour = []; + for (const level of levels) { + this.contour.push({ + zValue: level, lines: [], - }; + }); } this.swapAxes = swapAxes; } diff --git a/src/ContourBuilder.ts b/src/ContourBuilder.ts index 98f4ffb..9e68cab 100644 --- a/src/ContourBuilder.ts +++ b/src/ContourBuilder.ts @@ -129,14 +129,16 @@ * MODIFICATIONS. */ export class ContourBuilder { - level: number[]; + level: number; s: Sequence | null; private count: number; - constructor(level: number[]) { + + constructor(level: number) { this.level = level; this.s = null; this.count = 0; } + removeSeq(list: Sequence) { // if list is the first item, static ptr s is updated if (list.prev) { @@ -149,6 +151,7 @@ export class ContourBuilder { } --this.count; } + addSegment(a: Point, b: Point) { let ss = this.s; let ma: Sequence | null = null; @@ -278,7 +281,7 @@ function pointsEqual(a: Point, b: Point) { } function reverseList(list: Sequence) { - let pp = list.head; + let pp: SequenceNode | null = list.head; let temp; while (pp) { // swap prev/next pointers diff --git a/src/ShapeContourDrawer.ts b/src/ShapeContourDrawer.ts index 6e2dea6..bc25c24 100644 --- a/src/ShapeContourDrawer.ts +++ b/src/ShapeContourDrawer.ts @@ -69,7 +69,7 @@ import { ContourBuilder, Point, SequenceNode } from './ContourBuilder'; export interface ShapeContour { - level: number[]; + level: number; k: number; lines: Point[]; } @@ -78,7 +78,7 @@ export class ShapeContourDrawer { private contours: ContourBuilder[]; private swapAxes: boolean; - constructor(levels, swapAxes) { + constructor(levels: number[], swapAxes: boolean) { this.contours = new Array(levels.length); for (let i = 0; i < levels.length; i++) { this.contours[i] = new ContourBuilder(levels[i]); diff --git a/src/calculateContour.ts b/src/calculateContour.ts index 258a83c..a1c1149 100644 --- a/src/calculateContour.ts +++ b/src/calculateContour.ts @@ -75,6 +75,9 @@ const EPSILON = Number.EPSILON; const MINUSEPSILON = 0 - EPSILON; interface CalculateContourOptions { + /** + * Maximum number of ms before returning from the function, default unlimited. + */ timeout?: number; ilb?: number; iub?: number; @@ -94,32 +97,26 @@ interface CalculateContourOptions { * increasing value. * * @private - * @param {NumberMatrix} matrix - matrix of data to contour + * @param matrix - matrix of data to contour * * The following two, one dimensional arrays (x and y) contain * the horizontal and vertical coordinates of each sample points. - * @param {NumberArray} x - data matrix column coordinates - * @param {NumberArray} y - data matrix row coordinates - * @param {NumberArray} z - contour levels in increasing order. - * @param {object} contourDrawer object that implements contourDraw for drawing contour. Defaults to a + * @param x - data matrix column coordinates + * @param y - data matrix row coordinates + * @param z - contour levels in increasing order. + * @param contourDrawer object that implements contourDraw for drawing contour. Defaults to a * custom "contour builder", which populates the * contours property. - * @param {object} [options={}] - * @param {number} [options.timeout] - maximum number of ms before returning from the function, default unlimited - * @param {number} [options.ilb] - index bounds of data matrix - * @param {number} [options.iub] - index bounds of data matrix - * @param {number} [options.jlb] - index bounds of data matrix - * @param {number} [options.jub] - index bounds of data matrix - * @returns {boolean} - Whether contour generation had to stop early because it reached the timeout + * @returns Whether contour generation had to stop early because it reached the timeout */ export function calculateContour( - matrix: NumberMatrix, - x: NumberArray, - y: NumberArray, - z: NumberArray, + matrix: Readonly, + x: Readonly, + y: Readonly, + z: Readonly, contourDrawer: ContourDrawer, options: CalculateContourOptions = {}, -) { +): boolean { const { timeout, ilb = 0, diff --git a/src/index.ts b/src/index.ts index 5fc5506..0daf14d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,37 +1,29 @@ +import { NumberArray, NumberMatrix } from 'cheminfo-types'; + import { BasicContourDrawer } from './BasicContourDrawer'; import { ShapeContourDrawer } from './ShapeContourDrawer'; import { calculateContour } from './calculateContour'; -const defaultOptions = { - nbLevels: 10, - timeout: 0, -}; interface ConrecOptions { - xs?: number[]; - ys?: number[]; + xs?: Readonly; + ys?: Readonly; swapAxes?: boolean; } + export type ContourDrawer = BasicContourDrawer | ShapeContourDrawer; -/** - * - * @class Conrec - * @param {number[][]} matrix - * @param {number[]} [options.xs] - * @param {number[]} [options.ys] - * @param {boolean} [options.swapAxes] - */ + export class Conrec { - matrix: number[][]; + matrix: Readonly; rows: number; columns: number; - xs: number[]; - ys: number[]; + xs: Readonly; + ys: Readonly; swapAxes: boolean; hasMinMax: boolean; min: number; max: number; - constructor(matrix: number[][], options: ConrecOptions = {}) { + constructor(matrix: Readonly, options: ConrecOptions = {}) { const { swapAxes = false } = options; this.matrix = matrix; this.rows = matrix.length; @@ -55,46 +47,31 @@ export class Conrec { this.max = 0; } - /** - * @typedef {Object} Output - * @property {any} contours - * @property {boolean} timeout - Whether contour generation had to stop early because it reached the timeout - */ - - /** - * - * @param {number[]} [options.levels] - * @param {number} [options.nbLevels=10] - * @param {string} [options.contourDrawer='basic'] - 'basic' or 'shape' - * @param {number} [options.timeout=0] - * @return {Output} - */ drawContour(options: { - levels?: number[]; + levels?: readonly number[]; nbLevels?: number; - contourDrawer?: string; + contourDrawer?: 'basic' | 'shape'; timeout?: number; }) { - const { nbLevels, timeout } = { ...defaultOptions, ...options }; + const { nbLevels = 10, timeout = 0, contourDrawer = 'basic' } = options; let levels: number[]; if (options.levels) { - levels = options.levels.slice(); + levels = [...options.levels]; } else { this._computeMinMax(); const interval = (this.max - this.min) / (nbLevels - 1); levels = range(this.min, this.max + interval, interval); } levels.sort((a, b) => a - b); - let contourDrawer: ContourDrawer | null = null; - const contourDrawerType = options.contourDrawer || 'basic'; - if (typeof contourDrawerType === 'string') { - if (contourDrawerType === 'basic') { - contourDrawer = new BasicContourDrawer(levels, this.swapAxes); - } else if (contourDrawerType === 'shape') { - contourDrawer = new ShapeContourDrawer(levels, this.swapAxes); + let contourDrawerInstance: ContourDrawer; + if (typeof contourDrawer === 'string') { + if (contourDrawer === 'basic') { + contourDrawerInstance = new BasicContourDrawer(levels, this.swapAxes); + } else if (contourDrawer === 'shape') { + contourDrawerInstance = new ShapeContourDrawer(levels, this.swapAxes); } else { - throw new Error(`unknown contour drawer: ${contourDrawerType}`); + throw new Error(`invalid contour drawer: ${String(contourDrawer)}`); } } else { throw new TypeError('contourDrawer must be a string'); @@ -104,13 +81,13 @@ export class Conrec { this.xs, this.ys, levels, - contourDrawer, + contourDrawerInstance, { timeout, }, ); - return { contours: contourDrawer.getContour(), timeout: isTimeout }; + return { contours: contourDrawerInstance.getContour(), timeout: isTimeout }; } _computeMinMax() { @@ -123,13 +100,15 @@ export class Conrec { } } -function range(from: number, to: number, step: number) { +function range(from: number, to: number, step: number): number[] { const result: number[] = []; - for (let i = from; i < to; i += step) result.push(i); + for (let i = from; i < to; i += step) { + result.push(i); + } return result; } -function minMax(matrix: number[][]) { +function minMax(matrix: Readonly) { let min = Number.POSITIVE_INFINITY; let max = Number.NEGATIVE_INFINITY; for (const row of matrix) { diff --git a/tsconfig.json b/tsconfig.json index 7dfbeee..4ed6e69 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,7 @@ { "compilerOptions": { - "allowJs": true, - "checkJs": true, "esModuleInterop": true, - "moduleResolution": "node", - "noImplicitAny": false, + "moduleResolution": "node16", "outDir": "lib", "sourceMap": true, "strict": true,