canvas-datagrid 0.3.22 → 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.
@@ -1275,7 +1275,256 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
1275
1275
  self.controlInput.focus();
1276
1276
  }
1277
1277
  });
1278
+ } //#region group/ungroup columns
1279
+
1280
+
1281
+ var groupAreaHeight = self.getColumnGroupAreaHeight();
1282
+ var groupAreaWidth = self.getRowGroupAreaWidth();
1283
+
1284
+ var setCollapseStateForAllGroups = function setCollapseStateForAllGroups(allGroups, collapsed) {
1285
+ if (allGroups.length === 0) return;
1286
+
1287
+ for (var i = 0; i < allGroups.length; i++) {
1288
+ var groups = allGroups[i];
1289
+
1290
+ for (var j = 0; j < groups.length; j++) {
1291
+ var group = groups[j];
1292
+ group.collapsed = collapsed;
1293
+ }
1294
+ }
1295
+
1296
+ self.refresh();
1297
+ };
1298
+
1299
+ if (e.pos && e.pos.y < groupAreaHeight) {
1300
+ e.items.push({
1301
+ title: self.attributes.showRemoveAllGroupColumns,
1302
+ click: function click(ev) {
1303
+ ev.preventDefault();
1304
+ self.groupedColumns = [];
1305
+ self.refresh();
1306
+ }
1307
+ });
1308
+ e.items.push({
1309
+ title: self.attributes.showExpandAllGroupColumns,
1310
+ click: function click(ev) {
1311
+ ev.preventDefault();
1312
+ setCollapseStateForAllGroups(self.groupedColumns, false);
1313
+ }
1314
+ });
1315
+ e.items.push({
1316
+ title: self.attributes.showCollapseAllGroupColumns,
1317
+ click: function click(ev) {
1318
+ ev.preventDefault();
1319
+ setCollapseStateForAllGroups(self.groupedColumns, true);
1320
+ }
1321
+ });
1322
+ }
1323
+
1324
+ if (e.pos && e.pos.x < groupAreaWidth) {
1325
+ e.items.push({
1326
+ title: self.attributes.showRemoveAllGroupRows,
1327
+ click: function click(ev) {
1328
+ ev.preventDefault();
1329
+ self.groupedRows = [];
1330
+ self.refresh();
1331
+ }
1332
+ });
1333
+ e.items.push({
1334
+ title: self.attributes.showExpandAllGroupRows,
1335
+ click: function click(ev) {
1336
+ ev.preventDefault();
1337
+ setCollapseStateForAllGroups(self.groupedRows, false);
1338
+ }
1339
+ });
1340
+ e.items.push({
1341
+ title: self.attributes.showCollapseAllGroupRows,
1342
+ click: function click(ev) {
1343
+ ev.preventDefault();
1344
+ setCollapseStateForAllGroups(self.groupedRows, true);
1345
+ }
1346
+ });
1347
+ }
1348
+
1349
+ var canGroupByColumns = self.attributes.allowGroupingColumns && e.cell.isColumnHeader && e.cell.header && e.cell.header.index > 0;
1350
+ var canUngroupColumns = self.attributes.allowGroupingColumns && e.cell.isColumnHeader;
1351
+ var canGroupByRows = self.attributes.allowGroupingRows && e.cell.isRowHeader && e.cell.header;
1352
+ var canUngroupRows = self.attributes.allowGroupingRows && e.cell.isRowHeader;
1353
+ /**
1354
+ * The value for storing the return value from `self.getSchema()`
1355
+ * @type {any[]}
1356
+ */
1357
+
1358
+ var schema;
1359
+ /**
1360
+ * A map between columnIndex and column data
1361
+ * @type {Map<string,any>}
1362
+ */
1363
+
1364
+ var columns;
1365
+
1366
+ var getColumnsMap = function getColumnsMap() {
1367
+ if (!columns) {
1368
+ if (!schema) schema = self.getSchema();
1369
+ columns = new Map(schema.map(function (_col) {
1370
+ return [_col.columnIndex, _col];
1371
+ }));
1372
+ }
1373
+
1374
+ return columns;
1375
+ };
1376
+
1377
+ if (canGroupByColumns) {
1378
+ /** @type {number[]} */
1379
+ var groupIndexes = [];
1380
+ /** @type {number} */
1381
+
1382
+ var headerIndex = e.cell.header.index;
1383
+ var col = headerIndex;
1384
+
1385
+ for (; col >= 0; col--) {
1386
+ if (!self.isColumnSelected(col)) break;
1387
+ groupIndexes[0] = col;
1388
+ }
1389
+
1390
+ for (col = headerIndex;; col++) {
1391
+ if (!self.isColumnSelected(col)) break;
1392
+ groupIndexes[1] = col;
1393
+ }
1394
+
1395
+ if (col !== headerIndex && groupIndexes.length === 2 && groupIndexes[1] > groupIndexes[0] && self.isNewGroupRangeValid(self.groupedColumns, groupIndexes[0], groupIndexes[1])) {
1396
+ var _columns = getColumnsMap();
1397
+
1398
+ var groupTitles = [];
1399
+ var groupNames = [];
1400
+
1401
+ for (var i = 0; i < groupIndexes.length; i++) {
1402
+ var columnIndex = groupIndexes[i];
1403
+
1404
+ var column = _columns.get(columnIndex);
1405
+
1406
+ if (column) {
1407
+ groupNames.push(column.name);
1408
+ groupTitles.push(column.title || column.name || column.index);
1409
+ }
1410
+ }
1411
+
1412
+ if (groupNames[0] && groupNames[1]) {
1413
+ // show group options
1414
+ e.items.push({
1415
+ title: self.attributes.showGroupColumns.replace('%s', groupTitles[0] + '-' + groupTitles[1]),
1416
+ click: function click(ev) {
1417
+ ev.preventDefault();
1418
+ self.groupColumns(groupNames[0], groupNames[1]);
1419
+ self.controlInput.focus();
1420
+ }
1421
+ });
1422
+ }
1423
+ }
1424
+ }
1425
+
1426
+ if (canUngroupColumns) {
1427
+ var _columnIndex = e.cell.columnIndex;
1428
+ var groups = self.getGroupsColumnBelongsTo(_columnIndex);
1429
+
1430
+ var _columns2 = getColumnsMap();
1431
+
1432
+ var _loop = function _loop(_i) {
1433
+ var _groups$_i = groups[_i],
1434
+ from = _groups$_i.from,
1435
+ to = _groups$_i.to;
1436
+
1437
+ var cell0 = _columns2.get(from);
1438
+
1439
+ var cell1 = _columns2.get(to);
1440
+
1441
+ if (cell0 && cell1) {
1442
+ var formatArgs = (cell0.title || cell0.name || cell0.index) + '-' + (cell1.title || cell1.name || cell1.index);
1443
+ e.items.push({
1444
+ title: self.attributes.showRemoveGroupColumns.replace('%s', formatArgs),
1445
+ click: function click(ev) {
1446
+ ev.preventDefault();
1447
+ self.removeGroupColumns(cell0.name, cell1.name);
1448
+ self.controlInput.focus();
1449
+ }
1450
+ });
1451
+ } else {
1452
+ console.warn("Cannot find column ".concat(from, " or column ").concat(to));
1453
+ }
1454
+ };
1455
+
1456
+ for (var _i = 0; _i < groups.length; _i++) {
1457
+ _loop(_i);
1458
+ }
1459
+ }
1460
+
1461
+ if (canGroupByRows) {
1462
+ var range = [];
1463
+ var prev = -2;
1464
+ var ok = true;
1465
+ self.selections.forEach(function (row, index) {
1466
+ if (!ok) return;
1467
+
1468
+ if (prev < -1) {
1469
+ prev = index;
1470
+ range[0] = index;
1471
+ return;
1472
+ }
1473
+
1474
+ if (index !== prev + 1 || !row || row.length === 0) {
1475
+ ok = false;
1476
+ return;
1477
+ }
1478
+
1479
+ prev = index;
1480
+ range[1] = index;
1481
+ });
1482
+ var rangeTitle = range.map(function (rowIndex) {
1483
+ var index = self.getBoundRowIndexFromViewRowIndex(rowIndex);
1484
+ if (typeof index === 'number') return index + 1;
1485
+ return rowIndex + 1;
1486
+ }).join('-');
1487
+
1488
+ if (ok && range.length === 2 && self.isNewGroupRangeValid(self.groupedRows, range[0], range[1])) {
1489
+ e.items.push({
1490
+ title: self.attributes.showGroupRows.replace('%s', rangeTitle),
1491
+ click: function click(ev) {
1492
+ ev.preventDefault();
1493
+ self.groupRows(range[0], range[1]);
1494
+ }
1495
+ });
1496
+ }
1278
1497
  }
1498
+
1499
+ if (canUngroupRows) {
1500
+ var rowIndex = e.cell.rowIndex;
1501
+
1502
+ var _groups = self.getGroupsRowBelongsTo(rowIndex);
1503
+
1504
+ var _loop2 = function _loop2(_i2) {
1505
+ var _groups$_i2 = _groups[_i2],
1506
+ from = _groups$_i2.from,
1507
+ to = _groups$_i2.to;
1508
+ var rangeTitle = [from, to].map(function (rowIndex) {
1509
+ var index = self.getBoundRowIndexFromViewRowIndex(rowIndex);
1510
+ if (typeof index === 'number') return index + 1;
1511
+ return rowIndex + 1;
1512
+ }).join('-');
1513
+ e.items.push({
1514
+ title: self.attributes.showRemoveGroupRows.replace('%s', rangeTitle),
1515
+ click: function click(ev) {
1516
+ ev.preventDefault();
1517
+ self.removeGroupRows(from, to);
1518
+ self.controlInput.focus();
1519
+ }
1520
+ });
1521
+ };
1522
+
1523
+ for (var _i2 = 0; _i2 < _groups.length; _i2++) {
1524
+ _loop2(_i2);
1525
+ }
1526
+ } //#endregion group/ungroup columns
1527
+
1279
1528
  }
1280
1529
 
