'use strict'; /* *+------------------------------------------------------------------------+ *| Licensed Materials - Property of IBM *| IBM Cognos Products: BI Dashboard *| (C) Copyright IBM Corp. 2017 *| *| 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', '../../../lib/@waca/upgrades/UpgradeBase'], function (_, Class, UpgradeBase) { 'use strict'; //NOSONAR /*jshint maxcomplexity:15 */ /*jshint unused:false*/ // Slots can be in any order in dashboard spec, order them to ease the upgrade and the verification of result var SLOT_ORDERS = { 'locations': 0, 'locationColor': 1, 'pointColor': 2, 'pointSize': 3 }; var TILEDMAP_VISID = 'com.ibm.vis.rave2bundletiledmap'; var PROPERTY_METADATA = { oldPaletteId: 'contColorPalette', palettePrefix: 'colorPalette', oldHeatScalePaletteId: 'heatScalePalette' }; var Upgrade = Class.extend([UpgradeBase], { init: function init() { this.VERSION = 1007; }, /** * Perform upgrade * * @param {object} spec - spec to perform upgrade on * * @return {Promise} Promise to be resolved when upgrade performed */ up: function up(spec) { if (spec.widgets) { this._upgradeWidgets(spec); } return Promise.resolve(spec); }, _upgradeWidgets: function _upgradeWidgets(spec) { try { _.each(spec.widgets, function (model) { if (model.visId === TILEDMAP_VISID) { this._convertTiledMapVis(model); } }.bind(this)); } catch (error) { throw error; } }, // Build the new dataViews and slotmapping for tiledmap visualization _convertTiledMapVis: function _convertTiledMapVis(model) { // get existing slots var existingSlots = model.slotmapping.slots; if (!existingSlots || !existingSlots.length) { return; } var newDataViews = []; var newSlotMapping = { slots: [], layers: [] }; var slotIndexes = []; for (var i = 0; i < existingSlots.length; ++i) { var slotName = existingSlots[i].name; slotIndexes.push({ order: SLOT_ORDERS[slotName], existingSlotIndex: i }); } var sortedSlots = _.sortBy(slotIndexes, 'order'); // Convert each existing slot to new slot, new dataView, new layer _.each(sortedSlots, function (sortedSlot) { var slot = existingSlots[sortedSlot.existingSlotIndex]; switch (slot.name) { case 'locations': this._convertLocationSlot(model, slot, newDataViews, newSlotMapping); break; case 'locationColor': this._convertLocationColorSlot(model, slot, newDataViews, newSlotMapping); break; case 'pointColor': this._convertPointColorSlot(model, slot, newDataViews, newSlotMapping); break; case 'pointSize': this._convertPointSizeSlot(model, slot, newDataViews, newSlotMapping); break; default: break; } }.bind(this)); // replace old dataViews and old slotmapping with the new one model.data.dataViews = newDataViews; model.slotmapping = newSlotMapping; // upgrade map properties this._upgradeProperties(model); }, // If the old spec doesn't have palette or heatScalePalette property, nothing to upgrade // If the old spec has these properties, here is the rule for the upgrade // if the new spec has: // (a) 1 layer: then keep the same palette as R8 // (b) 2 layers: create a new property for the second layer palette and it should be different than the first one // - if R8 has palette 0, then set palette 1 for the second layer // - if R8 has palette != 0, then set palette 0 to the second layer. This way, we don't need to // know if the existing palette is the last palette or not // The heatScalePalette value is the same as R8 _upgradeProperties: function _upgradeProperties(model) { if (!model.properties) { return; } var properties = model.properties; var existingPalette = _.findWhere(properties, { id: PROPERTY_METADATA.oldPaletteId }); var existingHeatScale = _.findWhere(properties, { id: PROPERTY_METADATA.oldHeatScalePaletteId }); if (!existingPalette && !existingHeatScale) { return; } var existingPaletteNumber; var nbLayers = model.slotmapping.layers.length; if (existingPalette) { // First layer: update property id and keep the same palette value existingPalette.id = PROPERTY_METADATA.oldPaletteId + '_' + model.slotmapping.layers[0].id; existingPaletteNumber = existingPalette.value.substring(PROPERTY_METADATA.palettePrefix.length); // Second layer palette if (nbLayers > 1) { var newPaletteNumber; if (existingPaletteNumber === '0') { newPaletteNumber = '1'; } else { newPaletteNumber = '0'; } properties.push({ id: PROPERTY_METADATA.oldPaletteId + '_' + model.slotmapping.layers[1].id, value: PROPERTY_METADATA.palettePrefix + newPaletteNumber }); } } if (existingHeatScale) { // First layer: update palette id existingHeatScale.id = PROPERTY_METADATA.oldHeatScalePaletteId + '_' + model.slotmapping.layers[0].id; if (nbLayers > 1) { // Add property for second layer properties.push({ id: PROPERTY_METADATA.oldHeatScalePaletteId + '_' + model.slotmapping.layers[1].id, value: existingHeatScale.value }); } } }, _addNewDataView: function _addNewDataView(modelRef, newDataViews) { newDataViews.push({ id: _.uniqueId('model'), modelRef: modelRef, dataItems: [] }); return newDataViews[newDataViews.length - 1].id; }, _addNewLayer: function _addNewLayer(layers, layerInfo) { layers.push({ id: layerInfo.type, type: layerInfo.type, dataViewId: layerInfo.dataViewId }); return layers[layers.length - 1].id; }, _addNewDataItem: function _addNewDataItem(dataItems, oldDataItem) { var cloneDataItem = _.clone(oldDataItem); // update uniqueId to avoid collision cloneDataItem.id = _.uniqueId('model'); dataItems.push(cloneDataItem); return cloneDataItem.id; }, _convertLocationSlot: function _convertLocationSlot(model, slot, newDataViews, newSlotMapping) { // Do not create the region layer if location color is not mapped and we have pointSize/pointColor mapped. // Old locations will be mapped to pointLocations slot var oldSlots = _.pluck(model.slotmapping.slots, 'name'); var existLocationColor = oldSlots.indexOf('locationColor') > -1 ? true : false; var existPointSizeOrPointColor = oldSlots.indexOf('pointSize') > 0 || oldSlots.indexOf('pointColor') > 0 ? true : false; if (!existLocationColor && existPointSizeOrPointColor) { return; } // add dataView for layer "region" var oldDataView = model.data.dataViews[0]; var newDataViewId = this._addNewDataView(oldDataView.modelRef, newDataViews); // create layer "region" var layerInfo = { type: 'data.region', dataViewId: newDataViewId }; var newLayerId = this._addNewLayer(newSlotMapping.layers, layerInfo); // create slot "Locations" from the old slot "Locations" var newSlot = _.clone(slot); newSlot.layerId = newLayerId; // Copy data items from old slot newSlot.dataItems = []; _.each(slot.dataItems, function (dataItemRef) { var existingDataItem = _.findWhere(oldDataView.dataItems, { id: dataItemRef }); var newDataItemId = this._addNewDataItem(newDataViews[0].dataItems, existingDataItem); newSlot.dataItems.push(newDataItemId); }.bind(this)); newSlotMapping.slots.push(newSlot); }, _convertLocationColorSlot: function _convertLocationColorSlot(model, slot, newDataViews, newSlotMapping) { // DataView and layer for "region" should already exist, only create slot LocationColor and add dataItem for this slot var newSlot = _.clone(slot); newSlot.layerId = 'data.region'; var dataItemRef = slot.dataItems[0]; var existingDataItem = _.findWhere(model.data.dataViews[0].dataItems, { id: dataItemRef }); var newDataItemId = this._addNewDataItem(newDataViews[0].dataItems, existingDataItem); newSlot.dataItems = [newDataItemId]; newSlotMapping.slots.push(newSlot); }, _createPointLocationsSlot: function _createPointLocationsSlot(newSlotMapping, oldLocationSlot) { var pointLocationSlot = _.clone(oldLocationSlot); pointLocationSlot.name = 'pointLocations'; pointLocationSlot.caption = 'Point locations'; pointLocationSlot.dataItems = []; newSlotMapping.slots.push(pointLocationSlot); return pointLocationSlot; }, _createPointLayer: function _createPointLayer(model, newDataViews, newSlotMapping) { // create slot "pointLocations" from the slot "Locations" of region if this one exists var pointLocationSlot; var slots = model.slotmapping.slots; var index = slots.map(function (slot) { return slot.name; }).indexOf('locations'); if (index > -1) { pointLocationSlot = this._createPointLocationsSlot(newSlotMapping, slots[index]); } // Create new data view var modelRef = model.data.dataViews[0].modelRef; this._addNewDataView(modelRef, newDataViews); var newDataView = newDataViews[newDataViews.length - 1]; // create "point" layer var layerInfo = { type: 'data.point', dataViewId: newDataView.id }; var newLayerId = this._addNewLayer(newSlotMapping.layers, layerInfo); // copy data items from old location slot to pointLocations slot if (pointLocationSlot) { pointLocationSlot.layerId = newLayerId; var dataItemRefs = slots[index].dataItems; _.each(dataItemRefs, function (dataItemRef) { var existingDataItem = _.findWhere(model.data.dataViews[0].dataItems, { id: dataItemRef }); var newDataItemId = this._addNewDataItem(newDataView.dataItems, existingDataItem); pointLocationSlot.dataItems.push(newDataItemId); }.bind(this)); } }, _convertPointColorSlot: function _convertPointColorSlot(model, slot, newDataViews, newSlotMapping) { // create new DataView and layer for point layer this._createPointLayer(model, newDataViews, newSlotMapping); // Add slot "pointColor" var newSlot = _.clone(slot); newSlot.layerId = 'data.point'; // name and caption do not change var dataItemRef = slot.dataItems[0]; var existingDataItem = _.findWhere(model.data.dataViews[0].dataItems, { id: dataItemRef }); var newDataItemId = this._addNewDataItem(newDataViews[newDataViews.length - 1].dataItems, existingDataItem); newSlot.dataItems = [newDataItemId]; newSlotMapping.slots.push(newSlot); }, _convertPointSizeSlot: function _convertPointSizeSlot(model, slot, newDataViews, newSlotMapping) { var pointLayer; if (newSlotMapping.layers) { pointLayer = newSlotMapping.layers.find(function (layer) { return layer.id === 'data.point'; }); } if (!pointLayer) { // Point layer is not created yet, create new DataView and layer for point layer this._createPointLayer(model, newDataViews, newSlotMapping); } // convert pointSize slot var newSlot = _.clone(slot); newSlot.layerId = 'data.point'; // name and caption do not change var dataItemRef = slot.dataItems[0]; var existingDataItem = _.findWhere(model.data.dataViews[0].dataItems, { id: dataItemRef }); var newDataItemId = this._addNewDataItem(newDataViews[newDataViews.length - 1].dataItems, existingDataItem); newSlot.dataItems = [newDataItemId]; newSlotMapping.slots.push(newSlot); }, down: function down(spec) { return Promise.resolve(spec); } }); return new Upgrade(); }); //# sourceMappingURL=multiLayersSupport.js.map