@datarailsshared/dr_renderer 1.2.357 → 1.2.359

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datarailsshared/dr_renderer",
3
- "version": "1.2.357",
3
+ "version": "1.2.359",
4
4
  "description": "DataRails charts and tables renderer",
5
5
  "keywords": [
6
6
  "datarails",
@@ -12,6 +12,10 @@ let initDRPivotTable = function($, window, document) {
12
12
  document.ReportHippo.user.organization.settings && document.ReportHippo.user.organization.settings.use_new_ux;
13
13
  // const numberOfRows = 500; // change to activate the handsontable when num of rows bigger then this.
14
14
 
15
+ const isFlatKeyInPivotKeys = function(keys, flatKey) {
16
+ return keys.some(key => key.join(delim) === flatKey);
17
+ };
18
+
15
19
  DRPivotData = (function(superClass) {
16
20
  extend(DRPivotData, superClass);
17
21
 
@@ -199,10 +203,10 @@ let initDRPivotTable = function($, window, document) {
199
203
  let flatColKey = colKey.join(delim);
200
204
 
201
205
  if (this.keysLength === rowKey.length + colKey.length) {
202
- if (!this.rowKeys.some(rKey => rKey.join(delim) === flatRowKey)) {
206
+ if (!this.isKeysSortingDoneOnBackendSide && !isFlatKeyInPivotKeys(this.rowKeys, flatRowKey)) {
203
207
  this.rowKeys.push(rowKey);
204
208
  }
205
- if (!this.colKeys.some(cKey => cKey.join(delim) === flatColKey)) {
209
+ if (!this.isKeysSortingDoneOnBackendSide && !isFlatKeyInPivotKeys(this.colKeys, flatColKey)) {
206
210
  this.colKeys.push(colKey);
207
211
  }
208
212
  }
@@ -234,7 +238,6 @@ let initDRPivotTable = function($, window, document) {
234
238
  insight: insight,
235
239
  });
236
240
  }
237
-
238
241
  return;
239
242
  }
240
243
 
@@ -150,6 +150,7 @@ const FEATURES = {
150
150
  FORMAT_DATES_AS_OTHER_AXIS_TYPES: 'format_dates_as_other_axis_types',
151
151
  MULTIPLE_DIMENSION_TAGS: 'multiple_dimension_tags',
152
152
  USE_NEW_SCENARIO_TAG: 'use_new_scenario_tag',
153
+ ENABLE_SERVER_WIDGET_DATA_SORTING: 'enable_server_widget_data_sorting',
153
154
  }
154
155
 
155
156
  const TICKS_COUNT = 5;
@@ -205,6 +206,7 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
205
206
  highchartsRenderer.useTotalsCalculation = highchartsRenderer.hasFeature(FEATURES.ENABLE_SERVER_TOTALS_CALCULATION);
206
207
  disableAnimation = document.ReportHippo.user.organization && document.ReportHippo.user.organization.settings && document.ReportHippo.user.organization.settings.disable_animation
207
208
  highchartsRenderer.enabledNewWidgetValueFormatting = highchartsRenderer.hasFeature(FEATURES.ENABLE_NEW_WIDGET_VALUE_FORMATTING);
209
+ highchartsRenderer.isSortingOnBackendEnabled = highchartsRenderer.hasFeature(FEATURES.ENABLE_SERVER_WIDGET_DATA_SORTING);
208
210
  }
209
211
 
210
212
  // fix issue of use tootip.stickOnContact with tooltip.outside , source: https://github.com/highcharts/highcharts/pull/15960
@@ -1084,7 +1086,7 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
1084
1086
  if (chartOptions.series) {
1085
1087
  for (var i = 0; i < chartOptions.series.length; i++) {
1086
1088
  seriesDataLength += chartOptions.series[i].data ? chartOptions.series[i].data.length : 0;
1087
- if (seriesDataLength > 2000) {
1089
+ if (seriesDataLength > 1000) {
1088
1090
  toMatch = true;
1089
1091
  break;
1090
1092
  }
@@ -1541,6 +1543,7 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
1541
1543
  const chart_series = [];
1542
1544
  const row_n_keys = pivotData.getRowKeys();
1543
1545
  const col_n_keys = pivotData.getColKeys();
1546
+ const rows_by_cols = pivotData.rowKeysByCols;
1544
1547
 
1545
1548
  let resultObject = {
1546
1549
  data: [],
@@ -1570,7 +1573,9 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
1570
1573
  });
1571
1574
 
1572
1575
  if (col_index !== col_n_keys.length - 1) {
1573
- lodash.forEach(row_n_keys, function (row_n_value) {
1576
+
1577
+ const rowKeys = rows_by_cols ? rows_by_cols[col_index] : row_n_keys;
1578
+ lodash.forEach(rowKeys, function (row_n_value) {
1574
1579
  const agg = pivotData.getAggregator(row_n_value, col_n_value);
1575
1580
  let val = agg.value();
1576
1581
 
@@ -4798,20 +4803,22 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
4798
4803
  opts.rendererOptions.onlyOptions = true;
4799
4804
  }
4800
4805
 
4801
- const sortByValueSettings = lodash.filter(
4802
- lodash.get(widget, 'options.sortingFields', []),
4803
- sortingField => lodash.includes(['field_values', 'variance'], lodash.get(sortingField, 'sorting.sort_by'))
4804
- );
4805
-
4806
- if (sortByValueSettings.length) {
4807
- pivotData.sortByValueAttrs = lodash.map(sortByValueSettings, fieldSorting => fieldSorting.name);
4808
- let new_sorting_function = highchartsRenderer.generateSortingFunctionByValues(sortByValueSettings, pivotData, opts, widget);
4809
- opts.sorters = new_sorting_function;
4810
- optsFiltered.sorters = new_sorting_function;
4811
- pivotData.sorters = new_sorting_function;
4812
-
4813
- if (lodash.isObject(lodash.get(widget, 'pivot'))) {
4814
- widget.pivot.sorters = new_sorting_function;
4806
+ if (!highchartsRenderer.isSortingOnBackendEnabled) {
4807
+ const sortByValueSettings = lodash.filter(
4808
+ lodash.get(widget, 'options.sortingFields', []),
4809
+ sortingField => lodash.includes(['field_values', 'variance'], lodash.get(sortingField, 'sorting.sort_by'))
4810
+ );
4811
+
4812
+ if (sortByValueSettings.length) {
4813
+ pivotData.sortByValueAttrs = lodash.map(sortByValueSettings, fieldSorting => fieldSorting.name);
4814
+ let new_sorting_function = highchartsRenderer.generateSortingFunctionByValues(sortByValueSettings, pivotData, opts, widget);
4815
+ opts.sorters = new_sorting_function;
4816
+ optsFiltered.sorters = new_sorting_function;
4817
+ pivotData.sorters = new_sorting_function;
4818
+
4819
+ if (lodash.isObject(lodash.get(widget, 'pivot'))) {
4820
+ widget.pivot.sorters = new_sorting_function;
4821
+ }
4815
4822
  }
4816
4823
  }
4817
4824
 
@@ -4875,6 +4882,7 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
4875
4882
  rowFormats: highchartsRenderer.getTableFormatInfosForWidgetFields(widget, pivotOptions, widget.rows),
4876
4883
  rendererOptions: widget.options,
4877
4884
  dateValuesDictionary: pivotOptions ? pivotOptions.dateValuesDictionary : null,
4885
+ keysObject: pivotOptions ? pivotOptions.keysObject : null,
4878
4886
  };
4879
4887
 
4880
4888
  if (!subopts.rendererOptions) {
@@ -8777,8 +8785,8 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8777
8785
  };
8778
8786
 
8779
8787
  highchartsRenderer.getWidgetDataSorters = function (res, widget, defaultDateFormat) {
8780
-
8781
8788
  const isFormattingDatesAsOtherAxisTypes = highchartsRenderer.isFormattingDatesAsOtherAxisTypes();
8789
+ let sorters;
8782
8790
 
8783
8791
  if ($.pivotUtilities && !$.pivotUtilities.additionalFieldsList) {
8784
8792
  $.pivotUtilities.additionalFieldsList = [
@@ -8787,7 +8795,7 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8787
8795
  ];
8788
8796
  }
8789
8797
 
8790
- var datesFields = [];
8798
+ let datesFields = [];
8791
8799
  datesFields = lodash.filter(widget.rows, element => element.type == 'Date');
8792
8800
  datesFields = datesFields.concat(lodash.filter(widget.cols, element => element.type == 'Date'));
8793
8801
 
@@ -8811,8 +8819,6 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8811
8819
  } //'MMM - yyyy' format
8812
8820
  });
8813
8821
 
8814
- var data = res;
8815
-
8816
8822
  if (!isFormattingDatesAsOtherAxisTypes) {
8817
8823
  lodash.forEach(datesFields, function (row) {
8818
8824
  row.val_not_convert = highchartsRenderer.check_values_not_for_convert(widget, row.name);
@@ -8820,7 +8826,8 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8820
8826
  }
8821
8827
 
8822
8828
  if (datesFields.length > 0) {
8823
- lodash.forEach(data, function (element) {
8829
+ const invertedDateStringMap = {};
8830
+ lodash.forEach(res, function (element) {
8824
8831
  for (var i in datesFields) {
8825
8832
  if (element.hasOwnProperty(datesFields[i].name)) {
8826
8833
  datesFields[i].values.push(element[datesFields[i].name]);
@@ -8835,133 +8842,154 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8835
8842
  widget.pivot.dateValuesDictionary = {}
8836
8843
  }
8837
8844
  widget.pivot.dateValuesDictionary[dateStringValue] = element[datesFields[i].name];
8845
+ invertedDateStringMap[element[datesFields[i].name]] = dateStringValue;
8838
8846
  }
8839
8847
  element[datesFields[i].name] = dateStringValue;
8840
8848
  }
8841
8849
  }
8842
8850
  }
8843
8851
  });
8844
- }
8845
8852
 
8846
- lodash.forEach(datesFields, function (row) {
8847
- row.values = lodash.uniq(row.values);
8853
+ if (highchartsRenderer.isSortingOnBackendEnabled && !isFormattingDatesAsOtherAxisTypes && lodash.get(widget, 'pivot.keysObject')) {
8854
+ lodash.forEach(['col_keys', 'row_keys'], (keysListName, index) => {
8855
+ const widgetFields = index ? widget.rows : widget.cols;
8856
+ const uniqueFormattedKeysList = [];
8857
+ lodash.forEach(widget.pivot.keysObject[keysListName], subKeysList => {
8858
+ lodash.forEach(subKeysList, (key, index) => {
8859
+ if (widgetFields[index].type === 'Date') {
8860
+ subKeysList[index] = invertedDateStringMap[key] || key;
8861
+ }
8862
+ });
8863
+ if (!lodash.find(uniqueFormattedKeysList, formattedSubKeys => lodash.isEqual(formattedSubKeys, subKeysList))) {
8864
+ uniqueFormattedKeysList.push(subKeysList);
8865
+ }
8866
+ });
8867
+ widget.pivot.keysObject[keysListName] = uniqueFormattedKeysList;
8868
+ });
8869
+ }
8870
+ }
8848
8871
 
8849
- const isTimestampDateField = row.type === 'Date' && lodash.some(row.values, value => typeof value ==='number');
8850
- if (isTimestampDateField) {
8851
- const nullValueIndex = row.values.indexOf(NULL_VALUE);
8852
- if (~nullValueIndex) {
8853
- row.values.splice(nullValueIndex, 1);
8872
+ if (!highchartsRenderer.isSortingOnBackendEnabled) {
8873
+
8874
+ lodash.forEach(datesFields, function (row) {
8875
+ row.values = lodash.uniq(row.values);
8876
+
8877
+ const isTimestampDateField = row.type === 'Date' && lodash.some(row.values, value => typeof value ==='number');
8878
+ if (isTimestampDateField) {
8879
+ const nullValueIndex = row.values.indexOf(NULL_VALUE);
8880
+ if (~nullValueIndex) {
8881
+ row.values.splice(nullValueIndex, 1);
8882
+ }
8883
+ row.values = row.values.sort((a, b) => a - b);
8884
+ if (~nullValueIndex) {
8885
+ row.values.push(NULL_VALUE);
8886
+ }
8887
+ } else {
8888
+ row.values = row.values.sort();
8854
8889
  }
8855
- row.values = row.values.sort((a, b) => a - b);
8856
- if (~nullValueIndex) {
8857
- row.values.push(NULL_VALUE);
8890
+
8891
+ if (row.sorting && row.sorting.type == "largestToSmallest") {
8892
+ row.values = lodash.reverse(row.values);
8858
8893
  }
8859
- } else {
8860
- row.values = row.values.sort();
8861
- }
8894
+ delete row.sorting;
8862
8895
 
8863
- if (row.sorting && row.sorting.type == "largestToSmallest") {
8864
- row.values = lodash.reverse(row.values);
8865
- }
8866
- delete row.sorting;
8896
+ if (!isFormattingDatesAsOtherAxisTypes) {
8897
+ row.values = lodash.map(row.values, function (val) {
8898
+ return highchartsRenderer.returnRawDataValue(row.type, val, row.format, row.name, row.val_not_convert) + "";
8899
+ });
8900
+ }
8901
+ });
8867
8902
 
8868
- if (!isFormattingDatesAsOtherAxisTypes) {
8869
- row.values = lodash.map(row.values, function (val) {
8870
- return highchartsRenderer.returnRawDataValue(row.type, val, row.format, row.name, row.val_not_convert) + "";
8903
+ /* date string */
8904
+ var rowsAndCols = [];
8905
+ rowsAndCols = widget.rows.concat(widget.cols);
8906
+
8907
+ if (widget.chart_type === highchartsRenderer.CHART_TYPES.WATERFALL_BREAKDOWN) {
8908
+
8909
+ // if it is breakdown widget - redefine sorting according to breakdown_options
8910
+ // TODO: remove this when BE sort will be implemented (FE subtickets for story DR-18469)
8911
+ const isTwoColumnComparisonWidget = lodash.get(widget, 'options.breakdown_options.values.totals', []).length === 2;
8912
+ lodash.forEach(rowsAndCols, function (field) {
8913
+ const waterfallFieldType = field.id === widget.cols[0].id ? 'totals' : 'breakdown';
8914
+ if (waterfallFieldType !== 'totals' || isTwoColumnComparisonWidget) {
8915
+ field.sorting = {
8916
+ type: 'CustomOrder',
8917
+ values: lodash.map(
8918
+ widget.options.breakdown_options.values[waterfallFieldType],
8919
+ value => value.key
8920
+ ),
8921
+ };
8922
+ } else {
8923
+ field.sorting = null;
8924
+ }
8925
+ });
8926
+ } else if (isCustomSorting) {
8927
+ lodash.forEach(rowsAndCols, function (field) {
8928
+ const fieldToSort = lodash.find(
8929
+ widget.options.sortingFields, element => element.id === field.id && lodash.get(element, 'sorting.sort_by') === 'field_items'
8930
+ );
8931
+ field.sorting = fieldToSort ? fieldToSort.sorting : field.sorting;
8871
8932
  });
8872
8933
  }
8873
- });
8874
-
8875
- /* date string */
8876
- var rowsAndCols = [];
8877
- rowsAndCols = widget.rows.concat(widget.cols);
8878
8934
 
8879
- if (widget.chart_type === highchartsRenderer.CHART_TYPES.WATERFALL_BREAKDOWN) {
8880
-
8881
- // if it is breakdown widget - redefine sorting according to breakdown_options
8882
- // TODO: remove this when BE sort will be implemented
8883
- const isTwoColumnComparisonWidget = lodash.get(widget, 'options.breakdown_options.values.totals', []).length === 2;
8884
- lodash.forEach(rowsAndCols, function (field) {
8885
- const waterfallFieldType = field.id === widget.cols[0].id ? 'totals' : 'breakdown';
8886
- if (waterfallFieldType !== 'totals' || isTwoColumnComparisonWidget) {
8887
- field.sorting = {
8888
- type: 'CustomOrder',
8889
- values: lodash.map(
8890
- widget.options.breakdown_options.values[waterfallFieldType],
8891
- value => value.key
8892
- ),
8893
- };
8894
- } else {
8895
- field.sorting = null;
8896
- }
8897
- });
8898
- } else if (isCustomSorting) {
8899
8935
  lodash.forEach(rowsAndCols, function (field) {
8900
- const fieldToSort = lodash.find(
8901
- widget.options.sortingFields, element => element.id === field.id && lodash.get(element, 'sorting.sort_by') === 'field_items'
8902
- );
8903
- field.sorting = fieldToSort ? fieldToSort.sorting : field.sorting;
8904
- });
8905
- }
8906
-
8907
- lodash.forEach(rowsAndCols, function (field) {
8908
- if (field.sorting && (field.sorting.type == "DateString" || field.sorting.type == "largestToSmallest")) {
8909
- var find_field = lodash.find(datesFields, {name: field.name});
8910
- if (find_field) {
8911
- if (find_field.type != 'Date')
8912
- find_field.sorting = field.sorting;
8913
- } else {
8936
+ if (field.sorting && (field.sorting.type == "DateString" || field.sorting.type == "largestToSmallest")) {
8937
+ var find_field = lodash.find(datesFields, {name: field.name});
8938
+ if (find_field) {
8939
+ if (find_field.type != 'Date')
8940
+ find_field.sorting = field.sorting;
8941
+ } else {
8942
+ datesFields.push({
8943
+ "format": field.format,
8944
+ "name": field.name,
8945
+ "type": field.type,
8946
+ "values": [],
8947
+ "sorting": field.sorting,
8948
+ });
8949
+ }
8950
+ } else if (field.sorting && field.sorting.type == "CustomOrder" && field.sorting.values) {
8914
8951
  datesFields.push({
8915
8952
  "format": field.format,
8916
8953
  "name": field.name,
8917
8954
  "type": field.type,
8918
- "values": [],
8919
- "sorting": field.sorting,
8955
+ "values": field.sorting.values
8920
8956
  });
8921
8957
  }
8922
- } else if (field.sorting && field.sorting.type == "CustomOrder" && field.sorting.values) {
8923
- datesFields.push({
8924
- "format": field.format,
8925
- "name": field.name,
8926
- "type": field.type,
8927
- "values": field.sorting.values
8928
- });
8929
- }
8930
- });
8931
-
8932
- if (widget.vals && widget.vals.length > 1) {
8933
- datesFields.push({name: "DR_Values", values: lodash.map(widget.vals, 'name')});
8934
- }
8935
-
8936
- /****** END *******/
8958
+ });
8937
8959
 
8938
- // TODO: Remove. sortingValues looks like lagacy which is not in use neither in webclient nor in renderer
8939
- if (widget.options && widget.options.sortingValues) {
8940
- var field = lodash.find(datesFields, {name: widget.options.sortingValues.field});
8941
- if (field) {
8942
- field.values = widget.options.sortingValues.values;
8943
- field.sorting = null;
8944
- } else {
8945
- datesFields.push({
8946
- name: widget.options.sortingValues.field,
8947
- values: widget.options.sortingValues.values
8948
- });
8960
+ if (widget.vals && widget.vals.length > 1) {
8961
+ datesFields.push({name: "DR_Values", values: lodash.map(widget.vals, 'name')});
8949
8962
  }
8950
- }
8963
+
8964
+ /****** END *******/
8951
8965
 
8952
- let sorters = function (attr) {
8953
- var field = lodash.find(datesFields, {name: attr});
8954
- if (field)
8955
- if (field.sorting && field.sorting.type == "DateString") {
8956
- return $.pivotUtilities.sortDateStrings(field.sorting.month_order);
8957
- } else if (field.sorting && field.sorting.type == "largestToSmallest") {
8958
- if (field.sorting.is_absolute)
8959
- return $.pivotUtilities.largeToSmallSortByAbsolute;
8960
- return $.pivotUtilities.largeToSmallSort;
8966
+ // TODO: Remove. sortingValues looks like lagacy which is not in use neither in webclient nor in renderer
8967
+ if (widget.options && widget.options.sortingValues) {
8968
+ var field = lodash.find(datesFields, {name: widget.options.sortingValues.field});
8969
+ if (field) {
8970
+ field.values = widget.options.sortingValues.values;
8971
+ field.sorting = null;
8961
8972
  } else {
8962
- return $.pivotUtilities.sortAs(field.values);
8973
+ datesFields.push({
8974
+ name: widget.options.sortingValues.field,
8975
+ values: widget.options.sortingValues.values
8976
+ });
8963
8977
  }
8964
- };
8978
+ }
8979
+ sorters = function (attr) {
8980
+ var field = lodash.find(datesFields, {name: attr});
8981
+ if (field)
8982
+ if (field.sorting && field.sorting.type == "DateString") {
8983
+ return $.pivotUtilities.sortDateStrings(field.sorting.month_order);
8984
+ } else if (field.sorting && field.sorting.type == "largestToSmallest") {
8985
+ if (field.sorting.is_absolute)
8986
+ return $.pivotUtilities.largeToSmallSortByAbsolute;
8987
+ return $.pivotUtilities.largeToSmallSort;
8988
+ } else {
8989
+ return $.pivotUtilities.sortAs(field.values);
8990
+ }
8991
+ };
8992
+ }
8965
8993
 
8966
8994
  return sorters;
8967
8995
  };
@@ -8981,6 +9009,12 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8981
9009
 
8982
9010
  //highchartsRenderer.getGraphOptions(scope.data, override_values, res, scope.dataModel.templatesWithOutData, scope.openDrillDownList, drillDownFunction)
8983
9011
  highchartsRenderer.getGraphOptions = function (widget_obj, override_values, row_data, templates, openDrillDownListFunction, drillDownFunction) {
9012
+
9013
+ let keysObject;
9014
+ if (highchartsRenderer.isSortingOnBackendEnabled) {
9015
+ keysObject = row_data.pop();
9016
+ }
9017
+
8984
9018
  let res = highchartsRenderer.updateSelectedOverrideValues(widget_obj, override_values, row_data);
8985
9019
  res = highchartsRenderer.convertUniqueDateValues(widget_obj, templates, res);
8986
9020
 
@@ -8994,6 +9028,10 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
8994
9028
 
8995
9029
  let pivot = {};
8996
9030
 
9031
+ if (highchartsRenderer.isSortingOnBackendEnabled) {
9032
+ pivot.keysObject = keysObject;
9033
+ }
9034
+
8997
9035
  let templateNoData = lodash.find(templates, {id: widget_obj.template_id});
8998
9036
  if (templateNoData) {
8999
9037
 
@@ -9034,6 +9072,8 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
9034
9072
  subopts.onlyOptions = true;
9035
9073
  }
9036
9074
 
9075
+ subopts.keysObject = keysObject;
9076
+
9037
9077
  let hc_options = highchartsRenderer.rhPivotView(res, subopts, is_table, widget_obj);
9038
9078
 
9039
9079
  return hc_options;
package/src/pivottable.js CHANGED
@@ -686,8 +686,17 @@ let initPivotTable = function($, window, document) {
686
686
  });
687
687
  this.tree = {};
688
688
  this.insights = [];
689
- this.rowKeys = [];
690
- this.colKeys = [];
689
+
690
+ this.isKeysSortingDoneOnBackendSide = opts.keysObject && typeof opts.keysObject === 'object';
691
+ if (this.isKeysSortingDoneOnBackendSide) {
692
+ this.rowKeys = opts.keysObject.row_keys;
693
+ this.colKeys = opts.keysObject.col_keys;
694
+ // TODO: add also for breakdown sort object when BE story is ready.
695
+ } else {
696
+ this.rowKeys = [];
697
+ this.colKeys = [];
698
+ }
699
+
691
700
  this.rowTotals = {};
692
701
  this.colTotals = {};
693
702
  this.allTotal = this.aggregator(this, [], []);
@@ -859,12 +868,16 @@ let initPivotTable = function($, window, document) {
859
868
  };
860
869
 
861
870
  PivotData.prototype.getColKeys = function() {
862
- this.sortKeys();
871
+ if (!this.isKeysSortingDoneOnBackendSide) {
872
+ this.sortKeys();
873
+ }
863
874
  return this.colKeys;
864
875
  };
865
876
 
866
877
  PivotData.prototype.getRowKeys = function() {
867
- this.sortKeys();
878
+ if (!this.isKeysSortingDoneOnBackendSide) {
879
+ this.sortKeys();
880
+ }
868
881
  return this.rowKeys;
869
882
  };
870
883