Vis2SelectionController.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2016, 2020
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. */
  8. define(['underscore', '../../widgets/livewidget/nls/StringResources', '../../dataSources/utils/DatasourceUtil', '../../util/DashboardFormatter', '../../lib/@waca/core-client/js/core-client/utils/UniqueId', '../../util/EventUtils'], function (_, StringResources, DatasourceUtil, Formatter, UniqueId, EventUtils) {
  9. 'use strict';
  10. var Vis2SelectionController = function () {
  11. function Vis2SelectionController(attributes) {
  12. _classCallCheck(this, Vis2SelectionController);
  13. this._visAPI = attributes.visAPI || attributes.visModel;
  14. this._ownerWidget = attributes.visModel.ownerWidget;
  15. this.visualization = this._ownerWidget.content.getFeature('Visualization');
  16. this._pageContextAPI = attributes.pageContext;
  17. this.synchronizeData = attributes.synchronizeData;
  18. this.dashboardApi = this._ownerWidget.getDashboardApi();
  19. this.transaction = this.dashboardApi.getFeature('Transaction');
  20. this.registerEvents();
  21. }
  22. Vis2SelectionController.prototype.getAPI = function getAPI() {
  23. // Expose the controller as a deprecated feature for now
  24. return this;
  25. };
  26. Vis2SelectionController.prototype.destroy = function destroy() {
  27. this.remove();
  28. };
  29. /**
  30. * Get the 'title' for the selections toolbar (an array of category values delimited by |, or the number of selections if there are multiple)
  31. * @param selections the selections defining the categories to present.
  32. * @param {boolean} options.isRightClick True Indicates title returned should be for right click.
  33. * @returns {string} the toolbar's title eg: Camping Equipment | 2004 for a cluster chart, or '2 selected' for a non-cluster multiselection
  34. */
  35. Vis2SelectionController.prototype.getToolbarTitleForSelections = function getToolbarTitleForSelections(oSelections, options) {
  36. var aCustomSelections = this._getCustomTitleSelections(oSelections);
  37. var iNumSelected = oSelections.getCategorySetSize() + aCustomSelections.length;
  38. var pageContextSelectedCount = this.getSelectedCount();
  39. if (options && options.isRightClick && pageContextSelectedCount) {
  40. iNumSelected = pageContextSelectedCount + aCustomSelections.length;
  41. }
  42. iNumSelected = iNumSelected || 1;
  43. // are there multiple selections?
  44. if (iNumSelected > 1) {
  45. return StringResources.get('multiselectMsg', {
  46. count: iNumSelected
  47. });
  48. } else {
  49. var title = '';
  50. var aCategorySelections = oSelections.getCategorySelections().concat(aCustomSelections);
  51. _.each(aCategorySelections, function (selection) {
  52. // Apply any formatting this category selection has.
  53. var dataItemAPI = selection.slotDataItem;
  54. if (selection && selection.value) {
  55. var displayValue = selection.value.hasOwnProperty('d') ? selection.value.d : selection.value;
  56. if (title !== '') {
  57. title += ' | ';
  58. }
  59. title += dataItemAPI ? Formatter.format(displayValue, dataItemAPI.getFormat()) : displayValue;
  60. }
  61. }.bind(this));
  62. return title;
  63. }
  64. };
  65. /**
  66. * Get number of selected values plus points (visible)
  67. *
  68. * @returns sum of selected values plus points
  69. */
  70. Vis2SelectionController.prototype.getSelectedCount = function getSelectedCount() {
  71. var count = 0;
  72. var selections = this._visAPI.getFilterInfo({ type: 'selections' });
  73. if (selections && selections[0]) {
  74. var values = selections[0].values || selections[0].valueSummary;
  75. count = values ? values.length : count;
  76. }
  77. return count;
  78. };
  79. Vis2SelectionController.prototype._getSelectionValue = function _getSelectionValue(selection) {
  80. // Selection value can be one of the following:
  81. // 1. Primitive (Number)
  82. // 2. Object with 'd' for CatContDataItem (ie. lat long)
  83. // 3. Object with 'value' or 'v'
  84. if (selection.value.hasOwnProperty('d')) {
  85. return selection.value.d;
  86. } else if (selection.value.hasOwnProperty('v')) {
  87. return selection.value.v;
  88. } else if (selection.value.hasOwnProperty('value')) {
  89. return selection.value.value;
  90. }
  91. return selection.value;
  92. };
  93. /**
  94. * Get the 'labels' with values that correspond to the given selections (a set of measure names and, where possible, their values/formats).
  95. *
  96. * @param selections
  97. * @returns {Array}
  98. */
  99. Vis2SelectionController.prototype.getToolbarLabelsForSelections = function getToolbarLabelsForSelections(oSelections) {
  100. var aLabels = [];
  101. var aOrdinalSelections = oSelections.getOrdinalSelections();
  102. var existingTooltipEntries = {};
  103. _.each(aOrdinalSelections, function (selection) {
  104. var dataItemAPI = selection.slotDataItem;
  105. var dataItemId = dataItemAPI.getId();
  106. var existingTooltipEntry = existingTooltipEntries[dataItemId] || { value: null, count: 0 };
  107. //If the aggregation type isn't sum, append the aggregation type onto the name of the ordinal: eg: Revenue (Average)
  108. var ordinalFieldName = this._getOrdinalLabel(selection.slot, dataItemAPI);
  109. var ordinalValue = void 0;
  110. if (selection && selection.value || selection.value === 0) {
  111. var value = this._getSelectionValue(selection);
  112. // Guard against not having a valid number, maybe undefined
  113. if (!isNaN(value) && value !== null) {
  114. ordinalValue = Number(value);
  115. if (existingTooltipEntry.value !== null) {
  116. existingTooltipEntry.value += ordinalValue;
  117. } else {
  118. existingTooltipEntry.value = ordinalValue;
  119. }
  120. } else if (typeof value === 'string') {
  121. // handle the scenario that the value is already formatted
  122. existingTooltipEntry.value = value;
  123. }
  124. existingTooltipEntry.count++;
  125. }
  126. existingTooltipEntry.name = ordinalFieldName;
  127. existingTooltipEntry.dataType = dataItemAPI.getMetadataColumn().getDataType();
  128. existingTooltipEntry.formatSpec = dataItemAPI.getFormat();
  129. existingTooltipEntry.aggregate = dataItemAPI.getAggregation();
  130. existingTooltipEntries[dataItemId] = existingTooltipEntry;
  131. }.bind(this));
  132. _.each(existingTooltipEntries, function (entry) {
  133. var value = entry.value;
  134. if (entry.count > 1 && entry.aggregate !== 'sum' || value === 'N/A') {
  135. value = StringResources.get('value_is_not_available');
  136. }
  137. if (value === null || value === undefined || value === '') {
  138. value = entry.formatSpec ? Formatter.format(entry.value, entry.formatSpec) : StringResources.get('value_is_not_available');
  139. }
  140. aLabels.push({
  141. 'name': entry.name,
  142. 'dataType': entry.dataType,
  143. 'formatSpec': entry.formatSpec,
  144. 'value': value
  145. });
  146. });
  147. aLabels = _.uniq(aLabels, function (label) {
  148. return label.name + label.value;
  149. });
  150. aLabels.push.apply(aLabels, this._getCustomLabelSelections(oSelections));
  151. return aLabels;
  152. };
  153. Vis2SelectionController.prototype._getOrdinalLabel = function _getOrdinalLabel(slot, dataItem) {
  154. var aggregationType = dataItem.getAggregation();
  155. return aggregationType === 'sum' ? dataItem.getLabel() : StringResources.get('aggregatedColumnLabel', {
  156. aggregationTypeLabel: StringResources.get(aggregationType),
  157. column: dataItem.getLabel()
  158. });
  159. };
  160. /**
  161. * Select a new tuple
  162. * Note: the intent of this method is that it is atomic (meaning a single transaction and event)
  163. * If multi-select is needed, selectionArguments should allow variations.
  164. * @param selectionArguments
  165. * itemIds (required) - the one or more item's that have values to set.
  166. * tuple - a single tuple where one entry represents one part of the tuple
  167. * each term of the tuple should be of form { u: 'value' }
  168. * command - one of 'update' => merges the new tuple with the existing selections
  169. * 'remove' => removes the new tuple from the existing selections
  170. * slotsToClear: - to support select (without ctrl), clear all visible slots prior to replaceing with the new value.
  171. */
  172. Vis2SelectionController.prototype.select = function select(selectionArguments, transactionToken) {
  173. var _this = this;
  174. selectionArguments = selectionArguments || {};
  175. selectionArguments.brushingSpec = this._getBrushingItemSpec(selectionArguments.itemIds);
  176. this._visAPI.setPendingFilters(selectionArguments.pending ? true : false);
  177. var subTransactionToken = this.transaction.startTransaction(transactionToken);
  178. var transactionId = subTransactionToken && subTransactionToken.transactionId || selectionArguments.undoRedoTransactionId || UniqueId.get('select');
  179. var options = {
  180. payloadData: {
  181. undoRedoTransactionId: transactionId,
  182. silent: false,
  183. transactionToken: subTransactionToken
  184. },
  185. multiTuple: selectionArguments.multiTuple,
  186. synchOptions: {
  187. pageContext: this._getPendingPageContext(selectionArguments),
  188. newSelectionIsEmpty: this._newSelectionIsEmpty.bind(this)
  189. },
  190. skipFilterFocus: true
  191. };
  192. return this.synchronizeData.handleBrushingSelection(selectionArguments, options).then(function () {
  193. delete options.synchOptions;
  194. selectionArguments.isSynchronizedEntry = false;
  195. _this._select(selectionArguments, options);
  196. }).finally(function () {
  197. _this.transaction.endTransaction(subTransactionToken);
  198. });
  199. };
  200. Vis2SelectionController.prototype._getPendingPageContext = function _getPendingPageContext() {
  201. var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  202. return context.pending ? this._visAPI.setPendingFilters(true) : this._pageContextAPI;
  203. };
  204. //@returns the pageContext (normally, the actual pageContext but this can be overridden to be the pendingPageContext - (pendingFilters))
  205. Vis2SelectionController.prototype._getPageContext = function _getPageContext(options) {
  206. return options && options.pageContext ? options.pageContext : this._pageContextAPI;
  207. };
  208. /**
  209. * update a single item with the specified selectedValue
  210. * @param itemId - the itemId to update
  211. * @param selectedValue - a new value which should be of form { u: 'useValue' }
  212. * @param selectionArgs - command: 'update' - merge the value, 'remove' - remove the value from the tupleSet.
  213. * synchDataId: generated id shared between the pageContextEntry from different data sources
  214. * isSynchronizedEntry: true if selection is synchronized from another data source
  215. * @param options - options for this command including the transactionId or silent
  216. */
  217. Vis2SelectionController.prototype._updateEdgeSelection = function _updateEdgeSelection(itemId, selectedValue, selectionArgs, options) {
  218. var brushingSpec = this._getBrushingItemSpec(itemId, /*forClear*/false, selectionArgs);
  219. this._getPageContext(options).updateFilterContext(brushingSpec, {
  220. command: selectionArgs.command,
  221. values: this._getBrushingValueSpec(selectedValue, options)
  222. }, options);
  223. };
  224. /**
  225. * update the selections with a new dataPoint.
  226. * OR an edge with a value if itemIds/tuple are not an array OR an array of length 1.
  227. * @param itemIds - the items involved in the tuple (can be 1 which is equivalent to an edge selection)
  228. * @param valueTuple - a set of values of form {u: d:}. If no u and d are given, the value is assumed to be a use value.
  229. * @param selectionArgs - command: 'update' - merge the value, 'remove' - remove the value from the tupleSet.
  230. * synchDataId: generated id shared between the pageContextEntry from different data sources
  231. * isSynchronizedEntry: true if selection is synchronized from another data source
  232. * @returns the result of the update.
  233. */
  234. Vis2SelectionController.prototype._updateEdgeOrPointSelection = function _updateEdgeOrPointSelection(itemIds, valueTuple, selectionArgs, options) {
  235. var brushingSpec = this._getBrushingItemSpec(itemIds, /*forClear*/false, selectionArgs);
  236. return this._getPageContext(options).updateFilterContext(brushingSpec, {
  237. command: selectionArgs.command,
  238. values: this._getBrushingValueSpec(valueTuple, options)
  239. }, options);
  240. };
  241. /**
  242. * @param itemId - the itemId of the dataItem that might have selected values.
  243. * @returns true if the specified itemId has any selected items.
  244. */
  245. Vis2SelectionController.prototype.isItemSelected = function isItemSelected(itemId) {
  246. var item = this._getBrushingItem(itemId);
  247. return item && item.getValueCount() > 0 ? true : false;
  248. };
  249. /**
  250. * @param itemId - the itemId of the dataItem that might have selected values.
  251. * @param value - a value to check (should be of form { u: 'useValue' but 'useValue' is also accepted).
  252. * @returns true if the specified itemId has any selected items.
  253. */
  254. Vis2SelectionController.prototype.isValueSelected = function isValueSelected(itemId, value) {
  255. var pci = this._getBrushingItem(itemId);
  256. if (pci) {
  257. var valueIds = pci.getValueIds();
  258. return valueIds && valueIds.indexOf(value.u ? value.u : value) !== -1;
  259. }
  260. return false;
  261. };
  262. Vis2SelectionController.prototype._getBrushingItem = function _getBrushingItem(itemId) {
  263. return this._pageContextAPI.getPageContextItem({ itemId: itemId, origin: 'visualization', scope: this._visAPI.getScope(), eventGroupId: this._visAPI.getEventGroupId() });
  264. };
  265. /**
  266. * @param itemId - the itemId of the dataItem that might have selected values.
  267. * @returns an array of selected values. If none are selected, an empty array is returned.
  268. */
  269. Vis2SelectionController.prototype.getSelectedValues = function getSelectedValues(itemId) {
  270. var pci = this._getBrushingItem(itemId);
  271. if (pci) {
  272. return pci.getValueIds();
  273. }
  274. return [];
  275. };
  276. /**
  277. * @param itemIds - array of item IDs
  278. * @return array of tuples
  279. */
  280. Vis2SelectionController.prototype.getSelectedTuples = function getSelectedTuples(itemIds) {
  281. var brushingSelector = this._getBrushingItemSpec(itemIds);
  282. var pcpoint = this._pageContextAPI.getPageContextItem(brushingSelector);
  283. if (pcpoint && pcpoint.getValueCount()) {
  284. return pcpoint.getValues();
  285. }
  286. return [];
  287. };
  288. /**
  289. * Return keys for items (datapoint/edge).
  290. * @param tuples Array of data points or edge object
  291. */
  292. Vis2SelectionController.prototype.getItemKeys = function getItemKeys(tuples) {
  293. return _.map(tuples, function (tuple) {
  294. return EventUtils.getItemKey(tuple);
  295. });
  296. };
  297. //implementations functions.
  298. /**
  299. * implementation function.
  300. */
  301. Vis2SelectionController.prototype._select = function _select(selectionArgs, options) {
  302. var _this2 = this;
  303. //itemIds - ensure itemIds and tupleSet is an array.
  304. options = options || {};
  305. //If selectionArgs includes the pending flag, add the pendingPageContext (pendingFilters) to the options.
  306. options.pageContext = this._getPendingPageContext(selectionArgs);
  307. var itemIds = Array.isArray(selectionArgs.itemIds) ? selectionArgs.itemIds : [selectionArgs.itemIds];
  308. var tuple = Array.isArray(selectionArgs.tuple) ? selectionArgs.tuple : [selectionArgs.tuple];
  309. //Clear any items specified in slotsToClear.
  310. //An empty tuple can come in as one of the following:
  311. //1. undefined
  312. //2. []
  313. //3. [[]]
  314. //Adding a check to ensure that if any of the 3 above are encountered, to return and not allow highlighting.
  315. var newSelectionIsEmpty = this._newSelectionIsEmpty(tuple);
  316. options.silent = !newSelectionIsEmpty;
  317. this._clearSlotSelections(selectionArgs.slotsToClear, options);
  318. if (newSelectionIsEmpty) {
  319. return;
  320. }
  321. if (selectionArgs.edgeSelect) {
  322. options.payloadData = options.payloadData || {};
  323. //Currently, a few visualizations (mostly indentedList) break tuple selections down into selections on each edge
  324. //TODO: keep doing this for parity but should investigate if this ought to change.
  325. itemIds.forEach(function (itemId, i) {
  326. //An event should be sent on the final update.
  327. var flatTuple = _.flatten(tuple);
  328. options.payloadData.ignorePageContextChanged = i !== flatTuple.length - 1;
  329. options.silent = options.payloadData.ignorePageContextChanged;
  330. options.selectionInfo = selectionArgs.selectionInfo;
  331. _this2._updateEdgeSelection(itemIds[i], flatTuple[i], selectionArgs, options);
  332. });
  333. } else {
  334. //Normal Case: Most visualizations do tuple selections as actual tuple selections (dataPoint selections)
  335. options.silent = false;
  336. options.selectionInfo = selectionArgs.selectionInfo;
  337. this._updateEdgeOrPointSelection(itemIds, tuple, selectionArgs, options);
  338. }
  339. };
  340. /**
  341. * delete all page context entries that involve any of the hierarchies that are referenced in slotsToClear.
  342. * @param slotsToClear - the slots to clear hierarchies for (usually a simple call to getDataSlots() on the visualization)
  343. * @param options - typical options (silent, transactionId). Note that if newSelectionIsEmpty, silent will be false
  344. */
  345. Vis2SelectionController.prototype._clearSlotSelections = function _clearSlotSelections(slotsToClear, options) {
  346. var itemIdsToClear = [];
  347. _.each(slotsToClear, function (slotAPI) {
  348. var slotDataItems = slotAPI.getDataItemList();
  349. _.each(slotDataItems, function (dataItemAPI) {
  350. itemIdsToClear.push(dataItemAPI.getColumnId());
  351. }.bind(this));
  352. }.bind(this));
  353. //By specifying hierarchiesContain on the brushingSpec, we can clear all context entries in 1 shot.
  354. var brushingSpec = this._getBrushingItemSpec(itemIdsToClear, /*forClear*/true);
  355. brushingSpec.hierarchiesContain = itemIdsToClear;
  356. return this._getPageContext(options).deletePageContextItems(brushingSpec, options);
  357. };
  358. /**
  359. * @param itemIds - an itemId or array of itemIds.
  360. * @param forClear - if forClear is true, eventGroupId is not applied in the spec in order to clear any items which the source is moved to other event group.
  361. * @param selectionArgs - synchDataId: generated id shared between the pageContextEntry from different data sources
  362. * isSynchronizedEntry: true if selection is synchronized from another data source
  363. */
  364. Vis2SelectionController.prototype._getBrushingItemSpec = function _getBrushingItemSpec(itemIds, forClear, selectionArgs) {
  365. itemIds = Array.isArray(itemIds) ? itemIds : [itemIds];
  366. var hierarchies = _.map(itemIds, function (itemId) {
  367. return { hierarchyUniqueName: itemId };
  368. });
  369. var datasource = this.visualization.getDataSource();
  370. var itemKey = {
  371. origin: 'visualization',
  372. eventSourceId: this._ownerWidget.getId(),
  373. sourceId: datasource && datasource.getId(),
  374. scope: this._visAPI.getScope(),
  375. eventGroupId: this._visAPI.getEventGroupId(),
  376. hierarchies: hierarchies,
  377. hierarchyUniqueNames: itemIds //TODO: We shouldn't need this but pageContext complains.
  378. };
  379. var eventGroupId = this._visAPI.getEventGroupId();
  380. if (eventGroupId && !forClear) {
  381. itemKey.eventGroupId = eventGroupId;
  382. }
  383. if (selectionArgs) {
  384. if (selectionArgs.synchDataId) {
  385. itemKey.synchDataId = selectionArgs.synchDataId;
  386. }
  387. if (selectionArgs.isSynchronizedEntry) {
  388. itemKey.isSynchronizedEntry = selectionArgs.isSynchronizedEntry;
  389. }
  390. }
  391. return itemKey;
  392. };
  393. /**
  394. * This function accepts a single value or a single tuple as input.
  395. * The pageContext accepts a valueSpec which is either a simple object { u: d: }
  396. * or, for tuples, it expects "tupleSet form"
  397. * [
  398. * [{u: d:}, {u: d}], //One tuple in the tupleset.
  399. * ]
  400. * @param tuple - usually a tuple but can be a single { u: d: } value.
  401. * @param option.multiTuple - Indicates that the tuple param consist of multiple
  402. * tuples. For example
  403. * [
  404. * [{u: d1}, {u: d1}],[{u: d2}, {u: d2}],[{u: d3}, {u: d3}]
  405. * ]
  406. */
  407. Vis2SelectionController.prototype._getBrushingValueSpec = function _getBrushingValueSpec(tuple, option) {
  408. //Handle special case where tuple is just an object (a singe tuple with 1 part)
  409. var isSingleValue = !Array.isArray(tuple) || tuple.length === 1;
  410. var value = [];
  411. tuple = Array.isArray(tuple) ? tuple : [tuple];
  412. _.each(tuple, function (tuplePart) {
  413. if (Array.isArray(tuplePart)) {
  414. var v = [];
  415. _.each(tuplePart, function (tp) {
  416. v.push(this._getTuplePartValue(tp));
  417. }.bind(this));
  418. value.push(v);
  419. } else {
  420. value.push(this._getTuplePartValue(tuplePart));
  421. }
  422. }.bind(this));
  423. return isSingleValue || option.multiTuple ? value : [value];
  424. };
  425. Vis2SelectionController.prototype._getTuplePartValue = function _getTuplePartValue(tuplePart) {
  426. //Handle when tuplePart is an array as is the case in multi turple selection
  427. var resultValue = {};
  428. if (tuplePart && tuplePart.u !== undefined) {
  429. resultValue.u = tuplePart.u;
  430. resultValue.d = tuplePart.d !== undefined ? tuplePart.d : tuplePart.u;
  431. if (tuplePart.p || tuplePart.pu) {
  432. resultValue.p = tuplePart.p || tuplePart.pu;
  433. }
  434. } else {
  435. resultValue.u = tuplePart;
  436. resultValue.d = tuplePart;
  437. }
  438. return resultValue;
  439. };
  440. /**
  441. * Returns a boolean indicating whether can apply brushing for not
  442. *
  443. * @param {object} scope - the scope to verify the context of brushing
  444. */
  445. Vis2SelectionController.prototype._canApplyBrushing = function _canApplyBrushing() {
  446. var scope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  447. return scope.eventGroupId === this._visAPI.getEventGroupId() && scope.eventSourceId !== this._ownerWidget.getId() && scope.scope === this._visAPI.getScope();
  448. };
  449. /**
  450. * Call to handle the synchronize of data, i.e, create a page context entry if applicable per data source
  451. *
  452. * @param {object} payload - contains the context to handle the synchronization of data via the creation/update of a pagecontext entry of type 'visualization' per data source
  453. *
  454. */
  455. Vis2SelectionController.prototype._handleSynchronizeData = function _handleSynchronizeData() {
  456. var _this3 = this;
  457. var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  458. var synchData = payload.data;
  459. if (synchData) {
  460. // TODO livewidget cleanup -- use the new datasource instead of module here
  461. var module = this._visAPI.getModule();
  462. var dataSource = this.visualization.getDataSource();
  463. var thisTableRef = DatasourceUtil.getTableRef(dataSource, this.visualization.getSlots().getDataItemList().map(function (dataItem) {
  464. return dataItem.getColumnId();
  465. }));
  466. var ignoreSynchBrushData = function ignoreSynchBrushData() {
  467. var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  468. var ignoreSynchBrushData = data.ignoreSynchBrushData || [];
  469. return ignoreSynchBrushData.indexOf(_this3._ownerWidget.getId()) !== -1;
  470. };
  471. var getData = function getData(sourceId) {
  472. return synchData.find(function (item) {
  473. return item.sourceId === sourceId && DatasourceUtil.haveATableReference(thisTableRef, item.tableRef);
  474. });
  475. };
  476. var data = getData(dataSource.getId());
  477. if (data && !ignoreSynchBrushData(data) && !data.hasNotApplied && module && this._canApplyBrushing(payload.scope, thisTableRef, data.tableRef)) {
  478. //trigger broadcast to everyone with same source id but only one processing the triggering is sufficient to update the page context
  479. data.hasNotApplied = true;
  480. var selector = {
  481. origin: 'visualization',
  482. scope: payload.scope.scope,
  483. eventGroupId: payload.scope.eventGroupId,
  484. sourceId: dataSource.getId()
  485. };
  486. var slotsToClear = data.getNetSlotsToClear({
  487. dataSlots: this.visualization.getSlots().getMappedSlotList(),
  488. sourceModule: data.sourceModule,
  489. targetModule: module,
  490. tableNames: thisTableRef,
  491. pageContext: this._getPendingPageContext(payload.arguments),
  492. selector: selector,
  493. itemIds: data.itemIds,
  494. newSelectionIsEmpty: this._newSelectionIsEmpty(data.tuple)
  495. });
  496. var selectionArguments = {
  497. command: payload.arguments.command,
  498. pending: payload.arguments.pending,
  499. edgeSelect: this._ownerWidget.getEdgeSelection(),
  500. slotsToClear: data.append ? [] : slotsToClear,
  501. itemIds: data.itemIds,
  502. tuple: data.tuple,
  503. synchDataId: data.synchDataId,
  504. isSynchronizedEntry: true
  505. };
  506. this._select(selectionArguments, data.options);
  507. }
  508. }
  509. };
  510. Vis2SelectionController.prototype._getCustomTitleSelections = function _getCustomTitleSelections(oSelections) {
  511. return typeof oSelections.getCustomTitleSelections === 'function' ? oSelections.getCustomTitleSelections() : [];
  512. };
  513. Vis2SelectionController.prototype._getCustomLabelSelections = function _getCustomLabelSelections(oSelections) {
  514. return typeof oSelections.getCustomLabelSelections === 'function' ? oSelections.getCustomLabelSelections() : [];
  515. };
  516. Vis2SelectionController.prototype._newSelectionIsEmpty = function _newSelectionIsEmpty(tuple) {
  517. return !tuple || !_.flatten(tuple).length;
  518. };
  519. Vis2SelectionController.prototype.remove = function remove() {
  520. this.unregisterEvents();
  521. };
  522. Vis2SelectionController.prototype.registerEvents = function registerEvents() {
  523. this.dashboardApi.on('synchronizeData:applyBrushing', this._handleSynchronizeData, this);
  524. };
  525. Vis2SelectionController.prototype.unregisterEvents = function unregisterEvents() {
  526. this.dashboardApi.off('synchronizeData:applyBrushing', this._handleSynchronizeData, this);
  527. };
  528. return Vis2SelectionController;
  529. }();
  530. return Vis2SelectionController;
  531. });
  532. //# sourceMappingURL=Vis2SelectionController.js.map