@refinitiv-ui/efx-grid 6.0.13 → 6.0.15

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.
Files changed (47) hide show
  1. package/lib/column-format-dialog/index.d.ts +2 -1
  2. package/lib/column-format-dialog/index.js +2 -1
  3. package/lib/column-selection-dialog/index.d.ts +2 -1
  4. package/lib/column-selection-dialog/index.js +2 -1
  5. package/lib/core/dist/core.js +1220 -161
  6. package/lib/core/dist/core.min.js +1 -1
  7. package/lib/core/es6/data/DataCache.js +1 -1
  8. package/lib/core/es6/data/DataTable.d.ts +18 -3
  9. package/lib/core/es6/data/DataTable.js +203 -17
  10. package/lib/core/es6/data/DataView.d.ts +8 -1
  11. package/lib/core/es6/data/DataView.js +30 -2
  12. package/lib/core/es6/data/Segment.d.ts +37 -12
  13. package/lib/core/es6/data/Segment.js +584 -60
  14. package/lib/core/es6/data/SegmentCollection.d.ts +16 -2
  15. package/lib/core/es6/data/SegmentCollection.js +238 -80
  16. package/lib/core/es6/grid/Core.js +1 -1
  17. package/lib/filter-dialog/index.d.ts +2 -1
  18. package/lib/filter-dialog/index.js +2 -1
  19. package/lib/grid/index.d.ts +2 -1
  20. package/lib/grid/index.js +3 -2
  21. package/lib/row-segmenting/es6/RowSegmenting.d.ts +2 -0
  22. package/lib/row-segmenting/es6/RowSegmenting.js +26 -3
  23. package/lib/rt-grid/dist/rt-grid.js +1194 -158
  24. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  25. package/lib/rt-grid/es6/Grid.d.ts +4 -0
  26. package/lib/rt-grid/es6/Grid.js +75 -0
  27. package/lib/rt-grid/es6/RowDefinition.d.ts +4 -0
  28. package/lib/rt-grid/es6/RowDefinition.js +79 -2
  29. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.d.ts +1 -0
  30. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +194 -366
  31. package/lib/tr-grid-column-stack/es6/ColumnStack.d.ts +10 -3
  32. package/lib/tr-grid-column-stack/es6/ColumnStack.js +93 -36
  33. package/lib/tr-grid-util/es6/RowPainter.d.ts +2 -1
  34. package/lib/tr-grid-util/es6/RowPainter.js +7 -1
  35. package/lib/tr-grid-util/es6/jet/mockDataAPI.d.ts +1 -0
  36. package/lib/tr-grid-util/es6/jet/mockDataAPI.js +191 -52
  37. package/lib/types/es6/ColumnGrouping.d.ts +1 -0
  38. package/lib/types/es6/ColumnStack.d.ts +10 -3
  39. package/lib/types/es6/Core/data/DataTable.d.ts +18 -3
  40. package/lib/types/es6/Core/data/DataView.d.ts +8 -1
  41. package/lib/types/es6/Core/data/Segment.d.ts +36 -11
  42. package/lib/types/es6/Core/data/SegmentCollection.d.ts +15 -1
  43. package/lib/types/es6/RealtimeGrid/ColumnDefinition.d.ts +6 -1
  44. package/lib/types/es6/RealtimeGrid/Grid.d.ts +2 -0
  45. package/lib/types/es6/RowSegmenting.d.ts +2 -0
  46. package/lib/versions.json +4 -4
  47. package/package.json +15 -2
