123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- '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. 2018, 2020
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- define(['./Utils', './VisRecommenderDelegator', '../../../api/impl/Visualization', '../../../widgets/livewidget/models/LiveWidgetModel'], function (Utils, VisRecommenderDelegator, Visualization, LiveWidgetModel) {
- 'use strict';
- var VisualizationSmartsRecommender = function () {
- function VisualizationSmartsRecommender(_ref) {
- var features = _ref.features;
- _classCallCheck(this, VisualizationSmartsRecommender);
- this.features = features;
- this.transaction = features['Transaction'];
- this.state = features['state.internal'];
- this.logger = features['Logger'];
- this.visDefinitions = this.features['VisDefinitions'];
- this.moserDataSources = this.features['DataSources.moser'];
- this._visRecommenderDelegator = new VisRecommenderDelegator({
- dataSources: this.features['DataSources'],
- moserDataSources: this.moserDataSources,
- visDefinitions: this.visDefinitions,
- dashboardApi: this.features['Dashboard.API'],
- logger: this.logger
- });
- }
- VisualizationSmartsRecommender.prototype.destroy = function destroy() {
- this.features = null;
- this.transaction = null;
- this.state = null;
- this.logger = null;
- this.visDefinitions = null;
- this.creationTransactionToken = null;
- this._visRecommenderDelegator = null;
- };
- VisualizationSmartsRecommender.prototype.getAPI = function getAPI(type) {
- if (type === 'deprecated') {
- return this._deprecatedAPI;
- }
- return this._api;
- };
- VisualizationSmartsRecommender.prototype.isValidDataSource = function isValidDataSource(visualization) {
- return visualization.getDataSource() && visualization.getDataSource().getState() !== 'error';
- };
- VisualizationSmartsRecommender.prototype.getRecommendedVisualizations = function getRecommendedVisualizations(visualization) {
- var _this = this;
- if (this.isValidDataSource(visualization) && visualization.getSlots().isMappingComplete()) {
- return this.recommendAlternateVisualizations(visualization).then(function (recommendations) {
- return recommendations.map(function (recommendation) {
- return _this.visDefinitions.getById(recommendation.visId);
- });
- });
- } else {
- return Promise.resolve([]);
- }
- };
- VisualizationSmartsRecommender.prototype.getRecommendedTitle = function getRecommendedTitle(visualization) {
- if (this.isValidDataSource(visualization)) {
- return this._visRecommenderDelegator.getRecommendInfo(visualization).then(function (info) {
- return info.label;
- }).catch(function (error) {
- return Promise.reject(new Error(error));
- });
- } else {
- return Promise.resolve();
- }
- };
- VisualizationSmartsRecommender.prototype.setType = function setType(visualization, type, transactionToken) {
- var _this2 = this;
- var subTransaction = this.transaction.startTransaction(transactionToken);
- var newDefinition = this.visDefinitions.getByType(type);
- if (newDefinition) {
- if (!visualization.isTypeLocked()) {
- visualization.lockType(subTransaction);
- }
- if (this.isValidDataSource(visualization)) {
- return this._visRecommenderDelegator.recommendBindingsForSelectedViz(visualization, newDefinition.getId()).then(function (recommendation) {
- _this2._applyRecommendationToVisualization(visualization, recommendation, subTransaction);
- }).finally(function () {
- _this2.transaction.endTransaction(subTransaction);
- });
- } else {
- visualization.setType(type, subTransaction);
- this.transaction.endTransaction(subTransaction);
- return Promise.resolve();
- }
- }
- throw new Error('Invalid definition');
- };
- VisualizationSmartsRecommender.prototype.addDataItems = function addDataItems(visualization, dataItemSpecList, transactionToken) {
- var _this3 = this;
- var dataSource = visualization.getDataSource();
- if (!dataSource) {
- throw new Error('You must set a datasource in the visualization feature first');
- }
- var columnIds = dataItemSpecList.map(function (dataItemSpec) {
- return dataItemSpec.columnId;
- });
- var subTransactionToken = this.transaction.startTransaction(transactionToken);
- if (visualization.isTypeLocked()) {
- return this._visRecommenderDelegator.recommendBindingsForNewColumns(visualization, columnIds).then(function (recommendation) {
- _this3._applyRecommendationToVisualization(visualization, recommendation, subTransactionToken);
- }).finally(function () {
- _this3.transaction.endTransaction(subTransactionToken);
- });
- } else {
- return this._visRecommenderDelegator.recommendBestAlternateVisualization(visualization, columnIds).then(function (recommendation) {
- if (_this3.features.LiveWidgetSegment) {
- _this3.features.LiveWidgetSegment.track({ visualization: visualization, info: recommendation, category: 'fromRecommendation' });
- }
- _this3._applyRecommendationToVisualization(visualization, recommendation, subTransactionToken);
- }).finally(function () {
- _this3.transaction.endTransaction(subTransactionToken);
- });
- }
- };
- VisualizationSmartsRecommender.prototype.recommendBestVisualization = function recommendBestVisualization(visualization, transactionToken) {
- var _this4 = this;
- if (this.isValidDataSource(visualization)) {
- var subTransaction = this.transaction.startTransaction(transactionToken);
- if (visualization.isTypeLocked()) {
- visualization.unlockType(subTransaction);
- }
- return this._visRecommenderDelegator.recommendBestAlternateVisualization(visualization).then(function (recommendation) {
- if (_this4.features.LiveWidgetSegment) {
- _this4.features.LiveWidgetSegment.track({ visualization: visualization, info: recommendation, category: 'fromRecommendation' });
- }
- _this4._applyRecommendationToVisualization(visualization, recommendation, subTransaction);
- }).finally(function () {
- _this4.transaction.endTransaction(subTransaction);
- });
- }
- return Promise.resolve();
- };
- VisualizationSmartsRecommender.prototype.recommendAlternateVisualizations = function recommendAlternateVisualizations(visualization) {
- var result = void 0;
- if (this.isValidDataSource(visualization)) {
- var dataSource = visualization.getDataSource();
- var module = this.moserDataSources.getModule(dataSource.getId());
- var columnIds = Utils.getUnboundColumnsIds(visualization);
- result = this._visRecommenderDelegator.recommendAlternateVisualizations(columnIds, {
- assetId: module.getAssetId(),
- sourceType: module.getSourceType(),
- module: module
- });
- } else {
- result = Promise.resolve([]);
- }
- return result;
- };
- VisualizationSmartsRecommender.prototype.recommendAlternateVisualizationsAsWidgetSpecs = function recommendAlternateVisualizationsAsWidgetSpecs(visualization, baseWidgetSpec) {
- var _this5 = this;
- return this.recommendAlternateVisualizations(visualization).then(function (recommendations) {
- return _this5._transformWidgetRecommendationsToLiveWidgetSpecs(recommendations, baseWidgetSpec);
- });
- };
- VisualizationSmartsRecommender.prototype.recommendRelatedVisualizations = function recommendRelatedVisualizations(visualization) {
- var result = void 0;
- if (this.isValidDataSource(visualization)) {
- var dataSource = visualization.getDataSource();
- var columnIds = Utils.getUnboundColumnsIds(visualization);
- var topBottomItems = Utils.getTopBottomItems(visualization);
- var filterItems = Utils.getFilterItems(visualization);
- result = this.recommendRelatedVisualizationsFromColumnIds(dataSource.getId(), columnIds, [].concat(topBottomItems, filterItems));
- } else {
- result = Promise.resolve([]);
- }
- return result;
- };
- VisualizationSmartsRecommender.prototype.recommendAlternateVisualizationsFromColumnIds = function recommendAlternateVisualizationsFromColumnIds(dataSourceId, columnIds) {
- var module = this.moserDataSources.getModule(dataSourceId);
- return this._visRecommenderDelegator.recommendAlternateVisualizations(columnIds, {
- assetId: module.getAssetId(),
- sourceType: module.getSourceType(),
- module: module
- });
- };
- VisualizationSmartsRecommender.prototype.recommendRelatedVisualizationsFromColumnIds = function recommendRelatedVisualizationsFromColumnIds(dataSourceId, columnIds, filters, includeBestVisForTargetFields) {
- var module = this.moserDataSources.getModule(dataSourceId);
- return this._visRecommenderDelegator.recommendRelatedVisualizations(columnIds, {
- assetId: module.getAssetId(),
- sourceType: module.getSourceType(),
- module: module,
- filters: filters,
- includeBestVisForTargetFields: !!includeBestVisForTargetFields,
- moserDataSources: this.moserDataSources,
- visualization: this.visualization
- });
- };
- // deprecated interface -- called by explore
- VisualizationSmartsRecommender.prototype.recommendRelatedVisualizationsAsWidgetSpecs = function recommendRelatedVisualizationsAsWidgetSpecs(visualization, baseWidgetSpec) {
- var _this6 = this;
- return this.recommendRelatedVisualizations(visualization).then(function (recommendations) {
- return _this6._transformWidgetRecommendationsToLiveWidgetSpecs(recommendations, baseWidgetSpec);
- });
- };
- VisualizationSmartsRecommender.prototype.recommendCompareVisualizationsAsWidgetSpecs = function recommendCompareVisualizationsAsWidgetSpecs(visualization, widgetSpec) {
- var result = void 0;
- if (this.isValidDataSource(visualization)) {
- var dataSource = visualization.getDataSource();
- var module = this.moserDataSources.getModule(dataSource.getId());
- var options = {};
- options.module = module;
- options.columnIds = Utils.getUnboundColumnsIds(visualization);
- options.widgetSpec = widgetSpec;
- options.visualization = visualization;
- options.assetId = dataSource.getAssetId();
- options.sourceType = dataSource.getType();
- options.moserDataSources = this.moserDataSources;
- result = this._visRecommenderDelegator.recommendCompareVisualizations(options.columnIds, options);
- } else {
- result = Promise.resolve([]);
- }
- return result;
- };
- VisualizationSmartsRecommender.prototype._transformWidgetRecommendationsToLiveWidgetSpecs = function _transformWidgetRecommendationsToLiveWidgetSpecs(recommendations, basewidgetSpec) {
- var _this7 = this;
- var promises = [];
- var results = [];
- recommendations.forEach(function (recommendation) {
- basewidgetSpec = JSON.parse(JSON.stringify(basewidgetSpec));
- // Shoud be done throught the API -- but we need to be able to easily create a content API
- basewidgetSpec.name = recommendation.label;
- // Should be done through the filter API once it is ready
- if (recommendation.filters && recommendation.filters.length > 0) {
- basewidgetSpec.localFilters = recommendation.filters;
- }
- var widgetModelCopy = new LiveWidgetModel(basewidgetSpec);
- var visualization = new Visualization({
- doNotRegisterDataSourceUsage: true,
- content: _this7.content,
- features: {
- 'Models.internal': {
- getWidgetModel: function getWidgetModel() {
- return widgetModelCopy;
- }
- },
- 'Dashboard.API': _this7.features['Dashboard.API'],
- 'Dashboard.Logger': _this7.features['Logger'],
- 'Dashboard.Colors': _this7.features['Colors'],
- 'Dashboard.Transaction': _this7.features['Transaction'],
- 'Dashboard.DataSources': _this7.features['DataSources'],
- 'Dashboard.internal': _this7.features['Dashboard.internal'],
- 'Dashboard.VisDefinitions': _this7.features['VisDefinitions'],
- 'Dashboard.VisDefinitions.internal': _this7.features['VisDefinitions.internal']
- }
- });
- promises.push(visualization.initialize().then(function () {
- visualization.unlockType();
- _this7._applyRecommendationToVisualization(visualization, recommendation);
- // strip the thumbnailId from the base model
- var spec = widgetModelCopy.toJSON([], ['thumbnailId']);
- // return recommendation specs without ids will generate ids at the addition time
- delete spec.id;
- // TODO -- why this ?
- // the conversation expects a recommenderInfo for some reason..
- spec.recommenderInfo = {
- rtitle: recommendation.title,
- description: recommendation.description,
- label: recommendation.label
- };
- results.push({
- name: widgetModelCopy.get('name'),
- spec: spec
- });
- }));
- });
- console.log('recommendations... ', results);
- return Promise.all(promises).then(function () {
- return results;
- });
- };
- VisualizationSmartsRecommender.prototype._applyRecommendationToVisualization = function _applyRecommendationToVisualization(visualization, recommendation, transactionToken) {
- var subTransaction = this.transaction.startTransaction(transactionToken);
- // Get the original list of dataItems mapped to slots before the visId change.
- var originalSlots = visualization.getSlots();
- var originalMappedDataItemIdList = originalSlots.getMappingInfoList().map(function (diInfo) {
- return diInfo.dataItem && diInfo.dataItem.getId();
- });
- // Check if we are changing the viz
- if (recommendation.visId !== visualization.getDefinition().getId()) {
- var newDef = this.visDefinitions.getById(recommendation.visId);
- visualization.setType(newDef.getType(), subTransaction);
- }
- var slots = visualization.getSlots();
- var unmappedDataItemList = [];
- var mappedDataItemListBySlot = {};
- slots.getDataItemList().forEach(function (dataItem) {
- var mapping = slots.getMappingInfo(dataItem.getId());
- if (!mapping) {
- unmappedDataItemList.push(dataItem);
- } else {
- var slotId = mapping.slot.getId();
- if (!mappedDataItemListBySlot[slotId]) {
- mappedDataItemListBySlot[slotId] = [];
- }
- mappedDataItemListBySlot[slotId].push(dataItem);
- }
- });
- var recommendedColumns = {};
- for (var slotName in recommendation.slots) {
- recommendation.slots[slotName].forEach(function (value) {
- recommendedColumns[value] = true;
- });
- }
- // Check if the recommender has changed some mapping to a different slot. If so, we move the dataItem to the unmapped datsaItems so that it can be
- // picked by another slot
- var slotList = slots.getSlotList();
- slotList.forEach(function (slot) {
- var name = slot.getId();
- var dataItems = slot.getDataItemList(true);
- dataItems.forEach(function (dataItem) {
- if (!recommendation.slots[name] || !recommendation.slots[name].find(function (columnId) {
- return dataItem.getColumnId() === columnId;
- })) {
- unmappedDataItemList.push(dataItem);
- }
- });
- });
- var newMappingBySlot = {};
- slotList.forEach(function (slot) {
- var name = slot.getId();
- var slotId = slot.getId();
- var dataItemsToAdd = [];
- if (recommendation.slots[name]) {
- recommendation.slots[name].forEach(function (columnId) {
- var dataItem = void 0;
- var filterDataItems = function filterDataItems(di) {
- if (!dataItem && columnId === di.getColumnId()) {
- dataItem = di;
- return false;
- }
- return true;
- };
- // 1 - Search the previous mapped dataitems to this slot (if they exist)
- if (mappedDataItemListBySlot[slotId]) {
- // We filter to exclude the matched dataitems as we find them
- mappedDataItemListBySlot[slotId] = mappedDataItemListBySlot[slotId].filter(filterDataItems);
- }
- // 2 - Search the unmapped data items
- if (!dataItem) {
- // Search the unmapped list
- unmappedDataItemList = unmappedDataItemList.filter(filterDataItems);
- }
- // 3 - New column eing added, create a dataImte
- if (!dataItem) {
- dataItem = slots.createDataItems([{ columnId: columnId }], subTransaction)[0];
- }
- dataItemsToAdd.push(dataItem.getId());
- });
- } else {
- // slots which are not recommendable should maintain the original mappings
- // for example, heat slot for crosstab and table
- var unmappedSlot = slots.getSlot(slotId);
- var isHidden = unmappedSlot.getDefinition().isHidden();
- if (isHidden) {
- unmappedSlot.getDataItemList().forEach(function (dataItem) {
- if (!recommendedColumns[dataItem.getColumnId()]) {
- dataItemsToAdd.push(dataItem.getId());
- }
- });
- }
- }
- var dataItemList = slot.getDataItemList(true);
- var dataItemsToRemove = dataItemList.filter(function (dataItem) {
- return dataItem.isColumnUnavailable();
- });
- if (dataItemsToRemove.length > 0) {
- slot.removeDataItems(dataItemsToRemove.map(function (dataItem) {
- return dataItem.getId();
- }), subTransaction);
- }
- newMappingBySlot[slotId] = dataItemsToAdd;
- slot.removeDataItemsMapping(dataItemList.map(function (dataItem) {
- return dataItem.getId();
- }), subTransaction);
- });
- //Place slots which can generate measure groups at the end.
- //This means when a measure group is generated in addDataItemsMappings,
- //any other data items in the same slot will already exist, so it can be
- //placed in the correct position.
- var slotIds = Object.keys(newMappingBySlot).map(function (id) {
- return slots.getSlot(id);
- }).sort(function (slotA, slotB) {
- var a = slotA.getDefinition().getProperty('multiMeasure') ? 1 : -1,
- b = slotB.getDefinition().getProperty('multiMeasure') ? 1 : -1;
- return a - b;
- }).map(function (slot) {
- return slot.getId();
- });
- // Add all the new mappings
- slotIds.forEach(function (id) {
- if (newMappingBySlot[id].length > 0) {
- slots.getSlot(id).addDataItemsMapping(newMappingBySlot[id], -1, subTransaction);
- }
- });
- var mappingInfoList = slots.getMappingInfoList();
- // remove all leftover top bottom items if smarts returns top bottom items, such as for related-viz case
- if (recommendation.topBottom && recommendation.topBottom.length > 0) {
- recommendation.topBottom.forEach(function (_ref2) {
- var itemId = _ref2.itemId,
- spec = _ref2.spec;
- var mappingEntry = mappingInfoList.find(function (mappingInfoList) {
- return mappingInfoList.dataItem.getColumnId() === itemId;
- });
- if (mappingEntry) {
- var topBottom = {
- type: spec.type,
- value: spec.value
- };
- if (spec.context) {
- topBottom.context = {
- itemId: spec.context,
- aggregate: spec.aggregate
- };
- }
- mappingEntry.dataItem.setTopBottom(topBottom, subTransaction);
- }
- });
- }
- // Auto Group
- (recommendation.autoGroup || []).forEach(function (autoGroupItem) {
- var itemId = autoGroupItem.itemId,
- groupSize = autoGroupItem.groupSize;
- if (autoGroupItem && groupSize) {
- var mappingEntry = mappingInfoList.find(function (mappingInfoList) {
- return mappingInfoList.dataItem.getColumnId() === itemId;
- });
- if (mappingEntry) {
- mappingEntry.dataItem.setBinning({
- bins: groupSize
- }, subTransaction);
- }
- }
- });
- //Compare the final mapped DataItem list to the original one. Clean any dataItems that are no longer mapped.
- var mappedDataItemIdList = slots.getMappingInfoList().map(function (diInfo) {
- return diInfo.dataItem && diInfo.dataItem.getId();
- });
- var unmappedDataItemIdList = originalMappedDataItemIdList.filter(function (originalId) {
- return mappedDataItemIdList.indexOf(originalId) === -1;
- });
- if (unmappedDataItemIdList.length > 0) {
- slots.deleteDataItems(unmappedDataItemIdList, subTransaction);
- }
- this.transaction.endTransaction(subTransaction);
- };
- return VisualizationSmartsRecommender;
- }();
- return VisualizationSmartsRecommender;
- });
- //# sourceMappingURL=SmartsRecommenderFeature.js.map
|