1281
1530
  self.disposeAutocomplete = function () {
@@ -1306,6 +1555,59 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
1306
1555
  self.contextmenuEvent = function (e, overridePos) {
1307
1556
  if (!self.hasFocus && e.target !== self.canvas) {
1308
1557
  return;
1558
+ } // don't create context menu for parents if current position is located in child grid
1559
+
1560
+
1561
+ var children = Object.keys(self.childGrids);
1562
+
1563
+ for (var i = 0; i < children.length; i++) {
1564
+ var childGrid = self.childGrids[children[i]];
1565
+ var parentNode = childGrid && childGrid.parentNode;
1566
+ if (!parentNode) continue;
1567
+ var offsetLeft = parentNode.offsetLeft,
1568
+ offsetWidth = parentNode.offsetWidth,
1569
+ offsetTop = parentNode.offsetTop,
1570
+ offsetHeight = parentNode.offsetHeight;
1571
+ if ((e.x >= offsetLeft && e.x <= offsetLeft + offsetWidth) === false) continue;
1572
+ if ((e.y >= offsetTop && e.y <= offsetTop + offsetHeight) === false) continue;
1573
+ return; // in child grid
1574
+ } // don't create context menu for child if current position is located in parent grid
1575
+
1576
+
1577
+ if (self.isChildGrid && self.parentNode) {
1578
+ //#region check is current child grid closed
1579
+ var childGridsOfParent = self.parentGrid && self.parentGrid.childGrids;
1580
+ if (!childGridsOfParent || !Array.isArray(childGridsOfParent)) return;
1581
+ var matchedMe = childGridsOfParent.find(function (grid) {
1582
+ var nodeA = grid.parentNode;
1583
+ var nodeB = self.parentNode;
1584
+ return nodeA.offsetTop == nodeB.offsetTop && nodeA.offsetLeft === nodeB.offsetLeft;
1585
+ });
1586
+ if (!matchedMe) return; //#endregion
1587
+
1588
+ var x0 = self.parentNode.offsetLeft;
1589
+ var x1 = self.parentNode.offsetLeft + self.parentNode.offsetWidth;
1590
+ var y0 = self.parentNode.offsetTop;
1591
+ var y1 = self.parentNode.offsetTop + self.parentNode.offsetHeight;
1592
+ var node = self.parentNode.parentNode;
1593
+
1594
+ while (node) {
1595
+ var _node = node,
1596
+ _offsetLeft = _node.offsetLeft,
1597
+ _offsetWidth = _node.offsetWidth,
1598
+ _offsetTop = _node.offsetTop,
1599
+ _offsetHeight = _node.offsetHeight;
1600
+ if (_offsetLeft > x0) x0 = _offsetLeft;
1601
+ if (_offsetTop > y0) y0 = _offsetTop;
1602
+ var newX1 = _offsetLeft + _offsetWidth;
1603
+ var newY1 = _offsetTop + _offsetHeight;
1604
+ if (newX1 < x1) x1 = newX1;
1605
+ if (newY1 < y1) y1 = newY1;
1606
+ if (node.nodeType !== 'canvas-datagrid-tree') break;
1607
+ node = node.parentNode;
1608
+ }
1609
+
1610
+ if ((e.x >= x0 && e.x <= x1 && e.y >= y0 && e.y <= y1) === false) return;
1309
1611
  }
1310
1612
 
1311
1613
  function createDisposeEvent() {
@@ -1321,6 +1623,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
1321
1623
  ev = {
1322
1624
  NativeEvent: e,
1323
1625
  cell: self.getCellAt(pos.x, pos.y),
1626
+ pos: pos,
1324
1627
  items: items
1325
1628
  };
1326
1629
 
@@ -1394,8 +1697,10 @@ __webpack_require__.r(__webpack_exports__);
1394
1697
 
1395
1698
  /* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(self) {
1396
1699
  self.defaults = {
1397
- attributes: [['allowColumnReordering', true], ['allowColumnResize', true], ['allowColumnResizeFromCell', false], ['allowFreezingRows', false], ['allowFreezingColumns', false], ['allowMovingSelection', true], ['allowRowHeaderResize', true], ['allowRowReordering', false], ['allowRowResize', true], ['allowRowResizeFromCell', false], ['allowSorting', true], ['animationDurationShowContextMenu', 50], ['animationDurationHideContextMenu', 50], ['autoGenerateSchema', false], ['autoResizeColumns', false], ['autoResizeRows', false], ['autoScrollOnMousemove', false], ['autoScrollMargin', 5], ['blanksText', '(Blanks)'], ['borderDragBehavior', 'none'], ['borderResizeZone', 10], ['clearSettingsOptionText', 'Clear saved settings'], ['columnHeaderClickBehavior', 'sort'], ['columnSelectorHiddenText', '&nbsp;&nbsp;&nbsp;'], ['columnSelectorText', 'Add/Remove columns'], ['columnSelectorVisibleText', "\u2713"], ['contextHoverScrollAmount', 2], ['contextHoverScrollRateMs', 5], ['copyHeadersOnSelectAll', true], ['copyText', 'Copy'], ['debug', false], ['editable', true], ['ellipsisText', '...'], ['filterOptionText', 'Filter %s'], ['filterTextPrefix', '(filtered) '], ['filterFrozenRows', true], ['globalRowResize', false], ['hideColumnText', 'Hide %s'], ['hoverMode', 'cell'], ['keepFocusOnMouseOut', false], ['maxAutoCompleteItems', 200], ['multiLine', false], ['name', ''], ['pageUpDownOverlap', 1], ['pasteText', 'Paste'], ['persistantSelectionMode', false], ['removeFilterOptionText', 'Remove filter on %s'], ['reorderDeadZone', 3], ['resizeScrollZone', 20], ['rowGrabZoneSize', 5], ['saveAppearance', true], ['scrollAnimationPPSThreshold', 0.75], ['scrollPointerLock', false], ['scrollRepeatRate', 75], ['selectionFollowsActiveCell', false], ['selectionHandleBehavior', 'none'], ['selectionMode', 'cell'], ['selectionScrollIncrement', 20], ['selectionScrollZone', 20], ['showClearSettingsOption', true], ['showColumnHeaders', true], ['showColumnSelector', true], ['showCopy', false], ['showFilter', true], ['showFilterInCell', false], ['showNewRow', false], ['showOrderByOption', true], ['showOrderByOptionTextAsc', 'Order by %s ascending'], ['showOrderByOptionTextDesc', 'Order by %s descending'], ['showPaste', false], ['showPerformance', false], ['showRowHeaders', true], ['showRowNumbers', true], ['showRowNumberGaps', true], ['singleSelectionMode', false], ['snapToRow', false], ['sortFrozenRows', true], ['touchContextMenuTimeMs', 800], ['touchDeadZone', 3], ['touchEasingMethod', 'easeOutQuad'], ['touchReleaseAcceleration', 1000], ['touchReleaseAnimationDurationMs', 2000], ['touchScrollZone', 20], ['touchSelectHandleZone', 20], ['touchZoomSensitivity', 0.005], ['touchZoomMin', 0.5], ['touchZoomMax', 1.75], ['maxPixelRatio', 2], ['tree', false], ['treeHorizontalScroll', false]],
1398
- styles: [['activeCellBackgroundColor', 'rgba(255, 255, 255, 1)'], ['activeCellBorderColor', 'rgba(110, 168, 255, 1)'], ['activeCellBorderWidth', 1], ['activeCellColor', 'rgba(0, 0, 0, 1)'], ['activeCellFont', '16px sans-serif'], ['activeCellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'], ['activeCellHorizontalAlignment', 'left'], ['activeCellHoverColor', 'rgba(0, 0, 0, 1)'], ['activeCellOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['activeCellOverlayBorderWidth', 1], ['activeCellPaddingBottom', 5], ['activeCellPaddingLeft', 5], ['activeCellPaddingRight', 5], ['activeCellPaddingTop', 5], ['activeCellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'], ['activeCellSelectedColor', 'rgba(0, 0, 0, 1)'], ['activeCellVerticalAlignment', 'center'], ['activeColumnHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'], ['activeColumnHeaderCellColor', 'rgba(0, 0, 0, 1)'], ['activeRowHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'], ['activeRowHeaderCellColor', 'rgba(0, 0, 0, 1)'], ['autocompleteBottomMargin', 60], ['autosizeHeaderCellPadding', 8], ['autosizePadding', 5], ['buttonActiveBackgroundColor', 'rgba(255, 255, 255, 1)'], ['buttonActiveBorderColor', 'rgba(110, 168, 255, 1)'], ['buttonArrowColor', 'rgba(50, 50, 50, 1)'], ['buttonArrowDownHTML', '&#x25BC;'], ['buttonZIndex', 10000], ['buttonBackgroundColor', 'rgba(255, 255, 255, 1)'], ['buttonBorderColor', 'rgba(172, 172, 172, 1)'], ['buttonHoverBackgroundColor', 'rgba(240, 240, 240, 1)'], ['buttonMenuWindowMargin', 30], ['buttonPadding', '3px'], ['cellAutoResizePadding', 13], ['cellBackgroundColor', 'rgba(255, 255, 255, 1)'], ['cellBorderColor', 'rgba(195, 199, 202, 1)'], ['cellBorderWidth', 1], ['cellColor', 'rgba(0, 0, 0, 1)'], ['cellFont', '16px sans-serif'], ['cellGridHeight', 250], ['cellHeight', 24], ['cellHeightWithChildGrid', 150], ['cellHorizontalAlignment', 'left'], ['cellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'], ['cellHoverColor', 'rgba(0, 0, 0, 1)'], ['cellPaddingBottom', 5], ['cellPaddingLeft', 5], ['cellPaddingRight', 5], ['cellPaddingTop', 5], ['cellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'], ['cellSelectedColor', 'rgba(0, 0, 0, 1)'], ['cellVerticalAlignment', 'center'], ['cellWidth', 250], ['cellWidthWithChildGrid', 250], ['cellWhiteSpace', 'nowrap'], ['cellLineHeight', 1], ['cellLineSpacing', 3], ['childContextMenuArrowColor', 'rgba(43, 48, 43, 1)'], ['childContextMenuArrowHTML', '&#x25BA;'], ['childContextMenuMarginLeft', -11], ['childContextMenuMarginTop', -6], ['columnHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['columnHeaderCellBorderColor', 'rgba(172, 172, 172, 1)'], ['columnHeaderCellBorderWidth', 1], ['columnHeaderCellCapBackgroundColor', 'rgba(240, 240, 240, 1)'], ['columnHeaderCellCapBorderColor', 'rgba(172, 172, 172, 1)'], ['columnHeaderCellCapBorderWidth', 1], ['columnHeaderCellColor', 'rgba(50, 50, 50, 1)'], ['columnHeaderCellFont', '16px sans-serif'], ['columnHeaderCellHeight', 25], ['columnHeaderCellHorizontalAlignment', 'left'], ['columnHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['columnHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'], ['columnHeaderCellPaddingBottom', 5], ['columnHeaderCellPaddingLeft', 5], ['columnHeaderCellPaddingRight', 5], ['columnHeaderCellPaddingTop', 5], ['columnHeaderCellVerticalAlignment', 'center'], ['columnHeaderOrderByArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['columnHeaderOrderByArrowBorderWidth', 1], ['columnHeaderOrderByArrowColor', 'rgba(155, 155, 155, 1)'], ['columnHeaderOrderByArrowHeight', 8], ['columnHeaderOrderByArrowMarginLeft', 0], ['columnHeaderOrderByArrowMarginRight', 5], ['columnHeaderOrderByArrowMarginTop', 6], ['columnHeaderOrderByArrowWidth', 13], ['contextFilterButtonBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextFilterButtonBorderRadius', '3px'], ['contextFilterButtonHTML', '&#x25BC;'], ['contextFilterInputBackground', 'rgba(255,255,255,1)'], ['contextFilterInputBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextFilterInputBorderRadius', '0'], ['contextFilterInputColor', 'rgba(0,0,0,1)'], ['contextFilterInputFontFamily', 'sans-serif'], ['contextFilterInputFontSize', '14px'], ['contextFilterInvalidRegExpBackground', 'rgba(180, 6, 1, 1)'], ['contextFilterInvalidRegExpColor', 'rgba(255, 255, 255, 1)'], ['contextMenuArrowColor', 'rgba(43, 48, 43, 1)'], ['contextMenuArrowDownHTML', '&#x25BC;'], ['contextMenuArrowUpHTML', '&#x25B2;'], ['contextMenuBackground', 'rgba(240, 240, 240, 1)'], ['contextMenuBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextMenuBorderRadius', '3px'], ['contextMenuChildArrowFontSize', '12px'], ['contextMenuColor', 'rgba(43, 48, 43, 1)'], ['contextMenuCursor', 'default'], ['contextMenuFilterButtonFontFamily', 'sans-serif'], ['contextMenuFilterButtonFontSize', '10px'], ['contextMenuFilterInvalidExpresion', 'rgba(237, 155, 156, 1)'], ['contextMenuFontFamily', 'sans-serif'], ['contextMenuFontSize', '16px'], ['contextMenuHoverBackground', 'rgba(182, 205, 250, 1)'], ['contextMenuHoverColor', 'rgba(43, 48, 153, 1)'], ['contextMenuItemBorderRadius', '3px'], ['contextMenuItemMargin', '2px'], ['contextMenuLabelDisplay', 'inline-block'], ['contextMenuLabelMargin', '0 3px 0 0'], ['contextMenuLabelMaxWidth', '700px'], ['contextMenuLabelMinWidth', '75px'], ['contextMenuMarginLeft', 3], ['contextMenuMarginTop', -3], ['contextMenuOpacity', '0.98'], ['contextMenuPadding', '2px'], ['contextMenuWindowMargin', 30], ['contextMenuZIndex', 10000], ['cornerCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['cornerCellBorderColor', 'rgba(202, 202, 202, 1)'], ['debugBackgroundColor', 'rgba(0, 0, 0, .0)'], ['debugColor', 'rgba(255, 15, 24, 1)'], ['debugEntitiesColor', 'rgba(76, 231, 239, 1.00)'], ['debugFont', '11px sans-serif'], ['debugPerfChartBackground', 'rgba(29, 25, 26, 1.00)'], ['debugPerfChartTextColor', 'rgba(255, 255, 255, 0.8)'], ['debugPerformanceColor', 'rgba(252, 255, 37, 1.00)'], ['debugScrollHeightColor', 'rgba(248, 33, 103, 1.00)'], ['debugScrollWidthColor', 'rgba(66, 255, 27, 1.00)'], ['debugTouchPPSXColor', 'rgba(246, 102, 24, 1.00)'], ['debugTouchPPSYColor', 'rgba(186, 0, 255, 1.00)'], ['display', 'inline-block'], ['editCellBackgroundColor', 'white'], ['editCellBorder', 'solid 1px rgba(110, 168, 255, 1)'], ['editCellBoxShadow', '0 2px 5px rgba(0,0,0,0.4)'], ['editCellColor', 'black'], ['editCellFontFamily', 'sans-serif'], ['editCellFontSize', '16px'], ['editCellPaddingLeft', 4], ['editCellZIndex', 10000], ['filterButtonActiveBackgroundColor', 'rgba(225, 225, 225, 1)'], ['filterButtonArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['filterButtonArrowBorderWidth', 1], ['filterButtonArrowClickRadius', 5], ['filterButtonArrowColor', 'rgba(50, 50, 50, 1)'], ['filterButtonArrowHeight', 5], ['filterButtonArrowWidth', 8], ['filterButtonBackgroundColor', 'rgba(240, 240, 240, 1)'], ['filterButtonBorderColor', 'rgba(172, 172, 172, 1)'], ['filterButtonBorderRadius', 3], ['filterButtonHeight', 20], ['filterButtonHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['filterButtonMenuOffsetTop', 10], ['filterButtonWidth', 20], ['frozenMarkerHoverColor', 'rgba(236, 243, 255, 1)'], ['frozenMarkerHoverBorderColor', 'rgba(110, 168, 255, 1)'], ['frozenMarkerActiveColor', 'rgba(236, 243, 255, 1)'], ['frozenMarkerActiveBorderColor', 'rgba(110, 168, 255, 1)'], ['frozenMarkerColor', 'rgba(222, 222, 222, 1)'], ['frozenMarkerBorderColor', 'rgba(168, 168, 168, 1)'], ['frozenMarkerBorderWidth', 1], ['frozenMarkerWidth', 2], ['gridBackgroundColor', 'rgba(240, 240, 240, 1)'], ['gridBorderCollapse', 'collapse'], ['gridBorderColor', 'rgba(202, 202, 202, 1)'], ['gridBorderWidth', 1], ['height', 'auto'], ['maxHeight', 'inherit'], ['maxWidth', 'inherit'], ['minColumnWidth', 45], ['minHeight', 'inherit'], ['minRowHeight', 24], ['minWidth', 'inherit'], ['mobileContextMenuMargin', 10], ['mobileEditInputHeight', 30], ['mobileEditFontFamily', 'sans-serif'], ['mobileEditFontSize', '16px'], ['moveOverlayBorderWidth', 1], ['moveOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['moveOverlayBorderSegments', '12, 7'], ['name', 'default'], ['overflowY', 'auto'], ['overflowX', 'auto'], ['reorderMarkerBackgroundColor', 'rgba(0, 0, 0, 0.1)'], ['reorderMarkerBorderColor', 'rgba(0, 0, 0, 0.2)'], ['reorderMarkerBorderWidth', 1.25], ['reorderMarkerIndexBorderColor', 'rgba(66, 133, 244, 1)'], ['reorderMarkerIndexBorderWidth', 2.75], ['rowHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['rowHeaderCellBorderColor', 'rgba(200, 200, 200, 1)'], ['rowHeaderCellBorderWidth', 1], ['rowHeaderCellColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellFont', '16px sans-serif'], ['rowHeaderCellHeight', 25], ['rowHeaderCellHorizontalAlignment', 'left'], ['rowHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['rowHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'], ['rowHeaderCellPaddingBottom', 5], ['rowHeaderCellPaddingLeft', 5], ['rowHeaderCellPaddingRight', 5], ['rowHeaderCellPaddingTop', 5], ['rowHeaderCellRowNumberGapHeight', 5], ['rowHeaderCellRowNumberGapColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellSelectedBackgroundColor', 'rgba(217, 217, 217, 1)'], ['rowHeaderCellSelectedColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellVerticalAlignment', 'center'], ['rowHeaderCellWidth', 57], ['scrollBarActiveColor', 'rgba(125, 125, 125, 1)'], ['scrollBarBackgroundColor', 'rgba(240, 240, 240, 1)'], ['scrollBarBorderColor', 'rgba(202, 202, 202, 1)'], ['scrollBarBorderWidth', 0.5], ['scrollBarBoxBorderRadius', 4.125], ['scrollBarBoxColor', 'rgba(192, 192, 192, 1)'], ['scrollBarBoxMargin', 2], ['scrollBarBoxMinSize', 15], ['scrollBarBoxWidth', 8], ['scrollBarCornerBackgroundColor', 'rgba(240, 240, 240, 1)'], ['scrollBarCornerBorderColor', 'rgba(202, 202, 202, 1)'], ['scrollBarWidth', 11], ['selectionHandleBorderColor', 'rgba(255, 255, 255, 1)'], ['selectionHandleBorderWidth', 1.5], ['selectionHandleColor', 'rgba(66, 133, 244, 1)'], ['selectionHandleSize', 8], ['selectionHandleType', 'square'], ['selectionOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['selectionOverlayBorderWidth', 1], ['treeArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['treeArrowBorderWidth', 1], ['treeArrowClickRadius', 5], ['treeArrowColor', 'rgba(155, 155, 155, 1)'], ['treeArrowHeight', 8], ['treeArrowMarginLeft', 0], ['treeArrowMarginRight', 5], ['treeArrowMarginTop', 6], ['treeArrowWidth', 13], ['treeGridHeight', 250], ['width', 'auto']]
1700
+ attributes: [['allowColumnReordering', true], ['allowColumnResize', true], ['allowColumnResizeFromCell', false], ['allowFreezingRows', false], ['allowFreezingColumns', false], ['allowMovingSelection', true], ['allowRowHeaderResize', true], ['allowRowReordering', false], ['allowRowResize', true], ['allowRowResizeFromCell', false], ['allowSorting', true], ['allowGroupingRows', true], ['allowGroupingColumns', true], ['animationDurationShowContextMenu', 50], ['animationDurationHideContextMenu', 50], ['autoGenerateSchema', false], ['autoResizeColumns', false], ['autoResizeRows', false], ['autoScrollOnMousemove', false], ['autoScrollMargin', 5], ['blanksText', '(Blanks)'], ['borderDragBehavior', 'none'], ['borderResizeZone', 10], ['clearSettingsOptionText', 'Clear saved settings'], ['columnHeaderClickBehavior', 'sort'], ['columnSelectorHiddenText', '&nbsp;&nbsp;&nbsp;'], ['columnSelectorText', 'Add/Remove columns'], ['columnSelectorVisibleText', "\u2713"], ['contextHoverScrollAmount', 2], ['contextHoverScrollRateMs', 5], ['copyHeadersOnSelectAll', true], ['copyText', 'Copy'], ['debug', false], ['editable', true], ['ellipsisText', '...'], ['filterOptionText', 'Filter %s'], ['filterTextPrefix', '(filtered) '], ['filterFrozenRows', true], ['globalRowResize', false], ['hideColumnText', 'Hide %s'], ['hoverMode', 'cell'], ['keepFocusOnMouseOut', false], ['maxAutoCompleteItems', 200], ['multiLine', false], ['name', ''], ['pageUpDownOverlap', 1], ['pasteText', 'Paste'], ['persistantSelectionMode', false], ['removeFilterOptionText', 'Remove filter on %s'], ['reorderDeadZone', 3], ['resizeScrollZone', 20], ['rowGrabZoneSize', 5], ['saveAppearance', true], ['scrollAnimationPPSThreshold', 0.75], ['scrollPointerLock', false], ['scrollRepeatRate', 75], ['selectionFollowsActiveCell', false], ['selectionHandleBehavior', 'none'], ['selectionMode', 'cell'], ['selectionScrollIncrement', 20], ['selectionScrollZone', 20], ['showClearSettingsOption', true], ['showColumnHeaders', true], ['showColumnSelector', true], ['showCopy', false], ['showFilter', true], ['showFilterInCell', false], ['showNewRow', false], ['showOrderByOption', true], ['showOrderByOptionTextAsc', 'Order by %s ascending'], ['showOrderByOptionTextDesc', 'Order by %s descending'], //#region grouping
1701
+ ['showGroupColumns', 'Group columns %s'], ['showGroupRows', 'Group rows %s'], ['showRemoveGroupColumns', 'Remove group %s'], ['showRemoveGroupRows', 'Remove group %s'], ['showRemoveAllGroupColumns', 'Remove all column groups'], ['showRemoveAllGroupRows', 'Remove all row groups'], ['showExpandAllGroupColumns', 'Expand all column groups'], ['showExpandAllGroupRows', 'Expand all row groups'], ['showCollapseAllGroupColumns', 'Collapse all column groups'], ['showCollapseAllGroupRows', 'Collapse all row groups'], ['columnGroupIndicatorPosition', 'right'], ['rowGroupIndicatorPosition', 'bottom'], //#endregion grouping
1702
+ ['showPaste', false], ['showPerformance', false], ['showRowHeaders', true], ['showRowNumbers', true], ['showRowNumberGaps', true], ['singleSelectionMode', false], ['snapToRow', false], ['sortFrozenRows', true], ['touchContextMenuTimeMs', 800], ['touchDeadZone', 3], ['touchEasingMethod', 'easeOutQuad'], ['touchReleaseAcceleration', 1000], ['touchReleaseAnimationDurationMs', 2000], ['touchScrollZone', 20], ['touchSelectHandleZone', 20], ['touchZoomSensitivity', 0.005], ['touchZoomMin', 0.5], ['touchZoomMax', 1.75], ['maxPixelRatio', 2], ['tree', false], ['treeHorizontalScroll', false], ['rowTree', []], ['rowTreeColIndex', 0], ['columnTree', []], ['columnTreeRowStartIndex', 0], ['columnTreeRowEndIndex', 0]],
1703
+ styles: [['activeCellBackgroundColor', 'rgba(255, 255, 255, 1)'], ['activeCellBorderColor', 'rgba(110, 168, 255, 1)'], ['activeCellBorderWidth', 1], ['activeCellColor', 'rgba(0, 0, 0, 1)'], ['activeCellFont', '16px sans-serif'], ['activeCellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'], ['activeCellHorizontalAlignment', 'left'], ['activeCellHoverColor', 'rgba(0, 0, 0, 1)'], ['activeCellOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['activeCellOverlayBorderWidth', 1], ['activeCellPaddingBottom', 5], ['activeCellPaddingLeft', 5], ['activeCellPaddingRight', 5], ['activeCellPaddingTop', 5], ['activeCellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'], ['activeCellSelectedColor', 'rgba(0, 0, 0, 1)'], ['activeCellVerticalAlignment', 'center'], ['activeColumnHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'], ['activeColumnHeaderCellColor', 'rgba(0, 0, 0, 1)'], ['activeRowHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'], ['activeRowHeaderCellColor', 'rgba(0, 0, 0, 1)'], ['autocompleteBottomMargin', 60], ['autosizeHeaderCellPadding', 8], ['autosizePadding', 5], ['buttonActiveBackgroundColor', 'rgba(255, 255, 255, 1)'], ['buttonActiveBorderColor', 'rgba(110, 168, 255, 1)'], ['buttonArrowColor', 'rgba(50, 50, 50, 1)'], ['buttonArrowDownHTML', '&#x25BC;'], ['buttonZIndex', 10000], ['buttonBackgroundColor', 'rgba(255, 255, 255, 1)'], ['buttonBorderColor', 'rgba(172, 172, 172, 1)'], ['buttonHoverBackgroundColor', 'rgba(240, 240, 240, 1)'], ['buttonMenuWindowMargin', 30], ['buttonPadding', '3px'], ['cellAutoResizePadding', 13], ['cellBackgroundColor', 'rgba(255, 255, 255, 1)'], ['cellBorderColor', 'rgba(195, 199, 202, 1)'], ['cellBorderWidth', 1], ['cellColor', 'rgba(0, 0, 0, 1)'], ['cellFont', '16px sans-serif'], ['cellGridHeight', 250], ['cellHeight', 24], ['cellHeightWithChildGrid', 150], ['cellHorizontalAlignment', 'left'], ['cellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'], ['cellHoverColor', 'rgba(0, 0, 0, 1)'], ['cellPaddingBottom', 5], ['cellPaddingLeft', 5], ['cellPaddingRight', 5], ['cellPaddingTop', 5], ['cellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'], ['cellSelectedColor', 'rgba(0, 0, 0, 1)'], ['cellTreeIconBorderColor', 'rgba(162, 174, 207, 1)'], ['cellTreeIconFillColor', 'rgba(240, 240, 240, 1)'], ['cellTreeIconHoverFillColor', 'rgba(198, 217, 233, 1)'], ['cellTreeIconLineColor', 'rgba(43, 53, 81, 1)'], ['cellTreeIconLineWidth', 1.5], ['cellTreeIconMarginLeft', 0], ['cellTreeIconMarginRight', 5], ['cellTreeIconMarginTop', 6], ['cellTreeIconWidth', 13], ['cellVerticalAlignment', 'center'], ['cellWidth', 250], ['cellWidthWithChildGrid', 250], ['cellWhiteSpace', 'nowrap'], ['cellLineHeight', 1], ['cellLineSpacing', 3], ['childContextMenuArrowColor', 'rgba(43, 48, 43, 1)'], ['childContextMenuArrowHTML', '&#x25BA;'], ['childContextMenuMarginLeft', -11], ['childContextMenuMarginTop', -6], ['columnGroupRowHeight', 25], ['columnHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['columnHeaderCellBorderColor', 'rgba(172, 172, 172, 1)'], ['columnHeaderCellBorderWidth', 1], ['columnHeaderCellCapBackgroundColor', 'rgba(240, 240, 240, 1)'], ['columnHeaderCellCapBorderColor', 'rgba(172, 172, 172, 1)'], ['columnHeaderCellCapBorderWidth', 1], ['columnHeaderCellColor', 'rgba(50, 50, 50, 1)'], ['columnHeaderCellFont', '16px sans-serif'], ['columnHeaderCellHeight', 25], ['columnHeaderCellHorizontalAlignment', 'left'], ['columnHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['columnHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'], ['columnHeaderCellPaddingBottom', 5], ['columnHeaderCellPaddingLeft', 5], ['columnHeaderCellPaddingRight', 5], ['columnHeaderCellPaddingTop', 5], ['columnHeaderCellVerticalAlignment', 'center'], ['columnHeaderOrderByArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['columnHeaderOrderByArrowBorderWidth', 1], ['columnHeaderOrderByArrowColor', 'rgba(155, 155, 155, 1)'], ['columnHeaderOrderByArrowHeight', 8], ['columnHeaderOrderByArrowMarginLeft', 0], ['columnHeaderOrderByArrowMarginRight', 5], ['columnHeaderOrderByArrowMarginTop', 6], ['columnHeaderOrderByArrowWidth', 13], ['contextFilterButtonBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextFilterButtonBorderRadius', '3px'], ['contextFilterButtonHTML', '&#x25BC;'], ['contextFilterInputBackground', 'rgba(255,255,255,1)'], ['contextFilterInputBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextFilterInputBorderRadius', '0'], ['contextFilterInputColor', 'rgba(0,0,0,1)'], ['contextFilterInputFontFamily', 'sans-serif'], ['contextFilterInputFontSize', '14px'], ['contextFilterInvalidRegExpBackground', 'rgba(180, 6, 1, 1)'], ['contextFilterInvalidRegExpColor', 'rgba(255, 255, 255, 1)'], ['contextMenuArrowColor', 'rgba(43, 48, 43, 1)'], ['contextMenuArrowDownHTML', '&#x25BC;'], ['contextMenuArrowUpHTML', '&#x25B2;'], ['contextMenuBackground', 'rgba(240, 240, 240, 1)'], ['contextMenuBorder', 'solid 1px rgba(158, 163, 169, 1)'], ['contextMenuBorderRadius', '3px'], ['contextMenuChildArrowFontSize', '12px'], ['contextMenuColor', 'rgba(43, 48, 43, 1)'], ['contextMenuCursor', 'default'], ['contextMenuFilterButtonFontFamily', 'sans-serif'], ['contextMenuFilterButtonFontSize', '10px'], ['contextMenuFilterInvalidExpresion', 'rgba(237, 155, 156, 1)'], ['contextMenuFontFamily', 'sans-serif'], ['contextMenuFontSize', '16px'], ['contextMenuHoverBackground', 'rgba(182, 205, 250, 1)'], ['contextMenuHoverColor', 'rgba(43, 48, 153, 1)'], ['contextMenuItemBorderRadius', '3px'], ['contextMenuItemMargin', '2px'], ['contextMenuLabelDisplay', 'inline-block'], ['contextMenuLabelMargin', '0 3px 0 0'], ['contextMenuLabelMaxWidth', '700px'], ['contextMenuLabelMinWidth', '75px'], ['contextMenuMarginLeft', 3], ['contextMenuMarginTop', -3], ['contextMenuOpacity', '0.98'], ['contextMenuPadding', '2px'], ['contextMenuWindowMargin', 30], ['contextMenuZIndex', 10000], ['cornerCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['cornerCellBorderColor', 'rgba(202, 202, 202, 1)'], ['debugBackgroundColor', 'rgba(0, 0, 0, .0)'], ['debugColor', 'rgba(255, 15, 24, 1)'], ['debugEntitiesColor', 'rgba(76, 231, 239, 1.00)'], ['debugFont', '11px sans-serif'], ['debugPerfChartBackground', 'rgba(29, 25, 26, 1.00)'], ['debugPerfChartTextColor', 'rgba(255, 255, 255, 0.8)'], ['debugPerformanceColor', 'rgba(252, 255, 37, 1.00)'], ['debugScrollHeightColor', 'rgba(248, 33, 103, 1.00)'], ['debugScrollWidthColor', 'rgba(66, 255, 27, 1.00)'], ['debugTouchPPSXColor', 'rgba(246, 102, 24, 1.00)'], ['debugTouchPPSYColor', 'rgba(186, 0, 255, 1.00)'], ['display', 'inline-block'], ['editCellBackgroundColor', 'white'], ['editCellBorder', 'solid 1px rgba(110, 168, 255, 1)'], ['editCellBoxShadow', '0 2px 5px rgba(0,0,0,0.4)'], ['editCellColor', 'black'], ['editCellFontFamily', 'sans-serif'], ['editCellFontSize', '16px'], ['editCellPaddingLeft', 4], ['editCellZIndex', 10000], ['filterButtonActiveBackgroundColor', 'rgba(225, 225, 225, 1)'], ['filterButtonArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['filterButtonArrowBorderWidth', 1], ['filterButtonArrowClickRadius', 5], ['filterButtonArrowColor', 'rgba(50, 50, 50, 1)'], ['filterButtonArrowHeight', 5], ['filterButtonArrowWidth', 8], ['filterButtonBackgroundColor', 'rgba(240, 240, 240, 1)'], ['filterButtonBorderColor', 'rgba(172, 172, 172, 1)'], ['filterButtonBorderRadius', 3], ['filterButtonHeight', 20], ['filterButtonHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['filterButtonMenuOffsetTop', 10], ['filterButtonWidth', 20], ['frozenMarkerHoverColor', 'rgba(236, 243, 255, 1)'], ['frozenMarkerHoverBorderColor', 'rgba(110, 168, 255, 1)'], ['frozenMarkerActiveColor', 'rgba(236, 243, 255, 1)'], ['frozenMarkerActiveBorderColor', 'rgba(110, 168, 255, 1)'], ['frozenMarkerColor', 'rgba(222, 222, 222, 1)'], ['frozenMarkerBorderColor', 'rgba(168, 168, 168, 1)'], ['frozenMarkerBorderWidth', 1], ['frozenMarkerWidth', 2], ['groupingAreaBackgroundColor', 'rgba(240, 240, 240, 1)'], ['gridBackgroundColor', 'rgba(240, 240, 240, 1)'], ['gridBorderCollapse', 'collapse'], ['gridBorderColor', 'rgba(202, 202, 202, 1)'], ['gridBorderWidth', 1], ['groupIndicatorColor', 'rgba(155, 155, 155, 1)'], ['groupIndicatorBackgroundColor', 'rgba(255, 255, 255, 1)'], ['height', 'auto'], ['maxHeight', 'inherit'], ['maxWidth', 'inherit'], ['minColumnWidth', 45], ['minHeight', 'inherit'], ['minRowHeight', 24], ['minWidth', 'inherit'], ['mobileContextMenuMargin', 10], ['mobileEditInputHeight', 30], ['mobileEditFontFamily', 'sans-serif'], ['mobileEditFontSize', '16px'], ['moveOverlayBorderWidth', 1], ['moveOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['moveOverlayBorderSegments', '12, 7'], ['name', 'default'], ['overflowY', 'auto'], ['overflowX', 'auto'], ['reorderMarkerBackgroundColor', 'rgba(0, 0, 0, 0.1)'], ['reorderMarkerBorderColor', 'rgba(0, 0, 0, 0.2)'], ['reorderMarkerBorderWidth', 1.25], ['reorderMarkerIndexBorderColor', 'rgba(66, 133, 244, 1)'], ['reorderMarkerIndexBorderWidth', 2.75], ['rowGroupColumnWidth', 25], ['rowHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'], ['rowHeaderCellBorderColor', 'rgba(200, 200, 200, 1)'], ['rowHeaderCellBorderWidth', 1], ['rowHeaderCellColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellFont', '16px sans-serif'], ['rowHeaderCellHeight', 25], ['rowHeaderCellHorizontalAlignment', 'left'], ['rowHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'], ['rowHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'], ['rowHeaderCellPaddingBottom', 5], ['rowHeaderCellPaddingLeft', 5], ['rowHeaderCellPaddingRight', 5], ['rowHeaderCellPaddingTop', 5], ['rowHeaderCellRowNumberGapHeight', 5], ['rowHeaderCellRowNumberGapColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellSelectedBackgroundColor', 'rgba(217, 217, 217, 1)'], ['rowHeaderCellSelectedColor', 'rgba(50, 50, 50, 1)'], ['rowHeaderCellVerticalAlignment', 'center'], ['rowHeaderCellWidth', 57], ['scrollBarActiveColor', 'rgba(125, 125, 125, 1)'], ['scrollBarBackgroundColor', 'rgba(240, 240, 240, 1)'], ['scrollBarBorderColor', 'rgba(202, 202, 202, 1)'], ['scrollBarBorderWidth', 0.5], ['scrollBarBoxBorderRadius', 4.125], ['scrollBarBoxColor', 'rgba(192, 192, 192, 1)'], ['scrollBarBoxMargin', 2], ['scrollBarBoxMinSize', 15], ['scrollBarBoxWidth', 8], ['scrollBarCornerBackgroundColor', 'rgba(240, 240, 240, 1)'], ['scrollBarCornerBorderColor', 'rgba(202, 202, 202, 1)'], ['scrollBarWidth', 11], ['selectionHandleBorderColor', 'rgba(255, 255, 255, 1)'], ['selectionHandleBorderWidth', 1.5], ['selectionHandleColor', 'rgba(66, 133, 244, 1)'], ['selectionHandleSize', 8], ['selectionHandleType', 'square'], ['selectionOverlayBorderColor', 'rgba(66, 133, 244, 1)'], ['selectionOverlayBorderWidth', 1], ['treeArrowBorderColor', 'rgba(195, 199, 202, 1)'], ['treeArrowBorderWidth', 1], ['treeArrowClickRadius', 5], ['treeArrowColor', 'rgba(155, 155, 155, 1)'], ['treeArrowHeight', 8], ['treeArrowMarginLeft', 0], ['treeArrowMarginRight', 5], ['treeArrowMarginTop', 6], ['treeArrowWidth', 13], ['treeGridHeight', 250], ['width', 'auto']]
1399
1704
  };
1400
1705
  }
1401
1706
 
@@ -1524,8 +1829,19 @@ __webpack_require__.r(__webpack_exports__);
1524
1829
  return;
1525
1830
  }
1526
1831
 
1527
- self.input.style.left = pos.left + cell.x + self.canvasOffsetLeft - s.left + 'px';
1528
- self.input.style.top = pos.top + cell.y - self.style.cellBorderWidth + self.canvasOffsetTop - s.top + 'px';
1832
+ var groupAreaOffsetY = self.getColumnGroupAreaHeight();
1833
+ var groupAreaOffsetX = self.getRowGroupAreaWidth();
1834
+
1835
+ if (self.parentNode) {
1836
+ var _self$parentNode = self.parentNode,
1837
+ columnGroupsAreaHeight = _self$parentNode.columnGroupsAreaHeight,
1838
+ rowGroupsAreaWidth = _self$parentNode.rowGroupsAreaWidth;
1839
+ if (columnGroupsAreaHeight) groupAreaOffsetY += columnGroupsAreaHeight;
1840
+ if (rowGroupsAreaWidth) groupAreaOffsetX += rowGroupsAreaWidth;
1841
+ }
1842
+
1843
+ self.input.style.left = pos.left + cell.x + self.canvasOffsetLeft - s.left + groupAreaOffsetX + 'px';
1844
+ self.input.style.top = pos.top + cell.y - self.style.cellBorderWidth + self.canvasOffsetTop - s.top + groupAreaOffsetY + 'px';
1529
1845
  self.input.style.height = cell.height - borderWidth + 'px';
1530
1846
  self.input.style.width = cell.width - self.style.cellPaddingLeft + 'px';
1531
1847
  self.clipElement(self.input);
@@ -1538,12 +1854,19 @@ __webpack_require__.r(__webpack_exports__);
1538
1854
  s = e,
1539
1855
  h,
1540
1856
  w;
1857
+ var calculatedTree = false;
1541
1858
 
1542
1859
  while (e.offsetParent && e.nodeName !== 'CANVAS-DATAGRID') {
1543
- x += e.offsetLeft;
1544
- y += e.offsetTop;
1545
- h = e.offsetHeight;
1546
- w = e.offsetWidth;
1860
+ var isTree = e.nodeType === 'canvas-datagrid-tree';
1861
+
1862
+ if (!isTree || !calculatedTree) {
1863
+ x += e.offsetLeft;
1864
+ y += e.offsetTop;
1865
+ h = e.offsetHeight;
1866
+ w = e.offsetWidth;
1867
+ }
1868
+
1869
+ if (isTree) calculatedTree = true;
1547
1870
  e = e.offsetParent;
1548
1871
  }
1549
1872
 
@@ -1576,6 +1899,8 @@ __webpack_require__.r(__webpack_exports__);
1576
1899
  if (self.isChildGrid) {
1577
1900
  pos.x -= self.canvasOffsetLeft;
1578
1901
  pos.y -= self.canvasOffsetTop;
1902
+ if (self.parentNode.rowGroupsAreaWidth) pos.x -= self.parentNode.rowGroupsAreaWidth;
1903
+ if (self.parentNode.columnGroupsAreaHeight) pos.y -= self.parentNode.columnGroupsAreaHeight;
1579
1904
  }
1580
1905
 
1581
1906
  return {
@@ -2344,6 +2669,40 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2344
2669
 
2345
2670
  img.src = 'data:image/svg+xml;base64,' + btoa('<svg xmlns="http://www.w3.org/2000/svg" width="' + cell.width + '" height="' + cell.height + '">\n' + '<foreignObject class="node" x="0" y="0" width="100%" height="100%">\n' + '<body xmlns="http://www.w3.org/1999/xhtml" style="margin:0;padding:0;">\n' + v + '\n' + '</body>' + '</foreignObject>\n' + '</svg>\n');
2346
2671
  }
2672
+ /**
2673
+ * @param {number[]} coords [x0,y0, x1,y1, x2,y2, ...]
2674
+ */
2675
+
2676
+
2677
+ function strokeLines(coords) {
2678
+ if (coords.length < 4) return;
2679
+ self.ctx.beginPath();
2680
+ self.ctx.moveTo(coords[0] + self.canvasOffsetLeft, coords[1] + self.canvasOffsetTop);
2681
+
2682
+ for (var i = 2; i < coords.length; i += 2) {
2683
+ var x = coords[i] + self.canvasOffsetLeft;
2684
+ var y = coords[i + 1] + self.canvasOffsetTop;
2685
+ self.ctx.lineTo(x, y);
2686
+ }
2687
+
2688
+ self.ctx.stroke();
2689
+ }
2690
+ /**
2691
+ * @param {number} x based-X (left-top)
2692
+ * @param {number} y based-Y (left-top)
2693
+ * @param {number} width
2694
+ * @param {boolean} collapsed true: '+'; false: '-'
2695
+ */
2696
+
2697
+
2698
+ function drawGroupHandle(x, y, width, collapsed) {
2699
+ fillRect(x, y, width, width);
2700
+ strokeRect(x, y, width, width);
2701
+ var cx = x + width * 0.5;
2702
+ var cy = y + width * 0.5;
2703
+ strokeLines([x + width * 0.2, cy, x + width * 0.78, cy]);
2704
+ if (collapsed) strokeLines([cx, y + width * 0.22, cx, y + width * 0.8]);
2705
+ }
2347
2706
 
2348
2707
  function drawOrderByArrow(x, y) {
2349
2708
  var mt = self.style.columnHeaderOrderByArrowMarginTop * self.scale,
@@ -2407,6 +2766,52 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2407
2766
  return ml + aw + mr;
2408
2767
  }
2409
2768
 
2769
+ function drawCellTreeIcon(cell, tree, rowTree) {
2770
+ var parentCount = rowTree ? tree.parentCount : 0;
2771
+ var iconSize = self.style.cellTreeIconWidth * self.scale,
2772
+ marginTop = self.style.cellTreeIconMarginTop * self.scale,
2773
+ marginRight = self.style.cellTreeIconMarginRight * self.scale,
2774
+ marginLeft = self.style.cellTreeIconMarginLeft * self.scale + parentCount * (iconSize + cell.paddingLeft);
2775
+ var x = cell.x + cell.paddingLeft + self.canvasOffsetLeft + marginLeft,
2776
+ y = cell.y + self.canvasOffsetTop + marginTop;
2777
+
2778
+ if (tree.icon) {
2779
+ self.ctx.beginPath();
2780
+ var oldFillStyle = self.ctx.fillStyle;
2781
+ var oldStrokeStyle = self.ctx.strokeStyle;
2782
+
2783
+ if (cell.hovered && self.hovers.onCellTreeIcon) {
2784
+ self.ctx.fillStyle = self.style.cellTreeIconHoverFillColor;
2785
+ } else {
2786
+ self.ctx.fillStyle = self.style.cellTreeIconFillColor;
2787
+ }
2788
+
2789
+ self.ctx.fillRect(x, y, iconSize, iconSize);
2790
+ self.ctx.strokeStyle = self.style.cellTreeIconBorderColor;
2791
+ self.ctx.rect(x, y, iconSize, iconSize);
2792
+ self.ctx.stroke();
2793
+ self.ctx.beginPath();
2794
+
2795
+ if (tree.expand) {
2796
+ self.ctx.moveTo(x + 3, y + iconSize * 0.5);
2797
+ self.ctx.lineTo(x + iconSize - 3, y + iconSize * 0.5);
2798
+ } else {
2799
+ self.ctx.moveTo(x + 2, y + iconSize * 0.5);
2800
+ self.ctx.lineTo(x + iconSize - 2, y + iconSize * 0.5);
2801
+ self.ctx.moveTo(x + iconSize * 0.5, y + 2);
2802
+ self.ctx.lineTo(x + iconSize * 0.5, y + iconSize - 2);
2803
+ }
2804
+
2805
+ self.ctx.lineWidth = self.style.cellTreeIconLineWidth;
2806
+ self.ctx.strokeStyle = self.style.cellTreeIconLineColor;
2807
+ self.ctx.stroke();
2808
+ self.ctx.strokeStyle = oldStrokeStyle;
2809
+ self.ctx.fillStyle = oldFillStyle;
2810
+ }
2811
+
2812
+ return marginLeft + iconSize + marginRight;
2813
+ }
2814
+
2410
2815
  function drawFilterButtonArrow(x, y) {
2411
2816
  var mt = (self.style.filterButtonHeight - self.style.filterButtonArrowHeight) / 2 * self.scale,
2412
2817
  ml = (self.style.filterButtonWidth - self.style.filterButtonArrowWidth) / 2 * self.scale,
@@ -2712,6 +3117,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2712
3117
  }
2713
3118
 
2714
3119
  function drawText(cell) {
3120
+ var treeCellPadding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
2715
3121
  var ll = cell.text.lines.length,
2716
3122
  h = cell.fontHeight * cell.lineHeight,
2717
3123
  x,
@@ -2722,12 +3128,12 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2722
3128
  for (x = 0; x < cell.text.lines.length; x += 1) {
2723
3129
  line = cell.text.lines[x];
2724
3130
  var vPos = Math.max((cell.height - (wrap ? cell.text.height : cell.calculatedLineHeight)) * 0.5, 0) + h,
2725
- hPos = cell.paddingLeft + cell.treeArrowWidth + cell.orderByArrowWidth;
3131
+ hPos = cell.paddingLeft + treeCellPadding + cell.treeArrowWidth + cell.orderByArrowWidth;
2726
3132
 
2727
3133
  if (cell.horizontalAlignment === 'right') {
2728
- hPos = cell.paddingLeft + cell.paddedWidth - line.width;
3134
+ hPos = cell.paddingLeft + treeCellPadding + cell.paddedWidth - line.width;
2729
3135
  } else if (cell.horizontalAlignment === 'center') {
2730
- hPos = cell.paddingLeft + (cell.paddedWidth + cell.paddingRight) / 2 - line.width / 2;
3136
+ hPos = cell.paddingLeft + treeCellPadding + (cell.paddedWidth + cell.paddingRight) / 2 - line.width / 2;
2731
3137
  }
2732
3138
 
2733
3139
  if (cell.verticalAlignment === 'top') {
@@ -2773,6 +3179,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2773
3179
  s = self.getSchema(),
2774
3180
  x = 0,
2775
3181
  n = Math.min(self.frozenColumn, s.length),
3182
+ collapsedGroups = self.getCollapsedColumnGroups(),
2776
3183
  column;
2777
3184
  hiddenFrozenColumnCount = 0;
2778
3185
 
@@ -2782,7 +3189,15 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2782
3189
  if (column.hidden) {
2783
3190
  hiddenFrozenColumnCount += 1;
2784
3191
  } else {
2785
- w += self.getColumnWidth(x);
3192
+ var isCollapsed = collapsedGroups.findIndex(function (group) {
3193
+ return x >= group.from && x <= group.to;
3194
+ }) >= 0;
3195
+
3196
+ if (isCollapsed) {
3197
+ hiddenFrozenColumnCount += 1;
3198
+ } else {
3199
+ w += self.getColumnWidth(x);
3200
+ }
2786
3201
  }
2787
3202
 
2788
3203
  x += 1;
@@ -2860,6 +3275,19 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2860
3275
  u = self.currentCell || {},
2861
3276
  columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
2862
3277
  rowHeaderCellWidth = self.getRowHeaderCellWidth(),
3278
+ rowGroupsAreaWidth = self.getRowGroupAreaWidth(),
3279
+ columnGroupsAreaHeight = self.getColumnGroupAreaHeight(),
3280
+
3281
+ /** key: boundRowIndex, value: `{y,h}` */
3282
+ rowGroupsRectInfo = {},
3283
+
3284
+ /** value: `{y,h}` */
3285
+ rowGroupsFrozenInfo = {},
3286
+
3287
+ /** key: columnIndex, value: `{x,w}` */
3288
+ columnGroupsRectInfo = {},
3289
+ collapsedColumnGroups = self.getCollapsedColumnGroups(),
3290
+ collapsedRowGroups = self.getCollapsedRowGroups(),
2863
3291
  cellHeight = self.style.cellHeight;
2864
3292
  drawCount += 1;
2865
3293
  p = performance.now();
@@ -2869,6 +3297,36 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
2869
3297
  self.createRowOrders();
2870
3298
  }
2871
3299
 
3300
+ function saveRowGroupsRectInfo(cell) {
3301
+ var index = cell.boundRowIndex;
3302
+ if (index >= -1 === false) if (cell.rowIndex === -1) index = -1;else return;
3303
+ if (rowGroupsRectInfo[index]) return;
3304
+ rowGroupsRectInfo[index] = {
3305
+ y: cell.y,
3306
+ h: cell.height
3307
+ };
3308
+ }
3309
+
3310
+ function saveColumnGroupsRectInfo(cell) {
3311
+ var index = cell.columnIndex;
3312
+ if (columnGroupsRectInfo[index]) return;
3313
+ columnGroupsRectInfo[index] = {
3314
+ x: cell.x,
3315
+ w: cell.width
3316
+ };
3317
+ }
3318
+ /**
3319
+ * @param {number} columnIndex
3320
+ * @returns {boolean}
3321
+ */
3322
+
3323
+
3324
+ function isColumnCollapsedByGroup(columnIndex) {
3325
+ return collapsedColumnGroups.findIndex(function (group) {
3326
+ return columnIndex >= group.from && columnIndex <= group.to;
3327
+ }) >= 0;
3328
+ }
3329
+
2872
3330
  function drawScrollBars() {
2873
3331
  var drawCorner,
2874
3332
  en = self.scrollBox.entities,
@@ -3119,7 +3577,9 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3119
3577
  parentGrid: self.intf,
3120
3578
  innerHTML: '',
3121
3579
  activeHeader: activeHeader,
3122
- value: isHeader && !isRowHeader ? header.title || header.name : rawValue
3580
+ value: isHeader && !isRowHeader ? header.title || header.name : rawValue,
3581
+ isRowTree: rowOrderIndex >= 0 && columnOrderIndex == self.cellTree.rowTreeColIndex && self.cellTree.rows.length > 0 && self.cellTree.rows[rowOrderIndex].icon,
3582
+ isColumnTree: columnOrderIndex >= 0 && self.cellTree.columns[rowOrderIndex] && self.cellTree.columns[rowOrderIndex][columnOrderIndex].icon
3123
3583
  };
3124
3584
  cell.calculatedLineHeight = cell.fontHeight * cell.lineHeight + cell.lineSpacing;
3125
3585
  cell.paddedWidth = cell.width - cell.paddingRight - cell.paddingLeft;
@@ -3128,6 +3588,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3128
3588
  cell.userHeight = cell.isHeader ? self.sizes.rows[-1] : rowHeight;
3129
3589
  cell.userWidth = cell.isHeader ? self.sizes.columns.cornerCell : self.sizes.columns[headerIndex];
3130
3590
  self.visibleCells.unshift(cell);
3591
+ saveRowGroupsRectInfo(cell);
3592
+ saveColumnGroupsRectInfo(cell);
3131
3593
 
3132
3594
  if (self.dispatchEvent('beforerendercell', ev)) {
3133
3595
  return;
@@ -3270,7 +3732,27 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3270
3732
  if (cell.innerHTML || header.type === 'html') {
3271
3733
  drawHtml(cell);
3272
3734
  } else {
3273
- drawText(cell);
3735
+ var treeCellPadding = 0,
3736
+ isDrawText = true;
3737
+ if (cell.columnIndex == self.cellTree.rowTreeColIndex && !cell.isColumnHeader && self.cellTree.rows.length > 0 && Object.keys(self.cellTree.rows[cell.rowIndex]).length > 1) treeCellPadding = drawCellTreeIcon(cell, self.cellTree.rows[cell.rowIndex], true);
3738
+
3739
+ if (!cell.isRowHeader && cell.rowIndex > 0 && self.cellTree.columns[cell.rowIndex - 1] && self.cellTree.columns[cell.rowIndex - 1][cell.columnIndex].icon) {
3740
+ for (var r = cell.rowIndex - 1; r >= 0; r--) {
3741
+ if (!self.cellTree.columns[r]) break;
3742
+ if (!self.cellTree.columns[r][cell.columnIndex].icon) break;
3743
+
3744
+ if (!self.cellTree.columns[r][cell.columnIndex].expand) {
3745
+ isDrawText = false;
3746
+ break;
3747
+ }
3748
+ }
3749
+ }
3750
+
3751
+ if (isDrawText && !cell.isRowHeader && self.cellTree.columns[cell.rowIndex] && self.cellTree.columns[cell.rowIndex][cell.columnIndex].icon) {
3752
+ if (self.viewData.length > 0 && self.viewData[cell.rowIndex][cell.columnIndex].length > 0) treeCellPadding = drawCellTreeIcon(cell, self.cellTree.columns[cell.rowIndex][cell.columnIndex], false);
3753
+ }
3754
+
3755
+ if (isDrawText) drawText(cell, treeCellPadding);
3274
3756
  }
3275
3757
 
3276
3758
  if (wrap && cell.text && cell.text.height > rowHeight) {
@@ -3310,6 +3792,12 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3310
3792
  var previousRowNumber = self.getBoundRowIndexFromViewRowIndex(rowOrderIndex - 1);
3311
3793
  var hasRowGap = previousRowNumber !== undefined && cell.boundRowIndex > 0 && cell.boundRowIndex - previousRowNumber > 1;
3312
3794
 
3795
+ if (hasRowGap && collapsedRowGroups.length > 0) {
3796
+ hasRowGap = collapsedRowGroups.find(function (group) {
3797
+ return group.from === previousRowNumber && group.to === cell.boundRowIndex;
3798
+ }) >= 0;
3799
+ }
3800
+
3313
3801
  if (hasRowGap) {
3314
3802
  var barHeight = self.style.rowHeaderCellRowNumberGapHeight;
3315
3803
  var barColor = self.style.rowHeaderCellRowNumberGapColor;
@@ -3360,7 +3848,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3360
3848
  // added to the end, and we want to render that new row's number
3361
3849
 
3362
3850
  var filteredRowNumber = self.viewData && rowIndex < self.viewData.length ? self.getBoundRowIndexFromViewRowIndex(rowIndex) + 1 : self.originalData ? self.originalData.length + 1 : rowOrderIndex + 1;
3363
- var rowHeaderValue = self.hasActiveFilters() ? filteredRowNumber : rowIndex + 1;
3851
+ var rowHeaderValue = self.hasActiveFilters() || self.hasCollapsedRowGroup() ? filteredRowNumber : rowIndex + 1;
3364
3852
  var _rowHeaderCell = {
3365
3853
  rowHeaderCell: rowHeaderValue
3366
3854
  };
@@ -3393,7 +3881,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3393
3881
  i = self.orders.columns[o];
3394
3882
  header = schema[i];
3395
3883
 
3396
- if (!header.hidden) {
3884
+ if (!header.hidden && !isColumnCollapsedByGroup(o)) {
3397
3885
  d = {
3398
3886
  title: header.title,
3399
3887
  name: header.name,
@@ -3512,8 +4000,10 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3512
4000
  cellHeight = rowHeight; //draw normal columns
3513
4001
 
3514
4002
  for (columnOrderIndex = self.scrollIndexLeft; columnOrderIndex < g; columnOrderIndex += 1) {
3515
- headerIndex = self.orders.columns[columnOrderIndex];
3516
- x += drawCell(rowData, rowOrderIndex, rowIndex)(schema[headerIndex], headerIndex, columnOrderIndex);
4003
+ if (!isColumnCollapsedByGroup(columnOrderIndex)) {
4004
+ headerIndex = self.orders.columns[columnOrderIndex];
4005
+ x += drawCell(rowData, rowOrderIndex, rowIndex)(schema[headerIndex], headerIndex, columnOrderIndex);
4006
+ }
3517
4007
 
3518
4008
  if (x > self.width) {
3519
4009
  self.scrollIndexRight = columnOrderIndex;
@@ -3530,8 +4020,10 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3530
4020
  }
3531
4021
 
3532
4022
  for (columnOrderIndex = 0; columnOrderIndex < self.frozenColumn; columnOrderIndex += 1) {
3533
- headerIndex = self.orders.columns[columnOrderIndex];
3534
- x += drawCell(rowData, rowOrderIndex, rowIndex)(schema[headerIndex], headerIndex, columnOrderIndex);
4023
+ if (!isColumnCollapsedByGroup(columnOrderIndex)) {
4024
+ headerIndex = self.orders.columns[columnOrderIndex];
4025
+ x += drawCell(rowData, rowOrderIndex, rowIndex)(schema[headerIndex], headerIndex, columnOrderIndex);
4026
+ }
3535
4027
 
3536
4028
  if (x > self.width) {
3537
4029
  break;
@@ -3558,8 +4050,19 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3558
4050
  nodeType: 'canvas-datagrid-tree',
3559
4051
  scrollTop: self.scrollBox.scrollTop,
3560
4052
  scrollLeft: self.scrollBox.scrollLeft,
3561
- rowIndex: rowOrderIndex
4053
+ rowIndex: rowOrderIndex,
4054
+ columnGroupsAreaHeight: columnGroupsAreaHeight,
4055
+ rowGroupsAreaWidth: rowGroupsAreaWidth
3562
4056
  };
4057
+
4058
+ if (self.intf.parentNode) {
4059
+ var _self$intf$parentNode = self.intf.parentNode,
4060
+ _columnGroupsAreaHeight = _self$intf$parentNode.columnGroupsAreaHeight,
4061
+ _rowGroupsAreaWidth = _self$intf$parentNode.rowGroupsAreaWidth;
4062
+ treeGrid.parentNode.columnGroupsAreaHeight += _columnGroupsAreaHeight || 0;
4063
+ treeGrid.parentNode.rowGroupsAreaWidth += _rowGroupsAreaWidth || 0;
4064
+ }
4065
+
3563
4066
  self.visibleCells.unshift({
3564
4067
  rowIndex: rowOrderIndex,
3565
4068
  columnIndex: 0,
@@ -3586,6 +4089,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3586
4089
  self.visibleRows = [];
3587
4090
  schema = self.getSchema();
3588
4091
  self.visibleCells = [];
4092
+ self.visibleGroups = [];
3589
4093
  self.canvasOffsetTop = self.isChildGrid ? self.parentNode.offsetTop : 0.5;
3590
4094
  self.canvasOffsetLeft = self.isChildGrid ? self.parentNode.offsetLeft : -0.5;
3591
4095
  h = self.height;
@@ -3599,87 +4103,511 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3599
4103
  fillRect(0, 0, w, h);
3600
4104
  }
3601
4105
 
3602
- function drawFrozenRows() {
3603
- var rowOrderIndex,
3604
- ln = Math.min(viewData.length, self.frozenRow);
3605
- x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;
3606
- y = columnHeaderCellHeight;
4106
+ function initGroupArea() {
4107
+ self.ctx.translate(rowGroupsAreaWidth, columnGroupsAreaHeight);
4108
+ }
3607
4109
 
3608
- for (rowIndex = 0; rowIndex < ln; rowIndex += 1) {
3609
- rowOrderIndex = self.orders.rows[rowIndex];
4110
+ function drawGroupArea() {
4111
+ var mx = rowGroupsAreaWidth;
4112
+ var my = columnGroupsAreaHeight;
4113
+ var frozenColumnsWidth = getFrozenColumnsWidth();
4114
+ var frozenRowsHeight = rowGroupsFrozenInfo.y + rowGroupsFrozenInfo.h - columnHeaderCellHeight;
4115
+ var onTheLeft = self.attributes.columnGroupIndicatorPosition === 'left';
4116
+ var onTheTop = self.attributes.rowGroupIndicatorPosition === 'top';
4117
+ /** @type {CanvasRenderingContext2D} */
3610
4118
 
3611
- if (!drawRow(rowOrderIndex, rowIndex)) {
3612
- break;
3613
- }
3614
- }
4119
+ var ctx = self.ctx;
4120
+ ctx.save();
4121
+ ctx.fillStyle = self.style.groupingAreaBackgroundColor;
4122
+ fillRect(0, -my, w, my);
4123
+ fillRect(-mx, -my, mx, h);
4124
+ ctx.restore(); //#region Columns Grouping
3615
4125
 
3616
- if (self.attributes.allowFreezingRows) {
3617
- // HACK great, another stupid magic number.
3618
- // Background will appear as a 0.5px artifact behind the row freeze bar without this hack
3619
- y += self.style.frozenMarkerBorderWidth + self.style.frozenMarkerWidth - 0.4999999999;
3620
- }
4126
+ /** it extends `self.groupedRows` */
3621
4127
 
3622
- self.lastFrozenRowPixel = y;
3623
- }
4128
+ var groupedColumns = [];
3624
4129
 
3625
- function drawRows() {
3626
- self.ctx.save();
4130
+ for (var row = 0; row < self.groupedColumns.length; row++) {
4131
+ var groups = self.groupedColumns[row];
3627
4132
 
3628
- if (self.frozenRow > 0) {
3629
- radiusRect(0, self.lastFrozenRowPixel, self.width, self.height - self.lastFrozenRowPixel, 0);
3630
- self.ctx.clip();
4133
+ for (var j = 0; j < groups.length; j++) {
4134
+ groupedColumns.push(Object.assign({
4135
+ row: row
4136
+ }, groups[j]));
4137
+ }
3631
4138
  }
3632
4139
 
3633
- var columnOrderIndex,
3634
- rowOrderIndex,
3635
- headerIndex,
3636
- g = schema.length;
3637
- x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;
4140
+ if (groupedColumns.length > 0) {
4141
+ (function () {
4142
+ var rowHeight = self.style.columnGroupRowHeight;
4143
+ var toggleHandleSize = rowHeight * 0.5;
4144
+ var toggleHandlePadding = (rowHeight - toggleHandleSize) * 0.5;
3638
4145
 
3639
- if (!self.attributes.snapToRow) {
3640
- y += -self.scrollBox.scrollTop + self.scrollPixelTop + self.style.cellBorderWidth;
3641
- }
4146
+ var _loop = function _loop(i) {
4147
+ var group = groupedColumns[i];
4148
+ var row = group.row,
4149
+ collapsed = group.collapsed;
4150
+ var topY = -my + row * rowHeight;
4151
+ var centerY = topY + rowHeight * 0.5;
4152
+ var bottomY = topY + rowHeight - toggleHandlePadding;
4153
+ var leftmostX = rowHeaderCellWidth - toggleHandleSize - toggleHandlePadding;
3642
4154
 
3643
- for (rowIndex = self.frozenRow + self.scrollIndexTop; rowIndex < l; rowIndex += 1) {
3644
- rowOrderIndex = self.orders.rows[rowIndex];
3645
- self.scrollIndexBottom = rowIndex;
3646
- self.scrollPixelBottom = y;
4155
+ var drawGroupHandleAtX = function drawGroupHandleAtX(x) {
4156
+ return drawGroupHandle(x, topY + toggleHandlePadding, toggleHandleSize, group.collapsed);
4157
+ };
3647
4158
 
3648
- if (!drawRow(rowOrderIndex, rowIndex)) {
3649
- break;
3650
- }
3651
- }
4159
+ var pushToVisibleGroups = function pushToVisibleGroups(leftX, rightX) {
4160
+ return self.visibleGroups.push({
4161
+ type: 'c',
4162
+ collapsed: collapsed,
4163
+ from: group.from,
4164
+ to: group.to,
4165
+ row: row,
4166
+ x: leftX + mx,
4167
+ y: topY + my,
4168
+ x2: rightX + mx,
4169
+ y2: bottomY + my
4170
+ });
4171
+ }; //#region check the relationship between this group and frozen columns
3652
4172
 
3653
- if (self.attributes.showNewRow) {
3654
- if (self.attributes.showRowHeaders) {
3655
- x += rowHeaderCellWidth;
3656
- }
3657
4173
 
3658
- rowHeight = cellHeight = self.style.cellHeight;
3659
- rowOpen = false;
4174
+ var crossTheFrozen = group.from < self.frozenColumn && group.to >= self.frozenColumn;
4175
+ var notInFrozen = group.from >= self.frozenColumn; //#endregion
3660
4176
 
3661
- for (columnOrderIndex = self.scrollIndexLeft; columnOrderIndex < g; columnOrderIndex += 1) {
3662
- headerIndex = self.orders.columns[columnOrderIndex];
3663
- x += drawCell(self.newRow, viewData.length, viewData.length)(schema[headerIndex], headerIndex, columnOrderIndex);
4177
+ if (collapsed) {
4178
+ var _leftX = leftmostX + toggleHandleSize; // This group is not sticking on the first column
3664
4179
 
3665
- if (x > self.width + self.scrollBox.scrollLeft) {
3666
- break;
3667
- }
3668
- }
3669
4180
 
3670
- rowHeaders.push([self.newRow, viewData.length, viewData.length, y, rowHeight]);
3671
- }
4181
+ if (group.from > 0) {
4182
+ var colIndex = group.to + 1;
4183
+ var col = columnGroupsRectInfo[colIndex];
3672
4184
 
3673
- self.ctx.restore();
3674
- }
4185
+ if (!col) {
4186
+ colIndex = group.from - 1;
4187
+ col = columnGroupsRectInfo[colIndex];
4188
+ if (!col) return "continue"; // don't draw this group indicator because it is invisible
3675
4189
 
3676
- function drawMoveMarkers() {
3677
- if (!self.movingSelection) {
3678
- return;
3679
- }
4190
+ _leftX = col.x + col.w - toggleHandleSize * 0.5;
4191
+ } else {
4192
+ _leftX = col.x + toggleHandlePadding;
4193
+ }
3680
4194
 
3681
- self.ctx.lineWidth = self.style.moveOverlayBorderWidth;
3682
- self.ctx.strokeStyle = self.style.moveOverlayBorderColor;
4195
+ if (colIndex >= self.frozenColumn) {
4196
+ var compare = frozenColumnsWidth + rowHeaderCellWidth - toggleHandlePadding; // don't draw this group indicator because it is hidden by frozen columns
4197
+
4198
+ if (_leftX < compare) return "continue";
4199
+ }
4200
+ }
4201
+
4202
+ var _rightX = _leftX + toggleHandleSize;
4203
+
4204
+ ctx.save();
4205
+ ctx.strokeStyle = self.style.groupIndicatorColor;
4206
+ ctx.fillStyle = self.style.groupIndicatorBackgroundColor;
4207
+ drawGroupHandleAtX(_leftX);
4208
+ ctx.restore();
4209
+ pushToVisibleGroups(_leftX, _rightX);
4210
+ } // end of collapsed group
4211
+
4212
+ /** @type {number} pointer for loop */
4213
+
4214
+
4215
+ var ptr = void 0;
4216
+ var left = columnGroupsRectInfo[group.from];
4217
+ var right = columnGroupsRectInfo[group.to];
4218
+ var containsBegining = true;
4219
+ var containsEnd = true;
4220
+ ptr = group.from;
4221
+
4222
+ while (!left && ptr < group.to) {
4223
+ left = columnGroupsRectInfo[++ptr];
4224
+ containsBegining = false;
4225
+ }
4226
+
4227
+ ptr = group.to;
4228
+
4229
+ while (!right && ptr > group.from) {
4230
+ right = columnGroupsRectInfo[--ptr];
4231
+ containsEnd = false;
4232
+ }
4233
+
4234
+ if (!left || !right) return "continue";
4235
+ var rightX = right.x + right.w;
4236
+ var leftX = left.x;
4237
+
4238
+ if (crossTheFrozen) {
4239
+ var rightCompare = columnGroupsRectInfo[self.frozenColumn - 1];
4240
+
4241
+ if (rightCompare) {
4242
+ var compareX = rightCompare.x + rightCompare.w;
4243
+ if (!onTheLeft) compareX += toggleHandleSize;
4244
+
4245
+ if (compareX >= rightX) {
4246
+ right = rightCompare;
4247
+ rightX = right.x + right.w;
4248
+ containsEnd = false;
4249
+ }
4250
+ }
4251
+ }
4252
+
4253
+ var minLeftX = rowHeaderCellWidth + (notInFrozen ? frozenColumnsWidth : 0);
4254
+ if (rightX + (onTheLeft ? 0 : toggleHandleSize) < minLeftX) return "continue";
4255
+ rightX -= toggleHandlePadding;
4256
+ leftX += toggleHandlePadding;
4257
+ ctx.save();
4258
+ ctx.strokeStyle = self.style.groupIndicatorColor;
4259
+ ctx.fillStyle = self.style.groupIndicatorBackgroundColor;
4260
+ var lineCoords = [];
4261
+
4262
+ if (onTheLeft) {
4263
+ // avoid lines from two groups be overlapping
4264
+ minLeftX += toggleHandlePadding * 2;
4265
+ if (leftX < minLeftX) leftX = minLeftX;
4266
+ if (group.from === 0) leftX -= toggleHandlePadding * 2;
4267
+
4268
+ if (rightX >= leftX) {
4269
+ lineCoords.push(leftX, centerY, rightX, centerY);
4270
+ if (containsEnd) lineCoords.push(rightX, bottomY);
4271
+ } else {
4272
+ rightX = leftX;
4273
+ }
4274
+
4275
+ leftX -= toggleHandleSize;
4276
+ drawGroupHandleAtX(leftX); // add more clickable area into `visibleGroups`
4277
+
4278
+ rightX += toggleHandlePadding - 1;
4279
+ } else {
4280
+ // handle on the right
4281
+ if (leftX < minLeftX) leftX = minLeftX;
4282
+ if (group.from === 0) leftX -= toggleHandlePadding * 2;
4283
+
4284
+ if (containsEnd) {
4285
+ if (group.to === self.frozenColumn - 1) {
4286
+ rightX -= toggleHandleSize;
4287
+ } else {
4288
+ rightX += toggleHandlePadding * 2;
4289
+ }
4290
+
4291
+ drawGroupHandleAtX(rightX);
4292
+ }
4293
+
4294
+ if (leftX > rightX) {
4295
+ leftX = rightX;
4296
+ } else {
4297
+ if (group.from === 0) {
4298
+ containsBegining = true;
4299
+ leftX = leftmostX + toggleHandleSize;
4300
+ }
4301
+
4302
+ if (containsBegining) lineCoords.push(leftX, bottomY);
4303
+ lineCoords.push(leftX, centerY, rightX, centerY);
4304
+ } // add more clickable area into `visibleGroups`
4305
+
4306
+
4307
+ leftX -= toggleHandlePadding + 1;
4308
+ if (containsEnd) rightX += toggleHandleSize;
4309
+ }
4310
+
4311
+ strokeLines(lineCoords);
4312
+ ctx.restore();
4313
+ pushToVisibleGroups(leftX, rightX);
4314
+ };
4315
+
4316
+ for (var i = 0; i < groupedColumns.length; i++) {
4317
+ var _ret = _loop(i);
4318
+
4319
+ if (_ret === "continue") continue;
4320
+ }
4321
+ })();
4322
+ } //#endregion Columns Grouping
4323
+ //#region Rows Grouping
4324
+
4325
+ /** it extends `self.groupedRows` */
4326
+
4327
+
4328
+ var groupedRows = [];
4329
+
4330
+ for (var col = 0; col < self.groupedRows.length; col++) {
4331
+ var _groups = self.groupedRows[col];
4332
+
4333
+ for (var _j = 0; _j < _groups.length; _j++) {
4334
+ groupedRows.push(Object.assign({
4335
+ col: col
4336
+ }, _groups[_j]));
4337
+ }
4338
+ }
4339
+
4340
+ if (groupedRows.length > 0) {
4341
+ (function () {
4342
+ var colWidth = self.style.rowGroupColumnWidth;
4343
+ var toggleHandleSize = colWidth * 0.5;
4344
+ var toggleHandlePadding = (colWidth - toggleHandleSize) * 0.5;
4345
+
4346
+ var _loop2 = function _loop2(i) {
4347
+ var group = groupedRows[i];
4348
+ var col = group.col,
4349
+ collapsed = group.collapsed;
4350
+ var leftX = -mx + col * colWidth;
4351
+ var centerX = leftX + colWidth * 0.5;
4352
+ var rightX = leftX + colWidth - toggleHandlePadding;
4353
+ var topmostY = columnHeaderCellHeight - toggleHandleSize - toggleHandlePadding;
4354
+
4355
+ var drawGroupHandleAtY = function drawGroupHandleAtY(y) {
4356
+ return drawGroupHandle(leftX + toggleHandlePadding, y, toggleHandleSize, group.collapsed);
4357
+ };
4358
+
4359
+ var pushToVisibleGroups = function pushToVisibleGroups(topY, bottomY) {
4360
+ return self.visibleGroups.push({
4361
+ type: 'r',
4362
+ collapsed: collapsed,
4363
+ from: group.from,
4364
+ to: group.to,
4365
+ col: col,
4366
+ x: leftX + mx,
4367
+ y: topY + my,
4368
+ x2: rightX + mx,
4369
+ y2: bottomY + my
4370
+ });
4371
+ }; //#region check the relationship between this group and frozen columns
4372
+
4373
+
4374
+ var crossTheFrozen = group.from < self.frozenRow && group.to >= self.frozenRow;
4375
+ var notInFrozen = group.from >= self.frozenRow; //#endregion
4376
+
4377
+ if (collapsed) {
4378
+ var _topY = topmostY + toggleHandleSize; // This group is not sticking on the first column
4379
+
4380
+
4381
+ if (group.from > 0) {
4382
+ var _rowIndex = group.to + 1;
4383
+
4384
+ var _row = rowGroupsRectInfo[_rowIndex];
4385
+
4386
+ if (!_row) {
4387
+ _rowIndex = group.from - 1;
4388
+ _row = rowGroupsRectInfo[_rowIndex];
4389
+ if (!_row) return "continue"; // don't draw this group indicator because it is invisible
4390
+
4391
+ _topY = _row.y + _row.h - toggleHandleSize * 0.5;
4392
+ } else {
4393
+ _topY = _row.y;
4394
+ }
4395
+
4396
+ if (_rowIndex >= self.frozenRow) {
4397
+ var compare = frozenRowsHeight + columnHeaderCellHeight - toggleHandlePadding; // don't draw this group indicator because it is hidden by frozen columns
4398
+
4399
+ if (_topY < compare) return "continue";
4400
+ }
4401
+ }
4402
+
4403
+ var _bottomY = _topY + toggleHandleSize;
4404
+
4405
+ ctx.save();
4406
+ ctx.strokeStyle = self.style.groupIndicatorColor;
4407
+ ctx.fillStyle = self.style.groupIndicatorBackgroundColor;
4408
+ drawGroupHandleAtY(_topY);
4409
+ ctx.restore();
4410
+ pushToVisibleGroups(_topY, _bottomY);
4411
+ } // end of collapsed group
4412
+
4413
+ /** @type {number} pointer for loop */
4414
+
4415
+
4416
+ var ptr = void 0;
4417
+ var top = rowGroupsRectInfo[group.from];
4418
+ var bottom = rowGroupsRectInfo[group.to];
4419
+ var containsBegining = true;
4420
+ var containsEnd = true;
4421
+ ptr = group.from;
4422
+
4423
+ while (!top && ptr < group.to) {
4424
+ top = rowGroupsRectInfo[++ptr];
4425
+ containsBegining = false;
4426
+ }
4427
+
4428
+ ptr = group.to;
4429
+
4430
+ while (!bottom && ptr > group.from) {
4431
+ bottom = rowGroupsRectInfo[--ptr];
4432
+ containsEnd = false;
4433
+ }
4434
+
4435
+ if (!top || !bottom) return "continue";
4436
+ var bottomY = bottom.y + bottom.h;
4437
+ var topY = top.y;
4438
+
4439
+ if (crossTheFrozen) {
4440
+ var bottomCompare = rowGroupsRectInfo[self.frozenRow - 1];
4441
+
4442
+ if (bottomCompare) {
4443
+ var compareY = bottomCompare.y + bottomCompare.h;
4444
+ if (!onTheTop) compareY += toggleHandleSize;
4445
+
4446
+ if (compareY >= bottomY) {
4447
+ bottom = bottomCompare;
4448
+ bottomY = bottom.y + bottom.h;
4449
+ containsEnd = false;
4450
+ }
4451
+ }
4452
+ }
4453
+
4454
+ var minTopY = columnHeaderCellHeight + (notInFrozen ? frozenRowsHeight : 0);
4455
+ if (bottomY + (onTheTop ? 0 : toggleHandleSize) < minTopY) return "continue";
4456
+ bottomY -= toggleHandlePadding;
4457
+ topY += toggleHandlePadding;
4458
+ ctx.save();
4459
+ ctx.strokeStyle = self.style.groupIndicatorColor;
4460
+ ctx.fillStyle = self.style.groupIndicatorBackgroundColor;
4461
+ var lineCoords = [];
4462
+
4463
+ if (onTheTop) {
4464
+ // avoid lines from two groups be overlapping
4465
+ minTopY += toggleHandlePadding * 2;
4466
+ if (topY < minTopY) topY = minTopY;
4467
+ if (group.from === 0) topY -= toggleHandlePadding * 2;
4468
+
4469
+ if (bottomY >= topY) {
4470
+ lineCoords.push(centerX, topY, centerX, bottomY);
4471
+ if (containsEnd) lineCoords.push(rightX, bottomY);
4472
+ } else {
4473
+ bottomY = topY;
4474
+ }
4475
+
4476
+ topY -= toggleHandleSize;
4477
+ drawGroupHandleAtY(topY); // add more clickable area into `visibleGroups`
4478
+
4479
+ bottomY += toggleHandlePadding - 1;
4480
+ } else {
4481
+ // handle on the bottom
4482
+ if (topY < minTopY) topY = minTopY;
4483
+ if (group.from === 0) topY -= toggleHandlePadding * 2;
4484
+
4485
+ if (containsEnd) {
4486
+ if (group.to === self.frozenRow - 1) {
4487
+ bottomY -= toggleHandleSize;
4488
+ } else {// bottomY += toggleHandlePadding * 2;
4489
+ }
4490
+
4491
+ drawGroupHandleAtY(bottomY);
4492
+ }
4493
+
4494
+ if (topY > bottomY) {
4495
+ topY = bottomY;
4496
+ } else {
4497
+ if (group.from === 0) {
4498
+ containsBegining = true;
4499
+ topY = topmostY + toggleHandleSize;
4500
+ }
4501
+
4502
+ if (containsBegining) lineCoords.push(rightX, topY);
4503
+ lineCoords.push(centerX, topY, centerX, bottomY); // add more clickable area into `visibleGroups`
4504
+
4505
+ topY -= toggleHandlePadding + 1;
4506
+ } // add more clickable area into `visibleGroups`
4507
+
4508
+
4509
+ if (containsEnd) bottomY += toggleHandleSize;
4510
+ }
4511
+
4512
+ strokeLines(lineCoords);
4513
+ ctx.restore();
4514
+ pushToVisibleGroups(topY, bottomY);
4515
+ };
4516
+
4517
+ for (var i = 0; i < groupedRows.length; i++) {
4518
+ var _ret2 = _loop2(i);
4519
+
4520
+ if (_ret2 === "continue") continue;
4521
+ }
4522
+ })();
4523
+ } //#endregion Rows Grouping
4524
+
4525
+ }
4526
+
4527
+ function drawFrozenRows() {
4528
+ var rowOrderIndex,
4529
+ ln = Math.min(viewData.length, self.frozenRow);
4530
+ x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;
4531
+ y = columnHeaderCellHeight;
4532
+
4533
+ for (rowIndex = 0; rowIndex < ln; rowIndex += 1) {
4534
+ rowOrderIndex = self.orders.rows[rowIndex];
4535
+
4536
+ if (!drawRow(rowOrderIndex, rowIndex)) {
4537
+ break;
4538
+ }
4539
+ }
4540
+
4541
+ if (self.attributes.allowFreezingRows) {
4542
+ // HACK great, another stupid magic number.
4543
+ // Background will appear as a 0.5px artifact behind the row freeze bar without this hack
4544
+ y += self.style.frozenMarkerBorderWidth + self.style.frozenMarkerWidth - 0.4999999999;
4545
+ }
4546
+
4547
+ self.lastFrozenRowPixel = y;
4548
+ }
4549
+
4550
+ function drawRows() {
4551
+ self.ctx.save();
4552
+
4553
+ if (self.frozenRow > 0) {
4554
+ radiusRect(0, self.lastFrozenRowPixel, self.width, self.height - self.lastFrozenRowPixel, 0);
4555
+ self.ctx.clip();
4556
+ }
4557
+
4558
+ var columnOrderIndex,
4559
+ rowOrderIndex,
4560
+ headerIndex,
4561
+ g = schema.length;
4562
+ x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;
4563
+
4564
+ if (!self.attributes.snapToRow) {
4565
+ y += -self.scrollBox.scrollTop + self.scrollPixelTop + self.style.cellBorderWidth;
4566
+ }
4567
+
4568
+ for (rowIndex = self.frozenRow + self.scrollIndexTop; rowIndex < l; rowIndex += 1) {
4569
+ rowOrderIndex = self.orders.rows[rowIndex];
4570
+ self.scrollIndexBottom = rowIndex;
4571
+ self.scrollPixelBottom = y;
4572
+ if (self.cellTree.rows.length > 0 && Object.keys(self.cellTree.rows[rowOrderIndex]).length > 0 && self.cellTree.rows[rowOrderIndex].hide) continue;
4573
+
4574
+ if (!drawRow(rowOrderIndex, rowIndex)) {
4575
+ break;
4576
+ }
4577
+ }
4578
+
4579
+ if (self.attributes.showNewRow) {
4580
+ if (self.attributes.showRowHeaders) {
4581
+ x += rowHeaderCellWidth;
4582
+ }
4583
+
4584
+ rowHeight = cellHeight = self.style.cellHeight;
4585
+ rowOpen = false;
4586
+
4587
+ for (columnOrderIndex = self.scrollIndexLeft; columnOrderIndex < g; columnOrderIndex += 1) {
4588
+ if (!isColumnCollapsedByGroup(columnOrderIndex)) {
4589
+ headerIndex = self.orders.columns[columnOrderIndex];
4590
+ x += drawCell(self.newRow, viewData.length, viewData.length)(schema[headerIndex], headerIndex, columnOrderIndex);
4591
+ }
4592
+
4593
+ if (x > self.width + self.scrollBox.scrollLeft) {
4594
+ break;
4595
+ }
4596
+ }
4597
+
4598
+ rowHeaders.push([self.newRow, viewData.length, viewData.length, y, rowHeight]);
4599
+ }
4600
+
4601
+ self.ctx.restore();
4602
+ }
4603
+
4604
+ function drawMoveMarkers() {
4605
+ if (!self.movingSelection) {
4606
+ return;
4607
+ }
4608
+
4609
+ self.ctx.lineWidth = self.style.moveOverlayBorderWidth;
4610
+ self.ctx.strokeStyle = self.style.moveOverlayBorderColor;
3683
4611
  self.ctx.setLineDash(self.style.moveOverlayBorderSegments);
3684
4612
  moveBorders.forEach(function (c) {
3685
4613
  addBorderLine(c[0], c[1]);
@@ -3864,13 +4792,18 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
3864
4792
  self.ctx.strokeStyle = xHover ? self.style.frozenMarkerHoverBorderColor : self.style.frozenMarkerBorderColor;
3865
4793
  fillRect(0, my, self.width, self.style.frozenMarkerWidth);
3866
4794
  strokeRect(0, my, self.width, self.style.frozenMarkerWidth);
4795
+ var height = self.style.frozenMarkerWidth + self.style.frozenMarkerBorderWidth;
3867
4796
  self.visibleCells.unshift({
3868
4797
  x: 0,
3869
4798
  y: my,
3870
- height: self.style.frozenMarkerWidth + self.style.frozenMarkerBorderWidth,
4799
+ height: height,
3871
4800
  width: self.width,
3872
4801
  style: 'frozen-row-marker'
3873
4802
  });
4803
+ rowGroupsFrozenInfo = {
4804
+ y: my,
4805
+ h: height
4806
+ };
3874
4807
  }
3875
4808
 
3876
4809
  if (self.freezeMarkerPosition) {
@@ -4032,6 +4965,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4032
4965
  self.ctx.save();
4033
4966
  initDraw();
4034
4967
  drawBackground();
4968
+ initGroupArea();
4035
4969
  drawFrozenRows();
4036
4970
  drawRows();
4037
4971
  drawActiveCell();
@@ -4048,6 +4982,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4048
4982
  self.resize(true);
4049
4983
  }
4050
4984
 
4985
+ drawGroupArea();
4051
4986
  drawDebug();
4052
4987
  drawPerfLines();
4053
4988
 
@@ -4221,6 +5156,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4221
5156
  l = (self.viewData || []).length,
4222
5157
  columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
4223
5158
  rowHeaderCellWidth = self.getRowHeaderCellWidth(),
5159
+ topGroupAreaHeight = self.getColumnGroupAreaHeight(),
5160
+ leftGroupAreaWidth = self.getRowGroupAreaWidth(),
4224
5161
  ch = self.style.cellHeight,
4225
5162
  s = self.getSchema(); // sets actual DOM canvas element
4226
5163
 
@@ -4232,8 +5169,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4232
5169
  }
4233
5170
 
4234
5171
  function setScrollBoxSize() {
4235
- self.scrollBox.width = self.width - rowHeaderCellWidth;
4236
- self.scrollBox.height = self.height - columnHeaderCellHeight;
5172
+ self.scrollBox.width = self.width - rowHeaderCellWidth - leftGroupAreaWidth;
5173
+ self.scrollBox.height = self.height - columnHeaderCellHeight - topGroupAreaHeight;
4237
5174
  }
4238
5175
 
4239
5176
  function setCanvasSize() {
@@ -4243,8 +5180,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4243
5180
 
4244
5181
  dims = {
4245
5182
  // HACK +1 ? maybe it's a magic cell border? Required to line up properly in auto height mode.
4246
- height: columnHeaderCellHeight + dataHeight + cellBorder + 1,
4247
- width: dataWidth + rowHeaderCellWidth + cellBorder
5183
+ height: columnHeaderCellHeight + topGroupAreaHeight + dataHeight + cellBorder + 1,
5184
+ width: dataWidth + rowHeaderCellWidth + cellBorder + leftGroupAreaWidth
4248
5185
  };
4249
5186
  ['width', 'height'].forEach(function (dim) {
4250
5187
  //TODO: support inherit
@@ -4273,18 +5210,32 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4273
5210
  self.scrollCache.y[x] = dataHeight;
4274
5211
  }
4275
5212
 
5213
+ var collapsedColumnGroups = self.getCollapsedColumnGroups();
5214
+
5215
+ var isColumnCollapsed = function isColumnCollapsed(columnIndex) {
5216
+ return collapsedColumnGroups.findIndex(function (group) {
5217
+ return columnIndex >= group.from && columnIndex <= group.to;
5218
+ }) >= 0;
5219
+ };
5220
+ /** @type {number} it will be used in `reduceSchema` only */
5221
+
5222
+
5223
+ var frozenWidth = 0;
4276
5224
  dataWidth = s.reduce(function reduceSchema(accumulator, column, columnIndex) {
4277
5225
  // intentional redefintion of column. This causes scrollCache to be in the correct order
4278
- column = s[self.orders.columns[columnIndex]];
5226
+ var schemaIndex = self.orders.columns[columnIndex];
5227
+ var columnWidth = self.getColumnWidth(schemaIndex);
5228
+ column = s[schemaIndex];
5229
+ if (!column.hidden && !isColumnCollapsed(columnIndex)) accumulator += columnWidth;
4279
5230
 
4280
- if (column.hidden) {
5231
+ if (columnIndex < self.frozenColumn) {
4281
5232
  self.scrollCache.x[columnIndex] = accumulator;
4282
- return accumulator;
5233
+ frozenWidth = accumulator;
5234
+ } else {
5235
+ self.scrollCache.x[columnIndex] = Math.max(frozenWidth + columnWidth, accumulator);
4283
5236
  }
4284
5237
 
4285
- var va = accumulator + self.getColumnWidth(self.orders.columns[columnIndex]);
4286
- self.scrollCache.x[columnIndex] = va;
4287
- return va;
5238
+ return accumulator;
4288
5239
  }, 0) || 0;
4289
5240
 
4290
5241
  if (self.attributes.showNewRow) {
@@ -4309,8 +5260,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4309
5260
  // non-controversial
4310
5261
 
4311
5262
 
4312
- self.scrollBox.top = columnHeaderCellHeight + columnHeaderCellBorder;
4313
- self.scrollBox.left = rowHeaderCellWidth; // width and height of scroll box
5263
+ self.scrollBox.top = columnHeaderCellHeight + topGroupAreaHeight + columnHeaderCellBorder;
5264
+ self.scrollBox.left = rowHeaderCellWidth + leftGroupAreaWidth; // width and height of scroll box
4314
5265
 
4315
5266
  setScrollBoxSize(); // is the data larger than the scroll box
4316
5267
 
@@ -4356,24 +5307,24 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4356
5307
  // the dragged mouse.
4357
5308
  // https://github.com/TonyGermaneri/canvas-datagrid/issues/97
4358
5309
 
4359
- self.scrollBox.heightBoxRatio = (self.scrollBox.height - columnHeaderCellHeight - self.scrollCache.y[self.frozenRow]) / dataHeight;
5310
+ self.scrollBox.heightBoxRatio = (self.scrollBox.height - columnHeaderCellHeight - topGroupAreaHeight - self.scrollCache.y[self.frozenRow]) / dataHeight;
4360
5311
  self.scrollBox.scrollBoxHeight = self.scrollBox.height * self.scrollBox.heightBoxRatio - self.style.scrollBarWidth - b - d;
4361
5312
  self.scrollBox.scrollBoxWidth = Math.max(self.scrollBox.scrollBoxWidth, self.style.scrollBarBoxMinSize);
4362
5313
  self.scrollBox.scrollBoxHeight = Math.max(self.scrollBox.scrollBoxHeight, self.style.scrollBarBoxMinSize); // horizontal
4363
5314
 
4364
5315
  n.x += rowHeaderCellWidth;
4365
- n.y += self.height - self.style.scrollBarWidth - d;
4366
- n.width = self.width - self.style.scrollBarWidth - rowHeaderCellWidth - d - m;
5316
+ n.y += self.height - self.style.scrollBarWidth - d - topGroupAreaHeight;
5317
+ n.width = self.width - self.style.scrollBarWidth - rowHeaderCellWidth - leftGroupAreaWidth - d - m;
4367
5318
  n.height = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d; // horizontal box
4368
5319
 
4369
5320
  nb.y = n.y + self.style.scrollBarBoxMargin;
4370
5321
  nb.width = self.scrollBox.scrollBoxWidth;
4371
5322
  nb.height = self.style.scrollBarBoxWidth; // vertical
4372
5323
 
4373
- v.x += self.width - self.style.scrollBarWidth - self.style.scrollBarBorderWidth - d;
5324
+ v.x += self.width - leftGroupAreaWidth - self.style.scrollBarWidth - self.style.scrollBarBorderWidth - d;
4374
5325
  v.y += columnHeaderCellHeight + self.scrollCache.y[self.frozenRow];
4375
5326
  v.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
4376
- v.height = self.height - columnHeaderCellHeight - self.style.scrollBarWidth - d - m; // vertical box
5327
+ v.height = self.height - columnHeaderCellHeight - topGroupAreaHeight - self.style.scrollBarWidth - d - m; // vertical box
4377
5328
 
4378
5329
  vb.x = v.x + self.style.scrollBarBoxMargin;
4379
5330
  vb.y += self.scrollCache.y[self.frozenRow];
@@ -4535,13 +5486,26 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4535
5486
  self.hovers = {
4536
5487
  rowIndex: cell.rowIndex,
4537
5488
  columnIndex: cell.columnIndex,
4538
- onFilterButton: false
5489
+ onFilterButton: false,
5490
+ onCellTreeIcon: false
4539
5491
  };
4540
5492
 
4541
5493
  if (cell.isFilterable && x > cell.x + cell.width + self.canvasOffsetLeft - self.style.filterButtonWidth && x < cell.x + cell.width + self.canvasOffsetLeft && y > cell.y + cell.height + self.canvasOffsetTop - self.style.filterButtonHeight && y < cell.y + cell.height + self.canvasOffsetTop) {
4542
5494
  self.hovers.onFilterButton = true;
4543
5495
  self.draw();
4544
5496
  }
5497
+
5498
+ if (cell.isRowTree || cell.isColumnTree) {
5499
+ var pc = cell.isRowTree ? self.cellTree.rows[cell.rowIndex].parentCount : 0;
5500
+ var rc = self.style.cellTreeIconWidth * self.scale,
5501
+ rx = cell.x + cell.paddingLeft + self.canvasOffsetLeft + self.style.cellTreeIconMarginLeft + pc * (rc + cell.paddingLeft),
5502
+ ry = cell.y + self.canvasOffsetTop + self.style.cellTreeIconMarginTop * self.scale;
5503
+
5504
+ if (x >= rx && x <= rx + rc && y >= ry && y < ry + rc) {
5505
+ self.hovers.onCellTreeIcon = true;
5506
+ self.draw();
5507
+ }
5508
+ }
4545
5509
  }
4546
5510
 
4547
5511
  if (self.selecting || self.reorderObject) {
@@ -4602,12 +5566,16 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4602
5566
 
4603
5567
  self.draw();
4604
5568
  return;
5569
+ } else if (cell.hovered && self.hovers.onCellTreeIcon && e.type == 'mousedown') {
5570
+ self.toggleCollapseTree(cell.rowIndex, cell.columnIndex);
5571
+ return;
4605
5572
  } else {
4606
5573
  self.selectedFilterButton = {
4607
5574
  columnIndex: -1,
4608
5575
  rowIndex: -1
4609
5576
  };
4610
5577
  if (self.hovers.onFilterButton) return;
5578
+ if (self.hovers.onCellTreeIcon) return;
4611
5579
 
4612
5580
  if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
4613
5581
  if (self.selections[cell.rowIndex] && self.selections[cell.rowIndex].indexOf(cell.columnIndex) !== -1) {
@@ -4662,6 +5630,10 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4662
5630
  }
4663
5631
  }
4664
5632
 
5633
+ var columnGroup = self.getColumnGroupAt(self.mouse.x, self.mouse.y);
5634
+ if (columnGroup) self.cursor = 'pointer';
5635
+ var rowGroup = self.getRowGroupAt(self.mouse.x, self.mouse.y);
5636
+ if (rowGroup) self.cursor = 'pointer';
4665
5637
  self.cellBoundaryCrossed = false;
4666
5638
  self.rowBoundaryCrossed = false;
4667
5639
  self.columnBoundaryCrossed = false;
@@ -4718,10 +5690,26 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4718
5690
  return;
4719
5691
  }
4720
5692
 
5693
+ var group = self.getColumnGroupAt(pos.x, pos.y);
5694
+ if (!group) group = self.getRowGroupAt(pos.x, pos.y);
5695
+
5696
+ if (group) {
5697
+ if (self.toggleGroup(group)) {
5698
+ self.setStorageData();
5699
+ self.refresh();
5700
+ return;
5701
+ }
5702
+ }
5703
+
4721
5704
  if (!self.hasFocus) {
4722
5705
  return;
4723
5706
  }
4724
5707
 
5708
+ var leftOffset = self.getRowGroupAreaWidth();
5709
+ var topOffset = self.getColumnGroupAreaHeight();
5710
+ var xInGrid = pos.x - leftOffset;
5711
+ var yInGrid = pos.y - topOffset;
5712
+
4725
5713
  if (['rowHeaderCell', 'columnHeaderCell'].indexOf(self.currentCell.style) === -1 && !ctrl) {
4726
5714
  if (!self.hovers.onFilterButton) {
4727
5715
  self.setActiveCell(i.columnIndex, i.rowIndex);
@@ -4753,7 +5741,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4753
5741
  self.selections[i.rowIndex] = self.selections[i.rowIndex] || [];
4754
5742
 
4755
5743
  if (self.attributes.selectionMode === 'row' || self.currentCell.style === 'rowHeaderCell') {
4756
- if (self.currentCell.style === 'rowHeaderCell' && self.attributes.tree && pos.x > 0 && pos.x - self.currentCell.x < self.style.treeArrowWidth + self.style.treeArrowMarginLeft + self.style.treeArrowMarginRight + self.style.treeArrowClickRadius && pos.y - self.currentCell.y < self.style.treeArrowHeight + self.style.treeArrowMarginTop + self.style.treeArrowClickRadius && pos.y > 0) {
5744
+ if (self.currentCell.style === 'rowHeaderCell' && self.attributes.tree && xInGrid > 0 && xInGrid - self.currentCell.x < self.style.treeArrowWidth + self.style.treeArrowMarginLeft + self.style.treeArrowMarginRight + self.style.treeArrowClickRadius && yInGrid - self.currentCell.y < self.style.treeArrowHeight + self.style.treeArrowMarginTop + self.style.treeArrowClickRadius && yInGrid > 0) {
4757
5745
  self.toggleTree(i.rowIndex);
4758
5746
  return;
4759
5747
  }
@@ -4793,7 +5781,6 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4793
5781
 
4794
5782
  if (self.scrollBox.scrollLeft > self.scrollBox.scrollWidth - self.attributes.resizeScrollZone && self.dragMode === 'ew-resize') {
4795
5783
  self.resize(true);
4796
- self.scrollBox.scrollLeft += x;
4797
5784
  }
4798
5785
 
4799
5786
  if (self.dragMode === 'ew-resize') {
@@ -4826,30 +5813,18 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4826
5813
  self.ellipsisCache = {};
4827
5814
  };
4828
5815
 
4829
- self.stopDragResize = function (e) {
4830
- var pos = self.getLayerPos(e);
4831
- var hasMoved = !!(pos.x - self.dragStart.x);
4832
- var width = self.resizingStartingWidth + pos.x - self.dragStart.x;
5816
+ self.stopDragResize = function (event) {
5817
+ var pos = self.getLayerPos(event);
4833
5818
 
4834
5819
  if (self.dragMode === 'ew-resize') {
4835
- var selectedColumns = self.selections[0];
5820
+ var hasMoved = !!(pos.x - self.dragStart.x); // Check that dragItem is selected or part of selection.
5821
+
4836
5822
  var dragItemIsSelected = self.isColumnSelected(self.dragItem.columnIndex);
4837
5823
 
4838
- if (dragItemIsSelected) {
4839
- var _iterator = _createForOfIteratorHelper(selectedColumns),
4840
- _step;
5824
+ if (hasMoved && dragItemIsSelected) {
5825
+ var width = Math.max(self.resizingStartingWidth + pos.x - self.dragStart.x, self.style.minColumnWidth); // If the column is selected, resize it to width plus any other selected columns.
4841
5826
 
4842
- try {
4843
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
4844
- var selectedColumnIndex = _step.value;
4845
- var boundColumnIndex = self.getBoundColumnIndexFromViewColumnIndex(selectedColumnIndex);
4846
- if (hasMoved && dragItemIsSelected && self.isColumnSelected(selectedColumnIndex)) self.sizes.columns[boundColumnIndex] = width;
4847
- }
4848
- } catch (err) {
4849
- _iterator.e(err);
4850
- } finally {
4851
- _iterator.f();
4852
- }
5827
+ self.fitSelectedColumns(width);
4853
5828
  }
4854
5829
  }
4855
5830
 
@@ -4971,6 +5946,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
4971
5946
  if (Math.abs(x) > self.attributes.reorderDeadZone || Math.abs(y) > self.attributes.reorderDeadZone) {
4972
5947
  self.reorderObject = self.draggingItem;
4973
5948
  if (self.isMultiRowsSelected) self.reorderObject = self.getVisibleCellByIndex(-1, self.activeCell.rowIndex);
5949
+ if (!self.reorderObject) return;
4974
5950
  self.reorderTarget = self.currentCell;
4975
5951
  self.reorderObject.dragOffset = {
4976
5952
  x: x,
@@ -5117,6 +6093,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5117
6093
  rowHeaderCellWidth = self.getRowHeaderCellWidth();
5118
6094
  self.ignoreNextClick = true;
5119
6095
  self.freezeMarkerPosition = pos;
6096
+ pos.x -= self.getRowGroupAreaWidth();
6097
+ pos.y -= self.getColumnGroupAreaHeight();
5120
6098
 
5121
6099
  if (self.currentCell && self.currentCell.rowIndex !== undefined && self.dragMode === 'frozen-row-marker') {
5122
6100
  self.scrollBox.scrollTop = 0;
@@ -5498,12 +6476,12 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5498
6476
  }
5499
6477
  }
5500
6478
 
5501
- var _iterator2 = _createForOfIteratorHelper(self.selections),
5502
- _step2;
6479
+ var _iterator = _createForOfIteratorHelper(self.selections),
6480
+ _step;
5503
6481
 
5504
6482
  try {
5505
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
5506
- var selection = _step2.value;
6483
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
6484
+ var selection = _step.value;
5507
6485
 
5508
6486
  if (e.key === 'ArrowRight' && selection) {
5509
6487
  if (x > lastSelectedColumn) {
@@ -5526,9 +6504,9 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5526
6504
  }
5527
6505
  }
5528
6506
  } catch (err) {
5529
- _iterator2.e(err);
6507
+ _iterator.e(err);
5530
6508
  } finally {
5531
- _iterator2.f();
6509
+ _iterator.f();
5532
6510
  }
5533
6511
 
5534
6512
  self.selectionBounds = self.getSelectionBounds();
@@ -5615,8 +6593,13 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5615
6593
  }
5616
6594
  } else if (self.currentCell.context === 'ew-resize' && self.currentCell.style === 'cornerCell') {
5617
6595
  self.autosize();
5618
- } else if (['cell', 'activeCell'].includes(self.currentCell.style) && !self.hovers.onFilterButton) {
5619
- self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
6596
+ } else if (['cell', 'activeCell'].includes(self.currentCell.style) && !self.hovers.onFilterButton && !self.hovers.onCellTreeIcon) {
6597
+ if (self.currentCell.isRowTree || self.currentCell.isColumnTree) {
6598
+ self.cellTreeExpandCollapse(self.currentCell.rowIndex, self.currentCell.columnIndex);
6599
+ self.draw();
6600
+ } else {
6601
+ self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
6602
+ }
5620
6603
  }
5621
6604
  };
5622
6605
 
@@ -5821,19 +6804,19 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5821
6804
  });
5822
6805
  };
5823
6806
 
5824
- self.cut = function (e) {
6807
+ self.cut = function (event) {
5825
6808
  if (self.dispatchEvent('cut', {
5826
- NativeEvent: e
6809
+ NativeEvent: event
5827
6810
  })) {
5828
6811
  return;
5829
6812
  } // Expecting instance of `ClipboardEvent` with `clipboardData` attribute
5830
6813
 
5831
6814
 
5832
- if (!self.hasFocus || !e.clipboardData) {
6815
+ if (!self.hasFocus || !event.clipboardData) {
5833
6816
  return;
5834
6817
  }
5835
6818
 
5836
- self.copySelectedCellsToClipboard(e.clipboardData);
6819
+ self.copySelectedCellsToClipboard(event.clipboardData);
5837
6820
  var affectedCells = self.clearSelectedCells();
5838
6821
  self.dispatchEvent('aftercut', {
5839
6822
  cells: affectedCells
@@ -5841,22 +6824,23 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5841
6824
  requestAnimationFrame(function () {
5842
6825
  return self.draw();
5843
6826
  });
6827
+ event.preventDefault();
5844
6828
  };
5845
6829
 
5846
- self.copy = function (e) {
6830
+ self.copy = function (event) {
5847
6831
  if (self.dispatchEvent('copy', {
5848
- NativeEvent: e
6832
+ NativeEvent: event
5849
6833
  })) {
5850
6834
  return;
5851
6835
  } // Expecting instance of `ClipboardEvent` with `clipboardData` attribute
5852
6836
 
5853
6837
 
5854
- if (!self.hasFocus || !e.clipboardData) {
6838
+ if (!self.hasFocus || !event.clipboardData) {
5855
6839
  return;
5856
6840
  }
5857
6841
 
5858
- self.copySelectedCellsToClipboard(e.clipboardData);
5859
- e.preventDefault();
6842
+ self.copySelectedCellsToClipboard(event.clipboardData);
6843
+ event.preventDefault();
5860
6844
  };
5861
6845
 
5862
6846
  return;
@@ -6017,7 +7001,7 @@ var parseData = function parseData(data, mimeType) {
6017
7001
  };
6018
7002
 
6019
7003
  var htmlSafe = function htmlSafe(value) {
6020
- if (typeof value === 'number') return value;
7004
+ if (typeof value !== 'string') return value;
6021
7005
  return value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
6022
7006
  };
6023
7007
 
@@ -6039,7 +7023,7 @@ var createHTMLString = function createHTMLString(selectedData, isNeat) {
6039
7023
  var htmlString = '<table>';
6040
7024
  htmlString += selectedData.map(function (row) {
6041
7025
  return '<tr>' + Object.values(row).map(function (value) {
6042
- return '<td>' + htmlSafe(value) + '</td>';
7026
+ return ['<td>', htmlSafe(value), '</td>'].join('');
6043
7027
  }).join('') + '</tr>';
6044
7028
  }).join('');
6045
7029
  htmlString += '</table>';
@@ -6071,6 +7055,14 @@ __webpack_require__.r(__webpack_exports__);
6071
7055
  /*globals HTMLElement: false, Reflect: false, define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/
6072
7056
 
6073
7057
 
7058
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7059
+
7060
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7061
+
7062
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
7063
+
7064
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
7065
+
6074
7066
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
6075
7067
 
6076
7068
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
@@ -6141,6 +7133,21 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6141
7133
  self.scrollBox = {};
6142
7134
  self.visibleRows = [];
6143
7135
  self.visibleCells = [];
7136
+ /**
7137
+ * This array stored all groups information with context for drawing,
7138
+ * it is generated by drawing functions,
7139
+ * and be used for searching groups when users operate on the spreadsheet
7140
+ * Each item of this array contains these properties:
7141
+ * - `type`: its available values: 'c' and 'r'. indicates the type of this item, 'c' for column group
7142
+ * and 'r' for row group.
7143
+ * - `x`,`y`: the left-top point of this group's rendering area.
7144
+ * - `x2`, `y2`: the right-bottom of this group's rendering area.
7145
+ * - `collapsed`: this value indicates the collapsed status of this group.
7146
+ * - `from`, `to`: The column index range of this group (We use this value for searching the group)
7147
+ * - `row`: The row index for column groups (We use this value for searching the group)
7148
+ */
7149
+
7150
+ self.visibleGroups = [];
6144
7151
  self.sizes = {
6145
7152
  rows: {},
6146
7153
  columns: {},
@@ -6155,6 +7162,18 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6155
7162
  columnIndex: -1,
6156
7163
  rowIndex: -1
6157
7164
  };
7165
+ self.cellTree = {
7166
+ rows: [],
7167
+ columns: {},
7168
+ tempSchema: {},
7169
+ rowTreeColIndex: 0,
7170
+ columnTreeRowStartIndex: 0,
7171
+ columnTreeRowEndIndex: 0,
7172
+ origin: {
7173
+ rows: [],
7174
+ columns: {}
7175
+ }
7176
+ };
6158
7177
  self.hovers = {};
6159
7178
  self.attributes = {};
6160
7179
  self.style = {};
@@ -6170,9 +7189,31 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6170
7189
  self.scrollPixelLeft = 0;
6171
7190
  self.childGrids = {};
6172
7191
  self.openChildren = {};
7192
+ /**
7193
+ * Array for grouped columns
7194
+ * Each item in this array is an array and it represents some grouping in one row
7195
+ * A grouping descriptor has three properties:
7196
+ * - `from`: The column index of the first column
7197
+ * - `to`: The column index of the last column
7198
+ * - `collapsed`: Is this group be collapsed
7199
+ * @example [[{ from: 1, to: 2, collapsed: false }]]
7200
+ */
7201
+
7202
+ self.groupedColumns = [];
7203
+ /**
7204
+ * Array for grouped rows
7205
+ * Each item in this array is an array and it represents some grouping in one column
7206
+ * A grouping descriptor has three properties:
7207
+ * - `from`: The row index of the first row
7208
+ * - `to`: The row index of the last row
7209
+ * - `collapsed`: Is this group be collapsed
7210
+ * @example [[{ from: 1, to: 2, collapsed: false }]]
7211
+ */
7212
+
7213
+ self.groupedRows = [];
6173
7214
  self.scrollModes = ['vertical-scroll-box', 'vertical-scroll-top', 'vertical-scroll-bottom', 'horizontal-scroll-box', 'horizontal-scroll-right', 'horizontal-scroll-left'];
6174
7215
  self.componentL1Events = {};
6175
- self.eventNames = ['afterdraw', 'afterrendercell', 'afterrenderfilterbutton', 'attributechanged', 'beforebeginedit', 'beforecreatecellgrid', 'beforedraw', 'beforeendedit', 'beforerendercell', 'beforerendercellgrid', 'beforerenderfilterbutton', 'beginedit', 'cellmouseout', 'cellmouseover', 'click', 'collapsetree', 'contextmenu', 'copy', 'datachanged', 'dblclick', 'endedit', 'expandtree', 'formatcellvalue', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseup', 'newrow', 'ordercolumn', 'rendercell', 'rendercellgrid', 'renderorderbyarrow', 'rendertext', 'rendertreearrow', 'reorder', 'reordering', 'resize', 'resizecolumn', 'resizerow', 'schemachanged', 'scroll', 'selectionchanged', 'stylechanged', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'wheel'];
7216
+ self.eventNames = ['afterdraw', 'afterrendercell', 'afterrenderfilterbutton', 'aftercreategroup', 'attributechanged', 'beforebeginedit', 'beforecreatecellgrid', 'beforedraw', 'beforeendedit', 'beforerendercell', 'beforerendercellgrid', 'beforerenderfilterbutton', 'beginedit', 'cellmouseout', 'cellmouseover', 'click', 'collapsetree', 'contextmenu', 'copy', 'datachanged', 'dblclick', 'endedit', 'expandtree', 'formatcellvalue', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseup', 'newrow', 'ordercolumn', 'rendercell', 'rendercellgrid', 'renderorderbyarrow', 'rendertext', 'rendertreearrow', 'reorder', 'reordering', 'resize', 'resizecolumn', 'resizerow', 'schemachanged', 'scroll', 'selectionchanged', 'stylechanged', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'wheel'];
6176
7217
  self.mouse = {
6177
7218
  x: 0,
6178
7219
  y: 0
@@ -6419,6 +7460,166 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6419
7460
  self.getBoundColumnIndexFromViewColumnIndex = function (viewColumnIndex) {
6420
7461
  return self.orders.columns[viewColumnIndex];
6421
7462
  };
7463
+ /**
7464
+ * Get the height of the area about column groups for rendering and handling events.
7465
+ */
7466
+
7467
+
7468
+ self.getColumnGroupAreaHeight = function () {
7469
+ if (!self.attributes.allowGroupingColumns) {
7470
+ return 0;
7471
+ }
7472
+
7473
+ var groups = self.groupedColumns.length;
7474
+ var base = self.style.columnGroupRowHeight * self.scale;
7475
+ return base * groups;
7476
+ };
7477
+ /**
7478
+ * Get the width of the area about row groups for rendering and handling events.
7479
+ */
7480
+
7481
+
7482
+ self.getRowGroupAreaWidth = function () {
7483
+ if (!self.attributes.allowGroupingRows) {
7484
+ return 0;
7485
+ }
7486
+
7487
+ var groups = self.groupedRows.length;
7488
+ var base = self.style.rowGroupColumnWidth * self.scale;
7489
+ return base * groups;
7490
+ };
7491
+
7492
+ self.getCollapsedColumnGroups = function () {
7493
+ var result = [];
7494
+
7495
+ for (var rowIndex = 0; rowIndex < self.groupedColumns.length; rowIndex++) {
7496
+ var groups = self.groupedColumns[rowIndex];
7497
+
7498
+ for (var groupIndex = 0; groupIndex < groups.length; groupIndex++) {
7499
+ var group = groups[groupIndex];
7500
+ if (group.collapsed) result.push(group);
7501
+ }
7502
+ }
7503
+
7504
+ return result;
7505
+ };
7506
+
7507
+ self.getCollapsedRowGroups = function () {
7508
+ var result = [];
7509
+
7510
+ for (var rowIndex = 0; rowIndex < self.groupedRows.length; rowIndex++) {
7511
+ var groups = self.groupedRows[rowIndex];
7512
+
7513
+ for (var groupIndex = 0; groupIndex < groups.length; groupIndex++) {
7514
+ var group = groups[groupIndex];
7515
+ if (group.collapsed) result.push(group);
7516
+ }
7517
+ }
7518
+
7519
+ return result;
7520
+ };
7521
+ /**
7522
+ * Toggle the collapse status of a group (expanded/collapsed)
7523
+ * @param {{type:string,from:number,to:number}} group
7524
+ */
7525
+
7526
+
7527
+ self.toggleGroup = function (group) {
7528
+ if (group.type === 'c') {
7529
+ var from = group.from,
7530
+ to = group.to;
7531
+ /** @type {{from:number,to:number,collapsed:boolean}} */
7532
+
7533
+ var matchedGroup;
7534
+ /** @type {Array<Array<{from:number,to:number,collapsed:boolean}>>} */
7535
+
7536
+ var allGroups = self.groupedColumns;
7537
+
7538
+ for (var i = 0; i < allGroups.length; i++) {
7539
+ var groups = allGroups[i];
7540
+
7541
+ for (var gi = 0; gi < groups.length; gi++) {
7542
+ var _group = groups[gi];
7543
+
7544
+ if (_group.from === from && _group.to === to) {
7545
+ matchedGroup = _group;
7546
+ break;
7547
+ }
7548
+ }
7549
+
7550
+ if (matchedGroup) break;
7551
+ }
7552
+
7553
+ if (!matchedGroup) return;
7554
+ var nextCollapsed = !matchedGroup.collapsed;
7555
+ matchedGroup.collapsed = nextCollapsed;
7556
+ return true;
7557
+ }
7558
+
7559
+ if (group.type === 'r') {
7560
+ var _from = group.from,
7561
+ _to = group.to;
7562
+ /** @type {{from:number,to:number,collapsed:boolean}} */
7563
+
7564
+ var _matchedGroup;
7565
+ /** @type {Array<Array<{from:number,to:number,collapsed:boolean}>>} */
7566
+
7567
+
7568
+ var _allGroups = self.groupedRows;
7569
+
7570
+ for (var _i3 = 0; _i3 < _allGroups.length; _i3++) {
7571
+ var _groups = _allGroups[_i3];
7572
+
7573
+ for (var _gi = 0; _gi < _groups.length; _gi++) {
7574
+ var _group2 = _groups[_gi];
7575
+
7576
+ if (_group2.from === _from && _group2.to === _to) {
7577
+ _matchedGroup = _group2;
7578
+ break;
7579
+ }
7580
+ }
7581
+
7582
+ if (_matchedGroup) break;
7583
+ }
7584
+
7585
+ if (!_matchedGroup) return;
7586
+
7587
+ var _nextCollapsed = !_matchedGroup.collapsed;
7588
+
7589
+ _matchedGroup.collapsed = _nextCollapsed;
7590
+ return true;
7591
+ }
7592
+
7593
+ return false;
7594
+ };
7595
+
7596
+ self.isNewGroupRangeValid = function (groupsArray, from, to) {
7597
+ for (var i = 0; i < groupsArray.length; i++) {
7598
+ var groups = groupsArray[i];
7599
+
7600
+ for (var gIndex = 0; gIndex < groups.length; gIndex++) {
7601
+ var group = groups[gIndex];
7602
+ if (from === group.to + 1) return false;
7603
+ if (from > group.to) continue;
7604
+
7605
+ if (from === group.from) {
7606
+ if (to === group.to) return false;
7607
+ if (to > group.to) return true;
7608
+ break; // check smaller range
7609
+ }
7610
+
7611
+ if (from > group.from) {
7612
+ if (to > group.to) return false;
7613
+ break; // check smaller range
7614
+ }
7615
+
7616
+ if (to < group.to) return false;
7617
+ return true;
7618
+ }
7619
+ }
7620
+
7621
+ return true;
7622
+ };
6422
7623
 
6423
7624
  self.getColumnHeaderCellHeight = function () {
6424
7625
  if (!self.attributes.showColumnHeaders) {
@@ -6484,7 +7685,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6484
7685
  self.orders.rows = fillArray(0, self.originalData.length - 1);
6485
7686
  };
6486
7687
 
6487
- self.fitSelectedColumns = function () {
7688
+ self.fitSelectedColumns = function (width) {
6488
7689
  var selectedColumns = self.selections[0];
6489
7690
  var schema = self.getSchema();
6490
7691
 
@@ -6497,8 +7698,17 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6497
7698
 
6498
7699
  // Make sure the column is not the row header and that the whole column has in fact been selected.
6499
7700
  if (selectedColumn >= 0 && self.isColumnSelected(selectedColumn)) {
6500
- var column = schema[self.orders.columns[selectedColumn]];
6501
- self.fitColumnToValues(column.name);
7701
+ if (isNaN(width)) {
7702
+ var column = schema[self.orders.columns[selectedColumn]];
7703
+ self.fitColumnToValues(column.name);
7704
+ } else {
7705
+ self.sizes.columns[selectedColumn] = width;
7706
+ self.dispatchEvent('resizecolumn', {
7707
+ x: width,
7708
+ y: self.resizingStartingHeight,
7709
+ draggingItem: self.currentCell
7710
+ });
7711
+ }
6502
7712
  }
6503
7713
  }
6504
7714
  } catch (err) {
@@ -6562,6 +7772,19 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6562
7772
  return self.columnFilters && Object.keys(self.columnFilters).length > 0;
6563
7773
  };
6564
7774
 
7775
+ self.hasCollapsedRowGroup = function () {
7776
+ for (var i = 0; i < self.groupedRows.length; i++) {
7777
+ var groups = self.groupedRows[i];
7778
+
7779
+ for (var j = 0; j < groups.length; j++) {
7780
+ var g = groups[j];
7781
+ if (g.collapsed) return true;
7782
+ }
7783
+ }
7784
+
7785
+ return false;
7786
+ };
7787
+
6565
7788
  self.getFilteredAndSortedViewData = function (originalData) {
6566
7789
  // We make a copy of originalData here in order be able to
6567
7790
  // filter and sort rows without modifying the original array.
@@ -6574,7 +7797,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6574
7797
  }); // Apply filtering
6575
7798
 
6576
7799
  var _loop = function _loop() {
6577
- var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
7800
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i4], 2),
6578
7801
  headerName = _Object$entries2$_i[0],
6579
7802
  filterText = _Object$entries2$_i[1];
6580
7803
 
@@ -6595,11 +7818,81 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6595
7818
  });
6596
7819
  };
6597
7820
 
6598
- for (var _i3 = 0, _Object$entries2 = Object.entries(self.columnFilters); _i3 < _Object$entries2.length; _i3++) {
7821
+ for (var _i4 = 0, _Object$entries2 = Object.entries(self.columnFilters); _i4 < _Object$entries2.length; _i4++) {
6599
7822
  var _ret = _loop();
6600
7823
 
6601
7824
  if (_ret === "continue") continue;
6602
- } // Apply sorting
7825
+ } //#region Hide rows from collapsed group
7826
+
7827
+ /** @type {number[][]} */
7828
+
7829
+
7830
+ var collapsedGroups = [];
7831
+
7832
+ for (var i = 0; i < self.groupedRows.length; i++) {
7833
+ var rows = self.groupedRows[i];
7834
+
7835
+ for (var j = 0; j < rows.length; j++) {
7836
+ var r = rows[j];
7837
+ if (!r.collapsed) continue;
7838
+ collapsedGroups.push([r.from, r.to]);
7839
+ }
7840
+ }
7841
+
7842
+ if (collapsedGroups.length > 0) {
7843
+ //#region merge groups
7844
+ collapsedGroups.sort(function (a, b) {
7845
+ return a[0] - b[0];
7846
+ });
7847
+ var newLen = 0;
7848
+ var len = collapsedGroups.length;
7849
+
7850
+ for (var _i5 = 0; _i5 < len; _i5++) {
7851
+ var _r = collapsedGroups[_i5];
7852
+
7853
+ if (_i5 === len - 1) {
7854
+ collapsedGroups[newLen++] = _r;
7855
+ break;
7856
+ }
7857
+
7858
+ var to = _r[1];
7859
+
7860
+ var _collapsedGroups = _slicedToArray(collapsedGroups[_i5 + 1], 2),
7861
+ from2 = _collapsedGroups[0],
7862
+ to2 = _collapsedGroups[1];
7863
+
7864
+ if (from2 > to + 1) {
7865
+ collapsedGroups[newLen++] = _r;
7866
+ continue;
7867
+ }
7868
+
7869
+ collapsedGroups[_i5 + 1] = _r;
7870
+ if (to2 > to) collapsedGroups[_i5 + 1][1] = to2;
7871
+ }
7872
+
7873
+ collapsedGroups = collapsedGroups.slice(0, newLen); //#endregion merge groups
7874
+ //#region omit rows by groups
7875
+
7876
+ var g = collapsedGroups.shift();
7877
+
7878
+ for (var start = 0; start < newViewData.length; start++) {
7879
+ var it = newViewData[start][1];
7880
+ if (it < g[0]) continue;
7881
+ var end = start + 1;
7882
+
7883
+ for (; end < newViewData.length; end++) {
7884
+ var it2 = newViewData[end][1];
7885
+ if (it2 > g[1]) break;
7886
+ }
7887
+
7888
+ newViewData.splice(start, end - start);
7889
+ g = collapsedGroups.shift();
7890
+ if (!g) break;
7891
+ start--;
7892
+ } //#endregion omit rows by groups
7893
+
7894
+ } //#endregion Hide rows from collapsed group
7895
+ // Apply sorting
6603
7896
 
6604
7897
 
6605
7898
  var _iterator8 = _createForOfIteratorHelper(self.orderings.columns),
@@ -6805,13 +8098,336 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6805
8098
  self.orders.columns = self.storedSettings.orders.columns;
6806
8099
  }
6807
8100
 
6808
- self.orderBy = self.storedSettings.orderBy === undefined ? s[0].name : self.storedSettings.orderBy;
6809
- self.orderDirection = self.storedSettings.orderDirection === undefined ? 'asc' : self.storedSettings.orderDirection;
6810
-
6811
- if (self.storedSettings.orderBy !== undefined && self.getHeaderByName(self.orderBy) && self.orderDirection) {
6812
- self.order(self.orderBy, self.orderDirection);
6813
- }
8101
+ self.orderBy = self.storedSettings.orderBy === undefined ? s[0].name : self.storedSettings.orderBy;
8102
+ self.orderDirection = self.storedSettings.orderDirection === undefined ? 'asc' : self.storedSettings.orderDirection;
8103
+
8104
+ if (self.storedSettings.orderBy !== undefined && self.getHeaderByName(self.orderBy) && self.orderDirection) {
8105
+ self.order(self.orderBy, self.orderDirection);
8106
+ }
8107
+ }
8108
+ };
8109
+
8110
+ self.toggleCollapseTree = function (rowIndex, columnIndex, type) {
8111
+ var tempData = [];
8112
+ var collapsedCount = 0;
8113
+
8114
+ if (columnIndex == self.cellTree.rowTreeColIndex && (rowIndex > 0 || rowIndex == 0 && self.cellTree.rows[0].icon)) {
8115
+ var ctr = self.cellTree.rows;
8116
+
8117
+ switch (type) {
8118
+ case 'Expand':
8119
+ ctr[rowIndex].expand = true;
8120
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand = true;
8121
+ break;
8122
+
8123
+ case 'Collapse':
8124
+ ctr[rowIndex].expand = false;
8125
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand = false;
8126
+ break;
8127
+
8128
+ default:
8129
+ ctr[rowIndex].expand = !ctr[rowIndex].expand;
8130
+ self.cellTree.origin.rows[ctr[rowIndex].index].expand = ctr[rowIndex].expand;
8131
+ }
8132
+
8133
+ for (var ri = ctr[rowIndex].index + 1; ri <= ctr[rowIndex].lastchild; ri++) {
8134
+ var orTree = self.cellTree.origin.rows[ri];
8135
+
8136
+ if (ctr[rowIndex].expand) {
8137
+ orTree.hide = false;
8138
+ if (orTree.icon && !orTree.expand) ri = orTree.lastchild;
8139
+ } else {
8140
+ orTree.hide = true;
8141
+ }
8142
+ }
8143
+ } else if (self.cellTree.columns[rowIndex]) {
8144
+ var ctc = self.cellTree.columns[rowIndex];
8145
+
8146
+ switch (type) {
8147
+ case 'Expand':
8148
+ ctc[columnIndex].expand = true;
8149
+ break;
8150
+
8151
+ case 'Collapse':
8152
+ ctc[columnIndex].expand = false;
8153
+ break;
8154
+
8155
+ default:
8156
+ ctc[columnIndex].expand = !ctc[columnIndex].expand;
8157
+ }
8158
+
8159
+ for (var ci = ctc[columnIndex].index + 1; ci <= ctc[columnIndex].lastchild; ci++) {
8160
+ if (ctc[columnIndex].expand) self.cellTree.tempSchema[ci].hidden = false;else self.cellTree.tempSchema[ci].hidden = true;
8161
+ }
8162
+
8163
+ var rc = 0,
8164
+ _ri;
8165
+
8166
+ if (ctc[columnIndex].expand) {
8167
+ while (rc < ctc[columnIndex].child) {
8168
+ _ri = rowIndex + rc + 1;
8169
+
8170
+ for (var _ci = ctc[columnIndex].index; _ci <= ctc[columnIndex].lastchild; _ci++) {
8171
+ if (self.cellTree.origin.columns[_ri] && self.cellTree.origin.columns[_ri][_ci].icon && !self.cellTree.origin.columns[_ri][_ci].expand) {
8172
+ for (var si = _ci + 1; si <= self.cellTree.origin.columns[_ri][_ci].lastchild; si++) {
8173
+ self.cellTree.tempSchema[si].hidden = true;
8174
+ }
8175
+ }
8176
+ }
8177
+
8178
+ rc++;
8179
+ }
8180
+ }
8181
+ }
8182
+
8183
+ var otherData = {};
8184
+ var collapsed = [];
8185
+ self.cellTree.rows = [];
8186
+ self.cellTree.columns = {};
8187
+
8188
+ for (var k in self.cellTree.origin.rows) {
8189
+ var tempRow = [];
8190
+ var tree = self.cellTree.origin.rows[k];
8191
+
8192
+ if (!tree.hide) {
8193
+ var colTrees = [];
8194
+ var collapsedColCount = 0;
8195
+
8196
+ if (k < self.cellTree.columnTreeRowStartIndex) {
8197
+ tempData.push(self.originalData[k]);
8198
+ } else {
8199
+ if (k > self.cellTree.columnTreeRowEndIndex) {
8200
+ otherData[k] = self.viewData[k];
8201
+ collapsedCount++;
8202
+ } else {
8203
+ for (var l = 0; l < self.originalData[k].length; l++) {
8204
+ if (!self.cellTree.tempSchema[l].hidden) {
8205
+ if (l < self.cellTree.rowTreeColIndex) {
8206
+ if (!Object.prototype.hasOwnProperty.call(otherData, k)) otherData[k] = [];
8207
+ otherData[k].push(self.viewData[k][l]);
8208
+ }
8209
+
8210
+ tempRow.push(self.originalData[k][l]);
8211
+ if (Object.prototype.hasOwnProperty.call(self.cellTree.origin.columns, k)) colTrees.push(self.cellTree.origin.columns[k][l]);
8212
+ } else collapsedColCount++;
8213
+ }
8214
+
8215
+ tempRow.push.apply(tempRow, _toConsumableArray(Array(collapsedColCount).fill().map(function () {
8216
+ return '';
8217
+ })));
8218
+
8219
+ if (colTrees.length) {
8220
+ colTrees.push.apply(colTrees, _toConsumableArray(Array(collapsedColCount).fill().map(function () {
8221
+ return {};
8222
+ })));
8223
+ self.cellTree.columns[k] = colTrees;
8224
+ }
8225
+
8226
+ tempData.push(tempRow);
8227
+ }
8228
+ }
8229
+
8230
+ self.cellTree.rows.push(tree);
8231
+ } else {
8232
+ for (var _l = 0; _l < self.cellTree.rowTreeColIndex; _l++) {
8233
+ tempRow.push(self.viewData[k][_l]);
8234
+ }
8235
+
8236
+ otherData[k] = tempRow;
8237
+ collapsed.push(Array(self.viewData[0].length).fill().map(function () {
8238
+ return '';
8239
+ }));
8240
+ collapsedCount++;
8241
+ }
8242
+ }
8243
+
8244
+ if (collapsedCount) {
8245
+ var _self$cellTree$rows;
8246
+
8247
+ (_self$cellTree$rows = self.cellTree.rows).push.apply(_self$cellTree$rows, _toConsumableArray(Array(collapsedCount).fill().map(function (u, index) {
8248
+ return {
8249
+ index: self.cellTree.rows.length + index
8250
+ };
8251
+ })));
8252
+
8253
+ tempData.push.apply(tempData, collapsed);
8254
+ }
8255
+
8256
+ for (var _k in otherData) {
8257
+ if (_k > self.cellTree.columnTreeRowEndIndex) tempData[_k] = otherData[_k];else for (var _l2 in otherData[_k]) {
8258
+ tempData[_k][_l2] = otherData[_k][_l2];
8259
+ }
8260
+ }
8261
+
8262
+ self.viewData = tempData;
8263
+ };
8264
+
8265
+ self.cellTreeExpandCollapse = function (rowIndex, columnIndex, type) {
8266
+ if (columnIndex == self.cellTree.rowTreeColIndex && (rowIndex > 0 || rowIndex == 0 && self.cellTree.rows[0].icon)) {
8267
+ var ctr = self.cellTree.rows;
8268
+
8269
+ switch (type) {
8270
+ case 'Expand':
8271
+ ctr[rowIndex].expand = true;
8272
+ break;
8273
+
8274
+ case 'Collapse':
8275
+ ctr[rowIndex].expand = false;
8276
+ break;
8277
+
8278
+ default:
8279
+ ctr[rowIndex].expand = !ctr[rowIndex].expand;
8280
+ }
8281
+
8282
+ for (var ri = rowIndex + 1; ri <= ctr[rowIndex].lastchild; ri++) {
8283
+ if (ctr[rowIndex].expand) {
8284
+ ctr[ri].hide = false;
8285
+ if (ctr[ri].icon && !ctr[ri].expand) ri = ctr[ri].lastchild;
8286
+ } else {
8287
+ ctr[ri].hide = true;
8288
+ }
8289
+ }
8290
+ } else if (self.cellTree.columns[rowIndex]) {
8291
+ var ctc = self.cellTree.columns[rowIndex];
8292
+
8293
+ switch (type) {
8294
+ case 'Expand':
8295
+ ctc[columnIndex].expand = true;
8296
+ break;
8297
+
8298
+ case 'Collapse':
8299
+ ctc[columnIndex].expand = false;
8300
+ break;
8301
+
8302
+ default:
8303
+ ctc[columnIndex].expand = !ctc[columnIndex].expand;
8304
+ }
8305
+
8306
+ for (var ci = columnIndex + 1; ci <= ctc[columnIndex].lastchild; ci++) {
8307
+ if (ctc[columnIndex].expand) self.tempSchema[ci].hidden = false;else self.tempSchema[ci].hidden = true;
8308
+ }
8309
+
8310
+ var rc = 0,
8311
+ _ri2;
8312
+
8313
+ if (ctc[columnIndex].expand) {
8314
+ while (rc < ctc[columnIndex].child) {
8315
+ _ri2 = rowIndex + rc + 1;
8316
+
8317
+ for (var _ci2 = columnIndex; _ci2 <= ctc[columnIndex].lastchild; _ci2++) {
8318
+ if (self.cellTree.columns[_ri2] && self.cellTree.columns[_ri2][_ci2].icon && !self.cellTree.columns[_ri2][_ci2].expand) {
8319
+ for (var si = _ci2 + 1; si <= self.cellTree.columns[_ri2][_ci2].lastchild; si++) {
8320
+ self.tempSchema[si].hidden = true;
8321
+ }
8322
+ }
8323
+ }
8324
+
8325
+ rc++;
8326
+ }
8327
+ }
8328
+ }
8329
+ };
8330
+
8331
+ self.initCellTreeSettings = function () {
8332
+ if (self.viewData === undefined) return;
8333
+
8334
+ if (self.attributes.rowTree.length > 0 && self.viewData.length > 0) {
8335
+ self.cellTree.rows = Array(self.viewData.length).fill().map(function (u, index) {
8336
+ return {
8337
+ index: index
8338
+ };
8339
+ });
8340
+ self.cellTree.rowTreeColIndex = self.attributes.rowTreeColIndex;
8341
+ var invalidRowTree = false;
8342
+
8343
+ var _iterator9 = _createForOfIteratorHelper(self.attributes.rowTree),
8344
+ _step9;
8345
+
8346
+ try {
8347
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
8348
+ var rt = _step9.value;
8349
+
8350
+ if (self.cellTree.rows.length <= rt.end) {
8351
+ invalidRowTree = true;
8352
+ break;
8353
+ }
8354
+
8355
+ for (var ri = rt.begin; ri <= rt.end; ri++) {
8356
+ if (ri == rt.begin) {
8357
+ self.cellTree.rows[ri].icon = true;
8358
+ self.cellTree.rows[ri].lastchild = rt.end;
8359
+ self.cellTree.rows[ri].expand = true;
8360
+ if (!self.cellTree.rows[ri].parentCount) self.cellTree.rows[ri].parentCount = 0;
8361
+ } else {
8362
+ self.cellTree.rows[ri].hide = false;
8363
+ self.cellTree.rows[ri].parentIndex = rt.begin;
8364
+ if (self.cellTree.rows[ri] && self.cellTree.rows[ri].parentCount) self.cellTree.rows[ri].parentCount += 1;else self.cellTree.rows[ri].parentCount = 1;
8365
+ }
8366
+ }
8367
+ }
8368
+ } catch (err) {
8369
+ _iterator9.e(err);
8370
+ } finally {
8371
+ _iterator9.f();
8372
+ }
8373
+
8374
+ if (invalidRowTree) self.cellTree.rows = {};
8375
+ }
8376
+
8377
+ if (self.attributes.columnTree.length > 0 && self.viewData.length > 0) {
8378
+ self.cellTree.columnTreeRowStartIndex = self.attributes.columnTreeRowStartIndex;
8379
+ self.cellTree.columnTreeRowEndIndex = self.attributes.columnTreeRowEndIndex;
8380
+ var dataColumnLength = Object.keys(self.viewData[0]).length;
8381
+ var invalidColumnTree = false;
8382
+
8383
+ var _iterator10 = _createForOfIteratorHelper(self.attributes.columnTree),
8384
+ _step10;
8385
+
8386
+ try {
8387
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
8388
+ var ct = _step10.value;
8389
+
8390
+ if (dataColumnLength <= ct.end) {
8391
+ invalidColumnTree = true;
8392
+ break;
8393
+ }
8394
+
8395
+ if (!self.cellTree.columns[ct.row]) self.cellTree.columns[ct.row] = Array(dataColumnLength).fill().map(function (u, index) {
8396
+ return {
8397
+ index: index
8398
+ };
8399
+ });
8400
+
8401
+ for (var i = ct.begin; i <= ct.end; i++) {
8402
+ var ctc = self.cellTree.columns[ct.row][i];
8403
+
8404
+ if (i == ct.begin) {
8405
+ ctc.icon = true;
8406
+ ctc.lastchild = ct.end;
8407
+ ctc.length = ct.end - ct.begin;
8408
+ ctc.expand = true;
8409
+ if (ct.child) ctc.child = ct.child;else ctc.child = 0;
8410
+ }
8411
+ }
8412
+ }
8413
+ } catch (err) {
8414
+ _iterator10.e(err);
8415
+ } finally {
8416
+ _iterator10.f();
8417
+ }
8418
+
8419
+ self.cellTree.tempSchema = Array(dataColumnLength).fill().map(function () {
8420
+ return {
8421
+ hidden: false
8422
+ };
8423
+ });
8424
+ if (invalidColumnTree) self.cellTree.columns = {};
6814
8425
  }
8426
+
8427
+ self.cellTree.origin = {
8428
+ rows: self.cellTree.rows,
8429
+ columns: self.cellTree.columns
8430
+ };
6815
8431
  };
6816
8432
 
6817
8433
  self.getDomRoot = function () {
@@ -6994,6 +8610,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6994
8610
  self.intf.gotoCell = self.gotoCell;
6995
8611
  self.intf.gotoRow = self.gotoRow;
6996
8612
  self.intf.addButton = self.addButton;
8613
+ self.intf.toggleCellCollapseTree = self.toggleCellCollapseTree;
8614
+ self.intf.expandCollapseCellTree = self.expandCollapseCellTree;
6997
8615
  self.intf.getHeaderByName = self.getHeaderByName;
6998
8616
  self.intf.findColumnScrollLeft = self.findColumnScrollLeft;
6999
8617
  self.intf.findRowScrollTop = self.findRowScrollTop;
@@ -7001,6 +8619,14 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
7001
8619
  self.intf.findColumnMaxTextLength = self.findColumnMaxTextLength;
7002
8620
  self.intf.disposeContextMenu = self.disposeContextMenu;
7003
8621
  self.intf.getCellAt = self.getCellAt;
8622
+ self.intf.groupColumns = self.groupColumns;
8623
+ self.intf.groupRows = self.groupRows;
8624
+ self.intf.removeGroupColumns = self.removeGroupColumns;
8625
+ self.intf.removeGroupRows = self.removeGroupRows;
8626
+ self.intf.toggleGroupColumns = self.toggleGroupColumns;
8627
+ self.intf.toggleGroupRows = self.toggleGroupRows;
8628
+ self.intf.getGroupsColumnBelongsTo = self.getGroupsColumnBelongsTo;
8629
+ self.intf.getGroupsRowBelongsTo = self.getGroupsRowBelongsTo;
7004
8630
  self.intf.isCellVisible = self.isCellVisible;
7005
8631
  self.intf.isRowVisible = self.isRowVisible;
7006
8632
  self.intf.isColumnVisible = self.isColumnVisible;
@@ -7131,6 +8757,10 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
7131
8757
  self.tryLoadStoredSettings();
7132
8758
  }
7133
8759
 
8760
+ if (key === 'rowTree' || key === 'columnTree' || key === 'columnTreeRowEndIndex') {
8761
+ self.initCellTreeSettings();
8762
+ }
8763
+
7134
8764
  self.draw(true);
7135
8765
  self.dispatchEvent('attributechanged', {
7136
8766
  name: key,
@@ -7765,6 +9395,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
7765
9395
  self.dispatchEvent('datachanged', {
7766
9396
  data: self.originalData
7767
9397
  });
9398
+ self.initCellTreeSettings();
7768
9399
  self.resize(true);
7769
9400
  });
7770
9401
  }
@@ -8114,6 +9745,12 @@ __webpack_require__.r(__webpack_exports__);
8114
9745
  /*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/
8115
9746
 
8116
9747
 
9748
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
9749
+
9750
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
9751
+
9752
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
9753
+
8117
9754
  /* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(self) {
8118
9755
  /**
8119
9756
  * Converts a integer into a letter A - ZZZZZ...
@@ -8460,6 +10097,62 @@ __webpack_require__.r(__webpack_exports__);
8460
10097
  left: cells[0].x + cells[0].width + offset.x
8461
10098
  }, items, imgSrc);
8462
10099
  };
10100
+ /**
10101
+ * Expand/Collapse CellTree.
10102
+ * @memberof canvasDatagrid
10103
+ * @name toggleCellCollapseTree
10104
+ * @method
10105
+ * @param {array} treeData The array of cellTree to expand or collapse.
10106
+ */
10107
+
10108
+
10109
+ self.toggleCellCollapseTree = function (treeData) {
10110
+ for (var type in treeData) {
10111
+ var _iterator = _createForOfIteratorHelper(treeData[type]),
10112
+ _step;
10113
+
10114
+ try {
10115
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
10116
+ var t = _step.value;
10117
+ if (t.length > 0) self.toggleCollapseTree(t[0], t[1], type);
10118
+ }
10119
+ } catch (err) {
10120
+ _iterator.e(err);
10121
+ } finally {
10122
+ _iterator.f();
10123
+ }
10124
+ }
10125
+
10126
+ self.draw();
10127
+ };
10128
+ /**
10129
+ * Expand/Collapse CellTree.
10130
+ * @memberof canvasDatagrid
10131
+ * @name expandCollapseCellTree
10132
+ * @method
10133
+ * @param {array} treeData The array of cellTree to expand or collapse.
10134
+ */
10135
+
10136
+
10137
+ self.expandCollapseCellTree = function (treeData) {
10138
+ for (var type in treeData) {
10139
+ var _iterator2 = _createForOfIteratorHelper(treeData[type]),
10140
+ _step2;
10141
+
10142
+ try {
10143
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
10144
+ var t = _step2.value;
10145
+ if (t.length > 0) self.cellTreeExpandCollapse(t[0], t[1], type);
10146
+ }
10147
+ } catch (err) {
10148
+ _iterator2.e(err);
10149
+ } finally {
10150
+ _iterator2.f();
10151
+ }
10152
+ }
10153
+
10154
+ self.draw();
10155
+ };
8463
10156
  /**
8464
10157
  * Scrolls the cell at cell x, row y into view if it is not already.
8465
10158
  * @memberof canvasDatagrid
@@ -8473,9 +10166,16 @@ __webpack_require__.r(__webpack_exports__);
8473
10166
 
8474
10167
 
8475
10168
  self.scrollIntoView = function (x, y, offsetX, offsetY) {
8476
- if (self.visibleCells.filter(function (cell) {
10169
+ var matched = self.visibleCells.filter(function (cell) {
8477
10170
  return (cell.rowIndex === y || y === undefined) && (cell.columnIndex === x || x === undefined) && cell.x > 0 && cell.y > 0 && cell.x + cell.width < self.width && cell.y + cell.height < self.height;
8478
- }).length === 0) {
10171
+ });
10172
+
10173
+ if (matched.length === 1 && x !== undefined && y !== undefined) {
10174
+ // goto specific cell and its part be hidden by header
10175
+ if (matched[0].x < self.getRowHeaderCellWidth() || matched[0].y < self.getColumnHeaderCellHeight()) matched.length = 0;
10176
+ }
10177
+
10178
+ if (matched.length === 0) {
8479
10179
  self.gotoCell(x, y, offsetX, offsetY);
8480
10180
  }
8481
10181
  };
@@ -9004,6 +10704,315 @@ __webpack_require__.r(__webpack_exports__);
9004
10704
 
9005
10705
  self.setStorageData();
9006
10706
  };
10707
+ /**
10708
+ * Add grouping
10709
+ * @param {'columns'|'rows'} groupFor
10710
+ * @param {number} from
10711
+ * @param {number} to
10712
+ */
10713
+
10714
+
10715
+ function addGroup(groupFor, from, to) {
10716
+ var newRow = false;
10717
+ var allGroups = groupFor === 'rows' ? self.groupedRows : self.groupedColumns;
10718
+
10719
+ for (var i = allGroups.length - 1; i >= 0; i--) {
10720
+ var groups = allGroups[i];
10721
+ var min = groups[0].from,
10722
+ max = groups[groups.length - 1].to;
10723
+
10724
+ if (from <= min && to >= max) {
10725
+ if (from === min && to === max && groups.length === 1) return; // nothings happened
10726
+ // new group wrap this row
10727
+
10728
+ continue;
10729
+ }
10730
+
10731
+ for (var gi = 0; gi < groups.length; gi++) {
10732
+ var g = groups[gi];
10733
+ if (from > g.to) continue;
10734
+
10735
+ if (from >= g.from) {
10736
+ if (to > g.to) {
10737
+ if (from === g.from) {
10738
+ allGroups.splice(i, 0, [{
10739
+ from: from,
10740
+ to: to,
10741
+ collapsed: false
10742
+ }]);
10743
+ self.refresh();
10744
+ return;
10745
+ }
10746
+
10747
+ throw new Error("Can't group these ".concat(groupFor));
10748
+ }
10749
+
10750
+ if (to === g.to) {
10751
+ if (from === g.from) return; // nothings happened
10752
+ }
10753
+
10754
+ newRow = true;
10755
+ break;
10756
+ }
10757
+
10758
+ if (to >= g.from) {
10759
+ if (to < g.to) throw new Error("Can't group these ".concat(groupFor));
10760
+ allGroups.splice(i, 0, [{
10761
+ from: from,
10762
+ to: to,
10763
+ collapsed: false
10764
+ }]);
10765
+ } else {
10766
+ groups.splice(gi, 0, {
10767
+ from: from,
10768
+ to: to,
10769
+ collapsed: false
10770
+ });
10771
+ }
10772
+
10773
+ self.refresh();
10774
+ return;
10775
+ }
10776
+
10777
+ if (newRow) continue;
10778
+ groups.push({
10779
+ from: from,
10780
+ to: to,
10781
+ collapsed: false
10782
+ });
10783
+ self.refresh();
10784
+ return;
10785
+ }
10786
+
10787
+ if (newRow) allGroups.push([{
10788
+ from: from,
10789
+ to: to,
10790
+ collapsed: false
10791
+ }]);else allGroups.unshift([{
10792
+ from: from,
10793
+ to: to,
10794
+ collapsed: false
10795
+ }]);
10796
+ self.refresh();
10797
+ }
10798
+ /**
10799
+ * Remove grouping
10800
+ * @param {Array<Array<{from:number,to:number,collapsed:boolean}>>} allGroups
10801
+ * @param {number} from
10802
+ * @param {number} to
10803
+ */
10804
+
10805
+
10806
+ function removeGroup(allGroups, from, to) {
10807
+ for (var i = 0; i < allGroups.length; i++) {
10808
+ var groups = allGroups[i];
10809
+
10810
+ for (var gi = 0; gi < groups.length; gi++) {
10811
+ var group = groups[gi];
10812
+
10813
+ if (group.from === from && group.to === to) {
10814
+ if (groups.length <= 1) allGroups.splice(i, 1);else groups.splice(gi, 1);
10815
+ self.refresh();
10816
+ return;
10817
+ }
10818
+ }
10819
+ }
10820
+ }
10821
+ /**
10822
+ * Grouping columns
10823
+ * @memberof canvasDatagrid
10824
+ * @name groupColumns
10825
+ * @method
10826
+ * @param {number|string} firstColumnName Name of the first column to be grouped.
10827
+ * @param {number|string} lastColumnName Name of the last column to be grouped.
10828
+ */
10829
+
10830
+
10831
+ self.groupColumns = function (firstColumnName, lastColumnName) {
10832
+ /** @type {Array<{name: string,columnIndex:number}>} */
10833
+ var schema = self.getSchema();
10834
+ var firstOne, lastOne;
10835
+
10836
+ for (var i = 0; i < schema.length; i++) {
10837
+ var it = schema[i];
10838
+ if (firstOne && lastOne) break;
10839
+
10840
+ if (it.name === firstColumnName) {
10841
+ firstOne = it;
10842
+ continue;
10843
+ }
10844
+
10845
+ if (it.name === lastColumnName) {
10846
+ lastOne = it;
10847
+ continue;
10848
+ }
10849
+ }
10850
+
10851
+ if (!firstOne) throw new Error("No such column name for first column");
10852
+ if (!lastOne) throw new Error("No such column name for last column");
10853
+ if (lastOne.columnIndex > firstOne.columnIndex !== true) throw new Error("Can't group these columns");
10854
+ var from = firstOne.columnIndex;
10855
+ var to = lastOne.columnIndex;
10856
+ var ev = {
10857
+ group: {
10858
+ type: 'columns',
10859
+ from: from,
10860
+ to: to
10861
+ }
10862
+ };
10863
+
10864
+ try {
10865
+ addGroup('columns', from, to);
10866
+ } catch (error) {
10867
+ ev.error = error;
10868
+ }
10869
+
10870
+ self.dispatchEvent('aftercreategroup', ev);
10871
+ };
10872
+ /**
10873
+ * Grouping columns
10874
+ * @memberof canvasDatagrid
10875
+ * @name groupRows
10876
+ * @method
10877
+ * @param {number} rowIndexFrom The row index which is the beginning of the group
10878
+ * @param {number} rowIndexTo The row index which is the end of the group
10879
+ */
10880
+
10881
+
10882
+ self.groupRows = function (rowIndexFrom, rowIndexTo) {
10883
+ if (!Number.isInteger(rowIndexFrom) || rowIndexFrom < 0) throw new Error("No such row for the beginning of the group");
10884
+ var dataLength = self.viewData.length;
10885
+ if (!Number.isInteger(rowIndexFrom) || rowIndexTo <= rowIndexFrom || rowIndexTo >= dataLength) throw new Error("No such row for the end of the group");
10886
+ var ev = {
10887
+ group: {
10888
+ type: 'rows',
10889
+ from: rowIndexFrom,
10890
+ to: rowIndexTo
10891
+ }
10892
+ };
10893
+
10894
+ try {
10895
+ addGroup('rows', rowIndexFrom, rowIndexTo);
10896
+ } catch (error) {
10897
+ ev.error = error;
10898
+ }
10899
+
10900
+ self.dispatchEvent('aftercreategroup', ev);
10901
+ };
10902
+ /**
10903
+ * Remove grouping columns
10904
+ * @memberof canvasDatagrid
10905
+ * @name removeGroupColumns
10906
+ * @method
10907
+ * @param {number|string} firstColumnName Name of the first column to be grouped.
10908
+ * @param {number|string} lastColumnName Name of the last column to be grouped.
10909
+ */
10910
+
10911
+
10912
+ self.removeGroupColumns = function (firstColumnName, lastColumnName) {
10913
+ /** @type {Array<{name:string,columnIndex:number}>} */
10914
+ var schema = self.getSchema();
10915
+ var firstOne, lastOne;
10916
+
10917
+ for (var i = 0; i < schema.length; i++) {
10918
+ var it = schema[i];
10919
+ if (firstOne && lastOne) break;
10920
+
10921
+ if (it.name === firstColumnName) {
10922
+ firstOne = it;
10923
+ continue;
10924
+ }
10925
+
10926
+ if (it.name === lastColumnName) {
10927
+ lastOne = it;
10928
+ continue;
10929
+ }
10930
+ }
10931
+
10932
+ if (!firstOne) throw new Error("No such column name for first column");
10933
+ if (!lastOne) throw new Error("No such column name for last column");
10934
+ var from = firstOne.columnIndex;
10935
+ var to = lastOne.columnIndex;
10936
+ removeGroup(self.groupedColumns, from, to);
10937
+ };
10938
+ /**
10939
+ * Remove grouping columns
10940
+ * @memberof canvasDatagrid
10941
+ * @name removeGroupRows
10942
+ * @method
10943
+ * @param {number} rowIndexFrom The row index which is the beginning of the group
10944
+ * @param {number} rowIndexTo The row index which is the end of the group
10945
+ */
10946
+
10947
+
10948
+ self.removeGroupRows = function (rowIndexFrom, rowIndexTo) {
10949
+ removeGroup(self.groupedRows, rowIndexFrom, rowIndexTo);
10950
+ };
10951
+ /**
10952
+ * Toggle(expand/collapsed) grouping columns
10953
+ * @memberof canvasDatagrid
10954
+ * @name toggleGroupColumns
10955
+ * @method
10956
+ * @param {number|string} firstColumnName Name of the first column to be grouped.
10957
+ * @param {number|string} lastColumnName Name of the last column to be grouped.
10958
+ */
10959
+
10960
+
10961
+ self.toggleGroupColumns = function (firstColumnName, lastColumnName) {
10962
+ /** @type {Array<{name:string,columnIndex:number}>} */
10963
+ var schema = self.getSchema();
10964
+ var firstOne, lastOne;
10965
+
10966
+ for (var i = 0; i < schema.length; i++) {
10967
+ var it = schema[i];
10968
+ if (firstOne && lastOne) break;
10969
+
10970
+ if (it.name === firstColumnName) {
10971
+ firstOne = it;
10972
+ continue;
10973
+ }
10974
+
10975
+ if (it.name === lastColumnName) {
10976
+ lastOne = it;
10977
+ continue;
10978
+ }
10979
+ }
10980
+
10981
+ if (!firstOne || !lastOne) return;
10982
+ var from = firstOne.columnIndex;
10983
+ var to = lastOne.columnIndex;
10984
+
10985
+ if (self.toggleGroup({
10986
+ type: 'c',
10987
+ from: from,
10988
+ to: to
10989
+ })) {
10990
+ self.disposeContextMenu();
10991
+ self.setStorageData();
10992
+ self.refresh();
10993
+ }
10994
+ };
10995
+ /**
10996
+ * Toggle(expand/collapsed) grouping rows
10997
+ * @memberof canvasDatagrid
10998
+ * @name toggleGroupRows
10999
+ * @method
11000
+ * @param {number} rowIndexFrom The row index which is the beginning of the group
11001
+ * @param {number} rowIndexTo The row index which is the end of the group
11002
+ */
11003
+
11004
+
11005
+ self.toggleGroupRows = function (rowIndexFrom, rowIndexTo) {
11006
+ if (self.toggleGroup({
11007
+ type: 'r',
11008
+ from: rowIndexFrom,
11009
+ to: rowIndexTo
11010
+ })) {
11011
+ self.disposeContextMenu();
11012
+ self.setStorageData();
11013
+ self.refresh();
11014
+ }
11015
+ };
9007
11016
 
9008
11017
  self.isInGrid = function (e) {
9009
11018
  if (e.x < 0 || e.x > self.width || e.y < 0 || e.y > self.height) {
@@ -9094,6 +11103,10 @@ __webpack_require__.r(__webpack_exports__);
9094
11103
  } // TODO:
9095
11104
 
9096
11105
 
11106
+ if (!self.data) {
11107
+ self.data = {};
11108
+ }
11109
+
9097
11110
  if (!self.data[rowIndex]) {
9098
11111
  self.data[rowIndex] = {};
9099
11112
  } // TODO:
@@ -9132,6 +11145,64 @@ __webpack_require__.r(__webpack_exports__);
9132
11145
  });
9133
11146
  });
9134
11147
  };
11148
+ /**
11149
+ * Get the column group info given column belongs to
11150
+ * @memberof canvasDatagrid
11151
+ * @name getGroupsColumnBelongsTo
11152
+ * @method
11153
+ * @param {number} columnIndex Column index.
11154
+ * @returns {Array<{from:number,to:number,collapsed:boolean}>}
11155
+ */
11156
+
11157
+
11158
+ self.getGroupsColumnBelongsTo = function (columnIndex) {
11159
+ if (!self.attributes.allowGroupingColumns) return [];
11160
+ var result = [];
11161
+
11162
+ for (var i = 0; i < self.groupedColumns.length; i++) {
11163
+ var groups = self.groupedColumns[i];
11164
+
11165
+ for (var j = 0; j < groups.length; j++) {
11166
+ var group = groups[j];
11167
+
11168
+ if (columnIndex >= group.from && columnIndex <= group.to) {
11169
+ result.push(group);
11170
+ break;
11171
+ }
11172
+ }
11173
+ }
11174
+
11175
+ return result;
11176
+ };
11177
+ /**
11178
+ * Get the row group info given row belongs to
11179
+ * @memberof canvasDatagrid
11180
+ * @name getGroupsRowBelongsTo
11181
+ * @method
11182
+ * @param {number} rowIndex Row index.
11183
+ * @returns {Array<{from:number,to:number,collapsed:boolean}>}
11184
+ */
11185
+
11186
+
11187
+ self.getGroupsRowBelongsTo = function (rowIndex) {
11188
+ if (!self.attributes.allowGroupingRows) return [];
11189
+ var result = [];
11190
+
11191
+ for (var i = 0; i < self.groupedRows.length; i++) {
11192
+ var groups = self.groupedRows[i];
11193
+
11194
+ for (var j = 0; j < groups.length; j++) {
11195
+ var group = groups[j];
11196
+
11197
+ if (rowIndex >= group.from && rowIndex <= group.to) {
11198
+ result.push(group);
11199
+ break;
11200
+ }
11201
+ }
11202
+ }
11203
+
11204
+ return result;
11205
+ };
9135
11206
  /**
9136
11207
  * Checks if a given column is visible.
9137
11208
  * @memberof canvasDatagrid
@@ -9178,6 +11249,48 @@ __webpack_require__.r(__webpack_exports__);
9178
11249
  return c.columnIndex === x && c.rowIndex === y;
9179
11250
  })[0];
9180
11251
  };
11252
+ /**
11253
+ * @memberof canvasDatagrid
11254
+ * @name getColumnGroupAt
11255
+ * @method
11256
+ * @param {number} x Number of pixels from the left.
11257
+ * @param {number} y Number of pixels from the top.
11258
+ */
11259
+
11260
+
11261
+ self.getColumnGroupAt = function (x, y) {
11262
+ var groups = self.groupedColumns.length;
11263
+ if (groups <= 0) return;
11264
+ var yZero = self.getColumnGroupAreaHeight();
11265
+ if (y >= yZero) return;
11266
+
11267
+ for (var i = 0; i < self.visibleGroups.length; i++) {
11268
+ var g = self.visibleGroups[i];
11269
+ if (g.type !== 'c') continue;
11270
+ if (x >= g.x && y >= g.y && x <= g.x2 && y <= g.y2) return g;
11271
+ }
11272
+ };
11273
+ /**
11274
+ * @memberof canvasDatagrid
11275
+ * @name getRowGroupAt
11276
+ * @method
11277
+ * @param {number} x Number of pixels from the left.
11278
+ * @param {number} y Number of pixels from the top.
11279
+ */
11280
+
11281
+
11282
+ self.getRowGroupAt = function (x, y) {
11283
+ var groups = self.groupedRows.length;
11284
+ if (groups <= 0) return;
11285
+ var xZero = self.getRowGroupAreaWidth();
11286
+ if (x >= xZero) return;
11287
+
11288
+ for (var i = 0; i < self.visibleGroups.length; i++) {
11289
+ var g = self.visibleGroups[i];
11290
+ if (g.type !== 'r') continue;
11291
+ if (x >= g.x && y >= g.y && x <= g.x2 && y <= g.y2) return g;
11292
+ }
11293
+ };
9181
11294
  /**
9182
11295
  * Gets the cell at grid pixel coordinate x and y. Author's note. This function ties drawing and events together. This is a very complex function and is core to the component.
9183
11296
  * @memberof canvasDatagrid
@@ -9212,6 +11325,8 @@ __webpack_require__.r(__webpack_exports__);
9212
11325
  return;
9213
11326
  }
9214
11327
 
11328
+ x -= self.getRowGroupAreaWidth();
11329
+ y -= self.getColumnGroupAreaHeight();
9215
11330
  var border,
9216
11331
  tsz = useTouchScrollZones ? self.attributes.touchScrollZone : 0,
9217
11332
  moveMode = self.attributes.borderDragBehavior === 'move',