@refinitiv-ui/efx-grid 6.0.146 → 6.0.148
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/core/dist/core.js +497 -273
- package/lib/core/dist/core.min.js +1 -1
- package/lib/core/es6/data/DataTable.d.ts +1 -1
- package/lib/core/es6/data/DataTable.js +64 -59
- package/lib/core/es6/data/DataView.d.ts +1 -1
- package/lib/core/es6/data/DataView.js +5 -6
- package/lib/core/es6/data/Segment.d.ts +15 -1
- package/lib/core/es6/data/Segment.js +336 -169
- package/lib/core/es6/data/SegmentCollection.d.ts +1 -1
- package/lib/core/es6/data/SegmentCollection.js +91 -38
- package/lib/core/es6/grid/Core.js +1 -1
- package/lib/grid/index.js +1 -1
- package/lib/types/es6/Core/data/DataTable.d.ts +1 -1
- package/lib/types/es6/Core/data/DataView.d.ts +1 -1
- package/lib/types/es6/Core/data/Segment.d.ts +15 -1
- package/lib/types/es6/Core/data/SegmentCollection.d.ts +1 -1
- package/package.json +1 -1
@@ -8,7 +8,7 @@ import EventDispatcher from "../../../tr-grid-util/es6/EventDispatcher.js";
|
|
8
8
|
*/
|
9
9
|
let Segment = function(rid, sharedObj) {
|
10
10
|
this._rid = rid;
|
11
|
-
this.
|
11
|
+
this._childIds = [];
|
12
12
|
this._shared = sharedObj;
|
13
13
|
if(sharedObj.defaultCollapsing) {
|
14
14
|
this._collapsed = true;
|
@@ -39,14 +39,6 @@ Segment._subSegSortLogic = function(a, b) {
|
|
39
39
|
|
40
40
|
return 0;
|
41
41
|
};
|
42
|
-
/** @private
|
43
|
-
* @function
|
44
|
-
* @param {Segment} segment
|
45
|
-
* @param {number} idx
|
46
|
-
*/
|
47
|
-
Segment._assignSubSegmentOrder = function(segment, idx) {
|
48
|
-
segment.setOrder(idx + 1);
|
49
|
-
};
|
50
42
|
|
51
43
|
/** @type {Object}
|
52
44
|
* @private
|
@@ -57,14 +49,14 @@ Segment.prototype._shared = null;
|
|
57
49
|
* @private
|
58
50
|
*/
|
59
51
|
Segment.prototype._rid;
|
60
|
-
/** @type {!
|
52
|
+
/** @type {!Array.<string>}
|
61
53
|
* @private
|
62
54
|
*/
|
63
|
-
Segment.prototype.
|
64
|
-
/** @type {
|
55
|
+
Segment.prototype._childIds;
|
56
|
+
/** @type {Object}
|
65
57
|
* @private
|
66
58
|
*/
|
67
|
-
Segment.prototype.
|
59
|
+
Segment.prototype._childDataIds = null;
|
68
60
|
/** @type {boolean}
|
69
61
|
* @private
|
70
62
|
*/
|
@@ -73,6 +65,14 @@ Segment.prototype._collapsed = false;
|
|
73
65
|
* @private
|
74
66
|
*/
|
75
67
|
Segment.prototype._order = 0;
|
68
|
+
/** @type {number}
|
69
|
+
* @private
|
70
|
+
*/
|
71
|
+
Segment.prototype._offsetOrder = 0;
|
72
|
+
/** @type {number}
|
73
|
+
* @private
|
74
|
+
*/
|
75
|
+
Segment.prototype._depth = 0;
|
76
76
|
/** @type {boolean}
|
77
77
|
* @private
|
78
78
|
*/
|
@@ -82,10 +82,10 @@ Segment.prototype._disposed = false;
|
|
82
82
|
* @private
|
83
83
|
*/
|
84
84
|
Segment.prototype._subSegDef = null;
|
85
|
-
/** @type {
|
85
|
+
/** @type {boolean}
|
86
86
|
* @private
|
87
87
|
*/
|
88
|
-
Segment.prototype.
|
88
|
+
Segment.prototype._subSegment = false; // This indicates that the segment is autogenerated (subsegment)
|
89
89
|
/** @type {Object.<string, Segment>}
|
90
90
|
* @private
|
91
91
|
*/
|
@@ -93,7 +93,7 @@ Segment.prototype._subSegMap = null; // For immediate sub-segment children
|
|
93
93
|
/** @type {Array.<string>}
|
94
94
|
* @private
|
95
95
|
*/
|
96
|
-
Segment.prototype._subSegNames = null; // For immediate sub-segment child names
|
96
|
+
Segment.prototype._subSegNames = null; // For immediate sub-segment child names/ids
|
97
97
|
/** @type {string}
|
98
98
|
* @private
|
99
99
|
*/
|
@@ -102,10 +102,6 @@ Segment.prototype._subSegName = "";
|
|
102
102
|
* @private
|
103
103
|
*/
|
104
104
|
Segment.prototype._subSegVal;
|
105
|
-
/** @type {Segment}
|
106
|
-
* @private
|
107
|
-
*/
|
108
|
-
Segment.prototype._subSegParent = null;
|
109
105
|
|
110
106
|
|
111
107
|
/** @public
|
@@ -127,14 +123,13 @@ Segment.prototype.dispose = function() {
|
|
127
123
|
this._subSegMap = this._subSegNames = null;
|
128
124
|
}
|
129
125
|
if(this._collapsed) {
|
130
|
-
|
131
|
-
this._shared.dirtyCollapsingState = true;
|
132
|
-
}
|
126
|
+
this.markCollapsingStateDirty();
|
133
127
|
}
|
134
128
|
|
135
|
-
this.
|
129
|
+
this._childDataIds = null;
|
130
|
+
this._childIds.length = 0;
|
136
131
|
this._shared = null;
|
137
|
-
this.
|
132
|
+
this._subSegDef = this._subSegVal = null;
|
138
133
|
};
|
139
134
|
/** @public
|
140
135
|
* @return {string}
|
@@ -146,10 +141,17 @@ Segment.prototype.getId = function() {
|
|
146
141
|
* @return {string}
|
147
142
|
*/
|
148
143
|
Segment.prototype.getParentId = function() {
|
149
|
-
|
150
|
-
|
144
|
+
return this._shared.childToSegment[this._rid] || "";
|
145
|
+
};
|
146
|
+
/** @public
|
147
|
+
* @return {Segment}
|
148
|
+
*/
|
149
|
+
Segment.prototype.getParent = function() {
|
150
|
+
let parentId = this.getParentId();
|
151
|
+
if(parentId) {
|
152
|
+
return this._shared.segments[parentId] || null;
|
151
153
|
}
|
152
|
-
return
|
154
|
+
return null;
|
153
155
|
};
|
154
156
|
/** @public
|
155
157
|
* @param {Array.<string>=} out_ary
|
@@ -177,22 +179,44 @@ Segment.prototype.getSubSegmentIds = function(out_ary) {
|
|
177
179
|
/** @public
|
178
180
|
* @param {string} rid
|
179
181
|
* @param {string=} dataId Row id for retrieving data
|
180
|
-
* @return {boolean}
|
182
|
+
* @return {boolean} Returns true only a new child is added
|
181
183
|
*/
|
182
184
|
Segment.prototype.addChild = function(rid, dataId) {
|
183
|
-
if(rid) {
|
185
|
+
if(!rid) {
|
186
|
+
return false;
|
187
|
+
}
|
188
|
+
let prevSegmentId = this._shared.childToSegment[rid];
|
189
|
+
if(prevSegmentId) {
|
190
|
+
if(prevSegmentId !== this._rid) {
|
191
|
+
let prevSegment = this._shared.segments[prevSegmentId];
|
192
|
+
if(prevSegment && !prevSegment.hasSubSegments()) { // Children of a classified segment always stick the root segment
|
193
|
+
prevSegment.removeChild(rid);
|
194
|
+
}
|
195
|
+
this._shared.childToSegment[rid] = this._rid;
|
196
|
+
}
|
197
|
+
} else {
|
184
198
|
this._shared.childToSegment[rid] = this._rid;
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
199
|
+
}
|
200
|
+
|
201
|
+
if(dataId != null) { // Update data id
|
202
|
+
if(dataId && dataId !== rid) {
|
203
|
+
if(!this._childDataIds) {
|
204
|
+
this._childDataIds = {};
|
190
205
|
}
|
191
|
-
this.
|
192
|
-
|
193
|
-
|
206
|
+
this._childDataIds[rid] = dataId;
|
207
|
+
} else if(this._childDataIds) {
|
208
|
+
delete this._childDataIds[rid];
|
194
209
|
}
|
195
210
|
}
|
211
|
+
|
212
|
+
let at = this._childIds.indexOf(rid);
|
213
|
+
if(at < 0) {
|
214
|
+
if(this._collapsed) {
|
215
|
+
this._shared.dirtyCollapsingState = true; // TODO: Check if we need to update this only when new child is added
|
216
|
+
}
|
217
|
+
this._childIds.push(rid);
|
218
|
+
return true;
|
219
|
+
}
|
196
220
|
return false;
|
197
221
|
};
|
198
222
|
/** @public
|
@@ -201,8 +225,15 @@ Segment.prototype.addChild = function(rid, dataId) {
|
|
201
225
|
* @return {boolean}
|
202
226
|
*/
|
203
227
|
Segment.prototype.addChildren = function(rids, dataIds) {
|
228
|
+
if(!rids) {
|
229
|
+
return false;
|
230
|
+
}
|
204
231
|
let rowIds = Array.isArray(rids) ? rids : [rids];
|
205
232
|
let rowCount = rowIds.length;
|
233
|
+
if(!rowCount) {
|
234
|
+
return false;
|
235
|
+
}
|
236
|
+
|
206
237
|
let dirty = 0;
|
207
238
|
let i;
|
208
239
|
if(dataIds != null) {
|
@@ -222,27 +253,35 @@ Segment.prototype.addChildren = function(rids, dataIds) {
|
|
222
253
|
* @return {boolean}
|
223
254
|
*/
|
224
255
|
Segment.prototype.containsChild = function(rid) {
|
225
|
-
return this.
|
256
|
+
return this._childIds.indexOf(rid) >= 0;
|
257
|
+
};
|
258
|
+
/** @public
|
259
|
+
* @param {string} rid
|
260
|
+
* @return {number}
|
261
|
+
*/
|
262
|
+
Segment.prototype.getChildIndex = function(rid) {
|
263
|
+
return this._childIds.indexOf(rid);
|
226
264
|
};
|
227
265
|
/** @public
|
228
266
|
* @param {string} rid
|
229
267
|
* @return {boolean}
|
230
268
|
*/
|
231
269
|
Segment.prototype.removeChild = function(rid) {
|
232
|
-
if(this.
|
270
|
+
if(this._subSegment) {
|
233
271
|
return false; // Sub segments are not allowed to remove its children
|
234
272
|
}
|
235
|
-
if(!this.
|
273
|
+
if(!this._childIds.length) {
|
236
274
|
return false;
|
237
275
|
}
|
238
|
-
|
276
|
+
let at = this._childIds.indexOf(rid);
|
277
|
+
if(at < 0) {
|
239
278
|
return false; // The specified rid is not a child of this segment
|
240
279
|
}
|
241
280
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
281
|
+
if(this._shared.childToSegment[rid] === this._rid) {
|
282
|
+
delete this._shared.childToSegment[rid];
|
283
|
+
}
|
284
|
+
this._childIds.splice(at, 1); // Slow
|
246
285
|
|
247
286
|
if(this._collapsed) {
|
248
287
|
this._shared.dirtyCollapsingState = true;
|
@@ -254,10 +293,10 @@ Segment.prototype.removeChild = function(rid) {
|
|
254
293
|
* @return {boolean}
|
255
294
|
*/
|
256
295
|
Segment.prototype.removeChildren = function(rids) {
|
257
|
-
if(this.
|
296
|
+
if(this._subSegment) {
|
258
297
|
return false; // Sub segments are not allowed to remove its children
|
259
298
|
}
|
260
|
-
if(!this.
|
299
|
+
if(!this._childIds.length) {
|
261
300
|
return false;
|
262
301
|
}
|
263
302
|
let rowIds = Array.isArray(rids) ? rids : [rids];
|
@@ -272,21 +311,24 @@ Segment.prototype.removeChildren = function(rids) {
|
|
272
311
|
* @return {boolean}
|
273
312
|
*/
|
274
313
|
Segment.prototype.removeAllChildren = function() {
|
275
|
-
if(this.
|
314
|
+
if(this._subSegment) {
|
276
315
|
return false; // Sub segments are not allowed to remove its children
|
277
316
|
}
|
278
|
-
|
317
|
+
let childCount = this._childIds.length;
|
318
|
+
if(!this._childIds.length) {
|
279
319
|
return false;
|
280
320
|
}
|
321
|
+
let segmentId = this._rid;
|
281
322
|
let objMap = this._shared.childToSegment;
|
282
|
-
let chdr = this.
|
283
|
-
for(let
|
284
|
-
|
285
|
-
|
323
|
+
let chdr = this._childIds;
|
324
|
+
for(let i = 0; i < childCount; ++i) {
|
325
|
+
let rid = chdr[i];
|
326
|
+
if(objMap[rid] === segmentId) {
|
327
|
+
delete objMap[rid];
|
286
328
|
}
|
287
329
|
}
|
288
|
-
this.
|
289
|
-
this.
|
330
|
+
this._childIds.length = 0;
|
331
|
+
this._childDataIds = null;
|
290
332
|
|
291
333
|
if(this._collapsed) {
|
292
334
|
this._shared.dirtyCollapsingState = true;
|
@@ -297,24 +339,41 @@ Segment.prototype.removeAllChildren = function() {
|
|
297
339
|
* @return {!Array.<string>}
|
298
340
|
*/
|
299
341
|
Segment.prototype.getChildIds = function() {
|
300
|
-
return this.
|
342
|
+
return this._childIds; // WARNING: Returns private members
|
301
343
|
};
|
302
344
|
/** @public
|
303
345
|
* @return {!Object}
|
304
346
|
*/
|
305
347
|
Segment.prototype.getChildren = function() {
|
306
|
-
|
348
|
+
let obj = {};
|
349
|
+
let chdr = this._childIds;
|
350
|
+
let childCount = chdr.length;
|
351
|
+
let dataIds = this._childDataIds || {};
|
352
|
+
for(let i = 0; i < childCount; ++i) {
|
353
|
+
let rid = chdr[i];
|
354
|
+
obj[rid] = dataIds[rid] || rid;
|
355
|
+
}
|
356
|
+
return obj;
|
307
357
|
};
|
308
358
|
/** @public
|
309
359
|
* @return {number}
|
310
360
|
*/
|
311
361
|
Segment.prototype.getChildCount = function() {
|
312
|
-
return this.
|
362
|
+
return this._childIds.length;
|
363
|
+
};
|
364
|
+
/** When a segment is not empty, the visibility of its content need to be updated.
|
365
|
+
* @public
|
366
|
+
*/
|
367
|
+
Segment.prototype.markCollapsingStateDirty = function() {
|
368
|
+
// A segment can have a child and/or autogenerated segment (subsegment) to not be considered as empty.
|
369
|
+
if(this._childIds.length || this._subSegDef) {
|
370
|
+
this._shared.dirtyCollapsingState = true;
|
371
|
+
}
|
313
372
|
};
|
314
373
|
|
315
374
|
|
316
375
|
/** @public
|
317
|
-
* @return {Array.<string>}
|
376
|
+
* @return {Array.<string>}
|
318
377
|
*/
|
319
378
|
Segment.prototype.getClassification = function() {
|
320
379
|
if(this._subSegDef) {
|
@@ -327,8 +386,8 @@ Segment.prototype.getClassification = function() {
|
|
327
386
|
* @return {boolean}
|
328
387
|
*/
|
329
388
|
Segment.prototype.setClassification = function(fields) {
|
330
|
-
if(this.
|
331
|
-
return false; //
|
389
|
+
if(this._subSegment) {
|
390
|
+
return false; // subsegment cannot be classified
|
332
391
|
}
|
333
392
|
let classifiers = null;
|
334
393
|
if(this._subSegDef) {
|
@@ -371,9 +430,8 @@ Segment.prototype.setClassification = function(fields) {
|
|
371
430
|
return true;
|
372
431
|
} else if(classifiers) { // Remove existing ones
|
373
432
|
this._subSegDef.classifiers = null;
|
374
|
-
this._subSegDef.subSegments = null;
|
375
433
|
// this._subSegDef.classifierChanged = true;
|
376
|
-
this._subSegDef = null; // WARNING: All
|
434
|
+
this._subSegDef = null; // WARNING: All subsegments remain existing
|
377
435
|
return true;
|
378
436
|
}
|
379
437
|
return false;
|
@@ -390,7 +448,7 @@ Segment.prototype.classify = function(rows) {
|
|
390
448
|
let segmentCount = segmentNames ? segmentNames.length : 0;
|
391
449
|
|
392
450
|
if(!segmentCount) {
|
393
|
-
if(this.
|
451
|
+
if(this._depth >= classifierCount) {
|
394
452
|
return false; // Current segment level is beyond existing classification level and this segment should already be removed
|
395
453
|
}
|
396
454
|
}
|
@@ -400,7 +458,7 @@ Segment.prototype.classify = function(rows) {
|
|
400
458
|
sharedObj.dirtyCollapsingState = true;
|
401
459
|
}
|
402
460
|
|
403
|
-
// Prepare existing
|
461
|
+
// Prepare existing subsegments for checking change in its members
|
404
462
|
let i;
|
405
463
|
let segmentName = "";
|
406
464
|
let nonExistenceGroups = {};
|
@@ -414,9 +472,8 @@ Segment.prototype.classify = function(rows) {
|
|
414
472
|
nonExistenceGroups[segmentName] = 1;
|
415
473
|
|
416
474
|
segment = segmentMap[segmentName];
|
417
|
-
if(segment.
|
418
|
-
segment.
|
419
|
-
segment._childCount = 0;
|
475
|
+
if(segment._childIds.length) { // Quick cleaning up
|
476
|
+
segment._childIds.length = 0;
|
420
477
|
}
|
421
478
|
if(segment._collapsed) {
|
422
479
|
sharedObj.dirtyCollapsingState = true;
|
@@ -424,20 +481,23 @@ Segment.prototype.classify = function(rows) {
|
|
424
481
|
}
|
425
482
|
}
|
426
483
|
|
427
|
-
// Loop through row children and assign them to their corresponding
|
428
|
-
let
|
484
|
+
// Loop through row children and assign them to their corresponding subsegment
|
485
|
+
let rootSegment = !this._subSegment;
|
486
|
+
let dataIds = this._childDataIds || {};
|
429
487
|
let rid;
|
430
|
-
let
|
431
|
-
|
488
|
+
let chdr = this._childIds;
|
489
|
+
let childCount = chdr.length;
|
490
|
+
if(this._depth < classifierCount && rows) {
|
432
491
|
if(!segmentMap) {
|
433
492
|
segmentMap = this._subSegMap = {};
|
434
493
|
segmentNames = this._subSegNames = [];
|
435
494
|
}
|
436
495
|
|
437
|
-
let classifier = classifiers[this.
|
496
|
+
let classifier = classifiers[this._depth];
|
438
497
|
|
439
|
-
for(
|
440
|
-
|
498
|
+
for(i = 0; i < childCount; ++i) {
|
499
|
+
rid = chdr[i];
|
500
|
+
let dataId = dataIds[rid] || rid;
|
441
501
|
let record = rows[dataId];
|
442
502
|
let val = record ? record[classifier] : null; // WARNING: row could already be removed
|
443
503
|
|
@@ -454,31 +514,34 @@ Segment.prototype.classify = function(rows) {
|
|
454
514
|
|
455
515
|
segment = segmentMap[segmentName];
|
456
516
|
if(!segment) { // New group is detected
|
457
|
-
|
517
|
+
let subSegId = this._rid + "/" + segmentName;
|
518
|
+
segment = new Segment(subSegId, sharedObj);
|
458
519
|
segment._subSegDef = this._subSegDef;
|
459
|
-
segment.
|
520
|
+
segment._subSegment = true; // this indicates that the segment is autogenerated (subsegment)
|
521
|
+
segment._depth = this._depth + 1;
|
460
522
|
segment._subSegName = segmentName;
|
461
523
|
segment._subSegVal = val;
|
462
|
-
|
524
|
+
sharedObj.childToSegment[subSegId] = this._rid; // WARNING: this will mix autogenerated rows with actual rows
|
463
525
|
|
464
526
|
segmentMap[segmentName] = segment;
|
465
527
|
segmentNames.push(segmentName);
|
466
528
|
|
467
529
|
this._dispatch("subSegmentAdded", {
|
468
|
-
"rid":
|
530
|
+
"rid": subSegId,
|
469
531
|
"segment": segment
|
470
532
|
});
|
471
533
|
}
|
472
534
|
|
473
535
|
segment.addChild(rid, dataId);
|
474
536
|
}
|
475
|
-
} else if(
|
476
|
-
for(
|
537
|
+
} else if(rootSegment) { // In case of no classification
|
538
|
+
for(i = 0; i < childCount; ++i) {
|
539
|
+
rid = chdr[i];
|
477
540
|
sharedObj.childToSegment[rid] = this._rid; // Relocate child in case of it has been moved to a non existence group
|
478
541
|
}
|
479
542
|
}
|
480
543
|
|
481
|
-
// Remove all
|
544
|
+
// Remove all subsegments with no members
|
482
545
|
if(removalCount > 0) {
|
483
546
|
if(removalCount >= segmentNames.length) {
|
484
547
|
segmentNames.length = 0;
|
@@ -506,7 +569,7 @@ Segment.prototype.classify = function(rows) {
|
|
506
569
|
}
|
507
570
|
}
|
508
571
|
|
509
|
-
// Sort and classify existing
|
572
|
+
// Sort and classify existing subsegments
|
510
573
|
segmentCount = segmentNames ? segmentNames.length : 0;
|
511
574
|
if(segmentCount) {
|
512
575
|
segmentNames.sort(Segment._subSegSortLogic);
|
@@ -516,22 +579,17 @@ Segment.prototype.classify = function(rows) {
|
|
516
579
|
}
|
517
580
|
}
|
518
581
|
|
519
|
-
// Collecting all
|
520
|
-
if(
|
521
|
-
if(
|
522
|
-
|
523
|
-
let subSegments = this._subSegDef.subSegments = [];
|
524
|
-
this.getAllSubSegments(subSegments);
|
525
|
-
subSegments.forEach(Segment._assignSubSegmentOrder);
|
526
|
-
} else {
|
527
|
-
this._subSegDef.subSegments = null;
|
528
|
-
}
|
529
|
-
// this._subSegDef.classifierChanged = false;
|
582
|
+
// Collecting all subsegments including all descendants and reassigning segment order.
|
583
|
+
if(rootSegment && this._subSegDef) {
|
584
|
+
if(segmentCount) {
|
585
|
+
this.calcSubSegmentOrder(0);
|
530
586
|
}
|
587
|
+
// this._subSegDef.classifierChanged = false;
|
531
588
|
}
|
532
589
|
return true;
|
533
590
|
};
|
534
|
-
/**
|
591
|
+
/** SubSegment implies being classified
|
592
|
+
* @public
|
535
593
|
* @return {boolean}
|
536
594
|
*/
|
537
595
|
Segment.prototype.hasSubSegments = function() {
|
@@ -540,21 +598,37 @@ Segment.prototype.hasSubSegments = function() {
|
|
540
598
|
}
|
541
599
|
return false;
|
542
600
|
};
|
543
|
-
/**
|
601
|
+
/** SubSegment implies autogenerated segment
|
602
|
+
* @public
|
544
603
|
* @return {boolean}
|
545
604
|
*/
|
546
605
|
Segment.prototype.isSubSegment = function() {
|
547
|
-
return this.
|
606
|
+
return this._subSegment;
|
607
|
+
};
|
608
|
+
/** @public
|
609
|
+
* @return {boolean}
|
610
|
+
*/
|
611
|
+
Segment.prototype.isRootSegment = function() {
|
612
|
+
return this._shared.childToSegment[this._rid] ? false : true;
|
548
613
|
};
|
549
614
|
/** @public
|
550
615
|
* @return {Segment}
|
551
616
|
*/
|
552
617
|
Segment.prototype.getFirstAncestor = function() {
|
553
|
-
|
554
|
-
|
555
|
-
|
618
|
+
let ancestor = null;
|
619
|
+
if(this._subSegment && this._subSegDef) { // Quick way to get root
|
620
|
+
ancestor = this._subSegDef.root;
|
621
|
+
} else { // Slow
|
622
|
+
ancestor = this.getParent();
|
623
|
+
if(ancestor) {
|
624
|
+
let parentSeg = ancestor.getParent();
|
625
|
+
while(parentSeg) { // This could cause infinite loop
|
626
|
+
ancestor = parentSeg;
|
627
|
+
parentSeg = ancestor.getParent();
|
628
|
+
}
|
629
|
+
}
|
556
630
|
}
|
557
|
-
return null;
|
631
|
+
return ancestor || null;
|
558
632
|
};
|
559
633
|
/** @public
|
560
634
|
* @param {Array.<Segment>=} out_ary
|
@@ -576,13 +650,75 @@ Segment.prototype.getAllSubSegments = function(out_ary) {
|
|
576
650
|
}
|
577
651
|
return out_ary || null;
|
578
652
|
};
|
653
|
+
/** This method sets order, last order, and depth to entire tree structure in the segment, including the segment itself
|
654
|
+
* @public
|
655
|
+
* @param {number} counter
|
656
|
+
* @return {number}
|
657
|
+
*/
|
658
|
+
Segment.prototype.updateTreeStructure = function(counter) {
|
659
|
+
if(!counter) {
|
660
|
+
counter = 0;
|
661
|
+
if(!this._subSegment) { // Subsegment's depth cannot be reset back to 0
|
662
|
+
this._depth = 0; // WARNING: this assumes counter at 0 is the root segment
|
663
|
+
}
|
664
|
+
}
|
665
|
+
if(this.hasSubSegments()) {
|
666
|
+
return this.setLastOrder(counter); // Sub segments has already been calculated
|
667
|
+
}
|
668
|
+
let segmentSeparators = this._shared.segments;
|
669
|
+
let childCount = this._childIds.length;
|
670
|
+
let prevSeg = null;
|
671
|
+
for(let i = 0; i < childCount; ++i) {
|
672
|
+
let rid = this._childIds[i];
|
673
|
+
let segment = segmentSeparators[rid];
|
674
|
+
let segmentId = (segment) ? segment.getId() : "Uncategorized";
|
675
|
+
if(prevSeg !== segmentId) {
|
676
|
+
++counter; // 0 become 1
|
677
|
+
prevSeg = segmentId;
|
678
|
+
}
|
679
|
+
if(segment) {
|
680
|
+
segment._depth = this._depth + 1;
|
681
|
+
segment.setOrder(counter);
|
682
|
+
counter = segment.updateTreeStructure(counter);
|
683
|
+
}
|
684
|
+
}
|
685
|
+
|
686
|
+
return this.setLastOrder(counter);
|
687
|
+
};
|
688
|
+
/** @public
|
689
|
+
* @param {number} counter
|
690
|
+
* @return {number}
|
691
|
+
*/
|
692
|
+
Segment.prototype.calcSubSegmentOrder = function(counter) {
|
693
|
+
if(!this.hasSubSegments()) {
|
694
|
+
return this.setLastOrder(counter);
|
695
|
+
}
|
696
|
+
|
697
|
+
let segmentMap = this._subSegMap;
|
698
|
+
let childCount = this._subSegNames.length;
|
699
|
+
let prevSeg = null;
|
700
|
+
for(let i = 0; i < childCount; ++i) {
|
701
|
+
let segmentName = this._subSegNames[i];
|
702
|
+
let segment = segmentMap[segmentName];
|
703
|
+
let segmentId = (segment) ? segment.getId() : "Uncategorized";
|
704
|
+
if(prevSeg !== segmentId) {
|
705
|
+
++counter; // 0 become 1
|
706
|
+
prevSeg = segmentId;
|
707
|
+
}
|
708
|
+
if(segment) {
|
709
|
+
segment.setOrder(counter);
|
710
|
+
counter = segment.calcSubSegmentOrder(counter);
|
711
|
+
}
|
712
|
+
}
|
713
|
+
return this.setLastOrder(counter);
|
714
|
+
};
|
579
715
|
/** @public
|
580
716
|
* @return {number}
|
581
717
|
*/
|
582
718
|
Segment.prototype.getSegmentLevel = function() {
|
583
|
-
return this.
|
719
|
+
return this._depth;
|
584
720
|
};
|
585
|
-
/** This method will be called on
|
721
|
+
/** This method will be called on subsegments only
|
586
722
|
* @public
|
587
723
|
* @param {Object=} rows
|
588
724
|
* @param {Object=} clsSource
|
@@ -607,7 +743,7 @@ Segment.prototype.setRowData = function(rows, clsSource) {
|
|
607
743
|
let segment = this;
|
608
744
|
while(segment && segment.isSubSegment()) {
|
609
745
|
segment.getSubSegmentName(row);
|
610
|
-
segment = segment.
|
746
|
+
segment = segment.getParent();
|
611
747
|
}
|
612
748
|
};
|
613
749
|
/** @public
|
@@ -615,9 +751,9 @@ Segment.prototype.setRowData = function(rows, clsSource) {
|
|
615
751
|
* @return {string}
|
616
752
|
*/
|
617
753
|
Segment.prototype.getSubSegmentName = function(row) {
|
618
|
-
if(row && this.
|
754
|
+
if(row && this._subSegment) {
|
619
755
|
let classifiers = this.getClassification();
|
620
|
-
let field = classifiers[this.
|
756
|
+
let field = classifiers[this._depth - 1];
|
621
757
|
if(field) {
|
622
758
|
row[field] = this._subSegName;
|
623
759
|
}
|
@@ -633,9 +769,7 @@ Segment.prototype.collapse = function(bool) {
|
|
633
769
|
bool = (bool !== false);
|
634
770
|
if(this._collapsed !== bool) {
|
635
771
|
this._collapsed = bool;
|
636
|
-
|
637
|
-
this._shared.dirtyCollapsingState = true;
|
638
|
-
}
|
772
|
+
this.markCollapsingStateDirty();
|
639
773
|
return true;
|
640
774
|
}
|
641
775
|
return false;
|
@@ -653,82 +787,87 @@ Segment.prototype.expand = function(bool) {
|
|
653
787
|
Segment.prototype.isCollapsed = function() {
|
654
788
|
return this._collapsed;
|
655
789
|
};
|
656
|
-
/**
|
790
|
+
/** Get all collapsing state from all children (subsegments and child segments), excluding the segment itself
|
791
|
+
* @public
|
657
792
|
* @param {Object=} objMap
|
658
793
|
* @param {boolean=} parentState=false Collapsing state from parent segment
|
659
794
|
* @return {boolean}
|
660
795
|
*/
|
661
796
|
Segment.prototype.getCollapsingStates = function(objMap, parentState) {
|
662
|
-
let
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
797
|
+
let childList = this._subSegNames;
|
798
|
+
let segmentMap = this._subSegMap;
|
799
|
+
let subSegment = true; // Normal segments can have subsegments without being subsegment themselve
|
800
|
+
if(!childList && this._shared) { // Ensure that segment has not been disposed
|
801
|
+
childList = this._childIds;
|
802
|
+
segmentMap = this._shared.segments;
|
803
|
+
subSegment = false;
|
804
|
+
}
|
805
|
+
let childCount = childList ? childList.length : 0;
|
806
|
+
if(!childCount) {
|
807
|
+
return false;
|
669
808
|
}
|
670
809
|
|
810
|
+
let dirty = false;
|
811
|
+
let childCollapsed = (parentState || this._collapsed) ? true : false;
|
812
|
+
|
671
813
|
if(!objMap) {
|
672
814
|
objMap = {};
|
673
815
|
}
|
674
|
-
let
|
675
|
-
|
676
|
-
|
677
|
-
|
816
|
+
for(let i = 0; i < childCount; ++i) {
|
817
|
+
let rid = "";
|
818
|
+
let segment = null;
|
819
|
+
if(subSegment) {
|
820
|
+
segment = segmentMap[childList[i]]; // Use segment name to retrieve subsegment
|
821
|
+
rid = segment.getId();
|
822
|
+
} else {
|
823
|
+
rid = childList[i];
|
824
|
+
segment = segmentMap[rid]; // Use row id to retrieve segment from shared map
|
825
|
+
}
|
826
|
+
if(childCollapsed) {
|
827
|
+
objMap[rid] = childCollapsed; // Collapsing states for all children is registered here
|
678
828
|
dirty = true;
|
679
829
|
}
|
680
|
-
|
681
|
-
if(this._childCount) {
|
682
|
-
let collapsed = parentState || this._collapsed;
|
683
|
-
if(segmentNames) {
|
684
|
-
let segmentMap = this._subSegMap;
|
685
|
-
let segmentCount = segmentNames.length;
|
686
|
-
for(let i = 0; i < segmentCount; ++i) {
|
687
|
-
let segment = segmentMap[segmentNames[i]];
|
688
|
-
objMap[segment.getId()] = !!parentState;
|
689
|
-
if(segment.getCollapsingStates(objMap, collapsed)) {
|
690
|
-
dirty = true;
|
691
|
-
}
|
692
|
-
}
|
693
|
-
} else if(collapsed) {
|
694
|
-
let chdr = this._children;
|
695
|
-
for(let rid in chdr) {
|
696
|
-
objMap[rid] = collapsed;
|
697
|
-
}
|
830
|
+
if(segment && segment.getCollapsingStates(objMap, childCollapsed)) {
|
698
831
|
dirty = true;
|
699
832
|
}
|
700
833
|
}
|
701
834
|
return dirty;
|
702
835
|
};
|
703
836
|
|
837
|
+
/** @private
|
838
|
+
* @return {number}
|
839
|
+
*/
|
840
|
+
Segment.prototype._getOrder = function() {
|
841
|
+
return this._order * 10000;
|
842
|
+
};
|
843
|
+
/** @private
|
844
|
+
* @return {number}
|
845
|
+
*/
|
846
|
+
Segment.prototype._getLastOrder = function() {
|
847
|
+
return this._getOrder() + this._offsetOrder;
|
848
|
+
};
|
704
849
|
/** @public
|
705
850
|
* @return {number}
|
706
851
|
*/
|
707
852
|
Segment.prototype.getOrder = function() {
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
return ancestor.getOrder() + this._order;
|
713
|
-
}
|
853
|
+
let ancestor = this.getFirstAncestor();
|
854
|
+
if(ancestor) {
|
855
|
+
// WARNING: this._order cannot be greater than 9999
|
856
|
+
return ancestor._getOrder() + this._order;
|
714
857
|
}
|
715
|
-
return this.
|
858
|
+
return this._getOrder();
|
716
859
|
};
|
717
860
|
/** Get the last (highest) order from the entire tree regardless of the current position segment in the hierachy
|
718
861
|
* @public
|
719
862
|
* @return {number}
|
720
863
|
*/
|
721
864
|
Segment.prototype.getLastOrder = function() {
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
if(lastSegment) {
|
727
|
-
return lastSegment.getOrder();
|
728
|
-
}
|
729
|
-
}
|
865
|
+
let ancestor = this.getFirstAncestor();
|
866
|
+
if(ancestor) {
|
867
|
+
// WARNING: this._order cannot be greater than 9999
|
868
|
+
return ancestor._getLastOrder();
|
730
869
|
}
|
731
|
-
return this.
|
870
|
+
return this._getLastOrder();
|
732
871
|
};
|
733
872
|
/** @public
|
734
873
|
* @param {number} val
|
@@ -736,6 +875,13 @@ Segment.prototype.getLastOrder = function() {
|
|
736
875
|
Segment.prototype.setOrder = function(val) {
|
737
876
|
this._order = val;
|
738
877
|
};
|
878
|
+
/** @public
|
879
|
+
* @param {number} val
|
880
|
+
* @returns {number} Returns the number set
|
881
|
+
*/
|
882
|
+
Segment.prototype.setLastOrder = function(val) {
|
883
|
+
return (this._offsetOrder = val);
|
884
|
+
};
|
739
885
|
|
740
886
|
/** @private
|
741
887
|
* @type {Array.<string>}
|
@@ -743,9 +889,10 @@ Segment.prototype.setOrder = function(val) {
|
|
743
889
|
Segment._tabs = null;
|
744
890
|
/** @public
|
745
891
|
* @param {Array.<string>=} lines
|
892
|
+
* @param {number=} tabLevel
|
746
893
|
* @return {!Array.<string>} lines
|
747
894
|
*/
|
748
|
-
Segment.prototype.log = function(lines) {
|
895
|
+
Segment.prototype.log = function(lines, tabLevel) {
|
749
896
|
if(!lines) {
|
750
897
|
lines = [];
|
751
898
|
}
|
@@ -760,23 +907,43 @@ Segment.prototype.log = function(lines) {
|
|
760
907
|
tabCh += " ";
|
761
908
|
}
|
762
909
|
}
|
910
|
+
if(!tabLevel) {
|
911
|
+
tabLevel = 0;
|
912
|
+
}
|
913
|
+
|
763
914
|
let collapsedCh = this._collapsed ? "+ " : "- ";
|
764
|
-
lines.push(tabs[
|
915
|
+
lines.push(tabs[tabLevel] + collapsedCh + this._rid);
|
765
916
|
|
766
|
-
let
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
917
|
+
let childLevel = tabLevel + 1;
|
918
|
+
let childIndent = tabs[childLevel];
|
919
|
+
|
920
|
+
let childList = this._subSegNames;
|
921
|
+
let segmentMap = this._subSegMap;
|
922
|
+
let subSegment = true; // Normal segments can have subsegments without being subsegment themselve
|
923
|
+
if(!childList && this._shared) { // Ensure that segment has not been disposed
|
924
|
+
childList = this._childIds;
|
925
|
+
segmentMap = this._shared.segments;
|
926
|
+
subSegment = false;
|
927
|
+
}
|
928
|
+
let childCount = childList ? childList.length : 0;
|
929
|
+
|
930
|
+
for(i = 0; i < childCount; ++i) {
|
931
|
+
let rid = "";
|
932
|
+
let segment = null;
|
933
|
+
if(subSegment) {
|
934
|
+
segment = segmentMap[childList[i]]; // Use segment name to retrieve subsegment
|
935
|
+
rid = segment.getId();
|
936
|
+
} else {
|
937
|
+
rid = childList[i];
|
938
|
+
segment = segmentMap[rid]; // Use row id to retrieve segment from shared map
|
772
939
|
}
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
940
|
+
|
941
|
+
if(segment) {
|
942
|
+
segment.log(lines, childLevel);
|
943
|
+
} else {
|
944
|
+
lines.push(childIndent + "- " + rid);
|
777
945
|
}
|
778
946
|
}
|
779
|
-
|
780
947
|
return lines;
|
781
948
|
};
|
782
949
|
|