public mergeDataToDisplayStateAndTimeArrays()

in src/UXClient/Models/ChartComponentData.ts [82:243]


    public mergeDataToDisplayStateAndTimeArrays(data, aggregateExpressionOptions = null) {
        this.data = data;
        var newDisplayState: any = {};
        this.timeArrays = {};
        this.visibleTAs = {};
        this.allValues = [];
        this.allNumericValues = [];
        this.visibleTSCount = 0;
        this.fromMillis = Infinity;
        this.toMillis = 0;
        var aggregateCounterMap = {};

        this.usesSeconds = false;
        this.usesMillis = false;
        aggregateExpressionOptions = this.fillColors(aggregateExpressionOptions);
        let aggKeys = Utils.getAggKeys(this.data);

        this.data = this.data.map((aggregate: any, i: number) => {
            var aggName: string = Object.keys(aggregate)[0];
            let aggregateCopy = {...aggregate};
            let aggKey = aggKeys[i];

            this.data[i].aggKey = aggKey;
            aggregateCopy.aggKey = aggKey;
            
            if (this.displayState[aggKey]) {
                newDisplayState[aggKey] = {
                    visible: (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState) ? 
                    aggregateExpressionOptions[i].visibilityState[0] : this.displayState[aggKey].visible,
                    name: this.displayState[aggKey].name,
                    color: ((aggregateExpressionOptions[i] && aggregateExpressionOptions[i].color) ? 
                             aggregateExpressionOptions[i].color : this.displayState[aggKey].color),
                    interpolationFunction: aggregateExpressionOptions[i].interpolationFunction,
                    yExtent: aggregateExpressionOptions[i].yExtent,
                    includeEnvelope: aggregateExpressionOptions[i].includeEnvelope,
                    includeDots: aggregateExpressionOptions[i].includeDots,
                    splitBys: {},
                    dataType: aggregateExpressionOptions[i].dataType,
                    visibleSplitByCap: this.displayState[aggKey].visibleSplitByCap,
                    shownSplitBys: 20
                }
            } else {
                newDisplayState[aggKey] = {
                    visible: (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState) ? 
                        aggregateExpressionOptions[i].visibilityState[0] : true,
                    splitBys: {},
                    name: aggName,
                    color: ((aggregateExpressionOptions[i] && aggregateExpressionOptions[i].color) ? 
                             aggregateExpressionOptions[i].color : "teal"),
                    interpolationFunction: aggregateExpressionOptions[i].interpolationFunction,
                    yExtent: aggregateExpressionOptions[i].yExtent,
                    includeEnvelope: aggregateExpressionOptions[i].includeEnvelope,
                    includeDots: aggregateExpressionOptions[i].includeDots,
                    dataType: aggregateExpressionOptions[i].dataType,
                    visibleSplitByCap: 10,
                    shownSplitBys: 20
                }                    
            } 
            if (aggregateExpressionOptions) {
                newDisplayState[aggKey].contextMenuActions = aggregateExpressionOptions[i] ? 
                                                aggregateExpressionOptions[i].contextMenu : [];
                newDisplayState[aggKey].aggregateExpression = aggregateExpressionOptions[i];
                // impose cap on visible splitBys if relevant
                if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibleSplitByCap) {
                    newDisplayState[aggKey].visibleSplitByCap = aggregateExpressionOptions[i].visibleSplitByCap;
                }
            } else {
                //revert to previous context menu actions if no new ones passed in and old ones exist
                var oldContextMenuActions = (this.displayState[aggKey] && this.displayState[aggKey].contextMenuActions) ? 
                                                this.displayState[aggKey].contextMenuActions : [];
                newDisplayState[aggKey].contextMenuActions = oldContextMenuActions;
                var oldAggregateExpression = (this.displayState[aggKey] && this.displayState[aggKey].aggregateExpression) ? 
                                                this.displayState[aggKey].aggregateExpression : {};
                newDisplayState[aggKey].aggregateExpression = oldAggregateExpression;
            }
            if (newDisplayState[aggKey].aggregateExpression && newDisplayState[aggKey].aggregateExpression.searchSpan) {
                newDisplayState[aggKey].from = new Date(newDisplayState[aggKey].aggregateExpression.searchSpan.from);
                newDisplayState[aggKey].to = new Date(newDisplayState[aggKey].aggregateExpression.searchSpan.to);
                newDisplayState[aggKey].bucketSize = newDisplayState[aggKey].aggregateExpression.searchSpan.bucketSize ?
                    Utils.parseTimeInput(newDisplayState[aggKey].aggregateExpression.searchSpan.bucketSize) : 
                    null;
            }

            var aggregateVisible = newDisplayState[aggKey].visible;
            this.timeArrays[aggKey] = [];
            this.visibleTAs[aggKey] = {};

            Object.keys(data[i][aggName]).forEach((splitBy: string, splitByI: number) => {
                let shiftValue = Utils.parseShift(aggregateExpressionOptions[i].timeShift, 
                    aggregateExpressionOptions[i].startAt, 
                    aggregateExpressionOptions[i].searchSpan);
                this.timeArrays[aggKey][splitBy] = this.convertAggregateToArray(data[i][aggName][splitBy], aggKey, aggName, splitBy, 
                                                 newDisplayState[aggKey].from, newDisplayState[aggKey].to, 
                                                 newDisplayState[aggKey].bucketSize, shiftValue);  
                if (newDisplayState[aggKey].dataType === DataTypes.Categorical && aggregateExpressionOptions[i].rollupCategoricalValues){
                    this.timeArrays[aggKey][splitBy] = Utils.rollUpContiguous(this.timeArrays[aggKey][splitBy]);
                }             

                let isVisible;

                // first priority: set from passed in visibility state
                if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState && aggregateExpressionOptions[i].visibilityState.length === 2) {
                    isVisible = aggregateExpressionOptions[i].visibilityState[1].indexOf(splitBy) != -1;
                }
                //second priority: special case where solo split by and is ''
                else if (aggregateExpressionOptions[i] && aggregateExpressionOptions[i].visibilityState && Object.keys(data[i][aggName]).length === 1 && splitBy === '') {
                    isVisible = aggregateExpressionOptions[i].visibilityState[0];
                }
                // third priority: already set value
                else if (this.displayState[aggKey] && this.displayState[aggKey].splitBys[splitBy]) {
                    isVisible = this.displayState[aggKey].splitBys[splitBy].visible;
                }
                // last priority: set isVisible based on visibleSplitByCap 
                else {
                    isVisible = (splitByI < newDisplayState[aggKey].visibleSplitByCap);
                }
                
                newDisplayState[aggKey].splitBys[splitBy] = {
                    visible: isVisible,
                    visibleType: newDisplayState[aggKey].splitBys[splitBy] ? newDisplayState[aggKey].splitBys[splitBy].visibleType : null,
                    types: newDisplayState[aggKey].splitBys[splitBy] ? newDisplayState[aggKey].splitBys[splitBy].types : [],
                }
                if (this.timeArrays[aggKey][splitBy] && this.timeArrays[aggKey][splitBy].length && 
                    newDisplayState[aggKey].aggregateExpression && newDisplayState[aggKey].aggregateExpression.measureTypes) {
                    newDisplayState[aggKey].splitBys[splitBy].types = newDisplayState[aggKey].aggregateExpression.measureTypes
                } else {
                    newDisplayState[aggKey].splitBys[splitBy].types = this.determineMeasureTypes(this.timeArrays[aggKey][splitBy])
                }
                if (!newDisplayState[aggKey].splitBys[splitBy].visibleType || (newDisplayState[aggKey].splitBys[splitBy].types.indexOf(newDisplayState[aggKey].splitBys[splitBy].visibleType) === -1)){
                    var visibleMeasure = newDisplayState[aggKey].splitBys[splitBy].types.indexOf("avg") !== -1 ? "avg" : 
                        newDisplayState[aggKey].splitBys[splitBy].types[0];
                    newDisplayState[aggKey].splitBys[splitBy].visibleType = this.getVisibleType(aggKey, splitBy, visibleMeasure, newDisplayState[aggKey].splitBys[splitBy].types);
                }

                //add to visible display states if splitby is visible
                if (newDisplayState[aggKey]["splitBys"][splitBy]["visible"] && aggregateVisible) {
                    this.allValues = this.allValues.concat(this.timeArrays[aggKey][splitBy]);
                    if (newDisplayState[aggKey].dataType === DataTypes.Numeric) {
                        this.allNumericValues = this.allNumericValues.concat(this.timeArrays[aggKey][splitBy]);
                    }
                    this.usesSeconds = this.usesSeconds || this.doesTimeArrayUseSeconds(this.timeArrays[aggKey][splitBy]);
                    this.usesMillis = this.usesMillis || this.doesTimeArrayUseMillis(this.timeArrays[aggKey][splitBy]);
                    this.visibleTAs[aggKey][splitBy] = this.timeArrays[aggKey][splitBy];
                    this.visibleTSCount += 1;
                }
            });
            return aggregateCopy;
        });

        //ensure that the stickied Key exists in the new data, otherwise revert to null
        if (this.stickiedKey) {
            var splitBy = this.stickiedKey.splitBy;
            var aggKey = this.stickiedKey.aggregateKey;
            if (!(newDisplayState[aggKey] && newDisplayState[aggKey].visible &&
                 newDisplayState[aggKey].splitBys[splitBy] && newDisplayState[aggKey].splitBys[splitBy].visible)) {
                this.stickiedKey = null;
            }
        }

        this.displayState = newDisplayState;
        this.setAllTimestampsArray();
    }