UNPKG

@reactual/handsontable

Version:

Spreadsheet-like data grid editor

186 lines (160 loc) 4.46 kB
import {isObject} from './../helpers/object'; import {rangeEach} from './../helpers/number'; import {stringify} from './../helpers/mixed'; /** * @class SamplesGenerator * @util */ class SamplesGenerator { /** * Number of samples to take of each value length. * * @type {Number} */ static get SAMPLE_COUNT() { return 3; } constructor(dataFactory) { /** * Samples prepared for calculations. * * @type {Map} * @default {null} */ this.samples = null; /** * Function which give the data to collect samples. * * @type {Function} */ this.dataFactory = dataFactory; /** * Custom number of samples to take of each value length. * * @type {Number} * @default {null} */ this.customSampleCount = null; /** * `true` if duplicate samples collection should be allowed, `false` otherwise. * * @type {Boolean} * @default {false} */ this.allowDuplicates = false; } /** * Get the sample count for this instance. * * @returns {Number} */ getSampleCount() { if (this.customSampleCount) { return this.customSampleCount; } return SamplesGenerator.SAMPLE_COUNT; }; /** * Set the sample count. * * @param {Number} sampleCount Number of samples to be collected. */ setSampleCount(sampleCount) { this.customSampleCount = sampleCount; } /** * Set if the generator should accept duplicate values. * * @param {Boolean} allowDuplicates `true` to allow duplicate values. */ setAllowDuplicates(allowDuplicates) { this.allowDuplicates = allowDuplicates; } /** * Generate samples for row. You can control which area should be sampled by passing `rowRange` object and `colRange` object. * * @param {Object|Number} rowRange * @param {Object} colRange * @returns {Object} */ generateRowSamples(rowRange, colRange) { return this.generateSamples('row', colRange, rowRange); } /** * Generate samples for column. You can control which area should be sampled by passing `colRange` object and `rowRange` object. * * @param {Object} colRange Column index. * @param {Object} rowRange Column index. * @returns {Object} */ generateColumnSamples(colRange, rowRange) { return this.generateSamples('col', rowRange, colRange); } /** * Generate collection of samples. * * @param {String} type Type to generate. Can be `col` or `row`. * @param {Object} range * @param {Object|Number} specifierRange * @returns {Map} */ generateSamples(type, range, specifierRange) { const samples = new Map(); if (typeof specifierRange === 'number') { specifierRange = {from: specifierRange, to: specifierRange}; } rangeEach(specifierRange.from, specifierRange.to, (index) => { const sample = this.generateSample(type, range, index); samples.set(index, sample); }); return samples; } /** * Generate sample for specified type (`row` or `col`). * * @param {String} type Samples type `row` or `col`. * @param {Object} range * @param {Number} specifierValue * @returns {Map} */ generateSample(type, range, specifierValue) { const samples = new Map(); let sampledValues = []; let length; rangeEach(range.from, range.to, (index) => { let value; if (type === 'row') { value = this.dataFactory(specifierValue, index); } else if (type === 'col') { value = this.dataFactory(index, specifierValue); } else { throw new Error('Unsupported sample type'); } if (isObject(value)) { length = Object.keys(value).length; } else if (Array.isArray(value)) { length = value.length; } else { length = stringify(value).length; } if (!samples.has(length)) { samples.set(length, { needed: this.getSampleCount(), strings: [], }); } let sample = samples.get(length); if (sample.needed) { let duplicate = sampledValues.indexOf(value) > -1; if (!duplicate || this.allowDuplicates) { let computedKey = type === 'row' ? 'col' : 'row'; sample.strings.push({value, [computedKey]: index}); sampledValues.push(value); sample.needed--; } } }); return samples; } } export default SamplesGenerator;