PostProcessMultiEdgeShowNulls.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /*
  4. *+------------------------------------------------------------------------+
  5. *| Licensed Materials - Property of IBM
  6. *| IBM Cognos Products: BI Dashboard
  7. *| (C) Copyright IBM Corp. 2019, 2020
  8. *|
  9. *| US Government Users Restricted Rights - Use, duplication or disclosure
  10. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  11. *+------------------------------------------------------------------------+
  12. */
  13. define([], function () {
  14. 'use strict';
  15. /**
  16. * This post processor handles 'null suppression disabled'.
  17. * It is dependent on PostProcessMultiEdgeMeasures for multi-measure use cases so it has been chained after it.
  18. *
  19. * When null suppression is disabled, all edge items are returned in the DSS response (they are not when suppression is on)
  20. * BUT the pt array has no more cells than it would if suppression were on.
  21. *
  22. * This post processor generates null datapoints to fill those gaps so that rows/columns of null values
  23. * will be displayed.
  24. *
  25. * The post processor does not handle all shapes but supports all forms of crosstabs.
  26. * 2 or 3 edge responses (where one edge is a measure)
  27. **/
  28. return function () {
  29. /**
  30. * @Constructor
  31. * @param {Object} queryResultDataPoints - a map of multiEdgeData
  32. * @param {Object} queryResultData - the query result data
  33. */
  34. function PostProcessMultiEdgeShowNulls(_ref) {
  35. var queryResultDataPoints = _ref.queryResultDataPoints,
  36. queryResultData = _ref.queryResultData;
  37. _classCallCheck(this, PostProcessMultiEdgeShowNulls);
  38. this.multiEdgeData = queryResultDataPoints;
  39. this._queryResultData = queryResultData;
  40. //Pre-compute the index and size of each non-measure edge.
  41. var edges = this._queryResultData.edges;
  42. this.firstEdgeSize = queryResultDataPoints.getFirstEdgeSize(edges);
  43. //If there's 3 edges, the second nonMeasure edge will be firstEdge + 1 (usually just 1)
  44. this.secondEdgeSize = this.multiEdgeData.getSecondEdgeSize(edges);
  45. //Was the data clipped before we started?, if so, make sure it is marked as clipped at the end.
  46. var data = this._queryResultData.data;
  47. var clipMarkerIdx = data && data.length - 1;
  48. this.clipMarker = clipMarkerIdx > 0 && data[clipMarkerIdx] && data[clipMarkerIdx].hasNext ? data[clipMarkerIdx] : null;
  49. //In the query, we requested 3000 suppressed cells from DSS but if we simply process all of the data,
  50. //we could end up with thousands or tens of thousands more once nulls are inserted.
  51. //TODO: RTC297388 For now, just stop processing at a hard coded limit af 3000 cells
  52. // We should use some variation of _getQuerySpecLimit() in QueryProvider BOTH here and
  53. // on the query side but we need to think about this because now our request
  54. // includes the summaries and its difficult to know how much to bump up the limit.
  55. this._CELL_OUTPUT_LIMIT = 3000;
  56. }
  57. /**
  58. * Apply the users overrides for a multi-edge result. If this is not a multi-edge result,
  59. * this post processor is a no-op.
  60. * @return {QueryResultData}
  61. */
  62. PostProcessMultiEdgeShowNulls.prototype._processData = function _processData() {
  63. if (this._queryResultData.edges && this._queryResultData.edges.length > 1) {
  64. //Suppress nulls off handling.
  65. var edgeCount = this._queryResultData.edges.length;
  66. if (edgeCount === 2) {
  67. this._showNulls_2Edges();
  68. } else if (edgeCount === 3) {
  69. this._showNulls_3Edges();
  70. } else {
  71. throw new Error('only 2 and 3 edge responses are supported for zero suppression disabled');
  72. }
  73. if (this.clipMarker) {
  74. //If the data was clipped before, its still clipped after.
  75. this._queryResultData.data.push(this.clipMarker);
  76. }
  77. }
  78. //For V1 or single edge V2, this postProcessor is a no-op.
  79. return this._queryResultData;
  80. };
  81. //Show nulls in a 2 edge visualization (eg a crosstab with rows and measures) by
  82. //creating a complete array of points which include the data and null values where there is no data.
  83. PostProcessMultiEdgeShowNulls.prototype._showNulls_2Edges = function _showNulls_2Edges() {
  84. var output = [];
  85. this._addFirstEdgeCellsToOutput(output);
  86. this._queryResultData.data = output;
  87. return this._queryResultData;
  88. };
  89. //Show nulls in a 3 edge visualization (eg a crosstab with columns, rows and measures) by
  90. //creating a complete rectangle of points which include the data and null values where there is no data.
  91. PostProcessMultiEdgeShowNulls.prototype._showNulls_3Edges = function _showNulls_3Edges() {
  92. var output = [];
  93. var cellIdx = 0;
  94. for (var ptSecondEdgeId = 0; ptSecondEdgeId < this.secondEdgeSize; ++ptSecondEdgeId) {
  95. cellIdx = this._addFirstEdgeCellsToOutput(output, cellIdx, ptSecondEdgeId);
  96. if (output.length >= this._CELL_OUTPUT_LIMIT) {
  97. break;
  98. }
  99. }
  100. this._queryResultData.data = output;
  101. return this._queryResultData;
  102. };
  103. PostProcessMultiEdgeShowNulls.prototype._addFirstEdgeCellsToOutput = function _addFirstEdgeCellsToOutput(output) {
  104. var cellIdx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  105. var ptSecondEdgeId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
  106. //Add cells for each item in the first edge with 'gaps filled in'
  107. for (var ptFirstEdgeId = 0; ptFirstEdgeId < this.firstEdgeSize; ++ptFirstEdgeId) {
  108. output.push(this.multiEdgeData.getPtByEdgeIds(ptFirstEdgeId, ptSecondEdgeId));
  109. if (output.length >= this._CELL_OUTPUT_LIMIT) {
  110. this._addClipMarker(output);
  111. break;
  112. }
  113. }
  114. return cellIdx;
  115. };
  116. PostProcessMultiEdgeShowNulls.prototype._addClipMarker = function _addClipMarker(output) {
  117. //When the data is sparse, we could easily generate many more cells than the suppressed version.
  118. //We need to clip it (and mark that its clipped).
  119. output.push({ hasNext: true });
  120. };
  121. return PostProcessMultiEdgeShowNulls;
  122. }();
  123. });
  124. //# sourceMappingURL=PostProcessMultiEdgeShowNulls.js.map