All files / datamodel/src/operator bucket-creator.js

100% Statements 45/45
95% Branches 19/20
100% Functions 10/10
100% Lines 38/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                        10x 10x 10x 10x 10x 10x             10x 60x             10x 8x 8x   8x 8x 7x   8x 8x 23x 23x   8x 8x       10x     10x 197x 57x 32x       60x 2x     60x   1x       10x 10x     10x 10x   38x 10x   10x 34x   10x    
import { rowDiffsetIterator } from './row-diffset-iterator';
 
/**
 * Creates bin f from the data and the supplied config.
 *
 * @param {Array} data - The input data.
 * @param {Object} config - The config object.
 * @param {number} config.binSize - The size of the bin.
 * @param {number} config.numOfBins - The number of bins to be created.
 * @return {Array} Returns an array of created bins.
 */
export function createBinnedFieldData (field, rowDiffset, config) {
    let { buckets, binCount, binSize, start } = config;
    let dataStore = [];
    let binnedData = [];
    let [min, max] = field.domain();
    let oriMax = max;
    let stops = [];
    let binEnd;
    let prevEndpoint;
    let mid;
    let range;
 
    // create dataStore with index according to rowDiffSet
    rowDiffsetIterator(rowDiffset, (i) => {
        dataStore.push({
            data: field.data[i],
            index: i
        });
    });
 
    // create buckets if buckets not given
    if (!buckets) {
        max += 1;
        binSize = binSize || (max - min) / binCount;
 
        const extraBinELm = (max - min) % binSize;
        if (!binCount && extraBinELm !== 0) {
            max = max + binSize - extraBinELm;
        }
        binEnd = min + binSize;
        while (binEnd <= max) {
            stops.push(binEnd);
            binEnd += binSize;
        }
        start = start || min;
        buckets = { start, stops };
    }
 
    // initialize intial bucket start
    prevEndpoint = buckets.start === 0 ? 0 : buckets.start || min;
 
    // mark each data in dataStore to respective buckets
    buckets.stops.forEach((endPoint) => {
        let tempStore = dataStore.filter(datum => datum.data >= prevEndpoint && datum.data < endPoint);
        tempStore.forEach((datum) => { binnedData[datum.index] = `${prevEndpoint}-${endPoint}`; });
        prevEndpoint = endPoint;
    });
 
    // create a bin for values less than start
    dataStore.filter(datum => datum.data < buckets.start)
                    .forEach((datum) => { binnedData[datum.index] = `${min}-${buckets.start}`; });
 
    // create a bin for values more than end
    dataStore.filter(datum => datum.data >= buckets.stops[buckets.stops.length - 1])
                    .forEach((datum) =>
                    { binnedData[datum.index] = `${buckets.stops[buckets.stops.length - 1]}-${oriMax}`; });
 
    // create range and mid
    // append start to bucket marks
    buckets.stops.unshift(buckets.start);
    range = new Set(buckets.stops);
 
    // Add endpoints to buckets marks if not added
    if (min < buckets.start) { range.add(min); }
    if (oriMax > buckets.stops[buckets.stops.length - 1]) { range.add(oriMax); }
 
    range = [...range].sort((a, b) => a - b);
    mid = [];
 
    for (let i = 1; i < range.length; i++) {
        mid.push((range[i - 1] + range[i]) / 2);
    }
    return { data: binnedData, mid, range };
}