Rave2RenderHelper.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. 'use strict';
  2. /*
  3. *+------------------------------------------------------------------------+
  4. *| Licensed Materials - Property of IBM
  5. *| IBM Cognos Products: BI Dashboard
  6. *| (C) Copyright IBM Corp. 2016, 2017
  7. *|
  8. *| US Government Users Restricted Rights - Use, duplication or disclosure
  9. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10. *+------------------------------------------------------------------------+
  11. */
  12. /**
  13. * A utility class for RAVE2 related definition support
  14. */
  15. define(['../lib/@waca/core-client/js/core-client/ui/core/Class', 'underscore'], function (Class, _) {
  16. var Rave2RenderHelper = Class.extend({
  17. _raveView: null,
  18. init: function init(options) {
  19. this._raveView = options.raveView;
  20. },
  21. applyProps: function applyProps() {
  22. this._applyNativePros();
  23. this._applyRAVE2VisProps();
  24. },
  25. _applyNativePros: function _applyNativePros() {
  26. if (!this._raveView || !this._raveView.visModel) {
  27. return;
  28. }
  29. this._setOrdinalSlotDomain();
  30. },
  31. /**
  32. * Apply for RAVE2 Visualization properties
  33. */
  34. _applyRAVE2VisProps: function _applyRAVE2VisProps() {
  35. var oRaveVis = this._raveView._rave2Vis;
  36. var aProperties = this.getPropertiesToSet();
  37. aProperties.forEach(function (prop) {
  38. oRaveVis.property(prop.id, prop.value);
  39. });
  40. },
  41. /**
  42. Returns an array of properties to set
  43. **/
  44. getPropertiesToSet: function getPropertiesToSet() {
  45. if (!this._raveView || !this._raveView._rave2Vis) {
  46. return [];
  47. }
  48. var aProperties = [];
  49. _.each(this._raveView.visModel.properties.getModels(), function (prop) {
  50. if (prop.mapValuesFunction) {
  51. // Handler will return an array of properties to set
  52. // TODO: change to pass _raveView instead to remove the 3rd arguments for better legacy function integrity
  53. var aProps = prop.mapValuesFunction(prop, this._raveView.visModel, {
  54. 'maxDomainValue': this._maxDomainValue
  55. });
  56. if (aProps) {
  57. aProps.forEach(function (prop) {
  58. aProperties.push(prop);
  59. });
  60. }
  61. } else {
  62. if (prop.id !== 'colorPalette') {
  63. if (prop.value !== undefined && prop.value !== null) {
  64. aProperties.push({
  65. 'id': prop.id,
  66. 'value': prop.value
  67. });
  68. }
  69. }
  70. }
  71. }.bind(this));
  72. return aProperties;
  73. },
  74. getVisId: function getVisId() {
  75. return this._raveView.visModel.definition.id;
  76. },
  77. /**
  78. * This function sets the min and max value of a numeric data slot's value range, via which
  79. * it implements the vis property setting for 'maintain axis scales.' Therefore it should only
  80. * apply to those visualization that declares to support such property
  81. *
  82. * @param {array} aDomainRange value range, [<minValue>, <maxValue>]
  83. * */
  84. _setOrdinalSlotDomain: function _setOrdinalSlotDomain() {
  85. if (!this.isDomainInformationNeededForVisuzalition()) {
  86. this._maxDomainValue = null;
  87. return;
  88. } else {
  89. _.each(this._raveView.visModel.getDataSlots(), function (oSlot) {
  90. if (this.isDomainSupportedForSlot(oSlot)) {
  91. var aDomain = this.getDomainForSlot(oSlot);
  92. var oCurDataSlot = this.getRAVE2DataSet().slot(oSlot.definition.id);
  93. // For repeated slots the id of the repeated slot won't be in the rave2 data set
  94. if (!oCurDataSlot) {
  95. return;
  96. }
  97. var oEntry = oCurDataSlot.entry();
  98. if (oEntry) {
  99. oEntry.domain(aDomain);
  100. }
  101. }
  102. }.bind(this));
  103. }
  104. },
  105. isDomainInformationNeededForVisuzalition: function isDomainInformationNeededForVisuzalition() {
  106. var oMaintainAxisScales_propValue = this._raveView.visModel.getPropertyById('maintainAxisScales');
  107. if (oMaintainAxisScales_propValue === null || oMaintainAxisScales_propValue.getValue() !== true) {
  108. return false;
  109. }
  110. return true;
  111. },
  112. isDomainSupportedForSlot: function isDomainSupportedForSlot(oSlot) {
  113. return oSlot.getDefinition().type === 'ordinal';
  114. },
  115. /**
  116. * RAVE2 Vis instance could have multiple types of data models. One data model could have multiple data sets.
  117. * However, if the current RAVE2 Vis has only one data model, and the data model has only one data set, we
  118. * can use the only dataset as the default data set. This is to solve the problem that different type of RAVE2 Vis
  119. * has different data set ID. This should work for absolutely most of the configuration/bundles dashboard support.
  120. * For example, Dial bundle has only one dataModel, SimpleDialModel and this SimpleDialModel has one dataset
  121. * with id 'DialData'. There is an exception that Line&Column composite chart has one model with ID 'TabularModel'
  122. * while it has two dataSets, one with ID 'ColumnData', one with ID 'LineData', RAVE2 team is working on to let
  123. * RAVE2 composite to support only one dataSet.
  124. **/
  125. getRAVE2DataSet: function getRAVE2DataSet() {
  126. //Should we cache dataset?
  127. if (this._raveView._rave2Vis) {
  128. var oDataModel = this.getDefaultDataModel();
  129. if (oDataModel) {
  130. var aDataSets = oDataModel.dataSets();
  131. if (aDataSets && aDataSets.length >= 1) {
  132. return this._raveView._visDataModel.dataset(aDataSets[0].id());
  133. }
  134. }
  135. }
  136. return null;
  137. },
  138. getDefaultDataModel: function getDefaultDataModel() {
  139. //Should we cache the data model?
  140. if (this._raveView._rave2Vis) {
  141. var aDataModels = this._raveView._rave2Vis.getDataModels();
  142. if (aDataModels && aDataModels.length >= 1) {
  143. return aDataModels[0];
  144. }
  145. return null;
  146. }
  147. },
  148. getDomainForSlot: function getDomainForSlot(oSlot) {
  149. var visModel = this._raveView.visModel;
  150. var queryResults = visModel.getQueryResults();
  151. if (visModel.definition.useOrdinalNamesAsCategoryValues) {
  152. return [queryResults.minSeriesRange, queryResults.maxSeriesRange];
  153. }
  154. if (oSlot.getMapping() && oSlot.definition.type === 'ordinal') {
  155. var specField = this.getFactSpecField(oSlot, queryResults.getFieldValues(oSlot.getId()));
  156. var max = specField.min === specField.max ? specField.min + 1 : specField.max;
  157. // Keep track of the maximum domain value. Needed for dial chart where we have to set the maxValue property
  158. this._maxDomainValue = this._maxDomainValue && this._maxDomainValue > max ? this._maxDomainValue : max;
  159. return [specField.min, max];
  160. }
  161. return [];
  162. },
  163. /*<Start>: Functions below are mainly from existing ravespecpropertyhelper.js, which was developed for RAVE1 spec based rendering
  164. * we will need to make the following functions sharable and reusable, between ravespecpropertyhelper.js and this RAVE2 render helper
  165. * */
  166. getFactSpecField: function getFactSpecField(slot, range) {
  167. //Trim value range to user-specified settings
  168. this._trimXAndYAxisRange(slot.getId(), range);
  169. //TODO HACK: RAVE complains when there's a 0 value when plotting on a logarithmic scale
  170. var slotAndAxisScale = slot.getId() === 'yAxis' && this.yAxisScale === 'log' || slot.getId() === 'xAxis' && this.xAxisScale === 'log';
  171. var rangeMin = range ? range.min : 0;
  172. rangeMin = rangeMin === 0 && slotAndAxisScale ? 0.01 : rangeMin;
  173. var rangeMax = range ? range.max : 0;
  174. /*
  175. * If min and max are equal, Rave's vis renders with 0 at the mid point of the chart and animation is
  176. * extremely strange. So, make max = min + 1
  177. */
  178. rangeMax = rangeMax === rangeMin ? rangeMin + 1 : rangeMax;
  179. return {
  180. format: {
  181. scientific: 'never',
  182. fitMethod: 'none'
  183. },
  184. id: slot.getId(),
  185. label: slot.getLabel(),
  186. min: rangeMin,
  187. max: rangeMax
  188. };
  189. },
  190. _trimYAxisRange: function _trimYAxisRange(specField) {
  191. if (this.yMin !== undefined) {
  192. specField.min = this.yMin;
  193. }
  194. if (this.yMax !== undefined && this.yMax !== this.yMin) {
  195. specField.max = this.yMax;
  196. }
  197. if (specField.max < this.preferredYMin) {
  198. specField.max = this.preferredYMin;
  199. }
  200. },
  201. _trimXAxisRange: function _trimXAxisRange(specField) {
  202. if (this.xMin !== undefined) {
  203. specField.min = this.xMin;
  204. }
  205. if (this.xMax !== undefined && this.xMax !== this.xMin) {
  206. specField.max = this.xMax;
  207. }
  208. if (specField.max < this.preferredXMin) {
  209. specField.max = this.preferredXMin;
  210. }
  211. },
  212. _trimXAndYAxisRange: function _trimXAndYAxisRange(id, specField) {
  213. if (id === 'yAxis') {
  214. this._trimYAxisRange(specField);
  215. } else if (id === 'xAxis') {
  216. this._trimXAxisRange(specField);
  217. }
  218. }
  219. /*<End> sharable functions between this render helper class and the legacy ravespecpropertyhelper.js*/
  220. });
  221. return Rave2RenderHelper;
  222. });
  223. //# sourceMappingURL=Rave2RenderHelper.js.map