@fusioncharts/datatable
Version:
In memory tabular data storage
1 lines • 11.3 kB
JavaScript
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule=true;exports._singleSortedAddRow=_singleSortedAddRow;exports._singleSortedAddRowDate=_singleSortedAddRowDate;exports.default=void 0;var _datatableUtils=require("../utils/datatable-utils");var _datetimeOps=require("@fusioncharts/utils/src/time-intervals/datetime-ops");var _duration=require("@fusioncharts/utils/src/time-intervals/duration");var _interval=require("@fusioncharts/utils/src/ds-utils/interval");var _index=_interopRequireDefault(require("../aggregators/index.js"));var _globalConfig=require("../globalConfig");var _typeEnums=require("./type-enums");var _sortedSearch=require("../utils/sorted-search");var _comparators=require("../utils/comparators");var _fcTimeSeparator=_interopRequireDefault(require("@fusioncharts/utils/src/string/fc-time-separator"));var UNDEF;function groupBy(groupConfigArr,aggrConfigArr){var groupConfigArray=groupConfigArr,aggrConfigArray=aggrConfigArr;return{ops:"groupBy",type:_typeEnums.OperatorTypes.GroupBy,_updateArgs:function _updateArgs(groupConfiguration,aggrConfiguration){groupConfigArray=groupConfiguration;aggrConfigArray=aggrConfiguration},fn:function fn(_data,schema,config,generatorFn){var data=_data;if(generatorFn){data=generatorFn.call()}if(!groupConfigArray||groupConfigArray.length===0)throw new Error("groupConfigArray cannot be empty");if(!aggrConfigArray||aggrConfigArray.length===0)throw new Error("aggrConfigArray cannot be empty");if(!(groupConfigArray instanceof Array)&&groupConfigArray instanceof Object){groupConfigArray=[groupConfigArray]}if(!(aggrConfigArray instanceof Array)&&aggrConfigArray instanceof Object){aggrConfigArray=[aggrConfigArray]}if(groupConfigArray.length===1&&config&&groupConfigArray[0].column===config.indexBy){return _singleSortedGroupBy(data,schema,config,groupConfigArray[0],aggrConfigArray)}return _genericGroupBy(data,schema,config,groupConfigArray,aggrConfigArray)}}}function _createAggrSchema(schema,_groupConfig,_aggrConfig,cacheColumnConfig){var newSchema=[],groupConfig=_groupConfig,aggrConfig=_aggrConfig,groupConfigLength=groupConfig.length,aggrConfigLength=aggrConfig.length,column,type,aggregatorFn,i,operation,newColumn;groupConfig=groupConfig instanceof Array?groupConfig:[groupConfig];aggrConfig=aggrConfig instanceof Array?aggrConfig:[aggrConfig];for(i=0;i<groupConfigLength;i++){column=cacheColumnConfig(groupConfig[i].column,schema);newColumn={name:groupConfig[i].outputAs||groupConfig[i].column,type:column.type==="date"?"interval":column.type};if(column.enableUTC!==UNDEF){newColumn.enableUTC=column.enableUTC}newSchema.push(newColumn)}for(i=0;i<aggrConfigLength;i++){operation=aggrConfig[i].operation||"avg";column=cacheColumnConfig(aggrConfig[i].column,schema);aggregatorFn=_index.default.resolve(operation);if(!aggregatorFn)throw new Error(operation+" is not a defined operation");switch(operation){case"first":case"last":type=column.type;break;case"count":type="number";break;default:if(column.type!=="number")throw new Error(operation+" can apply only on numbers");type="number"}newSchema.push({name:aggrConfig[i].outputAs||aggrConfig[i].column+(operation?_fcTimeSeparator.default+operation:""),type:type})}return newSchema}function _singleSortedGroupBy(data,schema,config,groupConfig,aggrConfig){var newData=[],newSchema=[],dataLength=data.length,column,maxDate,timeDuration,startValFloorVal,startPos=0,lastEntry,cacheColumnConfig=_cacheColumnConfig(),cacheGroupCount=[],newDataLength,enableUTC,i;column=cacheColumnConfig(groupConfig.column,schema);column.outputAs=groupConfig.outputAs;newSchema=_createAggrSchema(schema,[column],aggrConfig,cacheColumnConfig);if(dataLength>0){enableUTC=column.enableUTC||(0,_globalConfig.getConfig)("enableUTC");if(column.type==="date"){var peaks,minDate,startValue;timeDuration=(0,_duration.duration)(groupConfig.timeUnit,Math.abs(groupConfig.binSize)||1);if(!data[0]||!data[0][column.index]||!data[dataLength-1]||!data[dataLength-1][column.index]){peaks=(0,_datatableUtils.columnExtents)(groupConfig.column,data,schema,config.indexBy)}minDate=data[0]&&data[0][column.index]||peaks.min;startValue=groupConfig.startValue&&parseInt(groupConfig.startValue,10);if(startValue&&groupConfig.timeUnit.name!=="Week"){if(startValue>=minDate){var comparer=function comparer(a,b){return(0,_comparators.numberComparator)(a[column.index],b)};startValFloorVal=(0,_datetimeOps.getDateStart)(startValue,(0,_duration.duration)(groupConfig.timeUnit,1),enableUTC,groupConfig.weekStartFrom);startPos=(0,_sortedSearch.leftMostExactOrGreater)(startValFloorVal,data,comparer,0,data.length)}else{startValFloorVal=(0,_datetimeOps.getDateStart)(minDate,timeDuration,enableUTC,groupConfig.weekStartFrom,startValue)}}else{startValFloorVal=(0,_datetimeOps.getDateStart)(minDate,(0,_duration.duration)(groupConfig.timeUnit,1),enableUTC,groupConfig.weekStartFrom)}maxDate=data[dataLength-1]&&data[dataLength-1][column.index]||peaks.max}if(startValFloorVal===UNDEF||startValFloorVal<=maxDate){var intervalConfig={duration:timeDuration,outputFormat:groupConfig.outputFormat,enableUTC:enableUTC,weekStartFrom:groupConfig.weekStartFrom};if(startValFloorVal!==UNDEF){lastEntry=[(0,_interval.interval)(startValFloorVal,intervalConfig)];newData.push(lastEntry)}for(i=startPos;i<dataLength;i++){if(data[i].length>0){if(column.type==="date"){lastEntry=_singleSortedAddRowDate(newData,lastEntry,data[i][column.index],intervalConfig,startValFloorVal)}else if(column.type==="string"||column.type==="number"){lastEntry=_singleSortedAddRow(newData,lastEntry,data[i][column.index])}newDataLength=newData.length-1;cacheGroupCount[newDataLength]=cacheGroupCount[newDataLength]||{};lastEntry&&_applyAggr(data[i],schema,lastEntry,1,aggrConfig,cacheColumnConfig,cacheGroupCount[newDataLength])}}}}return{data:newData,schema:newSchema,config:{indexBy:groupConfig.outputAs||groupConfig.column}}}function _singleSortedAddRow(newData,_lastEntry,value){var lastEntry=_lastEntry;if(!lastEntry||value!==lastEntry[0]){lastEntry=[value];newData.push(lastEntry)}return lastEntry}function _singleSortedAddRowDate(newData,_lastEntry,start,intervalConfig,minStart){var lastEntry=_lastEntry;if(start>=lastEntry[0].end){var startValFloorVal;switch(intervalConfig.duration.Unit){case"Month":case"Quarter":case"Year":startValFloorVal=(0,_datetimeOps.getDateStart)(start,intervalConfig.duration,intervalConfig.enableUTC,intervalConfig.weekStartFrom,minStart);break;default:startValFloorVal=start-(start-minStart)%intervalConfig.duration.ms;break}lastEntry=[(0,_interval.interval)(startValFloorVal,intervalConfig)];newData.push(lastEntry)}return lastEntry}function _cacheColumnConfig(){var cache={};return function(columnName,schema,data){if(!cache[columnName]){var columnIndex=(0,_datatableUtils.columnIndexOf)(columnName,schema),column=schema[columnIndex];if(column===UNDEF)throw new Error("incorrect column name in config - "+columnName);cache[columnName]=column;cache[columnName].column=columnName;cache[columnName].index=columnIndex;if(column.type==="date"&&data){cache[columnName].peaks=(0,_datatableUtils.columnExtents)(columnName,data,schema)}}return cache[columnName]}}function _genericGroupBy(data,schema,config,groupConfig,aggrConfig){var newData=[],newSchema=[],groupConfigCopy=[],loopData=true,dataLength=data.length,groupConfigLength=groupConfig.length,column,startValFloorVal,dateColumns={},cacheGroupCount=[],cacheColumnConfig=_cacheColumnConfig(),hashTable={},hashCount=0,indexBy,i;for(i=0;i<groupConfigLength;i++){column=cacheColumnConfig(groupConfig[i].column,schema,data);column.outputAs=groupConfig[i].outputAs;if(column.type==="date"){if(!dateColumns[i]){if(groupConfig[i].startValue>=column.peaks.max){loopData=false}dateColumns[i]=Object.assign({},column);dateColumns[i].intervalConfig={duration:(0,_duration.duration)(groupConfig[i].timeUnit,Math.abs(groupConfig[i].binSize)||1),outputFormat:groupConfig[i].outputFormat,enableUTC:column.enableUTC||(0,_globalConfig.getConfig)("enableUTC"),weekStartFrom:groupConfig[i].weekStartFrom};startValFloorVal=parseInt(groupConfig[i].startValue,10)||column.peaks.min;dateColumns[i].startValFloorVal=startValFloorVal&&(0,_datetimeOps.getDateStart)(startValFloorVal,(0,_duration.duration)(groupConfig[i].timeUnit,1),dateColumns[i].intervalConfig.enableUTC,dateColumns[i].intervalConfig.weekStartFrom,parseInt(groupConfig[i].startValue,10));dateColumns[i].max=column.peaks.max}}groupConfigCopy[i]=column;if(!indexBy&&groupConfig[i].column===config.indexBy){indexBy=groupConfig[i].outputAs||groupConfig[i].column}}newSchema=_createAggrSchema(schema,groupConfigCopy,aggrConfig,cacheColumnConfig);if(loopData&&dataLength>0){for(i=0;i<dataLength;i++){hashCount=_genericGroupByProcessRow(data[i],schema,groupConfig,aggrConfig,cacheColumnConfig,dateColumns,hashTable,hashCount,newData,cacheGroupCount)}}return{data:newData,schema:newSchema,config:{indexBy:indexBy}}}function _genericGroupByProcessRow(dataRow,schema,groupConfig,aggrConfig,cacheColumnConfig,dateColumns,hashTable,_hashCount,newData,cacheGroupCount){var j,column,hashVal="",currentRow=[],cacheGroupCountIndex,intervalObj,groupConfigLength=groupConfig.length,hashCount=_hashCount;if(dataRow.length>0){for(j=0;j<groupConfigLength;j++){column=cacheColumnConfig(groupConfig[j].column,schema);if(column.type==="date"){if(dateColumns[j].startValFloorVal>dataRow[column.index]){return hashCount}switch(groupConfig[j].timeUnit.name){case"Month":case"Quarter":case"Year":dateColumns[j].value=(0,_datetimeOps.getDateStart)(dataRow[column.index],dateColumns[j].intervalConfig.duration,dateColumns[j].intervalConfig.enableUTC,dateColumns[j].intervalConfig.weekStartFrom,dateColumns[j].startValFloorVal);break;default:dateColumns[j].value=dataRow[column.index]-(dataRow[column.index]-dateColumns[j].startValFloorVal)%dateColumns[j].intervalConfig.duration.ms;break}hashVal+=dateColumns[j].value+"-"}else{currentRow[j]=dataRow[column.index];hashVal+=dataRow[column.index]+"-"}}hashVal=hashVal.slice(0,-1);if(hashTable[hashVal]>=0){currentRow=newData[hashTable[hashVal]];cacheGroupCountIndex=hashTable[hashVal]}else{hashTable[hashVal]=hashCount++;for(var key in dateColumns){intervalObj=(0,_interval.interval)(dateColumns[key].value,dateColumns[key].intervalConfig);currentRow[key]=intervalObj}newData.push(currentRow);cacheGroupCountIndex=newData.length-1}cacheGroupCount[cacheGroupCountIndex]=cacheGroupCount[cacheGroupCountIndex]||{};currentRow&&_applyAggr(dataRow,schema,currentRow,groupConfigLength,aggrConfig,cacheColumnConfig,cacheGroupCount[cacheGroupCountIndex]);return hashCount}}function _applyAggr(dataRow,schema,lastEntry,entryIndex,aggrConfig,cacheColumnConfig,cacheGroupCountRow){var aggrConfigLength=aggrConfig.length,column,operation,count,i;for(i=0;i<aggrConfigLength;i++){column=cacheColumnConfig(aggrConfig[i].column,schema);if(dataRow[column.index]!==UNDEF&&dataRow[column.index]!==null){operation=aggrConfig[i].operation||"avg";switch(operation){case"sum":case"min":case"max":case"first":case"last":count=null;break;default:count=cacheGroupCountRow[i]=cacheGroupCountRow[i]&&cacheGroupCountRow[i]+1||1;break}lastEntry[entryIndex+i]=operation==="count"?count:_index.default.resolve(operation)(lastEntry[entryIndex+i]!==UNDEF?lastEntry[entryIndex+i]:null,dataRow[column.index],count)}}}var _default=exports.default=groupBy;
;