@@ -9711,7 +9711,7 @@ DataCache_DataCache.prototype._cloneRowData = function (obj, ric, newSubId) {
9711
9711
 
9712
9712
  /** @protected
9713
9713
  * @ignore
9714
- * @type {!Object.<string, Object.<string, *>>}
9714
+ * @type {!Object.<string, Object>}
9715
9715
  */
9716
9716
  DataCache_DataCache.prototype._rows;
9717
9717
 
@@ -9797,14 +9797,56 @@ DataCache_DataCache._proto = DataCache_DataCache.prototype;
9797
9797
 
9798
9798
 
9799
9799
  // CONCATENATED MODULE: ./node_modules/@grid/core/es6/data/Segment.js
9800
+
9801
+
9802
+
9800
9803
  /** @constructor
9801
9804
  * @param {string} rid
9805
+ * @param {!Object} sharedObj
9802
9806
  */
9803
- var Segment = function(rid) {
9807
+ var Segment = function(rid, sharedObj) {
9804
9808
  this._rid = rid;
9805
9809
  this._children = {};
9810
+ this._shared = sharedObj;
9806
9811
  };
9812
+ Ext["b" /* default */].inherits(Segment, EventDispatcher["b" /* default */]);
9807
9813
 
9814
+ /** @private
9815
+ * @function
9816
+ * @param {string} a
9817
+ * @param {string} b
9818
+ * @return {number}
9819
+ */
9820
+ Segment._subSegSortLogic = function(a, b) {
9821
+ if(a === "Uncategorized") {
9822
+ return 1;
9823
+ }
9824
+ if(b === "Uncategorized") {
9825
+ return -1;
9826
+ }
9827
+
9828
+ if(a < b) {
9829
+ return -1;
9830
+ }
9831
+ if(b < a) {
9832
+ return 1;
9833
+ }
9834
+
9835
+ return 0;
9836
+ };
9837
+ /** @private
9838
+ * @function
9839
+ * @param {Segment} segment
9840
+ * @param {number} idx
9841
+ */
9842
+ Segment._assignSubSegmentOrder = function(segment, idx) {
9843
+ segment.setOrder(idx + 1);
9844
+ };
9845
+
9846
+ /** @type {Object}
9847
+ * @private
9848
+ */
9849
+ Segment.prototype._shared = null;
9808
9850
 
9809
9851
  /** @type {string}
9810
9852
  * @private
@@ -9825,13 +9867,67 @@ Segment.prototype._collapsed = false;
9825
9867
  /** @type {number}
9826
9868
  * @private
9827
9869
  */
9828
- Segment.prototype._value = 0;
9870
+ Segment.prototype._order = 0;
9871
+ /** @type {boolean}
9872
+ * @private
9873
+ */
9874
+ Segment.prototype._disposed = false;
9875
+
9876
+ /** @type {Object}
9877
+ * @private
9878
+ */
9879
+ Segment.prototype._subSegDef = null;
9829
9880
  /** @type {number}
9830
9881
  * @private
9831
9882
  */
9832
- Segment.prototype._order = 0;
9883
+ Segment.prototype._subSegLevel = 0;
9884
+ /** @type {Object.<string, Segment>}
9885
+ * @private
9886
+ */
9887
+ Segment.prototype._subSegMap = null; // For immediate sub-segment children
9888
+ /** @type {Array.<string>}
9889
+ * @private
9890
+ */
9891
+ Segment.prototype._subSegNames = null; // For immediate sub-segment child names
9892
+ /** @type {string}
9893
+ * @private
9894
+ */
9895
+ Segment.prototype._subSegName = "";
9896
+ /** @type {*}
9897
+ * @private
9898
+ */
9899
+ Segment.prototype._subSegVal;
9900
+ /** @type {Segment}
9901
+ * @private
9902
+ */
9903
+ Segment.prototype._subSegParent = null;
9833
9904
 
9834
9905
 
9906
+ /** @public
9907
+ */
9908
+ Segment.prototype.dispose = function() {
9909
+ if(this._disposed) {
9910
+ return;
9911
+ }
9912
+ this._disposed = true;
9913
+
9914
+ this.removeAllEventListeners();
9915
+ var segmentNames = this._subSegNames;
9916
+ if(segmentNames) {
9917
+ var segmentCount = segmentNames.length;
9918
+ var segmentMap = this._subSegMap;
9919
+ for(var i = 0; i < segmentCount; ++i) {
9920
+ segmentMap[segmentNames[i]].dispose();
9921
+ }
9922
+ this._subSegMap = this._subSegNames = null;
9923
+ }
9924
+ if(this._collapsed) {
9925
+ this._shared.dirtyCollapsingState = true;
9926
+ }
9927
+
9928
+ this._shared = null;
9929
+ this._subSegParent = this._subSegDef = this._subSegVal = null;
9930
+ };
9835
9931
  /** @public
9836
9932
  * @return {string}
9837
9933
  */
@@ -9839,32 +9935,66 @@ Segment.prototype.getId = function() {
9839
9935
  return this._rid;
9840
9936
  };
9841
9937
  /** @public
9938
+ * @return {string}
9939
+ */
9940
+ Segment.prototype.getParentId = function() {
9941
+ if(this._subSegParent) {
9942
+ return this._subSegParent.getId();
9943
+ }
9944
+ return "";
9945
+ };
9946
+ /** @public
9947
+ * @param {Array.<string>=} out_ary
9948
+ * @return {Array.<string>}
9949
+ */
9950
+ Segment.prototype.getSubSegmentIds = function(out_ary) {
9951
+ var segmentNames = this._subSegNames;
9952
+ if(segmentNames) {
9953
+ if(!out_ary) {
9954
+ out_ary = [];
9955
+ }
9956
+ var segmentCount = segmentNames.length;
9957
+ var segmentMap = this._subSegMap;
9958
+ for(var i = 0; i < segmentCount; ++i) {
9959
+ var segmentName = segmentNames[i];
9960
+ var segment = segmentMap[segmentName];
9961
+ out_ary.push(segment.getId());
9962
+ segment.getSubSegmentIds(out_ary);
9963
+ }
9964
+
9965
+ return out_ary;
9966
+ }
9967
+ return null;
9968
+ };
9969
+ /** @public
9842
9970
  * @param {string} rid
9843
- * @param {Object=} objMap
9971
+ * @param {string=} dataId Row id for retrieving data
9844
9972
  * @return {boolean}
9845
9973
  */
9846
- Segment.prototype.addChild = function(rid, objMap) {
9847
- if(rid && !this._children[rid]) {
9848
- if(objMap) {
9849
- objMap[rid] = this._rid;
9974
+ Segment.prototype.addChild = function(rid, dataId) {
9975
+ if(rid) {
9976
+ this._shared.childToSegment[rid] = this._rid;
9977
+ if(this._collapsed) {
9978
+ this._shared.dirtyCollapsingState = true; // TODO: Check if we need to update this only when new child is added
9979
+ }
9980
+ if(!this._children[rid]) {
9981
+ this._children[rid] = dataId || rid;
9982
+ ++this._childCount;
9983
+ return true;
9850
9984
  }
9851
- this._children[rid] = 1;
9852
- ++this._childCount;
9853
- return true;
9854
9985
  }
9855
9986
  return false;
9856
9987
  };
9857
9988
  /** @public
9858
9989
  * @param {Array.<string>} rids
9859
- * @param {Object=} objMap
9860
9990
  * @return {boolean}
9861
9991
  */
9862
- Segment.prototype.addChildren = function(rids, objMap) {
9992
+ Segment.prototype.addChildren = function(rids) {
9863
9993
  var rowIds = Array.isArray(rids) ? rids : [rids];
9864
9994
  var rowCount = rowIds.length;
9865
9995
  var dirty = 0;
9866
9996
  for(var i = 0; i < rowCount; ++i) {
9867
- dirty |= this.addChild(rowIds[i], objMap);
9997
+ dirty |= this.addChild(rowIds[i]);
9868
9998
  }
9869
9999
  return dirty ? true : false;
9870
10000
  };
@@ -9877,26 +10007,37 @@ Segment.prototype.containsChild = function(rid) {
9877
10007
  };
9878
10008
  /** @public
9879
10009
  * @param {string} rid
9880
- * @param {Object=} objMap
9881
10010
  * @return {boolean}
9882
10011
  */
9883
- Segment.prototype.removeChild = function(rid, objMap) {
9884
- if(this._childCount && this._children[rid]) {
9885
- if(objMap) {
9886
- delete objMap[rid];
9887
- }
9888
- delete this._children[rid]; // Slow
9889
- --this._childCount;
9890
- return true;
10012
+ Segment.prototype.removeChild = function(rid) {
10013
+ if(this._subSegLevel) {
10014
+ return false; // Sub segments are not allowed to remove its children
9891
10015
  }
9892
- return false;
10016
+ if(!this._childCount) {
10017
+ return false;
10018
+ }
10019
+ if(!this._children[rid]) {
10020
+ return false; // The specified rid is not a child of this segment
10021
+ }
10022
+
10023
+ var objMap = this._shared.childToSegment;
10024
+ delete objMap[rid];
10025
+ delete this._children[rid]; // Slow
10026
+ --this._childCount;
10027
+
10028
+ if(this._collapsed) {
10029
+ this._shared.dirtyCollapsingState = true;
10030
+ }
10031
+ return true;
9893
10032
  };
9894
10033
  /** @public
9895
10034
  * @param {Array.<string>} rids
9896
- * @param {Object=} objMap
9897
10035
  * @return {boolean}
9898
10036
  */
9899
- Segment.prototype.removeChildren = function(rids, objMap) {
10037
+ Segment.prototype.removeChildren = function(rids) {
10038
+ if(this._subSegLevel) {
10039
+ return false; // Sub segments are not allowed to remove its children
10040
+ }
9900
10041
  if(!this._childCount) {
9901
10042
  return false;
9902
10043
  }
@@ -9904,7 +10045,7 @@ Segment.prototype.removeChildren = function(rids, objMap) {
9904
10045
  var rowCount = rowIds.length;
9905
10046
  var dirty = 0;
9906
10047
  for(var i = 0; i < rowCount; ++i) {
9907
- dirty |= this.removeChild(rowIds[i], objMap);
10048
+ dirty |= this.removeChild(rowIds[i]);
9908
10049
  }
9909
10050
  return dirty ? true : false;
9910
10051
  };
@@ -9912,21 +10053,27 @@ Segment.prototype.removeChildren = function(rids, objMap) {
9912
10053
  * @param {Object=} objMap
9913
10054
  * @return {boolean}
9914
10055
  */
9915
- Segment.prototype.removeAllChildren = function(objMap) {
9916
- if(this._childCount) {
9917
- if(objMap) {
9918
- var chdr = this._children;
9919
- for(var rid in chdr) {
9920
- if(objMap[rid]) {
9921
- delete objMap[rid];
9922
- }
9923
- }
10056
+ Segment.prototype.removeAllChildren = function() {
10057
+ if(this._subSegLevel) {
10058
+ return false; // Sub segments are not allowed to remove its children
10059
+ }
10060
+ if(!this._childCount) {
10061
+ return false;
10062
+ }
10063
+ var objMap = this._shared.childToSegment;
10064
+ var chdr = this._children;
10065
+ for(var rid in chdr) {
10066
+ if(objMap[rid]) {
10067
+ delete objMap[rid]; // TODO: Check if we need to do this
9924
10068
  }
9925
- this._children = {};
9926
- this._childCount = 0;
9927
- return true;
9928
10069
  }
9929
- return false;
10070
+ this._children = {};
10071
+ this._childCount = 0;
10072
+
10073
+ if(this._collapsed) {
10074
+ this._shared.dirtyCollapsingState = true;
10075
+ }
10076
+ return true;
9930
10077
  };
9931
10078
  /** @public
9932
10079
  * @return {!Array.<string>}
@@ -9942,6 +10089,309 @@ Segment.prototype.getChildCount = function() {
9942
10089
  };
9943
10090
 
9944
10091
 
10092
+ /** @public
10093
+ * @return {Array.<string>} fields
10094
+ */
10095
+ Segment.prototype.getClassification = function() {
10096
+ if(this._subSegDef) {
10097
+ return this._subSegDef.classifiers || null;
10098
+ }
10099
+ return null;
10100
+ };
10101
+ /** @public
10102
+ * @param {string|Array.<string>} fields
10103
+ * @return {boolean}
10104
+ */
10105
+ Segment.prototype.setClassification = function(fields) {
10106
+ if(this._subSegLevel) {
10107
+ return false; // non-root segment cannot be classified
10108
+ }
10109
+ var classifiers = null;
10110
+ if(this._subSegDef) {
10111
+ classifiers = this._subSegDef.classifiers;
10112
+ }
10113
+
10114
+ var newClassifiers = null;
10115
+ if(fields) {
10116
+ if(typeof fields === "string") {
10117
+ newClassifiers = [fields];
10118
+ } else if(Array.isArray(fields)) {
10119
+ newClassifiers = fields;
10120
+ }
10121
+ }
10122
+ var i;
10123
+ var fieldCount = newClassifiers ? newClassifiers.length : 0;
10124
+
10125
+ if(fieldCount) {
10126
+ var curCount = classifiers ? classifiers.length : 0;
10127
+ if(curCount === fieldCount) { // Check duplication
10128
+ for(i = 0; i < fieldCount; ++i) {
10129
+ if(newClassifiers[i] !== classifiers[i]) {
10130
+ break;
10131
+ }
10132
+ }
10133
+ if(i >= fieldCount) {
10134
+ return false; // nothing has change
10135
+ }
10136
+ }
10137
+
10138
+ if(!this._subSegDef) {
10139
+ this._subSegDef = {
10140
+ root: this,
10141
+ subSegments: null
10142
+ };
10143
+ }
10144
+
10145
+ this._subSegDef.classifiers = newClassifiers;
10146
+ // this._subSegDef.classifierChanged = true;
10147
+ return true;
10148
+ } else if(classifiers) { // Remove existing ones
10149
+ this._subSegDef.classifiers = null;
10150
+ this._subSegDef.subSegments = null;
10151
+ // this._subSegDef.classifierChanged = true;
10152
+ this._subSegDef = null; // WARNING: All sub segments remain existing
10153
+ return true;
10154
+ }
10155
+ return false;
10156
+ };
10157
+ /** @public
10158
+ * @param {Object.<string, Object>=} rows Object maps between row id and its record
10159
+ * @return {boolean}
10160
+ */
10161
+ Segment.prototype.classify = function(rows) {
10162
+ var classifiers = this._subSegDef ? this._subSegDef.classifiers : null;
10163
+ var classifierCount = classifiers ? classifiers.length : 0;
10164
+
10165
+ var segmentNames = this._subSegNames;
10166
+ var segmentCount = segmentNames ? segmentNames.length : 0;
10167
+
10168
+ if(!segmentCount) {
10169
+ if(this._subSegLevel >= classifierCount) {
10170
+ return false; // Current segment level is beyond existing classification level and this segment should already be removed
10171
+ }
10172
+ }
10173
+
10174
+ // Prepare existing sub segments for checking change in its members
10175
+ var i;
10176
+ var segmentName = "";
10177
+ var nonExistenceGroups = {};
10178
+ var removalCount = 0;
10179
+ var segmentMap = this._subSegMap;
10180
+ var segment = null;
10181
+ if(segmentCount) {
10182
+ removalCount = segmentCount;
10183
+ for(i = 0; i < removalCount; ++i) {
10184
+ segmentName = segmentNames[i];
10185
+ nonExistenceGroups[segmentName] = 1;
10186
+
10187
+ segment = segmentMap[segmentName];
10188
+ if(segment._childCount) { // Quick cleaning up
10189
+ segment._children = {};
10190
+ segment._childCount = 0;
10191
+ }
10192
+ }
10193
+ }
10194
+
10195
+ // Loop through row children and assign them to their corresponding sub segment
10196
+ var isRootSegment = !this._subSegLevel;
10197
+ var rid;
10198
+ var children = this._children;
10199
+ if(this._subSegLevel < classifierCount && rows) {
10200
+ if(!segmentMap) {
10201
+ segmentMap = this._subSegMap = {};
10202
+ segmentNames = this._subSegNames = [];
10203
+ }
10204
+
10205
+ var classifier = classifiers[this._subSegLevel];
10206
+
10207
+ for(rid in children) {
10208
+ var dataId = children[rid];
10209
+ var record = rows[dataId];
10210
+ var val = record ? record[classifier] : null; // WARNING: row could already be removed
10211
+
10212
+ this._shared.childToSegment[rid] = this._rid; // Relocate child in case of it has been moved to a non existence group
10213
+
10214
+ segmentName = "Uncategorized";
10215
+ if(val || val === 0 || val === false) { // Check for null, undefined, "", and NaN value
10216
+ segmentName = val + "";
10217
+ }
10218
+ if(nonExistenceGroups[segmentName]) {
10219
+ nonExistenceGroups[segmentName] = 0;
10220
+ --removalCount;
10221
+ }
10222
+
10223
+ segment = segmentMap[segmentName];
10224
+ if(!segment) { // New group is detected
10225
+ segment = new Segment(this._rid + "/" + segmentName, this._shared);
10226
+ segment._subSegDef = this._subSegDef;
10227
+ segment._subSegLevel = this._subSegLevel + 1;
10228
+ segment._subSegName = segmentName;
10229
+ segment._subSegVal = val;
10230
+ segment._subSegParent = this;
10231
+
10232
+ segmentMap[segmentName] = segment;
10233
+ segmentNames.push(segmentName);
10234
+
10235
+ this._dispatch("subSegmentAdded", {
10236
+ "rid": segment.getId(),
10237
+ "segment": segment
10238
+ });
10239
+ }
10240
+
10241
+ segment.addChild(rid, dataId);
10242
+ }
10243
+ } else if(isRootSegment) { // In case of no classification
10244
+ for(rid in children) {
10245
+ this._shared.childToSegment[rid] = this._rid; // Relocate child in case of it has been moved to a non existence group
10246
+ }
10247
+ }
10248
+
10249
+ // Remove all sub segments with no members
10250
+ if(removalCount > 0) {
10251
+ if(removalCount >= segmentNames.length) {
10252
+ segmentNames.length = 0;
10253
+ }
10254
+ for(segmentName in nonExistenceGroups) {
10255
+ if(nonExistenceGroups[segmentName]) {
10256
+ segment = segmentMap[segmentName];
10257
+ delete segmentMap[segmentName];
10258
+ // TODO: Slow
10259
+ var at = segmentNames.indexOf(segmentName);
10260
+ if(at >= 0) {
10261
+ segmentNames.splice(at, 1);
10262
+ }
10263
+
10264
+ this._dispatch("subSegmentRemoved", {
10265
+ "rid": segment.getId(),
10266
+ "segment": segment
10267
+ });
10268
+
10269
+ // segment.dispose(); Already done by segment collection
10270
+ }
10271
+ }
10272
+ if(!segmentNames.length) {
10273
+ segmentNames = this._subSegMap = this._subSegNames = null;
10274
+ }
10275
+ }
10276
+
10277
+ // Sort and classify existing sub segments
10278
+ segmentCount = segmentNames ? segmentNames.length : 0;
10279
+ if(segmentCount) {
10280
+ segmentNames.sort(Segment._subSegSortLogic);
10281
+ for(i = 0; i < segmentCount; ++i) {
10282
+ segment = segmentMap[segmentNames[i]];
10283
+ segment.classify(rows);
10284
+ }
10285
+ }
10286
+
10287
+ // Collecting all sub segments including all descendants and reassigning segment order.
10288
+ if(isRootSegment) { // If this is a root segment
10289
+ if(this._subSegDef) {
10290
+ if(segmentCount) {
10291
+ var subSegments = this._subSegDef.subSegments = [];
10292
+ this.getAllSubSegments(subSegments);
10293
+ subSegments.forEach(Segment._assignSubSegmentOrder);
10294
+ } else {
10295
+ this._subSegDef.subSegments = null;
10296
+ }
10297
+ // this._subSegDef.classifierChanged = false;
10298
+ }
10299
+ }
10300
+ return true;
10301
+ };
10302
+ /** @public
10303
+ * @return {boolean}
10304
+ */
10305
+ Segment.prototype.hasSubSegments = function() {
10306
+ if(this._subSegNames) {
10307
+ return this._subSegNames.length ? true : false;
10308
+ }
10309
+ return false;
10310
+ };
10311
+ /** @public
10312
+ * @return {boolean}
10313
+ */
10314
+ Segment.prototype.isSubSegment = function() {
10315
+ return this._subSegLevel ? true : false;
10316
+ };
10317
+ /** @public
10318
+ * @return {Segment}
10319
+ */
10320
+ Segment.prototype.getFirstAncestor = function() {
10321
+ if(this._subSegLevel && this._subSegDef) {
10322
+ var ancestor = this._subSegDef.root;
10323
+ return /** @type{Segment} */(ancestor) || null;
10324
+ }
10325
+ return null;
10326
+ };
10327
+ /** @public
10328
+ * @param {Array.<Segment>=} out_ary
10329
+ * @return {Array.<Segment>}
10330
+ */
10331
+ Segment.prototype.getAllSubSegments = function(out_ary) {
10332
+ var segmentNames = this._subSegNames;
10333
+ if(segmentNames) {
10334
+ if(!out_ary) {
10335
+ out_ary = [];
10336
+ }
10337
+ var segmentMap = this._subSegMap;
10338
+ var segmentCount = segmentNames.length;
10339
+ for(var i = 0; i < segmentCount; ++i) {
10340
+ var segment = segmentMap[segmentNames[i]];
10341
+ out_ary.push(segment);
10342
+ segment.getAllSubSegments(out_ary);
10343
+ }
10344
+ }
10345
+ return out_ary;
10346
+ };
10347
+ /** @public
10348
+ * @return {number}
10349
+ */
10350
+ Segment.prototype.getSegmentLevel = function() {
10351
+ return this._subSegLevel;
10352
+ };
10353
+ /** This method will be called on sub segments only
10354
+ * @public
10355
+ * @param {Object=} rows
10356
+ * @param {Object=} clsSource
10357
+ */
10358
+ Segment.prototype.setRowData = function(rows, clsSource) {
10359
+ if(!rows) {
10360
+ return;
10361
+ }
10362
+ var row = rows[this._rid];
10363
+ if(!row) {
10364
+ row = rows[this._rid] = {};
10365
+ }
10366
+
10367
+ if(!clsSource) {
10368
+ clsSource = rows;
10369
+ }
10370
+ row = clsSource[this._rid];
10371
+ if(!row) {
10372
+ row = clsSource[this._rid] = {};
10373
+ }
10374
+
10375
+ var segment = this;
10376
+ while(segment && segment.isSubSegment()) {
10377
+ segment.getSubSegmentName(row);
10378
+ segment = segment._subSegParent;
10379
+ }
10380
+ };
10381
+ /** @public
10382
+ * @param {Object=} row
10383
+ * @return {string}
10384
+ */
10385
+ Segment.prototype.getSubSegmentName = function(row) {
10386
+ if(row && this._subSegLevel) {
10387
+ var classifiers = this.getClassification();
10388
+ var field = classifiers[this._subSegLevel - 1];
10389
+ if(field) {
10390
+ row[field] = this._subSegName;
10391
+ }
10392
+ }
10393
+ return this._subSegName;
10394
+ };
9945
10395
 
9946
10396
  /** @public
9947
10397
  * @param {boolean=} bool
@@ -9951,6 +10401,7 @@ Segment.prototype.collapse = function(bool) {
9951
10401
  bool = (bool !== false);
9952
10402
  if(this._collapsed !== bool) {
9953
10403
  this._collapsed = bool;
10404
+ this._shared.dirtyCollapsingState = true;
9954
10405
  return true;
9955
10406
  }
9956
10407
  return false;
@@ -9970,44 +10421,109 @@ Segment.prototype.isCollapsed = function() {
9970
10421
  };
9971
10422
  /** @public
9972
10423
  * @param {Object=} objMap
9973
- * @return {!Object}
10424
+ * @param {boolean=} parentState=false Collapsing state from parent segment
10425
+ * @return {number}
9974
10426
  */
9975
- Segment.prototype.getCollapsingStates = function(objMap) {
10427
+ Segment.prototype.getCollapsingStates = function(objMap, parentState) {
10428
+ var segmentNames = this._subSegNames;
10429
+ if(!this._subSegLevel) { // Only root segment
10430
+ if(!segmentNames) { // No sub segment
10431
+ if(!this._collapsed) {
10432
+ return false;
10433
+ }
10434
+ }
10435
+ }
10436
+
9976
10437
  if(!objMap) {
9977
10438
  objMap = {};
9978
10439
  }
10440
+ var dirty = false;
10441
+ if(this._subSegLevel) { // Sub segments are also subjected to collapsing
10442
+ if(parentState) {
10443
+ objMap[this._rid] = true;
10444
+ dirty = true;
10445
+ }
10446
+ }
9979
10447
  if(this._childCount) {
9980
- var chdr = this._children;
9981
- var collapsed = this._collapsed;
9982
- for(var rid in chdr) {
9983
- objMap[rid] = collapsed;
10448
+ var collapsed = parentState || this._collapsed;
10449
+ if(segmentNames) {
10450
+ var segmentMap = this._subSegMap;
10451
+ var segmentCount = segmentNames.length;
10452
+ for(var i = 0; i < segmentCount; ++i) {
10453
+ var segment = segmentMap[segmentNames[i]];
10454
+ objMap[segment.getId()] = !!parentState;
10455
+ if(segment.getCollapsingStates(objMap, collapsed)) {
10456
+ dirty = true;
10457
+ }
10458
+ }
10459
+ } else if(collapsed) {
10460
+ var chdr = this._children;
10461
+ for(var rid in chdr) {
10462
+ objMap[rid] = collapsed;
10463
+ }
10464
+ dirty = true;
9984
10465
  }
9985
10466
  }
9986
- return objMap;
10467
+ return dirty;
9987
10468
  };
10469
+
9988
10470
  /** @public
9989
10471
  * @return {number}
9990
10472
  */
9991
- Segment.prototype.getValue = function() {
9992
- return this._value;
10473
+ Segment.prototype.getOrder = function() {
10474
+ if(this._subSegLevel) {
10475
+ var ancestor = this.getFirstAncestor();
10476
+ if(ancestor) {
10477
+ // WARNING: this._order cannot be greater than 9999
10478
+ return ancestor.getOrder() + this._order;
10479
+ }
10480
+ }
10481
+ return this._order * 10000;
9993
10482
  };
9994
10483
  /** @public
9995
10484
  * @param {number} val
9996
10485
  */
9997
- Segment.prototype.setValue = function(val) {
9998
- this._value = val;
10486
+ Segment.prototype.setOrder = function(val) {
10487
+ this._order = val;
9999
10488
  };
10000
- /** @public
10001
- * @return {number}
10489
+
10490
+ /** @private
10491
+ * @type {Array.<string>}
10002
10492
  */
10003
- Segment.prototype.getOrder = function() {
10004
- return this._order;
10005
- };
10493
+ Segment._tabs = null;
10006
10494
  /** @public
10007
- * @param {number} val
10495
+ * @param {Array.<string>} lines
10496
+ * @return {Array.<string>} lines
10008
10497
  */
10009
- Segment.prototype.setOrder = function(val) {
10010
- this._order = val;
10498
+ Segment.prototype.log = function(lines) {
10499
+ var i;
10500
+ var tabs = Segment._tabs;
10501
+ if(!tabs) {
10502
+ tabs = Segment._tabs = [];
10503
+ var tabCh = "";
10504
+ for(i = 0; i < 11; ++i) {
10505
+ tabs[i] = tabCh;
10506
+ tabCh += " ";
10507
+ }
10508
+ }
10509
+ var collapsedCh = this._collapsed ? "+ " : "- ";
10510
+ lines.push(tabs[this._subSegLevel] + collapsedCh + this._rid);
10511
+
10512
+ var segmentNames = this._subSegNames;
10513
+ if(segmentNames) {
10514
+ var segmentCount = segmentNames.length;
10515
+ var segmentMap = this._subSegMap;
10516
+ for(i = 0; i < segmentCount; ++i) {
10517
+ segmentMap[segmentNames[i]].log(lines);
10518
+ }
10519
+ } else if(this._childCount) {
10520
+ var indent = tabs[this._subSegLevel + 1];
10521
+ for(var rid in this._children) {
10522
+ lines.push(indent + "- " + rid);
10523
+ }
10524
+ }
10525
+
10526
+ return lines;
10011
10527
  };
10012
10528
 
10013
10529
 
@@ -10017,18 +10533,30 @@ Segment.prototype.setOrder = function(val) {
10017
10533
  // CONCATENATED MODULE: ./node_modules/@grid/core/es6/data/SegmentCollection.js
10018
10534
 
10019
10535
 
10536
+
10537
+
10020
10538
  /** @constructor
10021
10539
  */
10022
10540
  var SegmentCollection = function() {
10541
+ this._onSubSegmentAdded = this._onSubSegmentAdded.bind(this);
10542
+ this._onSubSegmentRemoved = this._onSubSegmentRemoved.bind(this);
10543
+
10023
10544
  this._segments = {};
10024
- this._childToSegmentId = {};
10545
+ this._insertionList = [];
10546
+ this._removalList = [];
10547
+
10548
+ this._shared = {
10549
+ childToSegment: {}, // child Id to segment Id
10550
+ dirtyCollapsingState: false
10551
+ };
10025
10552
  };
10553
+ Ext["b" /* default */].inherits(SegmentCollection, EventDispatcher["b" /* default */]);
10026
10554
 
10027
10555
 
10028
10556
  /** @type {!Object.<string, Segment>}
10029
10557
  * @private
10030
10558
  */
10031
- SegmentCollection.prototype._segments;
10559
+ SegmentCollection.prototype._segments; // Contains both segment and their sub segments
10032
10560
  /** @type {number}
10033
10561
  * @private
10034
10562
  */
@@ -10037,28 +10565,53 @@ SegmentCollection.prototype._segmentCount = 0;
10037
10565
  * @private
10038
10566
  */
10039
10567
  SegmentCollection.prototype._collapsedRids = null;
10568
+ /** @type {!Object}
10569
+ * @private
10570
+ */
10571
+ SegmentCollection.prototype._shared;
10572
+ /** @type {Array.<Segment>}
10573
+ * @private
10574
+ */
10575
+ SegmentCollection.prototype._segmentList = null; // Array of main segments
10576
+ /** @type {Array.<Segment>}
10577
+ * @private
10578
+ */
10579
+ SegmentCollection.prototype._insertionList = null; // Array of sub segments
10580
+ /** @type {Array.<string>}
10581
+ * @private
10582
+ */
10583
+ SegmentCollection.prototype._removalList = null; // Array of sub segment ids
10040
10584
  /** @type {boolean}
10041
10585
  * @private
10042
10586
  */
10043
- SegmentCollection.prototype._dirtyCollapsingState = false;
10044
- /** @type {!Object.<string, string>}
10587
+ SegmentCollection.prototype._classification = false;
10588
+ /** @type {boolean}
10045
10589
  * @private
10046
10590
  */
10047
- SegmentCollection.prototype._childToSegmentId;
10048
-
10591
+ SegmentCollection.prototype._classifierChanged = false;
10049
10592
 
10593
+ /** @public
10594
+ */
10595
+ SegmentCollection.prototype.dispose = function() {
10596
+ this.removeAllSegments();
10597
+ this._collapsedRids = null;
10598
+ this._segmentList = this._insertionList = this._removalList = null;
10599
+ };
10050
10600
  /** @public
10051
10601
  * @param {string} rid
10052
10602
  * @return {boolean} Returns true if there is any change. Otherwise, returns false
10053
10603
  */
10054
10604
  SegmentCollection.prototype.addSegment = function(rid) {
10055
10605
  if(rid && !this._segments[rid]) {
10056
- if(this._childToSegmentId[rid]) {
10606
+ if(this.getParentRowId(rid)) {
10057
10607
  console.log("child of a segment cannot be set as a segment separator");
10058
10608
  return false;
10059
10609
  }
10060
- this._segments[rid] = new data_Segment(rid);
10610
+ var segment = this._segments[rid] = new data_Segment(rid, this._shared);
10611
+ segment.addEventListener("subSegmentAdded", this._onSubSegmentAdded);
10612
+ segment.addEventListener("subSegmentRemoved", this._onSubSegmentRemoved);
10061
10613
  ++this._segmentCount;
10614
+ this._segmentList = null; // order could be changed
10062
10615
  return true;
10063
10616
  }
10064
10617
  return false;
@@ -10088,7 +10641,7 @@ SegmentCollection.prototype.containsSegment = function(rid) {
10088
10641
  * @return {string} parent row id of this segmentation. If the parent row id for this segmentation cannot be found, return ""
10089
10642
  */
10090
10643
  SegmentCollection.prototype.getParentRowId = function(rid) {
10091
- return this._childToSegmentId[rid] || "";
10644
+ return this._shared.childToSegment[rid] || "";
10092
10645
  };
10093
10646
  /** @public
10094
10647
  * @param {string} rid
@@ -10097,10 +10650,27 @@ SegmentCollection.prototype.getParentRowId = function(rid) {
10097
10650
  SegmentCollection.prototype.removeSegment = function(rid) {
10098
10651
  var segment = this._segments[rid];
10099
10652
  if(segment) {
10100
- if(segment.isCollapsed()) {
10101
- this._dirtyCollapsingState = true;
10653
+ if(this._segmentCount <= 1) {
10654
+ return this.removeAllSegments();
10655
+ }
10656
+ if(segment.isSubSegment()) {
10657
+ this._removalList.push(segment.getId());
10102
10658
  }
10103
- segment.removeAllChildren(this._childToSegmentId);
10659
+ var subSegIds = segment.getSubSegmentIds();
10660
+ if(subSegIds) {
10661
+ var len = subSegIds.length;
10662
+ for(var i = 0; i < len; ++i) {
10663
+ var subSegId = subSegIds[i];
10664
+ if(this._segments[subSegId]) {
10665
+ this._removalList.push(subSegId);
10666
+ delete this._segments[subSegId]; // Slow
10667
+ --this._segmentCount;
10668
+ }
10669
+ }
10670
+ }
10671
+ segment.removeAllChildren(); // This is important for updating childToSegment
10672
+ segment.dispose();
10673
+
10104
10674
  delete this._segments[rid]; // Slow
10105
10675
  --this._segmentCount;
10106
10676
  return true;
@@ -10112,10 +10682,15 @@ SegmentCollection.prototype.removeSegment = function(rid) {
10112
10682
  */
10113
10683
  SegmentCollection.prototype.removeAllSegments = function() {
10114
10684
  if(this._segmentCount) {
10685
+ for(var key in this._segments) {
10686
+ this._segments[key].dispose();
10687
+ }
10115
10688
  this._segments = {};
10116
- this._childToSegmentId = {};
10117
10689
  this._segmentCount = 0;
10118
- this._dirtyCollapsingState = true;
10690
+ this._segmentList = null;
10691
+ this._shared.childToSegment = {};
10692
+
10693
+ this._classification = this._classifierChanged = false;
10119
10694
  return true;
10120
10695
  }
10121
10696
  return false;
@@ -10156,11 +10731,7 @@ SegmentCollection.prototype.getSegmentIds = function() {
10156
10731
  SegmentCollection.prototype.collapseSegment = function(segmentId, bool) {
10157
10732
  var segment = this._segments[segmentId];
10158
10733
  if(segment) {
10159
- var dirty = segment.collapse(bool);
10160
- if(dirty) {
10161
- this._dirtyCollapsingState = true;
10162
- return true;
10163
- }
10734
+ return segment.collapse(bool);
10164
10735
  }
10165
10736
  return false;
10166
10737
  };
@@ -10183,7 +10754,6 @@ SegmentCollection.prototype.expandAllSegments = function() {
10183
10754
  dirty |= segmentSeparators[rid].expand();
10184
10755
  }
10185
10756
  if(dirty) {
10186
- this._dirtyCollapsingState = true;
10187
10757
  return true;
10188
10758
  }
10189
10759
  }
@@ -10204,17 +10774,19 @@ SegmentCollection.prototype.isCollapsedSegment = function(segmentId) {
10204
10774
  * @return {Object}
10205
10775
  */
10206
10776
  SegmentCollection.prototype.getCollapsedRows = function() {
10207
- if(this._dirtyCollapsingState) {
10208
- this._dirtyCollapsingState = false;
10777
+ if(this._shared.dirtyCollapsingState) {
10778
+ this._shared.dirtyCollapsingState = false;
10209
10779
  var collapsedRids = null;
10210
10780
  var count = 0;
10211
10781
  if(this._segmentCount) {
10212
10782
  var segmentSeparators = this._segments;
10213
10783
  collapsedRids = {};
10214
10784
  for(var rid in segmentSeparators) {
10215
- if(segmentSeparators[rid].isCollapsed()) {
10216
- segmentSeparators[rid].getCollapsingStates(collapsedRids);
10217
- ++count;
10785
+ var segment = segmentSeparators[rid];
10786
+ if(!segment.isSubSegment()) {
10787
+ if(segment.getCollapsingStates(collapsedRids)) {
10788
+ ++count;
10789
+ }
10218
10790
  }
10219
10791
  }
10220
10792
  }
@@ -10226,18 +10798,13 @@ SegmentCollection.prototype.getCollapsedRows = function() {
10226
10798
  /** @public
10227
10799
  * @param {string} segmentId
10228
10800
  * @param {string} rid
10801
+ * @param {string=} dataId Row id for retrieving data
10229
10802
  * @return {boolean} Returns true if there is any change. Otherwise, returns false
10230
10803
  */
10231
- SegmentCollection.prototype.addSegmentChild = function(segmentId, rid) {
10804
+ SegmentCollection.prototype.addSegmentChild = function(segmentId, rid, dataId) {
10232
10805
  var segment = this._segments[segmentId];
10233
- if(segment) {
10234
- var dirty = segment.addChild(rid, this._childToSegmentId);
10235
- if(dirty) {
10236
- if(segment.isCollapsed()) {
10237
- this._dirtyCollapsingState = true;
10238
- }
10239
- return true;
10240
- }
10806
+ if(segment && !segment.isSubSegment()) {
10807
+ return segment.addChild(rid, dataId);
10241
10808
  }
10242
10809
  return false;
10243
10810
  };
@@ -10248,14 +10815,8 @@ SegmentCollection.prototype.addSegmentChild = function(segmentId, rid) {
10248
10815
  */
10249
10816
  SegmentCollection.prototype.addSegmentChildren = function(segmentId, rids) {
10250
10817
  var segment = this._segments[segmentId];
10251
- if(segment) {
10252
- var dirty = segment.addChildren(rids, this._childToSegmentId);
10253
- if(dirty) {
10254
- if(segment.isCollapsed()) {
10255
- this._dirtyCollapsingState = true;
10256
- }
10257
- return true;
10258
- }
10818
+ if(segment && !segment.isSubSegment()) {
10819
+ return segment.addChildren(rids);
10259
10820
  }
10260
10821
  return false;
10261
10822
  };
@@ -10279,13 +10840,7 @@ SegmentCollection.prototype.containsSegmentChild = function(segmentId, rid) {
10279
10840
  SegmentCollection.prototype.removeSegmentChild = function(segmentId, rid) {
10280
10841
  var segment = this._segments[segmentId];
10281
10842
  if(segment) {
10282
- var dirty = segment.removeChild(rid, this._childToSegmentId);
10283
- if(dirty) {
10284
- if(segment.isCollapsed()) {
10285
- this._dirtyCollapsingState = true;
10286
- }
10287
- return true;
10288
- }
10843
+ return segment.removeChild(rid);
10289
10844
  }
10290
10845
  return false;
10291
10846
  };
@@ -10297,13 +10852,7 @@ SegmentCollection.prototype.removeSegmentChild = function(segmentId, rid) {
10297
10852
  SegmentCollection.prototype.removeSegmentChildren = function(segmentId, rids) {
10298
10853
  var segment = this._segments[segmentId];
10299
10854
  if(segment) {
10300
- var dirty = segment.removeChildren(rids, this._childToSegmentId);
10301
- if(dirty) {
10302
- if(segment.isCollapsed()) {
10303
- this._dirtyCollapsingState = true;
10304
- }
10305
- return true;
10306
- }
10855
+ return segment.removeChildren(rids);
10307
10856
  }
10308
10857
  return false;
10309
10858
  };
@@ -10311,20 +10860,20 @@ SegmentCollection.prototype.removeSegmentChildren = function(segmentId, rids) {
10311
10860
  * @return {boolean} Returns true if there is any change. Otherwise, returns false
10312
10861
  */
10313
10862
  SegmentCollection.prototype.removeAllSegmentChildren = function() {
10314
- this._childToSegmentId = {};
10863
+ this._shared.childToSegment = {};
10315
10864
  var segmentSeparators = this._segments;
10316
- var dirtyCollapsingState = this._dirtyCollapsingState;
10317
10865
  var dirty = false;
10318
10866
  for(var rid in segmentSeparators) {
10319
- var segment = this._segments[rid];
10867
+ var segment = segmentSeparators[rid];
10320
10868
  if(segment.removeAllChildren()) {
10321
10869
  dirty = true;
10322
- if(!dirtyCollapsingState && segment.isCollapsed()) {
10323
- dirtyCollapsingState = this._dirtyCollapsingState = true;
10324
- }
10325
10870
  }
10326
10871
  }
10327
10872
 
10873
+ if(dirty) {
10874
+ this.classify();
10875
+ }
10876
+
10328
10877
  return dirty;
10329
10878
  };
10330
10879
 
@@ -10338,22 +10887,18 @@ SegmentCollection.prototype.fillSegment = function(segmentId, rids) {
10338
10887
  return;
10339
10888
  }
10340
10889
  var segmentSeparators = this._segments;
10341
- var childToSegmentId = this._childToSegmentId;
10342
10890
  var curSegment = segmentSeparators[segmentId];
10343
- if(curSegment) {
10891
+ if(curSegment && !curSegment.isSubSegment()) {
10344
10892
  var segmentAt = rids.indexOf(segmentId);
10345
10893
  if(segmentAt >= 0) {
10346
- if(curSegment.isCollapsed()) {
10347
- this._dirtyCollapsingState = true;
10348
- }
10349
- curSegment.removeAllChildren(childToSegmentId);
10894
+ curSegment.removeAllChildren();
10350
10895
  for(var r = segmentAt + 1; r < rowCount; ++r) {
10351
10896
  var rid = rids[r];
10352
10897
  var segmentSeparator = segmentSeparators[rid];
10353
10898
  if(segmentSeparator) {
10354
10899
  break;
10355
10900
  }
10356
- curSegment.addChild(rid, childToSegmentId);
10901
+ curSegment.addChild(rid);
10357
10902
  }
10358
10903
  }
10359
10904
  }
@@ -10363,23 +10908,20 @@ SegmentCollection.prototype.fillSegment = function(segmentId, rids) {
10363
10908
  * @return {boolean} Return true if the fill segments have changed, otherwise return false
10364
10909
  */
10365
10910
  SegmentCollection.prototype.fillSegments = function(rids) {
10911
+ this._shared.childToSegment = {};
10912
+
10366
10913
  var rowCount = Array.isArray(rids) ? rids.length : 0;
10367
- this._childToSegmentId = {};
10368
10914
  var segmentSeparators = this._segments;
10369
- var childToSegmentId = this._childToSegmentId;
10370
10915
  var curSegment = null;
10371
10916
  var change = false;
10372
10917
  for(var r = 0; r < rowCount; ++r) {
10373
10918
  var rid = rids[r];
10374
10919
  var segmentSeparator = segmentSeparators[rid];
10375
- if(segmentSeparator) {
10920
+ if(segmentSeparator && !segmentSeparator.isSubSegment()) {
10376
10921
  curSegment = segmentSeparator;
10377
- if(curSegment.isCollapsed()) {
10378
- this._dirtyCollapsingState = true;
10379
- }
10380
10922
  curSegment.removeAllChildren();
10381
- } else if(curSegment) {
10382
- curSegment.addChild(rid, childToSegmentId);
10923
+ } else if(curSegment && !curSegment.isSubSegment()) {
10924
+ curSegment.addChild(rid);
10383
10925
  change = true;
10384
10926
  }
10385
10927
  }
@@ -10389,6 +10931,13 @@ SegmentCollection.prototype.fillSegments = function(rids) {
10389
10931
  * @param {Array.<string>} rids
10390
10932
  */
10391
10933
  SegmentCollection.prototype.calcSegmentOrder = function(rids) {
10934
+ var segmentList = this._segmentList;
10935
+ if(segmentList) {
10936
+ segmentList.length = 0;
10937
+ } else {
10938
+ segmentList = this._segmentList = [];
10939
+ }
10940
+
10392
10941
  var ridCount = rids ? rids.length : 0;
10393
10942
  var segmentSeparators = this._segments;
10394
10943
  var segmentCount = this._segmentCount;
@@ -10397,8 +10946,11 @@ SegmentCollection.prototype.calcSegmentOrder = function(rids) {
10397
10946
  var rid = rids[i];
10398
10947
  var segment = segmentSeparators[rid];
10399
10948
  if(segment) {
10400
- segment.setOrder(++order);
10401
- if(order >= segmentCount) {
10949
+ if(!segment.isSubSegment()) {
10950
+ this._segmentList.push(segment);
10951
+ segment.setOrder(++order); // WARNING: Segments and sub segments start with 1
10952
+ }
10953
+ if(--segmentCount <= 0) {
10402
10954
  break;
10403
10955
  }
10404
10956
  }
@@ -10414,7 +10966,7 @@ SegmentCollection.prototype.getSegmentValues = function(rids) {
10414
10966
  return null;
10415
10967
  }
10416
10968
  var segmentSeparators = this._segments;
10417
- var childToSegmentId = this._childToSegmentId;
10969
+ var childToSegmentId = this._shared.childToSegment;
10418
10970
  var curSegment = null;
10419
10971
  var prevSegment = null;
10420
10972
  var segmentValues = new Array(rowCount);
@@ -10444,6 +10996,126 @@ SegmentCollection.prototype.getSegmentValues = function(rids) {
10444
10996
 
10445
10997
  return prevSegment ? segmentValues : null;
10446
10998
  };
10999
+ /** @public
11000
+ * @return {string}
11001
+ */
11002
+ SegmentCollection.prototype.logStructure = function() {
11003
+ var segmentList = this._segmentList;
11004
+ if(!segmentList) {
11005
+ return "";
11006
+ }
11007
+ var segmentCount = segmentList.length;
11008
+ var lines = [];
11009
+ for(var i = 0; i < segmentCount; ++i) {
11010
+ segmentList[i].log(lines);
11011
+ }
11012
+
11013
+ return lines.join("\n");
11014
+ };
11015
+ /** @public
11016
+ * @return {string}
11017
+ */
11018
+ SegmentCollection.prototype.logRowIdMap = function() {
11019
+ var lines = [];
11020
+ var childToSegmentId = this._shared.childToSegment;
11021
+ for(var rid in childToSegmentId) {
11022
+ var segmentId = childToSegmentId[rid];
11023
+ lines.push(rid + " > " + segmentId);
11024
+ }
11025
+
11026
+ return lines.join("\n");
11027
+ };
11028
+
11029
+
11030
+ /** @public
11031
+ * @param {string} segmentId
11032
+ * @param {string|Array.<string>} fields
11033
+ * @return {boolean}
11034
+ */
11035
+ SegmentCollection.prototype.setSegmentClassification = function(segmentId, fields) {
11036
+ var segment = this._segments[segmentId];
11037
+ if(segment) {
11038
+ if(segment.setClassification(fields)) {
11039
+ if(segment.getClassification()) {
11040
+ this._classification = true;
11041
+ }
11042
+ this._classifierChanged = true;
11043
+
11044
+ return true;
11045
+ }
11046
+ }
11047
+ return false;
11048
+ };
11049
+ /** @public
11050
+ * @return {boolean}
11051
+ */
11052
+ SegmentCollection.prototype.hasClassification = function() {
11053
+ // WARNING: This include the time when classification is removed
11054
+ return this._classification || this._classifierChanged;
11055
+ };
11056
+ /** @public
11057
+ * @param {Object.<string, Object>} rows Object maps between row id and its record
11058
+ * @return {boolean}
11059
+ */
11060
+ SegmentCollection.prototype.classify = function(rows) {
11061
+ if(!this._segmentCount) {
11062
+ return false;
11063
+ }
11064
+ if(!this.hasClassification()) {
11065
+ return false;
11066
+ }
11067
+ this._classification = this._classifierChanged = false;
11068
+
11069
+ var segmentSeparators = this._segments;
11070
+ for(var rid in segmentSeparators) {
11071
+ var segment = this._segments[rid];
11072
+ if(!segment.isSubSegment()) {
11073
+ if(segment.getClassification()) {
11074
+ this._classification = true;
11075
+ }
11076
+ segment.classify(rows);
11077
+ }
11078
+ }
11079
+ if(this._insertionList.length || this._removalList.length) {
11080
+ this._dispatch("subSegmentChanged", {
11081
+ "insertionList": this._insertionList,
11082
+ "removalList": this._removalList
11083
+ });
11084
+ this._insertionList.length = 0;
11085
+ this._removalList.length = 0;
11086
+
11087
+ this._dispatch("classified", {});
11088
+ return true;
11089
+ }
11090
+
11091
+ this._dispatch("classified", {});
11092
+ return false;
11093
+ };
11094
+
11095
+ /** @private
11096
+ * @param {!Object} e
11097
+ */
11098
+ SegmentCollection.prototype._onSubSegmentAdded = function(e) {
11099
+ var rid = e["rid"];
11100
+ if(!this._segments[rid]) {
11101
+ var segment = /** @type{Segment} */(e["segment"]);
11102
+ this._insertionList.push(segment);
11103
+ this._segments[rid] = segment;
11104
+ this._segmentCount++;
11105
+
11106
+ segment.addEventListener("subSegmentAdded", this._onSubSegmentAdded);
11107
+ segment.addEventListener("subSegmentRemoved", this._onSubSegmentRemoved);
11108
+ } else {
11109
+ console.log("Incorrect logic detected.");
11110
+ }
11111
+ };
11112
+ /** @private
11113
+ * @param {!Object} e
11114
+ */
11115
+ SegmentCollection.prototype._onSubSegmentRemoved = function(e) {
11116
+ var rid = e["rid"];
11117
+ this.removeSegment(rid);
11118
+ };
10447
11119
 
10448
11120
 
10449
11121
  /* harmony default export */ var data_SegmentCollection = (SegmentCollection);
@@ -10453,6 +11125,7 @@ SegmentCollection.prototype.getSegmentValues = function(rids) {
10453
11125
 
10454
11126
 
10455
11127
 
11128
+ // eslint-disable-line
10456
11129
 
10457
11130
 
10458
11131
  /** Trigger when data within the table has been changed
@@ -10475,11 +11148,15 @@ var DataTable = function() {
10475
11148
 
10476
11149
  this._removeRows = this._removeRows.bind(this);
10477
11150
  this._bySegmentSeparator = this._bySegmentSeparator.bind(this);
11151
+ this._onClassifyingTimer = this._onClassifyingTimer.bind(this);
11152
+ this._onSubSegmentChanged = this._onSubSegmentChanged.bind(this);
10478
11153
 
10479
11154
  this._prevData = {};
10480
11155
  this._rids = [];
10481
11156
 
10482
11157
  this._compMap = {};
11158
+
11159
+ this._addEvent("subSegmentChanged");
10483
11160
  };
10484
11161
  Ext["b" /* default */].inherits(DataTable, data_DataCache);
10485
11162
 
@@ -10522,6 +11199,14 @@ DataTable.prototype._removedRows = null;
10522
11199
  * @type {Function}
10523
11200
  */
10524
11201
  DataTable.prototype._userSegmentComparer = null;
11202
+ /** @private
11203
+ * @type {Object.<string, Object>}
11204
+ */
11205
+ DataTable.prototype._clsSource = null;
11206
+ /** @private
11207
+ * @type {number}
11208
+ */
11209
+ DataTable.prototype._classifyingTimer = 0;
10525
11210
 
10526
11211
 
10527
11212
  /** @typedef {Function} DataTable~SortLogic
@@ -10550,8 +11235,17 @@ DataTable.prototype.dispose = function() {
10550
11235
  this.unlistenAll();
10551
11236
  this.clearAllData(true);
10552
11237
 
11238
+ if(this._classifyingTimer) {
11239
+ clearTimeout(this._onClassifyingTimer);
11240
+ this._classifyingTimer = 0;
11241
+ }
11242
+
10553
11243
  this._compMap = null; // Release user function that may be bound
10554
- this._segments = null;
11244
+ this._clsSource = null;
11245
+ if(this._segments) {
11246
+ this._segments.dispose();
11247
+ this._segments = null;
11248
+ }
10555
11249
  };
10556
11250
 
10557
11251
  /** {@link DataCache#getColumnData}
@@ -10701,6 +11395,7 @@ DataTable.prototype.setRowData = function(rid, values, eventArg) { // Data chang
10701
11395
  var segment = this._segments.getSegment(rid);
10702
11396
  if(segment) {
10703
11397
  if(this._segments.removeSegment(rid)) {
11398
+ // TODO: Handle sub segment removal
10704
11399
  segmentChanged = true;
10705
11400
  if(!this._segments.getSegmentCount()) {
10706
11401
  this._segments = null;
@@ -10708,12 +11403,7 @@ DataTable.prototype.setRowData = function(rid, values, eventArg) { // Data chang
10708
11403
  }
10709
11404
  }
10710
11405
  }
10711
- for(var i = this._rids.length; --i >= 0;) {
10712
- if(this._rids[i] === rid) {
10713
- this._rids.splice(i, 1);
10714
- break;
10715
- }
10716
- }
11406
+ DataTable._removeArrayItem(this._rids, rid);
10717
11407
  dirty = true;
10718
11408
  }
10719
11409
  }
@@ -10732,7 +11422,7 @@ DataTable.prototype.setRowData = function(rid, values, eventArg) { // Data chang
10732
11422
  }
10733
11423
  this._dispatchDataChange(e);
10734
11424
  }
10735
-
11425
+ this.requestClassifying(); // TODO: Check if needFiring method should have an effect on this request
10736
11426
  }
10737
11427
  return dirty;
10738
11428
  };
@@ -11033,12 +11723,34 @@ DataTable.prototype.removeRows = function(refs) {
11033
11723
  DataTable.prototype._removeRows = function(rid) {
11034
11724
  return !this._removedRows[rid];
11035
11725
  };
11726
+
11727
+ /** @private
11728
+ * @param {Array} ary
11729
+ * @param {*} item
11730
+ * @return {boolean}
11731
+ */
11732
+ DataTable._removeArrayItem = function(ary, item) {
11733
+ var at = ary.indexOf(item);
11734
+ if(at >= 0) {
11735
+ if(at >= ary.length) {
11736
+ ary.pop(); // Array.pop is 100 times faster than Array.splice
11737
+ } else {
11738
+ ary.splice(at, 1);
11739
+ }
11740
+ return true;
11741
+ }
11742
+ return false;
11743
+ };
11036
11744
  /** Remove all existing rows
11037
11745
  * @override
11038
11746
  */
11039
11747
  DataTable.prototype.clearAllData = function(suppressEvent) {
11040
11748
  DataTable.base(this, "clearAllData", true);
11041
11749
  this._prevData = {};
11750
+ // TODO: Clear all segments
11751
+ if(this._segments) {
11752
+ this._segments.removeAllSegmentChildren(); // This immediately remove all sub segments
11753
+ }
11042
11754
 
11043
11755
  if(this._rids.length) {
11044
11756
  this._rids.length = 0;
@@ -11345,6 +12057,7 @@ DataTable.prototype.setSegmentSeparator = function(rid, enabled) {
11345
12057
  if(enabled !== false) {
11346
12058
  if(!this._segments) {
11347
12059
  this._segments = new data_SegmentCollection();
12060
+ this._segments.addEventListener("subSegmentChanged", this._onSubSegmentChanged);
11348
12061
  }
11349
12062
  if(this._autoSegmentFilling) {
11350
12063
  var parentId = this._segments.getParentRowId(rid);
@@ -11417,6 +12130,29 @@ DataTable.prototype.isSegmentSeparator = function(rid) {
11417
12130
  }
11418
12131
  return false;
11419
12132
  };
12133
+ /** Get Segment object
12134
+ * @public
12135
+ * @param {string} rid Row id
12136
+ * @return {Segment} Return 0 if the given rid is not a segment
12137
+ */
12138
+ DataTable.prototype.getSegment = function(rid) {
12139
+ if(this._segments) {
12140
+ return this._segments.getSegment(rid);
12141
+ }
12142
+ return null;
12143
+ };
12144
+ /** Segment level starts from 1
12145
+ * @public
12146
+ * @param {string} rid
12147
+ * @return {number} Return 0 if the given rid is not a segment
12148
+ */
12149
+ DataTable.prototype.getSegmentLevel = function(rid) {
12150
+ var segment = this.getSegment(rid);
12151
+ if(segment) {
12152
+ return segment.getSegmentLevel() + 1;
12153
+ }
12154
+ return 0;
12155
+ };
11420
12156
  /**
11421
12157
  * @public
11422
12158
  * @param {string} rid
@@ -11490,6 +12226,7 @@ DataTable.prototype.fillSegment = function(segmentId) {
11490
12226
  if(this._segments) {
11491
12227
  this._segments.fillSegment(segmentId, this._rids);
11492
12228
  this.dispatchGlobalChange();
12229
+ this.requestClassifying();
11493
12230
  }
11494
12231
  };
11495
12232
  /** Remove all existing segment children in each segment and fill the segments with all contnet rows before the next segment separator
@@ -11501,6 +12238,7 @@ DataTable.prototype.fillSegments = function() {
11501
12238
  var dirty = this._segments.fillSegments(this._rids);
11502
12239
  if(dirty) {
11503
12240
  this.dispatchGlobalChange();
12241
+ this.requestClassifying();
11504
12242
  }
11505
12243
  return dirty;
11506
12244
  }
@@ -11509,15 +12247,17 @@ DataTable.prototype.fillSegments = function() {
11509
12247
  /** @public
11510
12248
  * @param {string} segmentId Row id
11511
12249
  * @param {string} rid Row id
12250
+ * @param {string=} dataId Row id for retrieving data
11512
12251
  * @return {boolean} Return true if there is any change
11513
12252
  */
11514
- DataTable.prototype.addSegmentChild = function(segmentId, rid) {
12253
+ DataTable.prototype.addSegmentChild = function(segmentId, rid, dataId) {
11515
12254
  if(this._segments) {
11516
- var dirty = this._segments.addSegmentChild(segmentId, rid);
12255
+ var dirty = this._segments.addSegmentChild(segmentId, rid, dataId);
11517
12256
  if(dirty) {
11518
12257
  if(this._sort(null)) {
11519
12258
  this._dispatchPositionChange();
11520
12259
  }
12260
+ this.requestClassifying();
11521
12261
  return true;
11522
12262
  }
11523
12263
  }
@@ -11535,6 +12275,7 @@ DataTable.prototype.addSegmentChildren = function(segmentId, rids) {
11535
12275
  if(this._sort(null)) {
11536
12276
  this._dispatchPositionChange();
11537
12277
  }
12278
+ this.requestClassifying();
11538
12279
  return true;
11539
12280
  }
11540
12281
  }
@@ -11550,6 +12291,7 @@ DataTable.prototype.removeSegmentChild = function(segmentId, rid) {
11550
12291
  var dirty = this._segments.removeSegmentChild(segmentId, rid);
11551
12292
  if(dirty) {
11552
12293
  this.dispatchGlobalChange();
12294
+ this.requestClassifying();
11553
12295
  }
11554
12296
  return dirty;
11555
12297
  }
@@ -11565,6 +12307,7 @@ DataTable.prototype.removeSegmentChildren = function(segmentId, rids) {
11565
12307
  var dirty = this._segments.removeSegmentChildren(segmentId, rids);
11566
12308
  if(dirty) {
11567
12309
  this.dispatchGlobalChange();
12310
+ this.requestClassifying();
11568
12311
  }
11569
12312
  return dirty;
11570
12313
  }
@@ -11575,7 +12318,7 @@ DataTable.prototype.removeSegmentChildren = function(segmentId, rids) {
11575
12318
  */
11576
12319
  DataTable.prototype.removeAllSegmentChildren = function() {
11577
12320
  if(this._segments) {
11578
- var dirty = this._segments.removeAllSegmentChildren();
12321
+ var dirty = this._segments.removeAllSegmentChildren(); // This immediately remove all sub segments
11579
12322
  if (dirty) {
11580
12323
  this.dispatchGlobalChange();
11581
12324
  }
@@ -11611,10 +12354,15 @@ DataTable.prototype.getSegmentChildIds = function(segmentId) {
11611
12354
  /** Sort all of existing segments by given compare function
11612
12355
  * @public
11613
12356
  * @param {Function} compare
12357
+ * @return {boolean}
11614
12358
  */
11615
12359
  DataTable.prototype.sortSegments = function (compare) {
11616
- if(!this._segments || typeof compare !== "function") {
11617
- return;
12360
+ if(!this._segments) {
12361
+ return false;
12362
+ }
12363
+ if(typeof compare !== "function") {
12364
+ this._segments.calcSegmentOrder(this._rids);
12365
+ return false;
11618
12366
  }
11619
12367
  var rids = this._rids;
11620
12368
  var segments = this._segments;
@@ -11658,7 +12406,9 @@ DataTable.prototype.sortSegments = function (compare) {
11658
12406
  this._segments.calcSegmentOrder(rids);
11659
12407
  this._sort(null);
11660
12408
  this._dispatchPositionChange();
12409
+ return true;
11661
12410
  }
12411
+ return false;
11662
12412
  };
11663
12413
  /** Sort all of existing segments by given compare function
11664
12414
  * @private
@@ -11673,6 +12423,112 @@ DataTable.prototype._bySegmentSeparator = function (segmentA, segmentB) {
11673
12423
  ));
11674
12424
  };
11675
12425
 
12426
+ /** A data source to be used with segment classification
12427
+ * @public
12428
+ * @param {DataCache} dc
12429
+ */
12430
+ DataTable.prototype.setClassificationSource = function(dc) {
12431
+ this._clsSource = null;
12432
+
12433
+ if(dc && dc._rows) {
12434
+ this._clsSource = dc._rows;
12435
+ }
12436
+ };
12437
+ /**
12438
+ * @public
12439
+ * @param {string} segmentId
12440
+ * @param {string|Array.<string>} fields
12441
+ * @return {boolean}
12442
+ */
12443
+ DataTable.prototype.setSegmentClassification = function(segmentId, fields) {
12444
+ if(this._segments) {
12445
+ var dirty = this._segments.setSegmentClassification(segmentId, fields);
12446
+ if(dirty) {
12447
+ return this.classifySegments();
12448
+ }
12449
+ }
12450
+ return false;
12451
+ };
12452
+ /** @public
12453
+ * @return {boolean}
12454
+ */
12455
+ DataTable.prototype.classifySegments = function() {
12456
+ if(this._segments) {
12457
+ if(this._rids.length) {
12458
+ return this._segments.classify(this._clsSource || this._rows);
12459
+ }
12460
+ }
12461
+ return false;
12462
+ };
12463
+
12464
+ /** @public
12465
+ */
12466
+ DataTable.prototype.requestClassifying = function() {
12467
+ if(this._segments && !this._classifyingTimer) {
12468
+ if(this._segments.hasClassification()) {
12469
+ this._classifyingTimer = setTimeout(this._onClassifyingTimer, 10);
12470
+ }
12471
+ }
12472
+ };
12473
+ /** @private
12474
+ */
12475
+ DataTable.prototype._onClassifyingTimer = function() {
12476
+ this._classifyingTimer = 0;
12477
+ this.classifySegments();
12478
+ };
12479
+ /** @private
12480
+ * @param {Object} e
12481
+ */
12482
+ DataTable.prototype._onSubSegmentChanged = function(e) {
12483
+ var insertionList = /** @type{Array.<Segment>} */(e["insertionList"]);
12484
+ var removalList = /** @type{Array.<string>} */(e["removalList"]);
12485
+
12486
+ var dirty = false;
12487
+ var rows = this._rows;
12488
+ var clsSource = this._clsSource || rows;
12489
+ var rids = this._rids;
12490
+ var prevData = this._prevData;
12491
+ var i;
12492
+
12493
+ var removalCount = removalList.length;
12494
+ var removedRows = {};
12495
+ for(i = 0; i < removalCount; i++) {
12496
+ var rid = removalList[i];
12497
+ if(rows[rid]) {
12498
+ removedRows[rid] = prevData[rid] = rows[rid];
12499
+ delete rows[rid];
12500
+ DataTable._removeArrayItem(rids, rid);
12501
+ dirty = true;
12502
+ // TODO: Remove classification source
12503
+ }
12504
+ }
12505
+
12506
+ var insertionCount = insertionList.length;
12507
+ for(i = 0; i < insertionCount; i++) {
12508
+ var segment = insertionList[i];
12509
+ var parentId = segment.getParentId();
12510
+ var segmentId = segment.getId();
12511
+
12512
+ if(!rows[segmentId]) {
12513
+ prevData[segmentId] = {};
12514
+ segment.setRowData(rows, clsSource);
12515
+
12516
+ var parentAt = rids.indexOf(parentId);
12517
+ if(parentAt < 0 || parentAt + 1 >= rids.length) {
12518
+ rids.push(segmentId);
12519
+ } else {
12520
+ rids.splice(parentAt + 1, 0, segmentId);
12521
+ }
12522
+ dirty = true;
12523
+ }
12524
+ }
12525
+ if(dirty) {
12526
+ e["removedRows"] = removedRows;
12527
+ this._dispatch("subSegmentChanged", e);
12528
+ this.dispatchGlobalChange(); // Rerender everything
12529
+ }
12530
+ };
12531
+
11676
12532
 
11677
12533
  /**
11678
12534
  * @public
@@ -12191,6 +13047,13 @@ var ROW_DEF = "ROW_DEF";
12191
13047
  */
12192
13048
  var RowDefinition = function(rowOptions) {
12193
13049
  this._changes = {};
13050
+ if(rowOptions && rowOptions["segmentId"]) {
13051
+ this._dataId = this._rowId = rowOptions["segmentId"];
13052
+ this._autoGenerated = true;
13053
+ this._subSegment = true;
13054
+ return;
13055
+ }
13056
+
12194
13057
  this._rowId = "_" + RowDefinition._runningId++ + "_";
12195
13058
  this._dataId = this._rowId;
12196
13059
 
@@ -12259,6 +13122,10 @@ RowDefinition.prototype._expanded = false;
12259
13122
  * @private
12260
13123
  */
12261
13124
  RowDefinition.prototype._autoGenerated = false;
13125
+ /** @type {boolean}
13126
+ * @private
13127
+ */
13128
+ RowDefinition.prototype._subSegment = false;
12262
13129
  /** @type {Object.<string, *>}
12263
13130
  * @private
12264
13131
  */
@@ -12822,7 +13689,16 @@ RowDefinition.prototype.registerToView = function(view, rowId) {
12822
13689
  }
12823
13690
  this._view = view;
12824
13691
 
12825
- var rowData = {};
13692
+ var rowData = null;
13693
+ if(this._subSegment) {
13694
+ rowData = this._view.getRowData(this.getRowId());
13695
+ if(rowData) {
13696
+ rowData[ROW_DEF] = this; // no event trigger
13697
+ }
13698
+ return;
13699
+ }
13700
+
13701
+ rowData = {};
12826
13702
  rowData[ROW_DEF] = this;
12827
13703
 
12828
13704
  var newRowId = this._view.insertRow(rowId, rowData, this.getRowId());
@@ -12903,11 +13779,68 @@ RowDefinition.prototype.addConstituent = function(ric) {
12903
13779
  var rowId = this.getRowId();
12904
13780
  var rowIndex = this._view.getRowIndex(rowId) + this.getChildCount(); // Children must be directly under its parent
12905
13781
  childDef.registerToView(this._view, this._view.getRowId(rowIndex));
12906
- this._view.addSegmentChild(rowId, childDef.getRowId());
13782
+ this._view.addSegmentChild(rowId, childDef.getRowId(), childDef.getDataId());
12907
13783
  }
12908
13784
 
12909
13785
  return newChild ? childDef : null;
12910
13786
  };
13787
+
13788
+ /** Used to convert autogenerated row to regular real-time row
13789
+ * @public
13790
+ */
13791
+ RowDefinition.prototype._toRealTimeRow = function() {
13792
+ if(!this._ric) { // Empty row
13793
+ return;
13794
+ }
13795
+ if(this.isRowHeader()) {
13796
+ return;
13797
+ }
13798
+
13799
+ this._realTimeField = true;
13800
+ this._dataId = this._rowId + this._ric; // JET/RTK will generate data id to be rowId (given from this rowDef) + ric;
13801
+
13802
+ this._autoGenerated = false;
13803
+ this._parent = null;
13804
+ this._depthLevel = 0;
13805
+
13806
+ this.subscribeForUpdates();
13807
+ };
13808
+
13809
+ /** @public
13810
+ */
13811
+ RowDefinition.prototype.unlinkChain = function() {
13812
+ if(!this._isChain) {
13813
+ return;
13814
+ }
13815
+
13816
+ if(this.isChainExpanded()) {
13817
+ var rowDefs = this.getDescendants();
13818
+ var len = rowDefs.length;
13819
+ for(var i = 0; i < len; i++) {
13820
+ rowDefs[i]._toRealTimeRow();
13821
+ }
13822
+ }
13823
+
13824
+ this.unsubscribeForUpdates();
13825
+
13826
+ var view = this._view;
13827
+ if(view) {
13828
+ var rid = this.getRowId();
13829
+ var segment = view.getSegment(rid);
13830
+ if(segment) {
13831
+ segment.setClassification(null);
13832
+ }
13833
+ view.setSegmentSeparator(rid, false);
13834
+ }
13835
+
13836
+ this._isChain = this._expanded = false;
13837
+ this._chainRic = "";
13838
+ this._userInput = this._ric;
13839
+ this._children = null;
13840
+
13841
+ this.subscribeForUpdates();
13842
+ };
13843
+
12911
13844
  /** @public
12912
13845
  * @return {boolean} Returns true if there is a change in view
12913
13846
  */
@@ -26333,6 +27266,7 @@ WrappedView.prototype.isRowFiltered = function(rid, rowData) {
26333
27266
 
26334
27267
  // eslint-disable-line
26335
27268
 
27269
+ // eslint-disable-line
26336
27270
 
26337
27271
 
26338
27272
 
@@ -28677,6 +29611,22 @@ DataView.prototype.isSegmentSeparator = function(rid) {
28677
29611
  return this._dt.isSegmentSeparator(rid);
28678
29612
  };
28679
29613
 
29614
+ /** Get Segment object
29615
+ * @public
29616
+ * @param {string} rid Row id
29617
+ * @return {Segment} Return 0 if the given rid is not a segment
29618
+ */
29619
+ DataView.prototype.getSegment = function(rid) {
29620
+ return this._dt.getSegment(rid);
29621
+ };
29622
+ /** Segment level starts from 1
29623
+ * @public
29624
+ * @param {string} rid Row id
29625
+ * @return {number} Return 0 if the given rid is not a segment
29626
+ */
29627
+ DataView.prototype.getSegmentLevel = function(rid) {
29628
+ return this._dt.getSegmentLevel(rid);
29629
+ };
28680
29630
  /**
28681
29631
  * @public
28682
29632
  * @param {string} rid
@@ -28758,13 +29708,14 @@ DataView.prototype.fillSegments = function() {
28758
29708
  /** @public
28759
29709
  * @param {string|number} segmentRef Row id or row index
28760
29710
  * @param {string|number} rowRef Row id, row index
29711
+ * @param {string=} dataId Row id for retrieving data
28761
29712
  * @return {boolean} Return true if there is any change
28762
29713
  */
28763
- DataView.prototype.addSegmentChild = function(segmentRef, rowRef) {
29714
+ DataView.prototype.addSegmentChild = function(segmentRef, rowRef, dataId) {
28764
29715
  if(this._dt._getSegmentSeparators()) {
28765
29716
  var segmentId = this._toRowId(segmentRef);
28766
29717
  var rowId = this._toRowId(rowRef);
28767
- return this._dt.addSegmentChild(segmentId, rowId);
29718
+ return this._dt.addSegmentChild(segmentId, rowId, dataId);
28768
29719
  }
28769
29720
  return false;
28770
29721
  };
@@ -28836,6 +29787,16 @@ DataView.prototype.sortSegments = function (compare) {
28836
29787
  this._dt.sortSegments(compare);
28837
29788
  };
28838
29789
 
29790
+ /**
29791
+ * @public
29792
+ * @param {string|number} segmentRef Row id or row index
29793
+ * @param {string|Array.<string>} fields
29794
+ * @return {boolean}
29795
+ */
29796
+ DataView.prototype.setSegmentClassification = function(segmentRef, fields) {
29797
+ return this._dt.setSegmentClassification(this._toRowId(segmentRef), fields);
29798
+ };
29799
+
28839
29800
  /** @public
28840
29801
  * @ignore
28841
29802
  * @return {Object}
@@ -33292,7 +34253,7 @@ Core.prototype._rowHeightTimerId = 0;
33292
34253
  * @return {string}
33293
34254
  */
33294
34255
  Core.getVersion = function () {
33295
- return "5.1.20";
34256
+ return "5.1.25";
33296
34257
  };
33297
34258
  /** {@link ElementWrapper#dispose}
33298
34259
  * @override
@@ -40825,6 +41786,7 @@ var Grid = function(placeholder, config) {
40825
41786
 
40826
41787
  t._onDataChanged = t._onDataChanged.bind(t);
40827
41788
  t._onDataComposed = t._onDataComposed.bind(t);
41789
+ t._onSubSegmentChanged = t._onSubSegmentChanged.bind(t);
40828
41790
  t._recalculateFormulas = t._recalculateFormulas.bind(t);
40829
41791
  t._updateStreamingData = t._updateStreamingData.bind(t);
40830
41792
  t.updateColumnTitle = t.updateColumnTitle.bind(t);
@@ -40888,6 +41850,8 @@ var Grid = function(placeholder, config) {
40888
41850
 
40889
41851
  t._dt = new DataTable();
40890
41852
  t._dt.setSortingLogic(/** @type{Function} */(t._mainSorter));
41853
+ t._dt.setClassificationSource(t._dc);
41854
+ t._dt.listen("subSegmentChanged", t._onSubSegmentChanged);
40891
41855
  t._dv = new DataView(t._dt);
40892
41856
  t._dv.listen("pageIndexChanged", t._dispatch.bind(t, "pageIndexChanged"));
40893
41857
  t._dv.listen("pageCountChanged", t._dispatch.bind(t, "pageCountChanged")); // TODO: When implementing filtered row, it may need to implement the conflator
@@ -42837,6 +43801,28 @@ Grid.prototype.setRic = function(rowRef, str) {
42837
43801
  }
42838
43802
  }
42839
43803
  };
43804
+ /** Unlink the chain and its constituents. When the chain is expanded,
43805
+ * the chain row and its members are converted from autogenerated to
43806
+ * regular real-time rows. Only the chain row will be transformed to
43807
+ * a conventional real-time row if the chain is collapsed.
43808
+ * All converted rows will continue to have their data updated.
43809
+ *
43810
+ * @public
43811
+ * @param {Grid~RowReference} rowRef
43812
+ */
43813
+ Grid.prototype.unlinkChain = function(rowRef) {
43814
+ var rowDef = this._getRowDefinition(rowRef);
43815
+ if(!rowDef) {
43816
+ return;
43817
+ }
43818
+
43819
+ if(!rowDef.isChain()) {
43820
+ return;
43821
+ }
43822
+
43823
+ rowDef.unlinkChain();
43824
+ };
43825
+
42840
43826
  /** Alias to setRic
42841
43827
  * @public
42842
43828
  * @function
@@ -43452,6 +44438,7 @@ Grid.prototype._updateStreamingData = function() {
43452
44438
  }
43453
44439
 
43454
44440
  if(this._dt) {
44441
+ this._dt.classifySegments();
43455
44442
  this._dt.dispatchGlobalChange();
43456
44443
  }
43457
44444
  };
@@ -43573,6 +44560,20 @@ Grid.prototype.toggleChain = function(rowRef) {
43573
44560
  rowDef.toggleChain();
43574
44561
  }
43575
44562
  };
44563
+ /**
44564
+ * @public
44565
+ * @param {Grid~RowReference} rowRef
44566
+ * @param {Array.<string>} fields
44567
+ * @return {boolean}
44568
+ */
44569
+ Grid.prototype.setClassification = function(rowRef, fields) {
44570
+ var rowDef = this._getRowDefinition(rowRef);
44571
+ if(rowDef) {
44572
+ return this._dt.setSegmentClassification(rowDef.getRowId(), fields);
44573
+ }
44574
+ return false;
44575
+ };
44576
+
43576
44577
  /** @description Focus grid element without moving window scrollbar
43577
44578
  * @public
43578
44579
  */
@@ -43677,6 +44678,41 @@ Grid.prototype._onDataComposed = function(e) {
43677
44678
 
43678
44679
  this._recalculateFormulas(e);
43679
44680
  };
44681
+ /** @private
44682
+ * @param {Object} e
44683
+ */
44684
+ Grid.prototype._onSubSegmentChanged = function(e) {
44685
+ var insertionList = /** @type{Array.<Segment>} */(e["insertionList"]);
44686
+ var removalList = /** @type{Array.<string>} */(e["removalList"]);
44687
+ var removedRows = /** @type{Object} */(e["removedRows"]);
44688
+
44689
+ var i;
44690
+ var removalCount = removalList.length;
44691
+ var rowDef = null;
44692
+ for(i = 0; i < removalCount; i++) {
44693
+ var rid = removalList[i];
44694
+ var removedRow = removedRows[rid];
44695
+ if(removedRow) {
44696
+ rowDef = removedRow[ROW_DEF];
44697
+ if(rowDef) {
44698
+ rowDef.dispose();
44699
+ removedRow[ROW_DEF] = null;
44700
+ }
44701
+ }
44702
+ }
44703
+
44704
+ var insertionCount = insertionList.length;
44705
+ for(i = 0; i < insertionCount; i++) {
44706
+ var segment = insertionList[i];
44707
+ // var parentId = segment.getParentId();
44708
+ var segmentId = segment.getId();
44709
+ rowDef = new RowDefinition({
44710
+ "segmentId": segmentId
44711
+ });
44712
+ rowDef.setDataSource(this._dc);
44713
+ rowDef.registerToView(this._dv);
44714
+ }
44715
+ };
43680
44716
 
43681
44717
  /** @private
43682
44718
  * @param {Object=} e