'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| IBM Cognos Products: BI Dashboard *| (C) Copyright IBM Corp. 2020 *| *| US Government Users Restricted Rights - Use, duplication or disclosure *| restricted by GSA ADP Schedule Contract with IBM Corp. *+------------------------------------------------------------------------+ */ define([], function () { 'use strict'; /** * This object hides the implementation of the pt array and allows a caller to have keyed access to point information. * The initial use is as a postProcessor helper. * The hope longer term is for DataQueryResultV2 to use this class rather than the pt array. * * For any key, all measure/calculation values can be accessed * AND, if a point does not exist, a null point will be returned. **/ return function () { /** * * @param {integer} edgeCount - the count of the number of edges in the result. * @param {integer} measureCount - the count of the number of measures (and calcs) in the result. * @param {integer} measureEdgeIdx - the edge where the measure is * @param {*} suppressionEnabled - true if suppression is enabled (used to determine the null value string) */ function QueryResultDataPointsV2(edgeCount, measureCount) { var measureEdgeIdx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1; var suppressionEnabled = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; _classCallCheck(this, QueryResultDataPointsV2); this._edgeCount = edgeCount; this._measureCount = measureCount; this._measureEdgeIdx = measureEdgeIdx; //If we extend to support single edge, this will be -1. this.missingValue = suppressionEnabled ? '' : null; this._measureMap = {}; this._createNullValueTemplate(); this._nullMeasureArray = this._createNullMeasureArray(); } /** * Return a point that corresponds to one or two edgeIds in '{ pt: [] }' form. * NOTE: This API is not called getPoint() because in future, we should have getPoint() * return a QueryResultDataPointAPI. * @param {integer} edge1Id * @param {integer=null} [edge2Id] * @returns a dataPoint in "pt form" - { pt: [] } */ QueryResultDataPointsV2.prototype.getPtByEdgeIds = function getPtByEdgeIds(edge1Id) { var edge2Id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var currentCell = this._measureMap[this._getPointKey(edge1Id, edge2Id)]; //If a pt exists at this coordinate, 'consume it', otherwise, fill with a null. if (currentCell && currentCell[0] === edge1Id && (edge2Id === null || currentCell[1] === edge2Id)) { return { pt: currentCell }; } return this._newNullValue(edge1Id, edge2Id); }; /** * Load points into an internal structure that can be accessed with get methods. * This api expects an input value list in the form that is returned in the dss response. * (internally, it stores a map of arrays similar to the pt array but this is not necessay longer term) * @param {*} valueList - the pt array as returned in the DSS response. */ QueryResultDataPointsV2.prototype.loadPoints = function loadPoints(valueList) { //Read the data and fill values in based on the measure being processed var measureMap = {}; for (var pointIdx = 0; pointIdx < valueList.length; ++pointIdx) { var point = valueList[pointIdx]; if (point.pt) { var currentMeasureNum = point.pt[this._measureEdgeIdx]; //Read the measureNum out of the point. //To merge measures into 1 pt entry, get the "pointKey" //(entries in the point excluding measure. eg 0,1 for col 0, row 1) var pointKey = this._buildPointKey(point.pt, this._measureEdgeIdx); var valueIndex = point.pt.length - 1; var pointValue = point.pt[valueIndex]; if (measureMap[pointKey]) { //This case will occur when there are multiple measures and we need to augment the entry //with a new measure value. Set the value for the nth measure into the existing map. var mapEntry = measureMap[pointKey]; mapEntry[valueIndex + currentMeasureNum] = pointValue; } else if (this._measureCount === 1) { //1 measure optimization: (and no calculations) case... //Since the internal form of a map entry is identical to the content of the pt array //and we aren't modifying it, we can simply use the original pt array for this point. //NOTE: This optimization would be invalid if the internal map entry format is changed. measureMap[pointKey] = point.pt; } else { //multi-measure case: create an array with measureCount 'null value' object references, //Replace the n'th measure with the non-null value. //NOTE: the result can be any combination of nulls and non-nulls depending on which measures have values. //[edge#,edge#,measureEdge,{ v:null}, { v:null } ... ] var newValue = this._nullMeasureArray.slice(0); newValue[currentMeasureNum] = pointValue; var newPt = point.pt.slice(0, valueIndex); newPt = newPt.concat(newValue); measureMap[pointKey] = newPt; } } } this._measureMap = measureMap; }; /** * @returns a count of the number of measures as passed in the constructor. */ QueryResultDataPointsV2.prototype.getMeasureCount = function getMeasureCount() { return this._measureCount; }; /** * @returns the edge where the measure is defined (or -1 if there is no measure edge) */ QueryResultDataPointsV2.prototype.getMeasureEdgeIndex = function getMeasureEdgeIndex() { return this._measureEdgeIndex; }; /** * @returns the size of the first categorical edge */ QueryResultDataPointsV2.prototype.getFirstEdgeSize = function getFirstEdgeSize(edges) { return this._getEdgeSize(edges, this._getFirstEdgeIndex()); }; /** * @returns the size of the second categorical edge (or null) */ QueryResultDataPointsV2.prototype.getSecondEdgeSize = function getSecondEdgeSize(edges) { var secondEdgeIndex = this._getSecondEdgeIndex(); return secondEdgeIndex !== null ? this._getEdgeSize(edges, secondEdgeIndex) : null; }; //Build a "point key" which is the value of a data row minus the measure index and measure value. //EXAMPLES: 2-edge crosstab point: [1, 0, { v:x }] ... key = 1 // 3-edge crosstab point: [1, 3, 0, { v: x }] ... key = 1,3 QueryResultDataPointsV2.prototype._buildPointKey = function _buildPointKey(pt, measureEdgeIdx) { var pointKey = []; pt.forEach(function (part, partIdx) { //In v2, a pt has a single cell value { v:x } as the last entry in the array. Exclude it from the key. if (partIdx !== measureEdgeIdx && partIdx < pt.length - 1) { pointKey.push(pt[partIdx]); } }); return pointKey.join(','); }; QueryResultDataPointsV2.prototype._getPointKey = function _getPointKey(edge1Id) { var edge2Id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; return edge1Id + (edge2Id !== null ? ',' + edge2Id : ''); }; //Generate a "null value entry" which is { pt: [ , , 0, { v: null} ] QueryResultDataPointsV2.prototype._newNullValue = function _newNullValue(ptFirstEdgeId) { var ptSecondEdgeId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var nullPt = this._nullValueTemplate.slice(0); //Set firstEdge as specified. nullPt[this._getFirstEdgeIndex()] = ptFirstEdgeId; if (ptSecondEdgeId !== null) { //Set edge1 as specified. nullPt[this._getSecondEdgeIndex()] = ptSecondEdgeId; } return { pt: nullPt }; }; //a null value template is a pt entry with 2 edge or 3 edge form and n { v:null } entries...1 per measure. //eg: [0, 0, 0, { v: null}, { v: null }] for a 3 edge, 2 measure crosstab. //It is used whenever we need to add a null as a starting point (then edgeId's are filled in.) QueryResultDataPointsV2.prototype._createNullValueTemplate = function _createNullValueTemplate() { this._nullValueTemplate = []; for (var i = 0; i < this._edgeCount; ++i) { this._nullValueTemplate.push(0); } this._nullValueTemplate = this._nullValueTemplate.concat(this._createNullMeasureArray()); }; QueryResultDataPointsV2.prototype._createNullMeasureArray = function _createNullMeasureArray() { var nullMeasureArray = []; for (var i = 0; i < this._measureCount; ++i) { nullMeasureArray.push({ v: this.missingValue }); } return nullMeasureArray; }; //The edge size is the number of items in the item array for an edge (minus the hasNext item) QueryResultDataPointsV2.prototype._getEdgeSize = function _getEdgeSize(edges, edgeIndex) { var edgeItems = edges[edgeIndex] && edges[edgeIndex].items; var edgeSize = edgeItems && edgeItems.length; if (edgeSize && edgeItems[edgeSize - 1].hasNext) { edgeSize--; } return edgeSize; }; QueryResultDataPointsV2.prototype._getFirstEdgeIndex = function _getFirstEdgeIndex() { return this.getMeasureEdgeIndex() === 0 ? 1 : 0; }; QueryResultDataPointsV2.prototype._getSecondEdgeIndex = function _getSecondEdgeIndex() { return this._edgeCount === 3 ? this._getFirstEdgeIndex() + 1 : null; }; return QueryResultDataPointsV2; }(); }); //# sourceMappingURL=QueryResultDataPoints.v2.js.map