canvas-datagrid 0.3.25 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/intf.js CHANGED
@@ -57,6 +57,33 @@ export default function (self, ctor) {
57
57
  self.scrollBox = {};
58
58
  self.visibleRows = [];
59
59
  self.visibleCells = [];
60
+ /**
61
+ * Each item of this array contains these properties:
62
+ * - `x`, `y`, `x2`, `y2`
63
+ * - `orderIndex0`, `orderIndex1`: The closed interval of the hiding rows/columns.
64
+ * - `dir`: The directon of the unhide indicator. 'l' and 'r' for columns, 't' and 'b' for rows
65
+ */
66
+ self.visibleUnhideIndicators = [];
67
+ /**
68
+ * Each item is a tuple conatins two numbers:
69
+ * its type difination: Array<[beginRowIndex, endRowIndex]>
70
+ * Each tuple represents a closed Interval
71
+ */
72
+ self.hiddenRowRanges = [];
73
+ /**
74
+ * This array stored all groups information with context for drawing,
75
+ * it is generated by drawing functions,
76
+ * and be used for searching groups when users operate on the spreadsheet
77
+ * Each item of this array contains these properties:
78
+ * - `type`: its available values: 'c' and 'r'. indicates the type of this item, 'c' for column group
79
+ * and 'r' for row group.
80
+ * - `x`,`y`: the left-top point of this group's rendering area.
81
+ * - `x2`, `y2`: the right-bottom of this group's rendering area.
82
+ * - `collapsed`: this value indicates the collapsed status of this group.
83
+ * - `from`, `to`: The column index range of this group (We use this value for searching the group)
84
+ * - `row`: The row index for column groups (We use this value for searching the group)
85
+ */
86
+ self.visibleGroups = [];
60
87
  self.sizes = {
61
88
  rows: {},
62
89
  columns: {},
@@ -71,6 +98,18 @@ export default function (self, ctor) {
71
98
  columnIndex: -1,
72
99
  rowIndex: -1,
73
100
  };
101
+ self.cellTree = {
102
+ rows: [],
103
+ columns: {},
104
+ tempSchema: {},
105
+ rowTreeColIndex: 0,
106
+ columnTreeRowStartIndex: 0,
107
+ columnTreeRowEndIndex: 0,
108
+ origin: {
109
+ rows: [],
110
+ columns: {},
111
+ },
112
+ };
74
113
  self.hovers = {};
75
114
  self.attributes = {};
76
115
  self.style = {};
@@ -86,6 +125,29 @@ export default function (self, ctor) {
86
125
  self.scrollPixelLeft = 0;
87
126
  self.childGrids = {};
88
127
  self.openChildren = {};
128
+
129
+ /**
130
+ * Array for grouped columns
131
+ * Each item in this array is an array and it represents some grouping in one row
132
+ * A grouping descriptor has three properties:
133
+ * - `from`: The column index of the first column
134
+ * - `to`: The column index of the last column
135
+ * - `collapsed`: Is this group be collapsed
136
+ * @example [[{ from: 1, to: 2, collapsed: false }]]
137
+ */
138
+ self.groupedColumns = [];
139
+
140
+ /**
141
+ * Array for grouped rows
142
+ * Each item in this array is an array and it represents some grouping in one column
143
+ * A grouping descriptor has three properties:
144
+ * - `from`: The row index of the first row
145
+ * - `to`: The row index of the last row
146
+ * - `collapsed`: Is this group be collapsed
147
+ * @example [[{ from: 1, to: 2, collapsed: false }]]
148
+ */
149
+ self.groupedRows = [];
150
+
89
151
  self.scrollModes = [
90
152
  'vertical-scroll-box',
91
153
  'vertical-scroll-top',
@@ -99,6 +161,7 @@ export default function (self, ctor) {
99
161
  'afterdraw',
100
162
  'afterrendercell',
101
163
  'afterrenderfilterbutton',
164
+ 'aftercreategroup',
102
165
  'attributechanged',
103
166
  'beforebeginedit',
104
167
  'beforecreatecellgrid',
@@ -314,7 +377,7 @@ export default function (self, ctor) {
314
377
  );
315
378
  const columnName = schema[boundColumnIndex].name;
316
379
 
317
- self.viewData[boundRowIndex][columnName] = '';
380
+ self.originalData[boundRowIndex][columnName] = '';
318
381
 
319
382
  affectedCells.push([
320
383
  rowIndex,
@@ -337,6 +400,124 @@ export default function (self, ctor) {
337
400
  self.getBoundColumnIndexFromViewColumnIndex = function (viewColumnIndex) {
338
401
  return self.orders.columns[viewColumnIndex];
339
402
  };
403
+ /**
404
+ * Get the height of the area about column groups for rendering and handling events.
405
+ */
406
+ self.getColumnGroupAreaHeight = function () {
407
+ if (!self.attributes.allowGroupingColumns) {
408
+ return 0;
409
+ }
410
+ const groups = self.groupedColumns.length;
411
+ const base = self.style.columnGroupRowHeight * self.scale;
412
+ return base * groups;
413
+ };
414
+ /**
415
+ * Get the width of the area about row groups for rendering and handling events.
416
+ */
417
+ self.getRowGroupAreaWidth = function () {
418
+ if (!self.attributes.allowGroupingRows) {
419
+ return 0;
420
+ }
421
+ const groups = self.groupedRows.length;
422
+ const base = self.style.rowGroupColumnWidth * self.scale;
423
+ return base * groups;
424
+ };
425
+ self.getCollapsedColumnGroups = function () {
426
+ const result = [];
427
+ for (let rowIndex = 0; rowIndex < self.groupedColumns.length; rowIndex++) {
428
+ const groups = self.groupedColumns[rowIndex];
429
+ for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
430
+ const group = groups[groupIndex];
431
+ if (group.collapsed) result.push(group);
432
+ }
433
+ }
434
+ return result;
435
+ };
436
+ self.getCollapsedRowGroups = function () {
437
+ const result = [];
438
+ for (let rowIndex = 0; rowIndex < self.groupedRows.length; rowIndex++) {
439
+ const groups = self.groupedRows[rowIndex];
440
+ for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
441
+ const group = groups[groupIndex];
442
+ if (group.collapsed) result.push(group);
443
+ }
444
+ }
445
+ return result;
446
+ };
447
+ /**
448
+ * Toggle the collapse status of a group (expanded/collapsed)
449
+ * @param {{type:string,from:number,to:number}} group
450
+ */
451
+ self.toggleGroup = function (group) {
452
+ if (group.type === 'c') {
453
+ const { from, to } = group;
454
+ /** @type {{from:number,to:number,collapsed:boolean}} */
455
+ let matchedGroup;
456
+ /** @type {Array<Array<{from:number,to:number,collapsed:boolean}>>} */
457
+ const allGroups = self.groupedColumns;
458
+ for (let i = 0; i < allGroups.length; i++) {
459
+ const groups = allGroups[i];
460
+ for (let gi = 0; gi < groups.length; gi++) {
461
+ const group = groups[gi];
462
+ if (group.from === from && group.to === to) {
463
+ matchedGroup = group;
464
+ break;
465
+ }
466
+ }
467
+ if (matchedGroup) break;
468
+ }
469
+ if (!matchedGroup) return;
470
+ const nextCollapsed = !matchedGroup.collapsed;
471
+ matchedGroup.collapsed = nextCollapsed;
472
+ return true;
473
+ }
474
+ if (group.type === 'r') {
475
+ const { from, to } = group;
476
+ /** @type {{from:number,to:number,collapsed:boolean}} */
477
+ let matchedGroup;
478
+ /** @type {Array<Array<{from:number,to:number,collapsed:boolean}>>} */
479
+ const allGroups = self.groupedRows;
480
+ for (let i = 0; i < allGroups.length; i++) {
481
+ const groups = allGroups[i];
482
+ for (let gi = 0; gi < groups.length; gi++) {
483
+ const group = groups[gi];
484
+ if (group.from === from && group.to === to) {
485
+ matchedGroup = group;
486
+ break;
487
+ }
488
+ }
489
+ if (matchedGroup) break;
490
+ }
491
+ if (!matchedGroup) return;
492
+ const nextCollapsed = !matchedGroup.collapsed;
493
+ matchedGroup.collapsed = nextCollapsed;
494
+ return true;
495
+ }
496
+ return false;
497
+ };
498
+ self.isNewGroupRangeValid = function (groupsArray, from, to) {
499
+ for (let i = 0; i < groupsArray.length; i++) {
500
+ const groups = groupsArray[i];
501
+ for (let gIndex = 0; gIndex < groups.length; gIndex++) {
502
+ const group = groups[gIndex];
503
+ if (from === group.to + 1) return false;
504
+ if (from > group.to) continue;
505
+
506
+ if (from === group.from) {
507
+ if (to === group.to) return false;
508
+ if (to > group.to) return true;
509
+ break; // check smaller range
510
+ }
511
+ if (from > group.from) {
512
+ if (to > group.to) return false;
513
+ break; // check smaller range
514
+ }
515
+ if (to < group.to) return false;
516
+ return true;
517
+ }
518
+ }
519
+ return true;
520
+ };
340
521
  self.getColumnHeaderCellHeight = function () {
341
522
  if (!self.attributes.showColumnHeaders) {
342
523
  return 0;
@@ -464,6 +645,16 @@ export default function (self, ctor) {
464
645
  self.hasActiveFilters = function () {
465
646
  return self.columnFilters && Object.keys(self.columnFilters).length > 0;
466
647
  };
648
+ self.hasCollapsedRowGroup = function () {
649
+ for (let i = 0; i < self.groupedRows.length; i++) {
650
+ const groups = self.groupedRows[i];
651
+ for (let j = 0; j < groups.length; j++) {
652
+ const g = groups[j];
653
+ if (g.collapsed) return true;
654
+ }
655
+ }
656
+ return false;
657
+ };
467
658
  self.getFilteredAndSortedViewData = function (originalData) {
468
659
  // We make a copy of originalData here in order be able to
469
660
  // filter and sort rows without modifying the original array.
@@ -476,6 +667,16 @@ export default function (self, ctor) {
476
667
  originalRowIndex,
477
668
  ]);
478
669
 
670
+ // Remove hidden rows here. So we can keep the bound indexes correct
671
+ if (self.hiddenRowRanges.length > 0) {
672
+ const ranges = self.hiddenRowRanges.sort((a, b) => b[1] - a[1]);
673
+ for (let i = 0; i < ranges.length; i++) {
674
+ const [beginRowIndex, endRowIndex] = ranges[i];
675
+ const countOfRows = endRowIndex - beginRowIndex + 1;
676
+ newViewData.splice(beginRowIndex, countOfRows);
677
+ }
678
+ }
679
+
479
680
  // Apply filtering
480
681
  for (const [headerName, filterText] of Object.entries(self.columnFilters)) {
481
682
  const header = self.getHeaderByName(headerName);
@@ -499,6 +700,59 @@ export default function (self, ctor) {
499
700
  });
500
701
  }
501
702
 
703
+ //#region Hide rows from collapsed group
704
+ /** @type {number[][]} */
705
+ let collapsedGroups = [];
706
+ for (let i = 0; i < self.groupedRows.length; i++) {
707
+ const rows = self.groupedRows[i];
708
+ for (let j = 0; j < rows.length; j++) {
709
+ const r = rows[j];
710
+ if (!r.collapsed) continue;
711
+ collapsedGroups.push([r.from, r.to]);
712
+ }
713
+ }
714
+ if (collapsedGroups.length > 0) {
715
+ //#region merge groups
716
+ collapsedGroups.sort((a, b) => a[0] - b[0]);
717
+ let newLen = 0;
718
+ const len = collapsedGroups.length;
719
+ for (let i = 0; i < len; i++) {
720
+ const r = collapsedGroups[i];
721
+ if (i === len - 1) {
722
+ collapsedGroups[newLen++] = r;
723
+ break;
724
+ }
725
+ const to = r[1];
726
+ const [from2, to2] = collapsedGroups[i + 1];
727
+ if (from2 > to + 1) {
728
+ collapsedGroups[newLen++] = r;
729
+ continue;
730
+ }
731
+ collapsedGroups[i + 1] = r;
732
+ if (to2 > to) collapsedGroups[i + 1][1] = to2;
733
+ }
734
+ collapsedGroups = collapsedGroups.slice(0, newLen);
735
+ //#endregion merge groups
736
+
737
+ //#region omit rows by groups
738
+ let g = collapsedGroups.shift();
739
+ for (let start = 0; start < newViewData.length; start++) {
740
+ const it = newViewData[start][1];
741
+ if (it < g[0]) continue;
742
+ let end = start + 1;
743
+ for (; end < newViewData.length; end++) {
744
+ const it2 = newViewData[end][1];
745
+ if (it2 > g[1]) break;
746
+ }
747
+ newViewData.splice(start, end - start);
748
+ g = collapsedGroups.shift();
749
+ if (!g) break;
750
+ start--;
751
+ }
752
+ //#endregion omit rows by groups
753
+ }
754
+ //#endregion Hide rows from collapsed group
755
+
502
756
  // Apply sorting
503
757
  for (const column of self.orderings.columns) {
504
758
  const sortFn = column.sortFunction(column.orderBy, column.orderDirection);
@@ -703,6 +957,340 @@ export default function (self, ctor) {
703
957
  }
704
958
  }
705
959
  };
960
+ self.toggleCollapseTree = function (rowIndex, columnIndex, type) {
961
+ let tempData = [];
962
+ let collapsedCount = 0;
963
+ if (
964
+ columnIndex == self.cellTree.rowTreeColIndex &&
965
+ (rowIndex > 0 || (rowIndex == 0 && self.cellTree.rows[0].icon))
966
+ ) {
967
+ let ctr = self.cellTree.rows;
968
+ switch (type) {
969
+ case 'Expand':
970
+ ctr[rowIndex].expand = true;
971
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand = true;
972
+ break;
973
+
974
+ case 'Collapse':
975
+ ctr[rowIndex].expand = false;
976
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand = false;
977
+ break;
978
+
979
+ default:
980
+ ctr[rowIndex].expand = !ctr[rowIndex].expand;
981
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand =
982
+ ctr[rowIndex].expand;
983
+ }
984
+ for (
985
+ let ri = ctr[rowIndex].index + 1;
986
+ ri <= ctr[rowIndex].lastchild;
987
+ ri++
988
+ ) {
989
+ let orTree = self.cellTree.origin.rows[ri];
990
+ if (ctr[rowIndex].expand) {
991
+ orTree.hide = false;
992
+ if (orTree.icon && !orTree.expand) ri = orTree.lastchild;
993
+ } else {
994
+ orTree.hide = true;
995
+ }
996
+ }
997
+ } else if (self.cellTree.columns[rowIndex]) {
998
+ let ctc = self.cellTree.columns[rowIndex];
999
+
1000
+ switch (type) {
1001
+ case 'Expand':
1002
+ ctc[columnIndex].expand = true;
1003
+ break;
1004
+
1005
+ case 'Collapse':
1006
+ ctc[columnIndex].expand = false;
1007
+ break;
1008
+
1009
+ default:
1010
+ ctc[columnIndex].expand = !ctc[columnIndex].expand;
1011
+ }
1012
+ for (
1013
+ let ci = ctc[columnIndex].index + 1;
1014
+ ci <= ctc[columnIndex].lastchild;
1015
+ ci++
1016
+ ) {
1017
+ if (ctc[columnIndex].expand)
1018
+ self.cellTree.tempSchema[ci].hidden = false;
1019
+ else self.cellTree.tempSchema[ci].hidden = true;
1020
+ }
1021
+ let rc = 0,
1022
+ _ri;
1023
+
1024
+ if (ctc[columnIndex].expand) {
1025
+ while (rc < ctc[columnIndex].child) {
1026
+ _ri = rowIndex + rc + 1;
1027
+
1028
+ for (
1029
+ let _ci = ctc[columnIndex].index;
1030
+ _ci <= ctc[columnIndex].lastchild;
1031
+ _ci++
1032
+ ) {
1033
+ if (
1034
+ self.cellTree.origin.columns[_ri] &&
1035
+ self.cellTree.origin.columns[_ri][_ci].icon &&
1036
+ !self.cellTree.origin.columns[_ri][_ci].expand
1037
+ ) {
1038
+ for (
1039
+ let si = _ci + 1;
1040
+ si <= self.cellTree.origin.columns[_ri][_ci].lastchild;
1041
+ si++
1042
+ ) {
1043
+ self.cellTree.tempSchema[si].hidden = true;
1044
+ }
1045
+ }
1046
+ }
1047
+
1048
+ rc++;
1049
+ }
1050
+ }
1051
+ }
1052
+ let otherData = {};
1053
+ let collapsed = [];
1054
+ self.cellTree.rows = [];
1055
+ self.cellTree.columns = {};
1056
+ for (let k in self.cellTree.origin.rows) {
1057
+ let tempRow = [];
1058
+ let tree = self.cellTree.origin.rows[k];
1059
+ if (!tree.hide) {
1060
+ let colTrees = [];
1061
+ let collapsedColCount = 0;
1062
+ if (k < self.cellTree.columnTreeRowStartIndex) {
1063
+ tempData.push(self.originalData[k]);
1064
+ } else {
1065
+ if (k > self.cellTree.columnTreeRowEndIndex) {
1066
+ otherData[k] = self.viewData[k];
1067
+ collapsedCount++;
1068
+ } else {
1069
+ for (let l = 0; l < self.originalData[k].length; l++) {
1070
+ if (!self.cellTree.tempSchema[l].hidden) {
1071
+ if (l < self.cellTree.rowTreeColIndex) {
1072
+ if (!Object.prototype.hasOwnProperty.call(otherData, k))
1073
+ otherData[k] = [];
1074
+ otherData[k].push(self.viewData[k][l]);
1075
+ }
1076
+ tempRow.push(self.originalData[k][l]);
1077
+ if (
1078
+ Object.prototype.hasOwnProperty.call(
1079
+ self.cellTree.origin.columns,
1080
+ k,
1081
+ )
1082
+ )
1083
+ colTrees.push(self.cellTree.origin.columns[k][l]);
1084
+ } else collapsedColCount++;
1085
+ }
1086
+ tempRow.push(
1087
+ ...Array(collapsedColCount)
1088
+ .fill()
1089
+ .map(function () {
1090
+ return '';
1091
+ }),
1092
+ );
1093
+ if (colTrees.length) {
1094
+ colTrees.push(
1095
+ ...Array(collapsedColCount)
1096
+ .fill()
1097
+ .map(() => {
1098
+ return {};
1099
+ }),
1100
+ );
1101
+ self.cellTree.columns[k] = colTrees;
1102
+ }
1103
+ tempData.push(tempRow);
1104
+ }
1105
+ }
1106
+ self.cellTree.rows.push(tree);
1107
+ } else {
1108
+ for (let l = 0; l < self.cellTree.rowTreeColIndex; l++) {
1109
+ tempRow.push(self.viewData[k][l]);
1110
+ }
1111
+ otherData[k] = tempRow;
1112
+ collapsed.push(
1113
+ Array(self.viewData[0].length)
1114
+ .fill()
1115
+ .map(function () {
1116
+ return '';
1117
+ }),
1118
+ );
1119
+ collapsedCount++;
1120
+ }
1121
+ }
1122
+ if (collapsedCount) {
1123
+ self.cellTree.rows.push(
1124
+ ...Array(collapsedCount)
1125
+ .fill()
1126
+ .map((u, index) => {
1127
+ return { index: self.cellTree.rows.length + index };
1128
+ }),
1129
+ );
1130
+ tempData.push(...collapsed);
1131
+ }
1132
+ for (let k in otherData) {
1133
+ if (k > self.cellTree.columnTreeRowEndIndex) tempData[k] = otherData[k];
1134
+ else
1135
+ for (let l in otherData[k]) {
1136
+ tempData[k][l] = otherData[k][l];
1137
+ }
1138
+ }
1139
+ self.viewData = tempData;
1140
+ };
1141
+ self.cellTreeExpandCollapse = function (rowIndex, columnIndex, type) {
1142
+ if (
1143
+ columnIndex == self.cellTree.rowTreeColIndex &&
1144
+ (rowIndex > 0 || (rowIndex == 0 && self.cellTree.rows[0].icon))
1145
+ ) {
1146
+ const ctr = self.cellTree.rows;
1147
+ switch (type) {
1148
+ case 'Expand':
1149
+ ctr[rowIndex].expand = true;
1150
+ break;
1151
+ case 'Collapse':
1152
+ ctr[rowIndex].expand = false;
1153
+ break;
1154
+ default:
1155
+ ctr[rowIndex].expand = !ctr[rowIndex].expand;
1156
+ }
1157
+ for (let ri = rowIndex + 1; ri <= ctr[rowIndex].lastchild; ri++) {
1158
+ if (ctr[rowIndex].expand) {
1159
+ ctr[ri].hide = false;
1160
+ if (ctr[ri].icon && !ctr[ri].expand) ri = ctr[ri].lastchild;
1161
+ } else {
1162
+ ctr[ri].hide = true;
1163
+ }
1164
+ }
1165
+ } else if (self.cellTree.columns[rowIndex]) {
1166
+ const ctc = self.cellTree.columns[rowIndex];
1167
+ switch (type) {
1168
+ case 'Expand':
1169
+ ctc[columnIndex].expand = true;
1170
+ break;
1171
+ case 'Collapse':
1172
+ ctc[columnIndex].expand = false;
1173
+ break;
1174
+ default:
1175
+ ctc[columnIndex].expand = !ctc[columnIndex].expand;
1176
+ }
1177
+
1178
+ for (let ci = columnIndex + 1; ci <= ctc[columnIndex].lastchild; ci++) {
1179
+ if (ctc[columnIndex].expand) self.tempSchema[ci].hidden = false;
1180
+ else self.tempSchema[ci].hidden = true;
1181
+ }
1182
+
1183
+ let rc = 0,
1184
+ ri;
1185
+ if (ctc[columnIndex].expand) {
1186
+ while (rc < ctc[columnIndex].child) {
1187
+ ri = rowIndex + rc + 1;
1188
+ for (let ci = columnIndex; ci <= ctc[columnIndex].lastchild; ci++) {
1189
+ if (
1190
+ self.cellTree.columns[ri] &&
1191
+ self.cellTree.columns[ri][ci].icon &&
1192
+ !self.cellTree.columns[ri][ci].expand
1193
+ ) {
1194
+ for (
1195
+ let si = ci + 1;
1196
+ si <= self.cellTree.columns[ri][ci].lastchild;
1197
+ si++
1198
+ )
1199
+ self.tempSchema[si].hidden = true;
1200
+ }
1201
+ }
1202
+ rc++;
1203
+ }
1204
+ }
1205
+ }
1206
+ };
1207
+
1208
+ self.initCellTreeSettings = function () {
1209
+ if (self.viewData === undefined) return;
1210
+ if (self.attributes.rowTree.length > 0 && self.viewData.length > 0) {
1211
+ self.cellTree.rows = Array(self.viewData.length)
1212
+ .fill()
1213
+ .map((u, index) => ({ index: index }));
1214
+ self.cellTree.rowTreeColIndex = self.attributes.rowTreeColIndex;
1215
+ let invalidRowTree = false;
1216
+ for (let rt of self.attributes.rowTree) {
1217
+ if (self.cellTree.rows.length <= rt.end) {
1218
+ invalidRowTree = true;
1219
+ break;
1220
+ }
1221
+
1222
+ for (let ri = rt.begin; ri <= rt.end; ri++) {
1223
+ if (ri == rt.begin) {
1224
+ self.cellTree.rows[ri].icon = true;
1225
+ self.cellTree.rows[ri].lastchild = rt.end;
1226
+ self.cellTree.rows[ri].expand = true;
1227
+ if (!self.cellTree.rows[ri].parentCount)
1228
+ self.cellTree.rows[ri].parentCount = 0;
1229
+ } else {
1230
+ self.cellTree.rows[ri].hide = false;
1231
+ self.cellTree.rows[ri].parentIndex = rt.begin;
1232
+ if (self.cellTree.rows[ri] && self.cellTree.rows[ri].parentCount)
1233
+ self.cellTree.rows[ri].parentCount += 1;
1234
+ else self.cellTree.rows[ri].parentCount = 1;
1235
+ }
1236
+ }
1237
+ }
1238
+ if (invalidRowTree) self.cellTree.rows = {};
1239
+ }
1240
+ if (self.attributes.columnTree.length > 0 && self.viewData.length > 0) {
1241
+ self.cellTree.columnTreeRowStartIndex =
1242
+ self.attributes.columnTreeRowStartIndex;
1243
+ self.cellTree.columnTreeRowEndIndex =
1244
+ self.attributes.columnTreeRowEndIndex;
1245
+ let dataColumnLength = Object.keys(self.viewData[0]).length;
1246
+ let invalidColumnTree = false;
1247
+ for (let ct of self.attributes.columnTree) {
1248
+ if (dataColumnLength <= ct.end) {
1249
+ invalidColumnTree = true;
1250
+ break;
1251
+ }
1252
+
1253
+ if (!self.cellTree.columns[ct.row])
1254
+ self.cellTree.columns[ct.row] = Array(dataColumnLength)
1255
+ .fill()
1256
+ .map((u, index) => ({ index: index }));
1257
+
1258
+ for (let i = ct.begin; i <= ct.end; i++) {
1259
+ const ctc = self.cellTree.columns[ct.row][i];
1260
+ if (i == ct.begin) {
1261
+ ctc.icon = true;
1262
+ ctc.lastchild = ct.end;
1263
+ ctc.length = ct.end - ct.begin;
1264
+ ctc.expand = true;
1265
+ if (ct.child) ctc.child = ct.child;
1266
+ else ctc.child = 0;
1267
+ }
1268
+ }
1269
+ }
1270
+ self.cellTree.tempSchema = Array(dataColumnLength)
1271
+ .fill()
1272
+ .map(function () {
1273
+ return { hidden: false };
1274
+ });
1275
+ if (invalidColumnTree) self.cellTree.columns = {};
1276
+ }
1277
+ self.cellTree.origin = {
1278
+ rows: self.cellTree.rows,
1279
+ columns: self.cellTree.columns,
1280
+ };
1281
+ };
1282
+
1283
+ self.unhideColumns = function (orderIndex0, orderIndex1) {
1284
+ const orders = self.orders.columns;
1285
+ const schema = self.getSchema();
1286
+ for (let i = orderIndex0; i <= orderIndex1; i++) {
1287
+ const columnIndex = orders[i];
1288
+ const s = schema[columnIndex];
1289
+ if (s && s.hidden) s.hidden = false;
1290
+ }
1291
+ self.refresh();
1292
+ };
1293
+
706
1294
  self.getDomRoot = function () {
707
1295
  return self.shadowRoot ? self.shadowRoot.host : self.parentNode;
708
1296
  };
@@ -874,6 +1462,8 @@ export default function (self, ctor) {
874
1462
  self.intf.gotoCell = self.gotoCell;
875
1463
  self.intf.gotoRow = self.gotoRow;
876
1464
  self.intf.addButton = self.addButton;
1465
+ self.intf.toggleCellCollapseTree = self.toggleCellCollapseTree;
1466
+ self.intf.expandCollapseCellTree = self.expandCollapseCellTree;
877
1467
  self.intf.getHeaderByName = self.getHeaderByName;
878
1468
  self.intf.findColumnScrollLeft = self.findColumnScrollLeft;
879
1469
  self.intf.findRowScrollTop = self.findRowScrollTop;
@@ -881,6 +1471,14 @@ export default function (self, ctor) {
881
1471
  self.intf.findColumnMaxTextLength = self.findColumnMaxTextLength;
882
1472
  self.intf.disposeContextMenu = self.disposeContextMenu;
883
1473
  self.intf.getCellAt = self.getCellAt;
1474
+ self.intf.groupColumns = self.groupColumns;
1475
+ self.intf.groupRows = self.groupRows;
1476
+ self.intf.removeGroupColumns = self.removeGroupColumns;
1477
+ self.intf.removeGroupRows = self.removeGroupRows;
1478
+ self.intf.toggleGroupColumns = self.toggleGroupColumns;
1479
+ self.intf.toggleGroupRows = self.toggleGroupRows;
1480
+ self.intf.getGroupsColumnBelongsTo = self.getGroupsColumnBelongsTo;
1481
+ self.intf.getGroupsRowBelongsTo = self.getGroupsRowBelongsTo;
884
1482
  self.intf.isCellVisible = self.isCellVisible;
885
1483
  self.intf.isRowVisible = self.isRowVisible;
886
1484
  self.intf.isColumnVisible = self.isColumnVisible;
@@ -923,6 +1521,9 @@ export default function (self, ctor) {
923
1521
  self.intf.cut = self.cut;
924
1522
  self.intf.paste = self.paste;
925
1523
  self.intf.setStyleProperty = self.setStyleProperty;
1524
+ self.intf.hideColumns = self.hideColumns;
1525
+ self.intf.hideRows = self.hideRows;
1526
+ self.intf.unhideRows = self.unhideRows;
926
1527
  Object.defineProperty(self.intf, 'defaults', {
927
1528
  get: function () {
928
1529
  return {
@@ -1010,6 +1611,13 @@ export default function (self, ctor) {
1010
1611
  if (key === 'name') {
1011
1612
  self.tryLoadStoredSettings();
1012
1613
  }
1614
+ if (
1615
+ key === 'rowTree' ||
1616
+ key === 'columnTree' ||
1617
+ key === 'columnTreeRowEndIndex'
1618
+ ) {
1619
+ self.initCellTreeSettings();
1620
+ }
1013
1621
  self.draw(true);
1014
1622
  self.dispatchEvent('attributechanged', {
1015
1623
  name: key,
@@ -1623,6 +2231,7 @@ export default function (self, ctor) {
1623
2231
  self.createRowOrders();
1624
2232
  self.tryLoadStoredSettings();
1625
2233
  self.dispatchEvent('datachanged', { data: self.originalData });
2234
+ self.initCellTreeSettings();
1626
2235
  self.resize(true);
1627
2236
  });
1628
2237
  },