'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 Cloud (C) Copyright IBM Corp. 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['../../../../lib/@waca/dashboard-common/dist/core/APIFactory', './api/SelectedAPI', '../../../../util/EventUtils', 'underscore'], function (APIFactory, SelectedAPI, EventUtils, _) { /** * VisSelected provides a fast lookup on the selected values for a particular item or tuple. */ var VisSelected = function () { /** * constructor attributes: * pageContextAPI - the pageContextAPI * itemIds - an array of itemIds */ function VisSelected(attributes) { var _this = this; _classCallCheck(this, VisSelected); this._includeParents = attributes.includeParents; this._ignoreEdgeSelections = attributes.ignoreEdgeSelections; this._edgeSelections = []; this._pointSelections = {}; this._selectedParents = {}; this._pageContextAPI = attributes.pageContextAPI; this._itemIds = attributes.itemIds; this._sourceId = attributes.sourceId; this.synchronizeData = attributes.synchronizeData; var pageContextMatchParams = { origin: 'visualization', scope: attributes.scope, eventGroupId: attributes.eventGroupId }; if (!this._ignoreEdgeSelections) { _.each(this._itemIds, function (itemId) { var pci = _this.synchronizeData.getPageContextItem(_this._sourceId, _this._pageContextAPI, itemId, pageContextMatchParams); if (pci && pci.getValueCount()) { var selectedValueMap = {}; var aTupleValues = []; _.each(pci.getValueIds(), function (valueId) { selectedValueMap[valueId] = 1; aTupleValues.push(valueId); }); _this._edgeSelections.push(selectedValueMap); } else { _this._edgeSelections.push({}); } }); } //Lookup pageContext entries for the items of interest and place the selected datapoints (if any) in a map. var hierarchies = _.map(this._itemIds, function (itemId) { return { hierarchyUniqueName: itemId }; }); for (var i = this._itemIds.length; i > 1; --i) { this._addDataPointSelections(_.head(hierarchies, i), pageContextMatchParams, attributes.includeParents); } //Cache 'parent selected points' to detect is something is a 'selectedChild point' (selectedChild points of edges are handled above) //A selected child point/cell is not really selected itself but are highlighted if there are selections of 'parent points' //When asking if point A.B.C is selected, we want to know if A.B is selected so that we can return it as a 'selectedChild'. //When asking if A.B.C.D is selected we want to know if A.B, A.B.C or B.C are selected so that we can return it as a 'selectedChild' for (var start = 0; start < this._itemIds.length - 1; ++start) { for (var end = this._itemIds.length; end > start + 1; --end) { //Set includeParents to false for selected children...we don't want to process parents of selected children again. this._addDataPointSelections(hierarchies.slice(start, end), pageContextMatchParams, /*includeParents*/false); } } } VisSelected.prototype.getAPI = function getAPI() { if (!this._api) { this._api = APIFactory.createAPI(this, [SelectedAPI]); } return this._api; }; VisSelected.prototype._addDataPointSelections = function _addDataPointSelections(hierarchies, pageContextMatchParams, includeParents) { var pcpoint = this._pageContextAPI.getPageContextItem(_.extend({ hierarchies: hierarchies }, pageContextMatchParams)); if (pcpoint && pcpoint.getValueCount()) { _.each(pcpoint.getDataPoints(), function (dataPoint) { this._pointSelections[this._getDataPointKey(dataPoint)] = 1; if (includeParents) { this._addSelectedParents(this._itemIds, dataPoint); } }.bind(this)); } }; /** * Given Year, Product, OrderMethod, gender * 2007, cars, fax, male * Year=2007 * Year=2007__Product=Cars * Year=2007__Product=Cars__OrderMethod=Fax * Year=2007__Product=Cars__OrderMethod=Fax__Gender=male * Product=cars * Product=cars__OrderMethod=fax * Product=cars__OrderMethod=fax__gender=male * OrderMethod=fax__gender=male * gender=male * * ASSUMPTION - all items from the beginning of an edge are provided * @return true for any in-order permutation */ VisSelected.prototype._addSelectedParents = function _addSelectedParents(itemIds, dataPoint) { //Generate a tuple for each of length 1 to length n-1 where n-1 is the length of the array. var itemList = itemIds; var tuple = dataPoint; while (itemList.length > 0) { for (var tupleLength = 1; tupleLength < itemList.length; ++tupleLength) { this._selectedParents[this._getParentKey(_.first(itemList, itemList.length), _.first(tuple, tupleLength))] = 1; } itemList = _.rest(itemList); tuple = _.rest(tuple); } }; /** * length of the longest selected point * AxBxC returns 3 * AxB returns 2 */ VisSelected.prototype._getMaxPointSelectionLength = function _getMaxPointSelectionLength() { var max = 0; var selections = Object.getOwnPropertyNames(this._pointSelections); for (var i = 0; i < selections.length; i++) { max = Math.max(selections[i].split(EventUtils.SEPARATOR).length, max); } return max; }; /** * @param tuple - a tuple of form [ { u:'x'}, { u:'y'} ] where each entry in the array corresponds to the itemIds array. * (also supports form [ 'x', 'y'] ) where x and y are assumed to be use values. * example: isSelected [ {u:'2005'}, {u:'Fax'} ] */ VisSelected.prototype.isSelected = function isSelected(tuple) { //First process the edges....For edges, if at least 1 is selected, the node is selected. for (var i = 0; i < tuple.length; ++i) { if (tuple[i] && _.isObject(this._edgeSelections[i]) && this._edgeSelections[i][tuple[i].u || tuple[i]]) { //Any match of an edge is a match. return true; } } //Process dataPoints....it has to be an exact match. if (this._pointSelections[this._getDataPointKey(tuple)]) { return true; } //if 'A' is a selected value, A.B is a selectedChild, A.B.C is a selectedChild etc. //if 'A.B' is a selected datapoint, A.B.C is a selectedChild (A is a parent) //if 'A.B.C' is a selected datapoint, A.B.C.D is a selectedChild but so is B.C.D (A.B, A are parents) var maxLength = this._getMaxPointSelectionLength(); for (var start = 0; start < tuple.length; ++start) { for (var end = tuple.length; end >= start; --end) { var slice = tuple.slice(start, end); if (slice.length <= maxLength && this._pointSelections[this._getDataPointKey(slice)]) { return true; } } } return false; }; VisSelected.prototype.isSelectedParent = function isSelectedParent(hierarchies, dataPoint) { return this._selectedParents[this._getParentKey(hierarchies, dataPoint)] ? true : false; }; /** * Same as isSelected but for a simple value object. * @param value - a value of form { u: 'x' } */ VisSelected.prototype.isValueSelected = function isValueSelected(value) { return this.isSelected([value]); }; VisSelected.prototype.hasSelections = function hasSelections() { var hasEdgeSelections = _.find(this._edgeSelections, function (edge) { return _.keys(edge).length > 0; }); return hasEdgeSelections || _.keys(this._pointSelections).length ? true : false; }; VisSelected.prototype._getDataPointKey = function _getDataPointKey(dataPoint) { return EventUtils.getDataPointKey(dataPoint); }; VisSelected.prototype._getParentKey = function _getParentKey(hierarchies, dataPoint) { var key = ''; var tempDataPoint = _.clone(dataPoint); //Make a copy to sort and keep dataPoint unchanged. var sortedDataPoint = tempDataPoint.sort(EventUtils.compareDataPointKey); _.each(sortedDataPoint, function (tuplePart, partIdx) { key += hierarchies[partIdx] + '=' + tuplePart.u + EventUtils.SEPARATOR; }); return key.slice(0, -1); }; VisSelected.prototype.getSelectedKeys = function getSelectedKeys() { var selectedKeys = []; //Get edge selection keys _.each(this._edgeSelections, function (edgeSelection) { selectedKeys = selectedKeys.concat(_.keys(edgeSelection)); }); //Get datapoint keys selectedKeys = selectedKeys.concat(_.keys(this._pointSelections)); return selectedKeys; }; return VisSelected; }(); return VisSelected; }); //# sourceMappingURL=VisSelected.js.map