'use strict'; /* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| IBM Cognos Products: BI Dashboard *| (C) Copyright IBM Corp. 2017, 2020 *| *| US Government Users Restricted Rights - Use, duplication or disclosure *| restricted by GSA ADP Schedule Contract with IBM Corp. *+------------------------------------------------------------------------+ */ define(['underscore', '../../lib/@waca/core-client/js/core-client/ui/core/Class', './VIPRData', './data/VIPRData', './VIPRSlotMapping', './VIPRConfig', 'com/ibm/vipr/VIPR', '../interactions/BinningActionsUtils', './properties/PropertiesHelper'], function (_, Class, VIPRData_Deprecated, VIPRData, VIPRSlotMapping, VIPRConfig, VIPR, BinningActionsUtils, PropertiesHelper) { 'use strict'; var VIPRUtils = Class.extend({ createDataSlots: function createDataSlots(viprDefinition) { var vizDef = viprDefinition.vizDef; var config = this._getConfiguration(viprDefinition.id); var result = this._addToSlots(vizDef.slots, vizDef.dataSets, config); return result; }, getPropertyPrefixes: function getPropertyPrefixes(viprDefinition) { var config = this._getConfiguration(viprDefinition.id); return config ? config.propertyPrefixes : undefined; }, getListenForPropChanges: function getListenForPropChanges(viprDefinition) { var config = this._getConfiguration(viprDefinition.id); return config ? config.listenForPropChanges : undefined; }, getGroupedProperty: function getGroupedProperty(viprDefinition) { var config = this._getConfiguration(viprDefinition.id); return config ? config.groupedProperty : undefined; }, includeAllProperties: function includeAllProperties(viprDefinition) { var config = this._getConfiguration(viprDefinition.id); return config && config.includeAllProperties ? config.includeAllProperties : false; }, _addMultiMeasureAndTagsToSlots: function _addMultiMeasureAndTagsToSlots(continuousSlots, slotCanAcceptMeasureGroupCategorical) { continuousSlots[0].multiMeasure = true; //to add tags to the slot, if we have a slot that name contains color , we add to that slot, otherwise to first non continues slot. var index = slotCanAcceptMeasureGroupCategorical.findIndex(function (slot) { return slot.name.toLowerCase().indexOf('color') !== -1; }); if (index !== -1) { slotCanAcceptMeasureGroupCategorical[index].tags = ['ca.dashboard.repeatHere=true']; } else { slotCanAcceptMeasureGroupCategorical[0].tags = ['ca.dashboard.repeatHere=true']; } }, // custom vis will support multi measure, based on following rules: // if each dataset has only one continues slot and at least one slot that is not continues(cat, any). _addMultiMeasureAndTagsToCustomVisDataset: function _addMultiMeasureAndTagsToCustomVisDataset(dataset, config) { if (config && config.isCustomVis) { var continuousSlots = _.filter(dataset.slots, function (slot) { if (slot.segments) { return _.filter(slot.segments, function (segments) { return segments.type === 'cont'; }); } return slot.type === 'cont'; }); var slotCanAcceptMeasureGroupCategorical = _.filter(dataset.slots, function (slot) { if (slot.segments) { return _.filter(slot.segments, function (segments) { return segments.type !== 'cont' && segments.subType !== 'geospatial'; }); } return slot.type !== 'cont' && slot.subType !== 'geospatial'; }); if (continuousSlots.length == 1 && slotCanAcceptMeasureGroupCategorical.length > 0) { this._addMultiMeasureAndTagsToSlots(continuousSlots, slotCanAcceptMeasureGroupCategorical); } } }, _addToSlots: function _addToSlots() { var slots = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var datasets = arguments[1]; var config = arguments[2]; var aSlots = {}; if (!_.isEmpty(datasets)) { var datasetName; _.each(datasets, function (dataset) { datasetName = dataset.name; this._addMultiMeasureAndTagsToCustomVisDataset(dataset, config); _.each(dataset.slots, function (slot) { if (!_.isEmpty(slot.segments)) { var oSlot; _.each(slot.segments, function (segment) { //VIPR confirms segment is sub class of VIPR slot oSlot = this._buildSlot(segment, config, datasetName); oSlot.group = slot.name; if (aSlots[segment.name]) { aSlots[segment.name].datasetIdList.push(datasetName); } else { aSlots[segment.name] = oSlot; } }.bind(this)); } else { if (aSlots[slot.name]) { aSlots[slot.name].datasetIdList.push(datasetName); } else { aSlots[slot.name] = this._buildSlot(slot, config, datasetName); } } }.bind(this)); }.bind(this)); } // Keep slots in the vida order, important for shared slots like in compositev2 var slotOrder = []; slots.forEach(function (slot) { if (!_.isEmpty(slot.segments)) { slot.segments.forEach(function (segment) { slotOrder.push(segment.name); }); } else { slotOrder.push(slot.name); } }); return slotOrder.map(function (name) { return aSlots[name]; }); }, _buildSlot: function _buildSlot(slot, config, datasetName) { var oCurSlot = this._getSlotObject(slot, config, datasetName); return config && config.slots ? _.extend(oCurSlot, config.slots[oCurSlot.id]) : oCurSlot; }, _getSlotObject: function _getSlotObject(vizDefSlot, config, datasetName) { var slotType = this._getSlotType(vizDefSlot); var slot = { id: vizDefSlot.name, caption: vizDefSlot.caption, type: slotType, role: vizDefSlot.role, maxStackItems: vizDefSlot.maxLevels, optional: vizDefSlot.optional, multiplier: this._isMultiplier(vizDefSlot), stackItems: slotType !== 'ordinal', multiItems: vizDefSlot.multiDataItem, coachMark: vizDefSlot.coachMark }; if (vizDefSlot.useCategoryAsValue) { slot.useCategoryAsValue = vizDefSlot.useCategoryAsValue; } if (datasetName) { slot.datasetIdList = [datasetName]; } if (vizDefSlot.multiMeasure) { slot.multiMeasure = vizDefSlot.multiMeasure; } if (vizDefSlot.tags) { slot.tags = vizDefSlot.tags; } return config && config.slots && config.slots[slot.id] ? _.extend(slot, config.slots[slot.id]) : slot; }, _getSlotType: function _getSlotType(slot) { if (slot.type === 'cat') { return 'category'; } else if (slot.type === 'cont') { return 'ordinal'; } return slot.type; }, _isMultiplier: function _isMultiplier(slot) { var multipliers = ['repeatHorizontal', 'repeatVertical']; return multipliers.indexOf(slot.name) >= 0; }, /** * @param {String} visId - id of the specic vis of interest * @returns {Object} single palette prop descriptions *'singlePaletteProps': { * column_color: { * id: 'defaultPaletteIndex', * labelId: 'propColumnColor', * defaultColorIndex: 0 * }, * line_color: { * id: 'lineColor', * labelId: 'propLineAndSymbolColor', * defaultColorIndex: 1 * } *} */ getSinglePaletteProperties: function getSinglePaletteProperties(visId) { var config = this._getConfiguration(visId); return config && config.colorPalettes && config.colorPalettes.single; }, getViprWidgetPropertyInstances: function getViprWidgetPropertyInstances(viprProperties, propertyIds) { var propertyInstances = []; propertyIds.forEach(function (propertyId) { var propertyInstance = viprProperties.get(propertyId); if (propertyInstance) { propertyInstances.push(propertyInstance); } }); return propertyInstances; }, /** * Get single palettes by checking the configuration * Preferable to check the config for single palette props, because it has properties like defaultColorIndex that arent included in the vizBundle * If no single palette config is available, check the viprProperties * @returns {Object[]} Single palette property array */ getSinglePalettes: function getSinglePalettes(viprProperties, visId) { var config = this._getConfiguration(visId); var paletteIds = config && config.colorPalettes && config.colorPalettes.single && Object.keys(config.colorPalettes.single) || []; if (paletteIds.length === 0) { return this.getSinglePalettesFromWidget(viprProperties); } return this.getViprWidgetPropertyInstances(viprProperties, paletteIds); }, /** * Get single palettes by checking the viprProperties itself * @returns {Object[]} Single palette property array */ getSinglePalettesFromWidget: function getSinglePalettesFromWidget(viprProperties) { var paletteIds = []; viprProperties.forEach(function (prop) { if (prop.type === 'color' && prop.tags && prop.tags.indexOf('palette') !== -1) { paletteIds.push(prop.name); } }); return this.getViprWidgetPropertyInstances(viprProperties, paletteIds); }, /** * Get all color palettes * @returns {Object[]} Palette property array */ getPalettes: function getPalettes(viprProperties, visId) { var paletteIds = []; viprProperties.forEach(function (prop) { if (prop.type === 'palette') { paletteIds.push(prop.name); } }); return this.getViprWidgetPropertyInstances(viprProperties, paletteIds).concat(this.getSinglePalettes(viprProperties, visId)); }, /** * @returns the default value from the bundle config if defined, undefined otherwise. */ getDefaultValueForProperty: function getDefaultValueForProperty(bundleId, propertyName) { var defaultValue = void 0; var config = this._getConfiguration(bundleId); // If the property is defined in the config file get it. if (config && config.properties && config.properties[propertyName]) { defaultValue = config.properties[propertyName].defaultValue; } return defaultValue; }, /** * Get the overriden property description from the configuration file if there is any. * @param {String} bundleId - id of the vis bundle * @param {String} propertyName - name of the property of interest */ getOverridenDefaultForProperty: function getOverridenDefaultForProperty(bundleId, propertyName) { var result = { defaultValue: null, isActive: false }; var config = this._getConfiguration(bundleId); // If the property is defined in the config file get it. if (config && config.properties && config.properties[propertyName]) { result.defaultValue = config.properties[propertyName].defaultValue; result.isActive = config.properties[propertyName].active; result.isReadOnly = config.properties[propertyName].isReadOnly; result.checkForValidValue = config.properties[propertyName].checkForValidValue; } return result; }, /** * @param {String} bundleId - Vis bundle id * @param {Object} property - Description of the property of interest * @param {String} propertyName - name of the property of interest. Note, we * can not just use the name in the property param as we may be using a deprecated * property which means the property would have the new prop name. */ overrideProperty: function overrideProperty(bundleId, property, propertyName) { var config = this._getConfiguration(bundleId); if (config && config.properties && config.properties[propertyName]) { // override the property // Need to clone the config prop or it will change the prop in the model. var clonedProp = _.clone(config.properties[propertyName]); property = _.defaults(clonedProp, property); property.overridden = true; } return property; }, isRenderWithoutCompletingMapping: function isRenderWithoutCompletingMapping(bundleId) { var config = this._getConfiguration(bundleId); return !!(config && config.renderWithoutCompletingMapping === true); //Default: false }, isRecommendable: function isRecommendable(bundleId) { var config = this._getConfiguration(bundleId); return !(config && config.isRecommendable === false); //Default: true }, /** * Determine whether the property name is part of the inclusion list * @param {string} bundleId visualization id * @param {string} propertyName name of the property */ isPropertyIncluded: function isPropertyIncluded(bundleId, propertyName) { var configuration = this._getConfiguration(bundleId); return configuration && _.contains(configuration.config.include, propertyName); }, /** * Determine whether the property name is part of the exclusion list * @param {string} bundleId visualization id * @param {string} propertyName name of the property */ isPropertyExcluded: function isPropertyExcluded(bundleId, propertyName) { var configuration = this._getConfiguration(bundleId); return _.contains(configuration.config.exclude, propertyName); }, noDataQuery: function noDataQuery(bundleId) { var config = this._getConfiguration(bundleId); return !!(config && config.noDataQuery === true); //Default: false }, /** * @return true if the charts are configrured to use FPD response as Chart-Insights API input */ useFPDAsInsightsInput: function useFPDAsInsightsInput(bundleId) { var config = this._getConfiguration(bundleId); return !!(config && config.useFPDAsInsightsInput === true); //Default: false }, isDisablePan: function isDisablePan(bundleId) { var config = this._getConfiguration(bundleId); return !!(config && config.disablePan === true); //Default: false }, aggregateAndSortOnClient: function aggregateAndSortOnClient(bundleId) { var config = this._getConfiguration(bundleId); return !!(config && config.aggregateAndSortOnClient === true); //Default: false }, /*Discussed with VIPR, currently we still need Data Row Limit guard*/ getDataRowLimit: function getDataRowLimit(bundleId) { var config = this._getConfiguration(bundleId); return config && config.dataRowLimit; }, /*Data Row Limit guard for IE*/ getDataRowLimitIE: function getDataRowLimitIE(bundleId) { var config = this._getConfiguration(bundleId); return config && config.dataRowLimitIE; }, getVisualizationTabs: function getVisualizationTabs(bundleId) { var config = this._getConfiguration(bundleId); return config && config.tabs; }, getQueryHints: function getQueryHints(bundleId) { var config = this._getConfiguration(bundleId); return config ? config.queryHints : null; }, doesConfigPropertyMatchExpected: function doesConfigPropertyMatchExpected(bundleId, configObjectProperty, expectedValue) { if (bundleId) { var config = this._getConfiguration(bundleId); if (config) { return config[configObjectProperty] ? config[configObjectProperty] === expectedValue : false; } } return false; }, getBinning: function getBinning(bundleId) { var config = this._getConfiguration(bundleId); return config && config.binning ? config.binning : {}; }, canApplyAutoBin: function canApplyAutoBin(bundleId) { var config = this.getBinning(bundleId); var doesConfigSupportAutobinning = this.doesWidgetConfigSupportAutobinning(config); return doesConfigSupportAutobinning; }, doesWidgetConfigSupportAutobinning: function doesWidgetConfigSupportAutobinning(config) { return BinningActionsUtils.doesWidgetConfigSupportAutobinning(config); }, _getConfiguration: function _getConfiguration(id) { return VIPRConfig.getConfig(id); }, _getConfigVal: function _getConfigVal(id, key) { if (this._getConfiguration(id) && this._getConfiguration(id)[key]) { return this._getConfiguration(id)[key]; } return false; }, applyRequiredConfiguration: function applyRequiredConfiguration(viprDefinitionId, requiredConfig, propertyValues) { // Merge the overrides into the existing configuration var lib = this._getConfiguration(viprDefinitionId); var override = lib.config.override; if (!override) { // If there are no overrides yet, create a new object override = {}; lib.config.override = override; } _.each(requiredConfig, function (property) { var value = propertyValues[property]; // See if there already is an override definition for this property. Otherwise, create it. if (!override[property]) { override[property] = {}; } override[property].defaultValue = value; }); }, //TODO: revise for properties support _applyPropertyType: function _applyPropertyType(prop, vizProp) { if (vizProp.type === 'color') { prop.type = 'ColorPicker'; prop.paletteType = 'ColorPalette'; } else if (vizProp.type === 'boolean') { prop.type = 'CheckBox'; prop.defaultValue = vizProp.defaultValue; } else if (vizProp.type === 'number') { // TODO prop.type = 'CheckBox'; } else if (vizProp.type === 'enum') { prop.type = 'DropDown'; prop.options = _.map(vizProp.possibleValues, function (option) { return { label: option.caption, value: option.name }; }); } return prop; }, /** * @deprecated * @param {Array of JSONObject} inputPayload * @return {VIPRData} A Collection of VIPRDataSet **/ createData: function createData(queryResults, visualization, content) { var hideAggTypeInAxisLabels = this.doesConfigPropertyMatchExpected(visualization.getDefinition().getId(), 'hideAggTypeInAxisLabels', true); return new VIPRData_Deprecated(queryResults, visualization, hideAggTypeInAxisLabels, content); }, createQueryResultData: function createQueryResultData(queryResults, visualization, content) { var hideAggTypeInAxisLabels = this.doesConfigPropertyMatchExpected(visualization.getDefinition().getId(), 'hideAggTypeInAxisLabels', true); return new VIPRData(queryResults, visualization, hideAggTypeInAxisLabels, content); }, createSlotMapping: function createSlotMapping(visualization) { return new VIPRSlotMapping(visualization); }, createMetaDataEntries: function createMetaDataEntries(vizDefinition) { return vizDefinition.metaDataEntries.slice(); }, isRequiredConfig: function isRequiredConfig(id, prop) { return this.getRequiredConfig(id) && this.getRequiredConfig(id).indexOf(prop.name) > -1; }, getRequiredConfig: function getRequiredConfig(id) { return this._getConfigVal(id, 'requiredConfig'); }, getCursor: function getCursor(id) { return this._getConfigVal(id, 'cursor'); }, isGeospatial: function isGeospatial(id) { return this._getConfigVal(id, 'geo'); }, supportsSortAction: function supportsSortAction(id) { return !this._getConfigVal(id, 'doesNotSupportSortAction'); }, supportsAnnotations: function supportsAnnotations(id) { return !this._getConfigVal(id, 'doesNotSupportAnnotations'); }, supportsContextualTopBottomAction: function supportsContextualTopBottomAction(id) { return !this._getConfigVal(id, 'doesNotSupportTopBottomAction'); }, supportsNonContextualTopBottomAction: function supportsNonContextualTopBottomAction(id) { return !this._getConfigVal(id, 'doesNotSupportTopBottomAction'); }, supportsFormatAction: function supportsFormatAction(id) { return !this._getConfigVal(id, 'doesNotSupportFormatAction'); }, supportsCustomGroupAction: function supportsCustomGroupAction(id) { return !this._getConfigVal(id, 'doesNotSupportCustomGroupAction'); }, supportsMaintainAxisScale: function supportsMaintainAxisScale(id) { return this._getConfigVal(id, 'supportsMaintainAxisScale'); }, supportsCustomDataSelection: function supportsCustomDataSelection(id) { return this._getConfigVal(id, 'enableCustomDataSelection'); }, /** * create a vida font object * @param vidaFontValues - an array of font props values [family,size,style,weight], e.g.: ['Anton', '12px', 'italic', 'weight'] * @returns {Object} return a vida font object, VIPR parse method would return null if the values don't parse * { * 'family': [], * 'size': value, * 'style': value, * 'weight': value * } */ createVidaFontProperty: function createVidaFontProperty(vidaFontValues) { if (vidaFontValues) { var family = VIPR.property.Font.parseFamily(vidaFontValues[0]); var size = VIPR.property.Length.parse(vidaFontValues[1]); var style = VIPR.property.FontStyle.parse(vidaFontValues[2]); var weight = VIPR.property.FontWeight.parse(vidaFontValues[3]); return VIPR.property.Font.create(family, size, style, weight); } }, /** * parse a valid string to a vida font object * @param fontPropValue - a font-style string, e.g.: 'Anton 12px italic weight' or 'font-family: Condiment-Regular; font-size: 24px;' * @returns {Object} return a vida font object, * { * 'family': [], * 'size': value, * 'style': value, * 'weight': value * } */ parseVidaFontProperty: function parseVidaFontProperty(fontPropValue) { return VIPR.property.Font.parse(fontPropValue); }, getViprProperiesAndGroups: function getViprProperiesAndGroups(viprDefinition, properties, groups) { var viprProperties = viprDefinition.vizDef.properties; _.forEach(viprDefinition.vizDef.configuration, function (config) { properties.push(config); }); return this._getViprProperiesAndGroups(viprProperties, properties, groups); }, _getViprProperiesAndGroups: function _getViprProperiesAndGroups(viprProperties, properties, groups) { var _this = this; _.forEach(viprProperties, function (viprProperty) { if (viprProperty.type === 'group') { var propertiesName = _.pluck(viprProperty.properties, 'name'); groups[viprProperty.name] = propertiesName; properties.push(viprProperty); return _this._getViprProperiesAndGroups(viprProperty.properties, properties, groups); } else { return properties.push(viprProperty); } }); }, _getPropertiesByNames: function _getPropertiesByNames(properties, propertiesNames) { var result = []; _.forEach(propertiesNames, function (name) { var property = _.find(properties, function (property) { return property.name === name; }); if (property) { result.push(property); } }); return result; }, _getPropertiesByType: function _getPropertiesByType(properties, type) { return _.filter(properties, function (property) { return property.type === type; }); }, buildVidaFontPropertiesFromParts: function buildVidaFontPropertiesFromParts(fontChanges, currentPropertyValue) { return PropertiesHelper.buildVidaFontPropertiesFromParts(this, fontChanges, currentPropertyValue); }, getVidaFontPropertiesPart: function getVidaFontPropertiesPart(part, fontPropertyValue) { return PropertiesHelper.getVidaFontPropertiesPart(this, part, fontPropertyValue); } }); // create a singleton instance return new VIPRUtils(); }); //# sourceMappingURL=VIPRUtils.js.map