Source: src/main/javascript/oracle/oj/ojcube/DataColumnCube.js

Oracle® JavaScript Extension Toolkit (JET)
1.1.2

E65298-01

/**
 * Copyright (c) 2015, Oracle and/or its affiliates.
 * All rights reserved.
 */
/*jslint browser: true*/


/**
 * @class oj.DataColumnCube
 * 
 * Creates an object used to convert rowset data into grouped "cubic" data, where the data values are specified by a single attribute within the rowset
 * (dataValues.labelAttr) and their header values designated by another rowset attribute (dataValues.valueAttr).
 *
 * @param {Array} rowset An array of objects containing attribute/value pairs.  The entire array or collection
 *                       will be read to group its attributes according to information given by layout and dataValues
 * @param {Array} layout An array of objects containing two properties: axis - a number representing the number of the axis of the levels;
 *                       levels - a slowest-to-fastest varying ordered array of objects containing:
 *                       attribute - an attribute of the rowset objects to assign to this axis and level.  If the attribute
 *                       is the same as that specified by labelAttr, then this level is the data value level
 * @param {Object} dataValues an object containing the following properties: labelAttr - the rowset attribute used to group the data values in the header
 *                            valueAttr - the rowset attribute used for the actual data values; (optional) defaultAggregation - the default type of
 *                            oj.CubeAggType to use to aggregate data values where necessary.  If the type is 'CUSTOM' then this should be an object with a 'type' property of oj.CubeAggType['CUSTOM'] and a 'callback' property specifying a function to call with each value.  The function takes two arguments, the first being the running value for the cell being calculated, the second being the new value to be aggregated with that running value; (optional) aggregation: an array of objects containing:
 *                            value - the value of labelAttr for which this aggregation should apply; aggregation - the oj.CubeAggType for that value; if aggregation is 'CUSTOM', then a 'callback' property should be added specifying a function (for arguments see above) to call with each value
 *                            (defaults to sum)
 * @see oj.Cube
 * @constructor
 * @since 1.1.0
* @export
 */
oj.DataColumnCube = function(rowset, layout, dataValues) {
    this.Init();
    this._dataValues = dataValues;
    this._valueAttr = dataValues['valueAttr'];
    this._labelAttr = dataValues['labelAttr'];
    var defAgg = dataValues['defaultAggregation'];
    this._defaultAggregation = defAgg ? oj.DataColumnCube._getDefaultAgg(defAgg) : {aggregation:oj.CubeAggType['SUM']};
    this._aggregation = dataValues['aggregation'];
    this._buildAggTypeLookup();
    
    oj.DataColumnCube.superclass.constructor.call(this, rowset, layout);
};

// Subclass from oj.Cube 
oj.Object.createSubclass(oj.DataColumnCube, oj.Cube, "oj.DataColumnCube");

/**
 * Initializes instance with the set options
 * @private
 */
oj.DataColumnCube.prototype.Init = function() 
{
  oj.DataColumnCube.superclass.Init.call(this);
};

oj.DataColumnCube.prototype.BuildCube = function() {
    oj.DataColumnCube.superclass.BuildCube.call(this);
};

oj.DataColumnCube.prototype.GetAggType = function(dataValue) {
    if (this._dataValueAggType[dataValue]) {
        return this._dataValueAggType[dataValue];
    }
    return this._defaultAggregation;
};

oj.DataColumnCube.prototype.GenerateCube = function(layout) {
    return new oj.DataColumnCube(null, layout, this._dataValues);
};

oj.DataColumnCube.prototype.GenerateLevel = function(level, axis) {    
    if (level['attribute'] === this._labelAttr) {
        // Data value level
        return new oj.CubeLevel(level['attribute'], axis, true);
    }
    // Regular level
    return new oj.CubeLevel(level['attribute'], axis, false);
};

oj.DataColumnCube.prototype.ProcessLevel = function(axis, levelNum, currNode, row, keys, addKeys) {
    if (levelNum >= axis.getLevels().length) {
        return keys;
    }
    var level = axis.getLevels()[levelNum];
    
    // Not the data value: process this and call for the next
    var value = row[level['attribute']];
    var node = currNode.AddNode(value, null, level);
    
    if (level.isDataValue()) {
        keys.AddDataValue(value, row[this._valueAttr]);
    }
    else {
        keys.UpdateKeys(node);
    }    
    
    return this.ProcessLevel(axis, levelNum+1, node, row, keys, addKeys);
};

oj.DataColumnCube._getDefaultAgg = function(agg) {
    if (oj.StringUtils.isString(agg)) {
        return {aggregation:agg};
    }
    return {aggregation:agg['aggregation'],callback:agg['callback']};
};
    
oj.DataColumnCube.prototype._buildAggTypeLookup = function() {
    this._dataValueAggType = [];
    if (this._aggregation) {
        for (var i = 0; i < this._aggregation.length; i++) {
            var dv = this._aggregation[i];
            var agg = dv['aggregation'];
            this._dataValueAggType[dv['value']] = agg ? {aggregation:agg, callback:dv['callback']} : this._defaultAggregation;
        }
    }
};