canvas-datagrid 0.3.25 → 0.4.0

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.
@@ -130,6 +130,8 @@ export default function (self) {
130
130
  l = (self.viewData || []).length,
131
131
  columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
132
132
  rowHeaderCellWidth = self.getRowHeaderCellWidth(),
133
+ topGroupAreaHeight = self.getColumnGroupAreaHeight(),
134
+ leftGroupAreaWidth = self.getRowGroupAreaWidth(),
133
135
  ch = self.style.cellHeight,
134
136
  s = self.getSchema();
135
137
  // sets actual DOM canvas element
@@ -148,8 +150,10 @@ export default function (self) {
148
150
  self.scrollBox.verticalBoxVisible = dataHeight > self.scrollBox.height;
149
151
  }
150
152
  function setScrollBoxSize() {
151
- self.scrollBox.width = self.width - rowHeaderCellWidth;
152
- self.scrollBox.height = self.height - columnHeaderCellHeight;
153
+ self.scrollBox.width =
154
+ self.width - rowHeaderCellWidth - leftGroupAreaWidth;
155
+ self.scrollBox.height =
156
+ self.height - columnHeaderCellHeight - topGroupAreaHeight;
153
157
  }
154
158
  function setCanvasSize() {
155
159
  if (self.isChildGrid) {
@@ -157,8 +161,13 @@ export default function (self) {
157
161
  }
158
162
  dims = {
159
163
  // HACK +1 ? maybe it's a magic cell border? Required to line up properly in auto height mode.
160
- height: columnHeaderCellHeight + dataHeight + cellBorder + 1,
161
- width: dataWidth + rowHeaderCellWidth + cellBorder,
164
+ height:
165
+ columnHeaderCellHeight +
166
+ topGroupAreaHeight +
167
+ dataHeight +
168
+ cellBorder +
169
+ 1,
170
+ width: dataWidth + rowHeaderCellWidth + cellBorder + leftGroupAreaWidth,
162
171
  };
163
172
  ['width', 'height'].forEach(function (dim) {
164
173
  //TODO: support inherit
@@ -190,18 +199,31 @@ export default function (self) {
190
199
  if (l > 1) {
191
200
  self.scrollCache.y[x] = dataHeight;
192
201
  }
202
+ const collapsedColumnGroups = self.getCollapsedColumnGroups();
203
+ const isColumnCollapsed = (columnIndex) =>
204
+ collapsedColumnGroups.findIndex(
205
+ (group) => columnIndex >= group.from && columnIndex <= group.to,
206
+ ) >= 0;
207
+ /** @type {number} it will be used in `reduceSchema` only */
208
+ let frozenWidth = 0;
193
209
  dataWidth =
194
210
  s.reduce(function reduceSchema(accumulator, column, columnIndex) {
195
211
  // intentional redefintion of column. This causes scrollCache to be in the correct order
196
- column = s[self.orders.columns[columnIndex]];
197
- if (column.hidden) {
212
+ const schemaIndex = self.orders.columns[columnIndex];
213
+ const columnWidth = self.getColumnWidth(schemaIndex);
214
+ column = s[schemaIndex];
215
+ if (!column.hidden && !isColumnCollapsed(columnIndex))
216
+ accumulator += columnWidth;
217
+ if (columnIndex < self.frozenColumn) {
198
218
  self.scrollCache.x[columnIndex] = accumulator;
199
- return accumulator;
219
+ frozenWidth = accumulator;
220
+ } else {
221
+ self.scrollCache.x[columnIndex] = Math.max(
222
+ frozenWidth + columnWidth,
223
+ accumulator,
224
+ );
200
225
  }
201
- var va =
202
- accumulator + self.getColumnWidth(self.orders.columns[columnIndex]);
203
- self.scrollCache.x[columnIndex] = va;
204
- return va;
226
+ return accumulator;
205
227
  }, 0) || 0;
206
228
  if (self.attributes.showNewRow) {
207
229
  dataHeight += ch;
@@ -224,8 +246,9 @@ export default function (self) {
224
246
  }
225
247
  /// calculate scroll bar dimensions
226
248
  // non-controversial
227
- self.scrollBox.top = columnHeaderCellHeight + columnHeaderCellBorder;
228
- self.scrollBox.left = rowHeaderCellWidth;
249
+ self.scrollBox.top =
250
+ columnHeaderCellHeight + topGroupAreaHeight + columnHeaderCellBorder;
251
+ self.scrollBox.left = rowHeaderCellWidth + leftGroupAreaWidth;
229
252
  // width and height of scroll box
230
253
  setScrollBoxSize();
231
254
  // is the data larger than the scroll box
@@ -274,6 +297,7 @@ export default function (self) {
274
297
  self.scrollBox.heightBoxRatio =
275
298
  (self.scrollBox.height -
276
299
  columnHeaderCellHeight -
300
+ topGroupAreaHeight -
277
301
  self.scrollCache.y[self.frozenRow]) /
278
302
  dataHeight;
279
303
  self.scrollBox.scrollBoxHeight =
@@ -291,9 +315,14 @@ export default function (self) {
291
315
  );
292
316
  // horizontal
293
317
  n.x += rowHeaderCellWidth;
294
- n.y += self.height - self.style.scrollBarWidth - d;
318
+ n.y += self.height - self.style.scrollBarWidth - d - topGroupAreaHeight;
295
319
  n.width =
296
- self.width - self.style.scrollBarWidth - rowHeaderCellWidth - d - m;
320
+ self.width -
321
+ self.style.scrollBarWidth -
322
+ rowHeaderCellWidth -
323
+ leftGroupAreaWidth -
324
+ d -
325
+ m;
297
326
  n.height = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
298
327
  // horizontal box
299
328
  nb.y = n.y + self.style.scrollBarBoxMargin;
@@ -302,13 +331,19 @@ export default function (self) {
302
331
  // vertical
303
332
  v.x +=
304
333
  self.width -
334
+ leftGroupAreaWidth -
305
335
  self.style.scrollBarWidth -
306
336
  self.style.scrollBarBorderWidth -
307
337
  d;
308
338
  v.y += columnHeaderCellHeight + self.scrollCache.y[self.frozenRow];
309
339
  v.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
310
340
  v.height =
311
- self.height - columnHeaderCellHeight - self.style.scrollBarWidth - d - m;
341
+ self.height -
342
+ columnHeaderCellHeight -
343
+ topGroupAreaHeight -
344
+ self.style.scrollBarWidth -
345
+ d -
346
+ m;
312
347
  // vertical box
313
348
  vb.x = v.x + self.style.scrollBarBoxMargin;
314
349
  vb.y += self.scrollCache.y[self.frozenRow];
@@ -469,6 +504,7 @@ export default function (self) {
469
504
  rowIndex: cell.rowIndex,
470
505
  columnIndex: cell.columnIndex,
471
506
  onFilterButton: false,
507
+ onCellTreeIcon: false,
472
508
  };
473
509
  if (
474
510
  cell.isFilterable &&
@@ -488,6 +524,26 @@ export default function (self) {
488
524
  self.hovers.onFilterButton = true;
489
525
  self.draw();
490
526
  }
527
+ if (cell.isRowTree || cell.isColumnTree) {
528
+ const pc = cell.isRowTree
529
+ ? self.cellTree.rows[cell.rowIndex].parentCount
530
+ : 0;
531
+ const rc = self.style.cellTreeIconWidth * self.scale,
532
+ rx =
533
+ cell.x +
534
+ cell.paddingLeft +
535
+ self.canvasOffsetLeft +
536
+ self.style.cellTreeIconMarginLeft +
537
+ pc * (rc + cell.paddingLeft),
538
+ ry =
539
+ cell.y +
540
+ self.canvasOffsetTop +
541
+ self.style.cellTreeIconMarginTop * self.scale;
542
+ if (x >= rx && x <= rx + rc && y >= ry && y < ry + rc) {
543
+ self.hovers.onCellTreeIcon = true;
544
+ self.draw();
545
+ }
546
+ }
491
547
  }
492
548
  if (self.selecting || self.reorderObject) {
493
549
  delta = {
@@ -549,12 +605,20 @@ export default function (self) {
549
605
  }
550
606
  self.draw();
551
607
  return;
608
+ } else if (
609
+ cell.hovered &&
610
+ self.hovers.onCellTreeIcon &&
611
+ e.type == 'mousedown'
612
+ ) {
613
+ self.toggleCollapseTree(cell.rowIndex, cell.columnIndex);
614
+ return;
552
615
  } else {
553
616
  self.selectedFilterButton = {
554
617
  columnIndex: -1,
555
618
  rowIndex: -1,
556
619
  };
557
620
  if (self.hovers.onFilterButton) return;
621
+ if (self.hovers.onCellTreeIcon) return;
558
622
  if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
559
623
  if (
560
624
  self.selections[cell.rowIndex] &&
@@ -627,6 +691,12 @@ export default function (self) {
627
691
  }
628
692
  }
629
693
  }
694
+ const columnGroup = self.getColumnGroupAt(self.mouse.x, self.mouse.y);
695
+ if (columnGroup) self.cursor = 'pointer';
696
+
697
+ const rowGroup = self.getRowGroupAt(self.mouse.x, self.mouse.y);
698
+ if (rowGroup) self.cursor = 'pointer';
699
+
630
700
  self.cellBoundaryCrossed = false;
631
701
  self.rowBoundaryCrossed = false;
632
702
  self.columnBoundaryCrossed = false;
@@ -675,9 +745,25 @@ export default function (self) {
675
745
  ) {
676
746
  return;
677
747
  }
748
+
749
+ let group = self.getColumnGroupAt(pos.x, pos.y);
750
+ if (!group) group = self.getRowGroupAt(pos.x, pos.y);
751
+ if (group) {
752
+ if (self.toggleGroup(group)) {
753
+ self.setStorageData();
754
+ self.refresh();
755
+ return;
756
+ }
757
+ }
758
+
678
759
  if (!self.hasFocus) {
679
760
  return;
680
761
  }
762
+
763
+ const leftOffset = self.getRowGroupAreaWidth();
764
+ const topOffset = self.getColumnGroupAreaHeight();
765
+ const xInGrid = pos.x - leftOffset;
766
+ const yInGrid = pos.y - topOffset;
681
767
  if (
682
768
  ['rowHeaderCell', 'columnHeaderCell'].indexOf(self.currentCell.style) ===
683
769
  -1 &&
@@ -715,17 +801,17 @@ export default function (self) {
715
801
  if (
716
802
  self.currentCell.style === 'rowHeaderCell' &&
717
803
  self.attributes.tree &&
718
- pos.x > 0 &&
719
- pos.x - self.currentCell.x <
804
+ xInGrid > 0 &&
805
+ xInGrid - self.currentCell.x <
720
806
  self.style.treeArrowWidth +
721
807
  self.style.treeArrowMarginLeft +
722
808
  self.style.treeArrowMarginRight +
723
809
  self.style.treeArrowClickRadius &&
724
- pos.y - self.currentCell.y <
810
+ yInGrid - self.currentCell.y <
725
811
  self.style.treeArrowHeight +
726
812
  self.style.treeArrowMarginTop +
727
813
  self.style.treeArrowClickRadius &&
728
- pos.y > 0
814
+ yInGrid > 0
729
815
  ) {
730
816
  self.toggleTree(i.rowIndex);
731
817
  return;
@@ -765,7 +851,6 @@ export default function (self) {
765
851
  self.dragMode === 'ew-resize'
766
852
  ) {
767
853
  self.resize(true);
768
- self.scrollBox.scrollLeft += x;
769
854
  }
770
855
  if (self.dragMode === 'ew-resize') {
771
856
  self.sizes.columns[
@@ -1127,6 +1212,8 @@ export default function (self) {
1127
1212
 
1128
1213
  self.ignoreNextClick = true;
1129
1214
  self.freezeMarkerPosition = pos;
1215
+ pos.x -= self.getRowGroupAreaWidth();
1216
+ pos.y -= self.getColumnGroupAreaHeight();
1130
1217
  if (
1131
1218
  self.currentCell &&
1132
1219
  self.currentCell.rowIndex !== undefined &&
@@ -1647,9 +1734,21 @@ export default function (self) {
1647
1734
  self.autosize();
1648
1735
  } else if (
1649
1736
  ['cell', 'activeCell'].includes(self.currentCell.style) &&
1650
- !self.hovers.onFilterButton
1737
+ !self.hovers.onFilterButton &&
1738
+ !self.hovers.onCellTreeIcon
1651
1739
  ) {
1652
- self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
1740
+ if (self.currentCell.isRowTree || self.currentCell.isColumnTree) {
1741
+ self.cellTreeExpandCollapse(
1742
+ self.currentCell.rowIndex,
1743
+ self.currentCell.columnIndex,
1744
+ );
1745
+ self.draw();
1746
+ } else {
1747
+ self.beginEditAt(
1748
+ self.currentCell.columnIndex,
1749
+ self.currentCell.rowIndex,
1750
+ );
1751
+ }
1653
1752
  }
1654
1753
  };
1655
1754
  self.scrollWheel = function (e) {
@@ -112,7 +112,7 @@ const createHTMLString = function (selectedData, isNeat) {
112
112
  (row) =>
113
113
  '<tr>' +
114
114
  Object.values(row)
115
- .map((value) => '<td>' + htmlSafe(value) + '</td>')
115
+ .map((value) => ['<td>', htmlSafe(value), '</td>'].join(''))
116
116
  .join('') +
117
117
  '</tr>',
118
118
  )