UNPKG

handsontable

Version:

Handsontable is a JavaScript Data Grid available for React, Angular and Vue.

176 lines (167 loc) • 5.48 kB
import "core-js/modules/es.array.push.js"; import "core-js/modules/esnext.iterator.constructor.js"; import "core-js/modules/esnext.iterator.every.js"; import "core-js/modules/esnext.iterator.for-each.js"; import { deepObjectSize, isObject } from "./object.mjs"; const COLUMN_LABEL_BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length; /** * Generates spreadsheet-like column names: A, B, C, ..., Z, AA, AB, etc. * * @param {number} index Column index. * @returns {string} */ export function spreadsheetColumnLabel(index) { let dividend = index + 1; let columnLabel = ''; let modulo; while (dividend > 0) { modulo = (dividend - 1) % COLUMN_LABEL_BASE_LENGTH; columnLabel = String.fromCharCode(65 + modulo) + columnLabel; dividend = parseInt((dividend - modulo) / COLUMN_LABEL_BASE_LENGTH, 10); } return columnLabel; } /** * Generates spreadsheet-like column index from theirs labels: A, B, C ...., Z, AA, AB, etc. * * @param {string} label Column label. * @returns {number} */ export function spreadsheetColumnIndex(label) { let result = 0; if (label) { for (let i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) { result += COLUMN_LABEL_BASE_LENGTH ** j * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1); } } result -= 1; return result; } /** * Creates 2D array of Excel-like values "A1", "A2", ... * * @param {number} rows Number of rows to generate. * @param {number} columns Number of columns to generate. * @returns {Array} */ export function createSpreadsheetData() { let rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; const _rows = []; let i; let j; for (i = 0; i < rows; i++) { const row = []; for (j = 0; j < columns; j++) { row.push(spreadsheetColumnLabel(j) + (i + 1)); } _rows.push(row); } return _rows; } /** * Creates 2D array of Excel-like values "A1", "A2", as an array of objects. * * @param {number} rows Number of rows to generate. * @param {number} colCount Number of columns to generate. * @returns {Array} */ export function createSpreadsheetObjectData() { let rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; let colCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; const _rows = []; let i; let j; for (i = 0; i < rows; i++) { const row = {}; for (j = 0; j < colCount; j++) { row[`prop${j}`] = spreadsheetColumnLabel(j) + (i + 1); } _rows.push(row); } return _rows; } /** * Generates an empty data object. * * @param {number} rows Number of rows to generate. * @param {number} columns Number of columns to generate. * @returns {Array} */ export function createEmptySpreadsheetData(rows, columns) { const data = []; let row; for (let i = 0; i < rows; i++) { row = []; for (let j = 0; j < columns; j++) { row.push(''); } data.push(row); } return data; } /** * Transform a data row (either an array or an object) or an array of data rows to array of changes in a form of `[row, * prop/col, value]`. Convenient to use with `setDataAtRowProp` and `setSourceDataAtCell` methods. * * @param {Array|object} dataRow Object of row data, array of row data or an array of either. * @param {number} rowOffset Row offset to be passed to the resulting change list. Defaults to `0`. * @returns {Array} Array of changes (in a form of an array). */ export function dataRowToChangesArray(dataRow) { let rowOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; let dataRows = dataRow; const changesArray = []; if (!Array.isArray(dataRow) || !Array.isArray(dataRow[0])) { dataRows = [dataRow]; } dataRows.forEach((row, rowIndex) => { if (Array.isArray(row)) { row.forEach((value, column) => { changesArray.push([rowIndex + rowOffset, column, value]); }); } else { Object.keys(row).forEach(propName => { changesArray.push([rowIndex + rowOffset, propName, row[propName]]); }); } }); return changesArray; } /** * Count the number of keys (or, basically, columns when the data is an array or arrays) in the first row of the * provided dataset. * * @param {Array} data The dataset. * @returns {number} Number of keys in the first row of the dataset. */ export function countFirstRowKeys(data) { let result = 0; if (Array.isArray(data)) { if (data[0] && Array.isArray(data[0])) { result = data[0].length; } else if (data[0] && isObject(data[0])) { result = deepObjectSize(data[0]); } } return result; } /** * Check whether the provided dataset is a *non-empty* array of arrays. * * @param {Array} data Dataset to be checked. * @returns {boolean} `true` if data is an array of arrays, `false` otherwise. */ export function isArrayOfArrays(data) { return !!(Array.isArray(data) && data.length && data.every(el => Array.isArray(el))); } /** * Check whether the provided dataset is a *non-empty* array of objects. * * @param {Array} data Dataset to be checked. * @returns {boolean} `true` if data is an array of objects, `false` otherwise. */ export function isArrayOfObjects(data) { return !!(Array.isArray(data) && data.length && data.every(el => typeof el === 'object' && !Array.isArray(el) && el !== null)); }