123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- '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. 2019, 2021
- * 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/QueryProviderAPI', '../../../filters/FilterQuerySpec', '../../../apiHelpers/SlotAPIHelper', './QueryDataItemBuilder', './DataQueryUtils', '../../../lib/@waca/core-client/js/core-client/utils/BrowserUtils', '../../../widgets/livewidget/query/CommonQueryBuilder', 'underscore'], function (APIFactory, QueryProviderAPI, FilterQuerySpec, SlotAPIHelper, QueryDataItemBuilder, DataQueryUtils, BrowserUtils, CommonQueryBuilder, _) {
- var _class, _temp;
- var QueryProvider = (_temp = _class = function () {
- function QueryProvider(_ref) {
- var content = _ref.content,
- dashboardAPI = _ref.dashboardAPI;
- _classCallCheck(this, QueryProvider);
- this.content = content;
- this.dashboard = dashboardAPI;
- this.content.getFeature('DataQueryExecution').registerQueryProvider(this.getAPI());
- }
- QueryProvider.prototype.getAPI = function getAPI() {
- if (!this.api) {
- this.api = APIFactory.createAPI(this, [QueryProviderAPI]);
- }
- return this.api;
- };
- QueryProvider.prototype.getType = function getType() {
- return 'main';
- };
- /**
- * @returns a list of query specs.
- */
- QueryProvider.prototype.getQuerySpecList = function getQuerySpecList() {
- var _this = this;
- var visualization = this.content.getFeature('Visualization');
- var dataSource = visualization.getDataSource();
- var dataSourceId = dataSource && dataSource.getId();
- var mappedSlotsList = visualization.getSlots().getMappedSlotList();
- var layerToQuerySlotsMap = new Map();
- var mappingCompleteLayerList = this._getMappingCompleteLayers() || [];
- var _loop = function _loop(i) {
- var slot = mappedSlotsList[i];
- if (_this._canQuery(slot)) {
- var layerIds = slot.getDefinition().getDatasetIdList();
- layerIds.forEach(function (layerId) {
- if (mappingCompleteLayerList.indexOf(layerId) === -1) {
- //skip the layer if the required slots for that layer are NOT filled
- return;
- }
- if (!layerToQuerySlotsMap.has(layerId)) {
- layerToQuerySlotsMap.set(layerId, []);
- }
- layerToQuerySlotsMap.get(layerId).push(slot);
- });
- }
- };
- for (var i = 0; i < mappedSlotsList.length; i++) {
- _loop(i);
- }
- var querySpecList = [];
- var mainQuerySpecList = this._getMainQuerySpecList(layerToQuerySlotsMap);
- querySpecList.push.apply(querySpecList, mainQuerySpecList);
- querySpecList.push.apply(querySpecList, this._getMinMaxQuerySpecList(layerToQuerySlotsMap, mainQuerySpecList));
- for (var j = 0; j < querySpecList.length; j++) {
- querySpecList[j].dataSourceId = dataSourceId;
- }
- return querySpecList;
- };
- QueryProvider.prototype._getMappingCompleteLayers = function _getMappingCompleteLayers() {
- var visualization = this.content.getFeature('Visualization');
- var datasetIds = visualization.getDefinition().getDatasetList().map(function (dataset) {
- return dataset.id;
- });
- var slots = visualization.getSlots();
- return datasetIds.filter(function (id) {
- return slots.isMappingComplete(id);
- });
- };
- QueryProvider.prototype._getQuerySpecLimit = function _getQuerySpecLimit() {
- //DEFAULT limit
- var dataRowLimit = QueryProvider.DEFAULT_ROWLIMIT;
- var definition = this.content.getFeature('Visualization').getDefinition();
- if (definition.getProperty('dataRowLimit')) {
- //Some charts have difficulty rendering a large set of rows, in this case, a smaller dataRowLimit is set in the definition.
- dataRowLimit = definition.getProperty('dataRowLimit');
- // Reduce data limit on IE
- if (BrowserUtils.isIE() && definition.getProperty('dataRowLimitIE')) {
- dataRowLimit = definition.getProperty('dataRowLimitIE');
- }
- }
- return dataRowLimit;
- };
- QueryProvider.prototype._getMainQuerySpecList = function _getMainQuerySpecList(layerToQuerySlotsMap) {
- var _this2 = this;
- var queryDataItemBuilder = this._getQueryDataItemBuilder(layerToQuerySlotsMap);
- var querySpecList = [];
- var outputEdgeFilterExceptions = [];
- var queryHints = this._getQueryHints(layerToQuerySlotsMap);
- layerToQuerySlotsMap.forEach(function (querySlots, layerId) {
- var specObject = {
- id: layerId,
- type: 'main',
- spec: {
- version: '1',
- dataItems: [],
- projections: [],
- limit: _this2._getQuerySpecLimit()
- }
- };
- querySlots.forEach(function (slot) {
- var _specObject$spec$proj, _specObject$spec$data;
- (_specObject$spec$proj = specObject.spec.projections).push.apply(_specObject$spec$proj, _this2._getProjectionsForSlot(slot));
- (_specObject$spec$data = specObject.spec.dataItems).push.apply(_specObject$spec$data, _this2._getDataItemsForSlot(slot, queryDataItemBuilder, outputEdgeFilterExceptions));
- });
- var excludeNonProjectedRangeFilters = DataQueryUtils.shouldExcludeNonProjectedRangeFilters(layerToQuerySlotsMap, layerId);
- var filters = _this2._getFilters(layerId, outputEdgeFilterExceptions, excludeNonProjectedRangeFilters);
- if (filters && filters.length) {
- specObject.spec.filters = filters;
- }
- /**
- * @todo: useAPI. should check for empty queryHints.
- * but for now we reserve the same behavior as current that it includes empty queryHints.
- * if (_.keys(queryHints).length) { specObject.spec.queryHints = queryHints; }
- */
- specObject.spec.queryHints = queryHints;
- var suppression = _this2._getSuppression();
- if (suppression) {
- specObject.spec.suppress = [suppression];
- }
- querySpecList.push(specObject);
- });
- return querySpecList;
- };
- QueryProvider.prototype._findDataItemInSlotsById = function _findDataItemInSlotsById(slots, id) {
- var _dataItem = void 0;
- slots.forEach(function (slot) {
- slot.getDataItemList().forEach(function (dataItem) {
- if (dataItem.getId() === id) {
- _dataItem = dataItem;
- }
- });
- });
- return _dataItem;
- };
- QueryProvider.prototype._getMinMaxQuerySpecList = function _getMinMaxQuerySpecList(layerToQuerySlotsMap, mainQuerySpecList) {
- var _this3 = this;
- var minMaxQuerySpecList = [];
- var shouldAxisScaleBeFixed = this.content.getPropertyValue('maintainAxisScales');
- layerToQuerySlotsMap.forEach(function (querySlots, layerId) {
- var containsCategorySlots = !!querySlots.find(function (slot) {
- return slot.getDataItemList()[0].getType() === 'attribute';
- });
- if (shouldAxisScaleBeFixed && containsCategorySlots) {
- var mainQuerySpecObj = mainQuerySpecList.find(function (obj) {
- return obj.id === layerId;
- });
- var projectionsAndDataItems = {
- dataItems: mainQuerySpecObj.spec.dataItems,
- limit: mainQuerySpecObj.spec.limit
- };
- var minMaxProjections = JSON.parse(JSON.stringify(mainQuerySpecObj.spec.projections));
- minMaxProjections = minMaxProjections.filter(function (id) {
- var dataItem = _this3._findDataItemInSlotsById(querySlots, id);
- return dataItem && dataItem.getType() === 'fact';
- });
- // No need for a minmax query when no measures are projected
- if (minMaxProjections && minMaxProjections.length) {
- projectionsAndDataItems.projections = minMaxProjections;
- var aItemsToExclude = [];
- querySlots.forEach(function (slot) {
- if (slot.getDefinition().getProperty('useInTopBottomQueries') === false) {
- aItemsToExclude = aItemsToExclude.concat(slot.getDataItemList().map(function (dataItem) {
- return dataItem.getId();
- }));
- } else if (slot.isStacked()) {
- // If the slot is stacked and has multiple data items then we can not add it to the min max query
- // In this scenario the slot is shown as a nested set of data items and we need to remove using the id.
- aItemsToExclude = aItemsToExclude.concat(slot.getId());
- }
- });
- // Make one query to get min and max only with the fields from the current widget, plus the global filters and slicers (filters from other widgets).
- var topBottomQuery = CommonQueryBuilder.buildMinMaxQueryFromDataItems(projectionsAndDataItems, {
- 'itemsToExclude': aItemsToExclude
- }, _this3.dashboard.getGlassCoreSvc('.Logger'));
- minMaxQuerySpecList.push({
- id: layerId,
- type: 'minmax',
- spec: topBottomQuery
- });
- }
- }
- });
- return minMaxQuerySpecList;
- };
- QueryProvider.prototype._canQuery = function _canQuery(slot) {
- // If the slot has a multimeasure series item and
- // it is the one and only item in the slot, we can't generate a query from the slot.
- return !(SlotAPIHelper.isMultiMeasuresSeriesSlot(slot) && !slot.isStacked());
- };
- QueryProvider.prototype._isSlotWithStackedProjection = function _isSlotWithStackedProjection(slot) {
- // if the slot contains at least 2 items(except multi-measure) and it is stacked(slotDefinition)
- var validDataItems = SlotAPIHelper.getValidDataItems(slot);
- return slot.isStacked() && validDataItems.length > 1;
- };
- /**
- * return the projections for the specified slot
- * @param {*} querySlot queriable slot
- */
- QueryProvider.prototype._getProjectionsForSlot = function _getProjectionsForSlot(querySlot) {
- if (this._isSlotWithStackedProjection(querySlot)) {
- return [querySlot.getId()];
- } else {
- var validDataItems = SlotAPIHelper.getValidDataItems(querySlot);
- return validDataItems.map(function (dataItem) {
- return dataItem.getId();
- });
- }
- };
- /**
- * return the dataItems for the specified slot
- * @param {*} querySlot queriable slot
- * @param {*} queryDataItemBuilder
- */
- QueryProvider.prototype._getDataItemsForSlot = function _getDataItemsForSlot(querySlot, queryDataItemBuilder, outputEdgeFilterExceptions) {
- var validDataItems = SlotAPIHelper.getValidDataItems(querySlot);
- var dataItemQuerySpecs = validDataItems.map(function (dataItem) {
- var itemSpec = queryDataItemBuilder.build(dataItem, querySlot, outputEdgeFilterExceptions);
- return itemSpec;
- });
- if (this._isSlotWithStackedProjection(querySlot)) {
- dataItemQuerySpecs.push({
- id: querySlot.getId(),
- nest: validDataItems.map(function (item) {
- return item.getId();
- })
- });
- }
- return dataItemQuerySpecs;
- };
- QueryProvider.prototype._getQueryDataItemBuilder = function _getQueryDataItemBuilder(layerToQuerySlotsMap) {
- var internalVisualization = this.content.getFeature('Visualization.internal');
- var dataItemList = internalVisualization.getSlots().getDataItemList();
- var applyServerSort = dataItemList && _.find(dataItemList, function (dataItem) {
- return dataItem.getColumnId() === '_multiMeasuresSeries';
- }) !== undefined;
- return new QueryDataItemBuilder({
- internalVisualization: internalVisualization,
- layerToQuerySlotsMap: layerToQuerySlotsMap,
- applyServerSort: applyServerSort
- });
- };
- QueryProvider.prototype._getFilters = function _getFilters(layerId, outputEdgeFilterExceptions, excludeNonProjectedRangeFilters) {
- var internalVisualization = this.content.getFeature('Visualization.internal');
- var localFilterList = internalVisualization.getLocalFilters().getFilterList();
- var updatedFilterSpecList = DataQueryUtils.convertExcludeEmptyValuesFilters(localFilterList, internalVisualization.getDataSource());
- var searchFilters = internalVisualization.getSearchFilterList();
- var filterSpec = new FilterQuerySpec(internalVisualization);
- var hasSharedSlot = !!internalVisualization.getDefinition().getSlotList().find(function (slot) {
- return slot.getDatasetIdList().length > 1;
- });
- filterSpec.addFiltersToSpec(updatedFilterSpecList, {
- layerId: layerId,
- edgeFilterExceptions: outputEdgeFilterExceptions,
- excludeNonProjectedRangeFilters: excludeNonProjectedRangeFilters,
- projectInAllLayers: hasSharedSlot
- });
- filterSpec.addFiltersToSpec(searchFilters, {
- layerId: layerId
- });
- return filterSpec.hasFilterSpec() ? filterSpec.getFilterSpec() : null;
- };
- /**
- * Turn on multiEdgeSort based on following rules:
- * 1: if slot is isMultiMeasuresSeries and is Rank, does not consider as edge
- * 2: if slot is isMultiMeasuresSeries and is stacked, considered as one edge
- * 3: if slot is stacked, it is considered as one edge
- * 4: if slot is of type ordinal, does not consider as edge
- * if number of edges is more than one, then turn on multiEdgeSort otherwise not
- * @return {boolean} true if number of edges to sort is more than 1.
- * @private
- */
- QueryProvider.prototype._isMultiEdgeSortNeeded = function _isMultiEdgeSortNeeded(layerToQuerySlotsMap) {
- var visualization = this.content.getFeature('Visualization');
- if (!visualization.getDefinition().getMultiEdgeSort()) {
- return false;
- }
- var numberOfEdges = 0;
- layerToQuerySlotsMap.forEach(function (querySlots) {
- querySlots.forEach(function (slot) {
- var dataItems = slot.getDataItemList();
- if (dataItems.length > 0 && dataItems[0].getType() !== 'fact') {
- numberOfEdges++;
- }
- });
- });
- return numberOfEdges > 1;
- };
- QueryProvider.prototype._getSuppression = function _getSuppression() {
- var suppression = this.content.getPropertyValue('suppression');
- if (suppression === QueryProvider.SUPPRESSION_NONE) {
- return QueryProvider.SUPPRESSION_NONE;
- }
- };
- QueryProvider.prototype._getQueryHints = function _getQueryHints(layerToQuerySlotsMap) {
- var queryHints = {};
- var suppression = this._getSuppression();
- if (suppression) {
- queryHints.suppress = suppression;
- }
- if (this._isMultiEdgeSortNeeded(layerToQuerySlotsMap)) {
- queryHints.multiEdgeSort = true;
- }
- var refreshProperty = this.content.getPropertyValue('queryRefresh');
- if (refreshProperty && refreshProperty.autoRefresh) {
- // Set the dataCacheExpiry to 40% of the refresh time
- var refreshValue = refreshProperty.value;
- var dataCacheExpiryValue = void 0;
- switch (refreshProperty.unit) {
- case 'seconds':
- dataCacheExpiryValue = parseInt(refreshValue * 4 / 10) || 1;
- break;
- case 'minutes':
- dataCacheExpiryValue = parseInt(refreshValue * 60 * 4 / 10) || 1;
- break;
- case 'hours':
- dataCacheExpiryValue = parseInt(refreshValue * 3600 * 4 / 10) || 1;
- break;
- default:
- dataCacheExpiryValue = 1;
- }
- queryHints.dataCacheExpiry = dataCacheExpiryValue.toString();
- queryHints.autoRefreshTime = '' + Date.now();
- }
- return queryHints;
- };
- return QueryProvider;
- }(), _class.DEFAULT_ROWLIMIT = 3000, _class.SUPPRESSION_NONE = 'none', _temp);
- return QueryProvider;
- });
- //# sourceMappingURL=QueryProvider.js.map
|