canvas-datagrid 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/canvas-datagrid.debug.js +3433 -1522
- package/dist/canvas-datagrid.debug.map +1 -1
- package/dist/canvas-datagrid.js +1 -1
- package/dist/canvas-datagrid.module.js +1 -1
- package/dist/canvas-datagrid.module.js.map +1 -1
- package/dist/types.d.ts +295 -70
- package/lib/component.js +1 -2
- package/lib/contextMenu.js +10 -102
- package/lib/defaults.js +7 -0
- package/lib/docs.js +37 -3
- package/lib/dom.js +2 -1
- package/lib/draw.js +169 -69
- package/lib/events/index.js +587 -277
- package/lib/intf.js +33 -219
- package/lib/main.js +3 -0
- package/lib/publicMethods.js +17 -386
- package/lib/selections/index.js +985 -0
- package/lib/selections/type.d.ts +38 -0
- package/lib/selections/util.js +1319 -0
- package/package.json +4 -4
package/lib/defaults.js
CHANGED
|
@@ -25,9 +25,11 @@ export default function (self) {
|
|
|
25
25
|
['autoResizeRows', false],
|
|
26
26
|
['autoScrollOnMousemove', false],
|
|
27
27
|
['autoScrollMargin', 5],
|
|
28
|
+
['allowShrinkingSelection', false],
|
|
28
29
|
['blanksText', '(Blanks)'],
|
|
29
30
|
['borderDragBehavior', 'none'],
|
|
30
31
|
['borderResizeZone', 10],
|
|
32
|
+
['clearCellsWhenShrinkingSelection', false],
|
|
31
33
|
['clearSettingsOptionText', 'Clear saved settings'],
|
|
32
34
|
['columnHeaderClickBehavior', 'sort'],
|
|
33
35
|
['columnSelectorHiddenText', ' '],
|
|
@@ -59,6 +61,7 @@ export default function (self) {
|
|
|
59
61
|
['persistantSelectionMode', false],
|
|
60
62
|
['removeFilterOptionText', 'Remove filter on %s'],
|
|
61
63
|
['reorderDeadZone', 3],
|
|
64
|
+
['resizeAfterDragged', false],
|
|
62
65
|
['resizeScrollZone', 20],
|
|
63
66
|
['rowGrabZoneSize', 5],
|
|
64
67
|
['columnGrabZoneSize', 30],
|
|
@@ -334,6 +337,8 @@ export default function (self) {
|
|
|
334
337
|
['reorderMarkerBorderWidth', 1.25],
|
|
335
338
|
['reorderMarkerIndexBorderColor', 'rgba(66, 133, 244, 1)'],
|
|
336
339
|
['reorderMarkerIndexBorderWidth', 2.75],
|
|
340
|
+
['resizeMarkerColor', 'rgba(0, 0, 0, 0.2)'],
|
|
341
|
+
['resizeMarkerSize', 2],
|
|
337
342
|
['rowGroupColumnWidth', 25],
|
|
338
343
|
['rowHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'],
|
|
339
344
|
['rowHeaderCellBorderColor', 'rgba(200, 200, 200, 1)'],
|
|
@@ -371,6 +376,8 @@ export default function (self) {
|
|
|
371
376
|
['selectionHandleColor', 'rgba(66, 133, 244, 1)'],
|
|
372
377
|
['selectionHandleSize', 8],
|
|
373
378
|
['selectionHandleType', 'square'],
|
|
379
|
+
['fillOverlayBorderColor', 'rgba(127, 127, 127, 1)'],
|
|
380
|
+
['fillOverlayBorderWidth', 2],
|
|
374
381
|
['selectionOverlayBorderColor', 'rgba(66, 133, 244, 1)'],
|
|
375
382
|
['selectionOverlayBorderWidth', 1],
|
|
376
383
|
['treeArrowBorderColor', 'rgba(195, 199, 202, 1)'],
|
package/lib/docs.js
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
* @param {number} [args.autoScrollMargin=5] - Number of pixels of mouse movement to trigger auto scroll.
|
|
30
30
|
* @param {boolean} [args.allowFreezingRows=false] - When true, the UI provides a drag-able cutter to freeze rows.
|
|
31
31
|
* @param {boolean} [args.allowFreezingColumns=false] - When true, the UI provides a drag-able cutter to freeze columns.
|
|
32
|
+
* @param {boolean} [args.allowShrinkingSelection=false] - When true, this allows users to shrink the selection by dragging and dropping the handle inwards, similar to Excel. (Not supported yet.)
|
|
33
|
+
* @param {boolean} [args.clearCellsWhenShrinkingSelection=false] - When true, this allows the clearing of the previously selected cells after the handle is moved inwards. (Not supported yet.)
|
|
32
34
|
* @param {boolean} [args.filterFrozenRows=true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by filters when {@link canvasDatagrid#param:allowFreezingRows} is true.
|
|
33
35
|
* @param {boolean} [args.sortFrozenRows=true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by sorters when {@link canvasDatagrid#param:allowSorting} is true.
|
|
34
36
|
* @param {boolean} [args.allowColumnReordering=true] - When true columns can be reordered.
|
|
@@ -80,6 +82,7 @@
|
|
|
80
82
|
* @param {string} [args.rowGroupIndicatorPosition='bottom'] - Ths position of the row group indicator(icon), available values: 'top' and 'bottom'.
|
|
81
83
|
* @param {boolean} [args.showOrderByOption=true] - Show an option on the context menu sort rows.
|
|
82
84
|
* @param {boolean} [args.showPaste=false] - Show the paste option in the context menu when applicable.
|
|
85
|
+
* @param {boolean} [args.resizeAfterDragged] - Resize after the handle is dropped, similar to Excel.
|
|
83
86
|
* @param {array} [args.schema=[]] - Sets the schema. See {@link canvasDatagrid.schema}.
|
|
84
87
|
* @param {array} [args.data=[]] - Sets the data. See {@link canvasDatagrid.data}.
|
|
85
88
|
* @param {number} [args.touchReleaseAnimationDurationMs=2000] - How long the ease animation runs after touch release.
|
|
@@ -91,7 +94,7 @@
|
|
|
91
94
|
* @param {string} [args.copyText=Copy] - The text that appears on the context menu when copy is available.
|
|
92
95
|
* @param {string} [args.columnHeaderClickBehavior=sort] - Can be any of sort, select, none. When sort is selected, left clicking a column header will result in sorting ascending, then sorting descending if already sorted by this column. If select is selected then clicking a column header will result in the column becoming selected. Holding control/command or shift will select multiple columns in this mode.
|
|
93
96
|
* @param {boolean} [args.scrollPointerLock=false] - When true, clicking on the scroll box to scroll will cause the mouse cursor to disappear to prevent it from exiting the area observable to the grid.
|
|
94
|
-
* @param {string} [args.selectionHandleBehavior='none'] - When set to a value other than none a handle will appear in the lower right corner of the desktop version of the grid.
|
|
97
|
+
* @param {string} [args.selectionHandleBehavior='none'] - When set to a value other than none, a handle will appear in the lower right corner of the desktop version of the grid.
|
|
95
98
|
* @param {string} [args.columnSelectorVisibleText='   '] - When a column is hidden, this is the value to the left of the title in the column selector content menu.
|
|
96
99
|
* @param {string} [args.columnSelectorHiddenText='\u2713'] - When a column is visible, this is the value to the left of the title in the column selector content menu.
|
|
97
100
|
* @param {string} [args.columnSelectorText='Add/remove columns'] - The text of the column selector context menu.
|
|
@@ -106,6 +109,7 @@
|
|
|
106
109
|
* @param {number} [args.touchZoomMin=0.5] - The minimum zoom scale.
|
|
107
110
|
* @param {number} [args.touchZoomMax=1.75] - The maximum zoom scale.
|
|
108
111
|
* @param {number} [args.maxPixelRatio=1.5] - The maximum pixel ratio for high DPI displays. High DPI displays can cause sluggish performance, this caps resolution the grid is rendered at. Standard resolution (e.g.: 1920x1080) have a pixel ratio of 1:1 while higher resolution displays can be higher (e.g.: Retina display 2:1). Higher numbers are sharper (higher resolution) up to the max of your display (usually 2), lower numbers are lower resolution, down to 1. It might be fun to set a value lower than 1, I've never done it.
|
|
112
|
+
* @param {object} [args.fillCellCallback] - The callback function that is called when a cell is filled.
|
|
109
113
|
* @param {canvasDatagrid.style} [args.style={}] - Sets selected values in style.
|
|
110
114
|
* @param {canvasDatagrid.filter} [args.filters={}] - Sets selected values in filters. See {@link canvasDatagrid.filters}.
|
|
111
115
|
* @param {canvasDatagrid.sorter} [args.sorters={}] - Sets selected values in sorters. See {@link canvasDatagrid.sorters}.
|
|
@@ -256,6 +260,32 @@
|
|
|
256
260
|
* @property {object} text.width - The width of the text, including truncation and ellipsis.
|
|
257
261
|
* @property {object} text.value - The value of the text, including truncation and ellipsis.
|
|
258
262
|
*/
|
|
263
|
+
/**
|
|
264
|
+
* The additional function to invoke when a cell is filled. The return value of this
|
|
265
|
+
* function sets the new data of the cell.
|
|
266
|
+
* @function
|
|
267
|
+
* @name canvasDataGrid.fillCellCallback
|
|
268
|
+
* @param {object} args - Arguments that are passed to the function.
|
|
269
|
+
* @param {array} args.rows - Data that is being filled into all the cells, including this one.
|
|
270
|
+
* @param {string} args.direction - Direction of the fill operation, which can be 'horizontal' for x axis, 'vertical' for y axis, or 'both' when it goes both ways, e.g., when pasting unevenly.
|
|
271
|
+
* @param {object} args.newRowData - New row data that is going to replace 'existingRowData'. The result of this function will be kept in this object.
|
|
272
|
+
* @param {object} args.existingRowData - Existing data of the row. This will be replaced with 'newRowData'.
|
|
273
|
+
* @param {number} args.rowIndex - Index of the row on the grid.
|
|
274
|
+
* @param {number} args.rowOffset - Position/offset of 'cells' in 'rows'. Starts with '0'.
|
|
275
|
+
* @param {array} args.cells - New data for all the cells, including this one, for the current row. This is the same as accessing 'rows' using 'rowOffset'.
|
|
276
|
+
* @param {boolean} args.reversed - Whether the fill operation is applied in the reverse order, meaning if horizontal, we are going from right to left, and if vertical, we are going from bottom to top.
|
|
277
|
+
* @param {boolean} args.isFillingRow - Whether the current row is being filled. If the 'direction' is 'vertical', this will always be true, or sometimes true if the 'direction' is 'both'.
|
|
278
|
+
* @param {number} args.fillingRowPosition - Increase in position since the first filling of the rows. This will be '-1' if 'isFillingRow' is false. Starts with '0'.
|
|
279
|
+
* @param {number} args.fillingRowLength - Total length that 'fillingRowPosition' will go. This will be '-1' if 'isFillingRow' is false.
|
|
280
|
+
* @param {object} args.column - Column that this cell is on.
|
|
281
|
+
* @param {number} args.columnIndex - The index of the column on the grid.
|
|
282
|
+
* @param {string} args.newCellData - Data from 'cells' to be set for this cell. You can modify this and return the result to set the new data for this cell.
|
|
283
|
+
* @param {string} args.existingCellData - Existing data on this cell that is about to be replaced with the data you will return.
|
|
284
|
+
* @param {number} args.columnOffset - Position/offset of the 'newCellData' in 'cells'. Starts with '0'.
|
|
285
|
+
* @param {boolean} args.isFillingColumn - Whether the current column is being filled. If the 'direction' is 'horizontal', this will always be true, or sometimes true if the 'direction' is 'both'.
|
|
286
|
+
* @param {number} args.fillingColumnPosition - Increase in position since the first filling of the columns. This will be '-1' if 'isFillingColumn' is false. Starts with '0'.
|
|
287
|
+
* @param {number} args.fillingColumnLength - Total length that 'fillingColumnPosition' will go. This will be '-1' if 'isFillingColumn' is false.
|
|
288
|
+
*/
|
|
259
289
|
/**
|
|
260
290
|
* Styles for the canvas data grid. Standard CSS styles still apply but are not listed here.
|
|
261
291
|
* @class
|
|
@@ -277,8 +307,8 @@
|
|
|
277
307
|
* @property {string} [activeCellSelectedBackgroundColor=rgba(236, 243, 255, 1)] - Style of activeCellSelectedBackgroundColor.
|
|
278
308
|
* @property {string} [activeCellSelectedColor=rgba(0, 0, 0, 1)] - Style of activeCellSelectedColor.
|
|
279
309
|
* @property {string} [activeCellVerticalAlignment=center] - Style of activeCellVerticalAlignment.
|
|
280
|
-
* @property {string} [
|
|
281
|
-
* @property {string} [
|
|
310
|
+
* @property {string} [activeColumnHeaderCellBackgroundColor=rgba(225, 225, 225, 1)] - Style of activeColumnHeaderCellBackgroundColor.
|
|
311
|
+
* @property {string} [activeColumnHeaderCellColor=rgba(0, 0, 0, 1)] - Style of activeColumnHeaderCellColor.
|
|
282
312
|
* @property {string} [activeRowHeaderCellBackgroundColor=rgba(225, 225, 225, 1)] - Style of activeRowHeaderCellBackgroundColor.
|
|
283
313
|
* @property {string} [activeRowHeaderCellColor=rgba(0, 0, 0, 1)] - Style of activeRowHeaderCellColor.
|
|
284
314
|
* @property {number} [autocompleteBottomMargin=60] - Style of autocompleteBottomMargin.
|
|
@@ -364,6 +394,8 @@
|
|
|
364
394
|
* @property {string} [editCellColor=black] - Style of editCellColor.
|
|
365
395
|
* @property {string} [editCellBackgroundColor=white] - Style of editCellBackgroundColor.
|
|
366
396
|
* @property {number} [editCellZIndex=10000] - Style of editCellZIndex.
|
|
397
|
+
* @property {string} [fillOverlayBorderColor=rgba(127, 127, 127, 1)] - Style of fillOverlayBorderColor.
|
|
398
|
+
* @property {number} [fillOverlayBorderWidth=2] - Style of fillOverlayBorderWidth.
|
|
367
399
|
* @property {string} [gridBackgroundColor=rgba(240, 240, 240, 1)] - Style of gridBackgroundColor.
|
|
368
400
|
* @property {string} [gridBorderColor=rgba(202, 202, 202, 1)] - Style of gridBorderColor.
|
|
369
401
|
* @property {number} [gridBorderWidth=1] - Style of gridBorderWidth.
|
|
@@ -403,6 +435,8 @@
|
|
|
403
435
|
* @property {number} [reorderMarkerBorderWidth=1.25] - Style of reorderMarkerBorderWidth.
|
|
404
436
|
* @property {string} [reorderMarkerIndexBorderColor=rgba(66, 133, 244, 1)] - Style of reorderMarkerIndexBorderColor.
|
|
405
437
|
* @property {number} [reorderMarkerIndexBorderWidth=2.75] - Style of reorderMarkerIndexBorderWidth.
|
|
438
|
+
* @property {string} [resizeMarkerColor=rgba(0, 0, 0, 0.2)] - Style of resizeMarkerColor.
|
|
439
|
+
* @property {number} [resizeMarkerSize=2] - Style of resizeMarkerSize.
|
|
406
440
|
* @property {number} [rowGroupColumnWidth=25] - Style of rowGroupColumnWidth.
|
|
407
441
|
* @property {string} [rowHeaderCellBackgroundColor=rgba(240, 240, 240, 1)] - Style of rowHeaderCellBackgroundColor.
|
|
408
442
|
* @property {string} [rowHeaderCellBorderColor=rgba(152, 152, 152, 1)] - Style of rowHeaderCellBorderColor.
|
package/lib/dom.js
CHANGED
|
@@ -755,6 +755,7 @@ export default function (self) {
|
|
|
755
755
|
Object.keys(css[className]).map(function (prop) {
|
|
756
756
|
el.style[prop] = css[className][prop];
|
|
757
757
|
});
|
|
758
|
+
el.className = className;
|
|
758
759
|
}
|
|
759
760
|
return;
|
|
760
761
|
};
|
|
@@ -803,7 +804,7 @@ export default function (self) {
|
|
|
803
804
|
self.eventParent.addEventListener('mousedown', self.mousedown, false);
|
|
804
805
|
self.eventParent.addEventListener('dblclick', self.dblclick, false);
|
|
805
806
|
self.eventParent.addEventListener('click', self.click, false);
|
|
806
|
-
|
|
807
|
+
self.eventParent.addEventListener('mouseup', self.mouseup, false);
|
|
807
808
|
window.addEventListener('mousemove', self.mousemove);
|
|
808
809
|
self[self.isChildGrid ? 'parentGrid' : 'eventParent'].addEventListener(
|
|
809
810
|
'wheel',
|
package/lib/draw.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
/*globals XMLSerializer: false, define: true, Blob: false, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
+
import { isCellSelected } from './selections/util';
|
|
6
|
+
|
|
5
7
|
export default function (self) {
|
|
6
8
|
var perfCounters = [],
|
|
7
9
|
cachedImagesDrawn = false,
|
|
@@ -943,13 +945,17 @@ export default function (self) {
|
|
|
943
945
|
selectionHandles.push([cell, 'tr']);
|
|
944
946
|
cell.selectionHandle = 'tr';
|
|
945
947
|
}
|
|
946
|
-
if (
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
948
|
+
if (cell.selectionBorderTop && cell.selectionBorderLeft) {
|
|
949
|
+
if (self.mobile) {
|
|
950
|
+
selectionHandles.push([cell, 'tl']);
|
|
951
|
+
cell.selectionHandle = 'tl';
|
|
952
|
+
}
|
|
953
|
+
if (self.fillOverlay.handle) {
|
|
954
|
+
self.fillOverlay.snapTo = {
|
|
955
|
+
x: cell.x,
|
|
956
|
+
y: cell.y,
|
|
957
|
+
};
|
|
958
|
+
}
|
|
953
959
|
}
|
|
954
960
|
if (
|
|
955
961
|
cell.selectionBorderBottom &&
|
|
@@ -966,6 +972,22 @@ export default function (self) {
|
|
|
966
972
|
) {
|
|
967
973
|
selectionHandles.push([cell, 'br']);
|
|
968
974
|
cell.selectionHandle = 'br';
|
|
975
|
+
|
|
976
|
+
if (self.fillOverlay.handle) {
|
|
977
|
+
self.fillOverlay.handle.x = cell.x + cell.width;
|
|
978
|
+
self.fillOverlay.handle.y = cell.y + cell.height;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if (self.fillOverlay.handle) {
|
|
983
|
+
// Some corners may not be displaying, so we get at least
|
|
984
|
+
// one correct axis in order to display a fill overlay.
|
|
985
|
+
if (self.fillOverlay.snapTo.x === -1 && cell.selectionBorderLeft) {
|
|
986
|
+
self.fillOverlay.snapTo.x = cell.x;
|
|
987
|
+
}
|
|
988
|
+
if (self.fillOverlay.snapTo.y === -1 && cell.selectionBorderTop) {
|
|
989
|
+
self.fillOverlay.snapTo.y = cell.y;
|
|
990
|
+
}
|
|
969
991
|
}
|
|
970
992
|
}
|
|
971
993
|
}
|
|
@@ -975,21 +997,23 @@ export default function (self) {
|
|
|
975
997
|
propPrefix,
|
|
976
998
|
offsetPoint,
|
|
977
999
|
) {
|
|
978
|
-
offsetPoint = offsetPoint || { x: 0, y: 0 };
|
|
979
1000
|
cell.selectionBorder = '';
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1001
|
+
// TODO: optimize it by `getSelectionStateFromCells`
|
|
1002
|
+
const isSelected = offsetPoint
|
|
1003
|
+
? (row, col) =>
|
|
1004
|
+
isCellSelected(
|
|
1005
|
+
self.selections,
|
|
1006
|
+
row - offsetPoint.y,
|
|
1007
|
+
col - offsetPoint.x,
|
|
1008
|
+
)
|
|
1009
|
+
: (row, col) => isCellSelected(self.selections, row, col);
|
|
1010
|
+
const lastColumnIndex = Math.max(schema.length - 1, 0);
|
|
1011
|
+
const lastRowIndex = Math.max(viewData.length - 1, 0);
|
|
1012
|
+
const { isRowHeader, rowIndex, columnIndex } = cell;
|
|
1013
|
+
|
|
1014
|
+
if (!isRowHeader && isSelected(rowIndex, columnIndex)) {
|
|
987
1015
|
if (
|
|
988
|
-
(!
|
|
989
|
-
self.selections[cell.rowIndex - 1 + -offsetPoint.y].indexOf(
|
|
990
|
-
cell.columnIndex + -offsetPoint.x,
|
|
991
|
-
) === -1 ||
|
|
992
|
-
cell.rowIndex === 0) &&
|
|
1016
|
+
(!isSelected(rowIndex - 1, columnIndex) || rowIndex === 0) &&
|
|
993
1017
|
!cell.isHeader
|
|
994
1018
|
) {
|
|
995
1019
|
drawArray.push([cell, 't']);
|
|
@@ -997,32 +1021,21 @@ export default function (self) {
|
|
|
997
1021
|
cell[propPrefix + 'Border'] += 't';
|
|
998
1022
|
}
|
|
999
1023
|
if (
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
cell.columnIndex + -offsetPoint.x,
|
|
1003
|
-
) === -1
|
|
1024
|
+
rowIndex >= lastRowIndex ||
|
|
1025
|
+
!isSelected(rowIndex + 1, columnIndex)
|
|
1004
1026
|
) {
|
|
1005
1027
|
drawArray.push([cell, 'b']);
|
|
1006
1028
|
cell[propPrefix + 'BorderBottom'] = true;
|
|
1007
1029
|
cell[propPrefix + 'Border'] += 'b';
|
|
1008
1030
|
}
|
|
1009
|
-
if (
|
|
1010
|
-
!self.selections[cell.rowIndex + -offsetPoint.y] ||
|
|
1011
|
-
cell.columnIndex === 0 ||
|
|
1012
|
-
self.selections[cell.rowIndex + -offsetPoint.y].indexOf(
|
|
1013
|
-
cell.columnIndex - 1 + -offsetPoint.x,
|
|
1014
|
-
) === -1
|
|
1015
|
-
) {
|
|
1031
|
+
if (columnIndex === 0 || !isSelected(rowIndex, columnIndex - 1)) {
|
|
1016
1032
|
drawArray.push([cell, 'l']);
|
|
1017
1033
|
cell[propPrefix + 'BorderLeft'] = true;
|
|
1018
1034
|
cell[propPrefix + 'Border'] += 'l';
|
|
1019
1035
|
}
|
|
1020
1036
|
if (
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
self.selections[cell.rowIndex + -offsetPoint.y].indexOf(
|
|
1024
|
-
cell.columnIndex + 1 + -offsetPoint.x,
|
|
1025
|
-
) === -1
|
|
1037
|
+
columnIndex >= lastColumnIndex ||
|
|
1038
|
+
!isSelected(rowIndex, columnIndex + 1)
|
|
1026
1039
|
) {
|
|
1027
1040
|
drawArray.push([cell, 'r']);
|
|
1028
1041
|
cell[propPrefix + 'BorderRight'] = true;
|
|
@@ -1031,6 +1044,10 @@ export default function (self) {
|
|
|
1031
1044
|
}
|
|
1032
1045
|
}
|
|
1033
1046
|
function drawCell(rowData, rowOrderIndex, rowIndex) {
|
|
1047
|
+
const isActiveRowHeader =
|
|
1048
|
+
self.orders.rows[self.activeCell.rowIndex] === rowOrderIndex ||
|
|
1049
|
+
self.isRowSelected(rowOrderIndex);
|
|
1050
|
+
|
|
1034
1051
|
return function drawEach(header, headerIndex, columnOrderIndex) {
|
|
1035
1052
|
if (header.hidden) {
|
|
1036
1053
|
return 0;
|
|
@@ -1046,9 +1063,12 @@ export default function (self) {
|
|
|
1046
1063
|
self.filterable.rows.includes(rowIndex) &&
|
|
1047
1064
|
self.filterable.columns.includes(headerIndex),
|
|
1048
1065
|
wrap = self.style.cellWhiteSpace !== 'nowrap',
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
self.selections
|
|
1066
|
+
// TODO: optimize it by `getSelectionStateFromCells`
|
|
1067
|
+
selected = isCellSelected(
|
|
1068
|
+
self.selections,
|
|
1069
|
+
rowOrderIndex,
|
|
1070
|
+
columnOrderIndex,
|
|
1071
|
+
),
|
|
1052
1072
|
hovered =
|
|
1053
1073
|
self.hovers.rowIndex === rowOrderIndex &&
|
|
1054
1074
|
(self.attributes.hoverMode === 'row' ||
|
|
@@ -1062,17 +1082,6 @@ export default function (self) {
|
|
|
1062
1082
|
isColumnHeaderCellCap = cellStyle === 'columnHeaderCellCap',
|
|
1063
1083
|
rawValue = rowData ? rowData[header.name] : undefined,
|
|
1064
1084
|
isGrid = header.type === 'canvas-datagrid',
|
|
1065
|
-
activeHeader =
|
|
1066
|
-
(self.orders.rows[self.activeCell.rowIndex] === rowOrderIndex ||
|
|
1067
|
-
self.selectedRows.indexOf(rowOrderIndex) >= 0 ||
|
|
1068
|
-
self.orders.columns[self.activeCell.columnIndex] ===
|
|
1069
|
-
headerIndex ||
|
|
1070
|
-
self.selectedColumns.indexOf(headerIndex) >= 0) &&
|
|
1071
|
-
(columnOrderIndex === -1 || rowOrderIndex === -1)
|
|
1072
|
-
? isRowHeader
|
|
1073
|
-
? 'activeRowHeaderCell'
|
|
1074
|
-
: 'activeColumnHeaderCell'
|
|
1075
|
-
: false,
|
|
1076
1085
|
val,
|
|
1077
1086
|
f = self.formatters[header.type || 'string'],
|
|
1078
1087
|
orderByArrowSize = 0,
|
|
@@ -1083,6 +1092,19 @@ export default function (self) {
|
|
|
1083
1092
|
row: rowData,
|
|
1084
1093
|
header: header,
|
|
1085
1094
|
};
|
|
1095
|
+
|
|
1096
|
+
const isActiveColumnHeader =
|
|
1097
|
+
self.orders.columns[self.activeCell.columnIndex] === headerIndex ||
|
|
1098
|
+
self.isColumnSelected(self.activeCell.viewColumnIndex);
|
|
1099
|
+
let activeHeader = false;
|
|
1100
|
+
if (
|
|
1101
|
+
(isActiveColumnHeader || isActiveRowHeader) &&
|
|
1102
|
+
(columnOrderIndex === -1 || rowOrderIndex === -1)
|
|
1103
|
+
)
|
|
1104
|
+
activeHeader = isRowHeader
|
|
1105
|
+
? 'activeRowHeaderCell'
|
|
1106
|
+
: 'activeColumnHeaderCell';
|
|
1107
|
+
|
|
1086
1108
|
if (isColumnHeaderCellCap) {
|
|
1087
1109
|
cellWidth = w - x;
|
|
1088
1110
|
}
|
|
@@ -2427,10 +2449,7 @@ export default function (self) {
|
|
|
2427
2449
|
self.ctx.lineWidth = self.style.reorderMarkerBorderWidth;
|
|
2428
2450
|
self.ctx.strokeStyle = self.style.reorderMarkerBorderColor;
|
|
2429
2451
|
if (self.dragMode === 'row-reorder') {
|
|
2430
|
-
|
|
2431
|
-
if (!self.selections[k] || k == self.reorderObject.rowIndex) continue;
|
|
2432
|
-
b.height += self.getRowHeight(k);
|
|
2433
|
-
}
|
|
2452
|
+
b.height = self.getSelectedRowsHeight();
|
|
2434
2453
|
b.width = w;
|
|
2435
2454
|
b.x = 0;
|
|
2436
2455
|
m.width = w;
|
|
@@ -2441,7 +2460,7 @@ export default function (self) {
|
|
|
2441
2460
|
self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;
|
|
2442
2461
|
self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;
|
|
2443
2462
|
if (
|
|
2444
|
-
self.
|
|
2463
|
+
!self.isRowSelected(self.reorderTarget.sortRowIndex) &&
|
|
2445
2464
|
self.currentCell.rowIndex !== self.reorderObject.rowIndex &&
|
|
2446
2465
|
self.currentCell.rowIndex > -1 &&
|
|
2447
2466
|
self.currentCell.rowIndex < l
|
|
@@ -2454,14 +2473,7 @@ export default function (self) {
|
|
|
2454
2473
|
);
|
|
2455
2474
|
}
|
|
2456
2475
|
} else if (self.dragMode === 'column-reorder' && self.reorderObject) {
|
|
2457
|
-
|
|
2458
|
-
if (selectedColumns) {
|
|
2459
|
-
for (var k = 1; k < selectedColumns.length; k++) {
|
|
2460
|
-
b.width += self.getColumnWidth(
|
|
2461
|
-
self.orders.columns[selectedColumns[k]],
|
|
2462
|
-
);
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2476
|
+
b.width = self.getSelectedColumnsWidth();
|
|
2465
2477
|
b.height = h;
|
|
2466
2478
|
b.y = 0;
|
|
2467
2479
|
m.height = h;
|
|
@@ -2473,8 +2485,7 @@ export default function (self) {
|
|
|
2473
2485
|
self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;
|
|
2474
2486
|
self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;
|
|
2475
2487
|
if (
|
|
2476
|
-
self.
|
|
2477
|
-
-1 &&
|
|
2488
|
+
!self.isColumnSelected(self.reorderTarget.sortColumnIndex) &&
|
|
2478
2489
|
self.currentCell.sortColumnIndex !==
|
|
2479
2490
|
self.reorderObject.sortColumnIndex &&
|
|
2480
2491
|
self.reorderTarget.columnIndex !== self.reorderObject.columnIndex &&
|
|
@@ -2490,16 +2501,43 @@ export default function (self) {
|
|
|
2490
2501
|
}
|
|
2491
2502
|
}
|
|
2492
2503
|
}
|
|
2504
|
+
function drawResizeMarkers() {
|
|
2505
|
+
if (
|
|
2506
|
+
!self.attributes.resizeAfterDragged ||
|
|
2507
|
+
!self.draggingItem ||
|
|
2508
|
+
!self.pendingDragResize ||
|
|
2509
|
+
(self.dragMode != 'ew-resize' && self.dragMode != 'ns-resize')
|
|
2510
|
+
) {
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2514
|
+
const resizingRow = self.dragMode == 'ns-resize';
|
|
2515
|
+
const height = resizingRow ? self.style.resizeMarkerSize : self.height;
|
|
2516
|
+
const width = resizingRow ? self.width : self.style.resizeMarkerSize;
|
|
2517
|
+
const minX =
|
|
2518
|
+
self.dragStart.x -
|
|
2519
|
+
(self.resizingStartingWidth - self.style.minColumnWidth);
|
|
2520
|
+
const minY =
|
|
2521
|
+
self.dragStart.y -
|
|
2522
|
+
(self.resizingStartingHeight - self.style.minRowHeight);
|
|
2523
|
+
const x = resizingRow ? 0 : Math.max(self.pendingDragResize.x, minX);
|
|
2524
|
+
const y = !resizingRow ? 0 : Math.max(self.pendingDragResize.y, minY);
|
|
2525
|
+
|
|
2526
|
+
self.ctx.fillStyle = self.style.resizeMarkerColor;
|
|
2527
|
+
fillRect(x, y, width, height);
|
|
2528
|
+
}
|
|
2493
2529
|
function drawBorder() {
|
|
2494
2530
|
self.ctx.lineWidth = self.style.gridBorderWidth;
|
|
2495
2531
|
self.ctx.strokeStyle = self.style.gridBorderColor;
|
|
2496
2532
|
strokeRect(0, 0, self.width, self.height);
|
|
2497
2533
|
}
|
|
2498
2534
|
function drawSelectionBorders() {
|
|
2499
|
-
self.ctx.lineWidth = self.style.selectionOverlayBorderWidth;
|
|
2500
|
-
self.ctx.strokeStyle = self.style.selectionOverlayBorderColor;
|
|
2501
2535
|
function dsb(c) {
|
|
2502
|
-
|
|
2536
|
+
if (!self.fillOverlay.handle) {
|
|
2537
|
+
self.ctx.lineWidth = self.style.selectionOverlayBorderWidth;
|
|
2538
|
+
self.ctx.strokeStyle = self.style.selectionOverlayBorderColor;
|
|
2539
|
+
addBorderLine(c[0], c[1]);
|
|
2540
|
+
}
|
|
2503
2541
|
}
|
|
2504
2542
|
selectionBorders
|
|
2505
2543
|
.filter(function (c) {
|
|
@@ -2542,9 +2580,14 @@ export default function (self) {
|
|
|
2542
2580
|
})
|
|
2543
2581
|
.forEach(dsb);
|
|
2544
2582
|
self.ctx.restore();
|
|
2583
|
+
|
|
2584
|
+
drawFillOverlay();
|
|
2545
2585
|
}
|
|
2546
2586
|
function drawSelectionHandles() {
|
|
2547
|
-
if (
|
|
2587
|
+
if (
|
|
2588
|
+
(self.mobile || self.attributes.allowMovingSelection) &&
|
|
2589
|
+
self.attributes.editable
|
|
2590
|
+
) {
|
|
2548
2591
|
self.ctx.lineWidth = self.style.selectionHandleBorderWidth;
|
|
2549
2592
|
self.ctx.strokeStyle = self.style.selectionHandleBorderColor;
|
|
2550
2593
|
self.ctx.fillStyle = self.style.selectionHandleColor;
|
|
@@ -2565,6 +2608,62 @@ export default function (self) {
|
|
|
2565
2608
|
});
|
|
2566
2609
|
}
|
|
2567
2610
|
}
|
|
2611
|
+
function drawFillOverlay() {
|
|
2612
|
+
if (!self.fillOverlay.handle || !self.fillOverlay.snapTo) {
|
|
2613
|
+
return;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
self.ctx.save();
|
|
2617
|
+
|
|
2618
|
+
const overlay = self.fillOverlay;
|
|
2619
|
+
const handle = overlay.handle;
|
|
2620
|
+
const toX = overlay.snapTo.x;
|
|
2621
|
+
const toY = overlay.snapTo.y;
|
|
2622
|
+
|
|
2623
|
+
// The cell that the cursor is moving over. This may be unavailable
|
|
2624
|
+
// when the cursor is outside the grid or is pointing to something else.
|
|
2625
|
+
//
|
|
2626
|
+
// When unavailable, we use the actual position of the cursor to draw
|
|
2627
|
+
// the overlay.
|
|
2628
|
+
const snap = overlay.snap;
|
|
2629
|
+
|
|
2630
|
+
// Calculate the X, Y coordinates of the cursor with snap positions and
|
|
2631
|
+
// the direction of the movement in mind.
|
|
2632
|
+
//
|
|
2633
|
+
// When the movement is horizontal, we get the Y coordinate from the handle,
|
|
2634
|
+
// and vice-versa.
|
|
2635
|
+
const cursorX =
|
|
2636
|
+
overlay.direction === 'x'
|
|
2637
|
+
? snap
|
|
2638
|
+
? snap.x + (overlay.x < toX ? 0 : snap.width)
|
|
2639
|
+
: overlay.x
|
|
2640
|
+
: handle.x;
|
|
2641
|
+
const cursorY =
|
|
2642
|
+
overlay.direction === undefined || overlay.direction === 'y'
|
|
2643
|
+
? snap
|
|
2644
|
+
? snap.y + (overlay.y < toY ? 0 : snap.height)
|
|
2645
|
+
: overlay.y
|
|
2646
|
+
: handle.y;
|
|
2647
|
+
|
|
2648
|
+
// The final coordinates of the rect. We use 'minX' and 'minY' to avoid
|
|
2649
|
+
// drawing on the frozen area.
|
|
2650
|
+
const x = Math.max(Math.min(toX, cursorX), overlay.minX);
|
|
2651
|
+
const y = Math.max(Math.min(toY, cursorY), overlay.minY);
|
|
2652
|
+
|
|
2653
|
+
// Width and height of the rect are the difference between the
|
|
2654
|
+
// coordinates of both the rect and the cursor. The user may be pointing
|
|
2655
|
+
// behind and/or upwards of the rect, so we need to take that into
|
|
2656
|
+
// account.
|
|
2657
|
+
const width = Math.max(toX, cursorX) - x;
|
|
2658
|
+
const height = Math.max(toY, cursorY) - y;
|
|
2659
|
+
|
|
2660
|
+
self.ctx.strokeStyle = self.style.fillOverlayBorderColor;
|
|
2661
|
+
self.ctx.lineWidth = self.style.fillOverlayBorderWidth;
|
|
2662
|
+
self.ctx.setLineDash([3, 3]);
|
|
2663
|
+
strokeRect(x, y, width, height);
|
|
2664
|
+
self.ctx.setLineDash([]);
|
|
2665
|
+
self.ctx.restore();
|
|
2666
|
+
}
|
|
2568
2667
|
function drawActiveCell() {
|
|
2569
2668
|
if (!aCell) {
|
|
2570
2669
|
return;
|
|
@@ -2981,6 +3080,7 @@ export default function (self) {
|
|
|
2981
3080
|
drawSelectionHandles();
|
|
2982
3081
|
drawReorderMarkers();
|
|
2983
3082
|
drawMoveMarkers();
|
|
3083
|
+
drawResizeMarkers();
|
|
2984
3084
|
drawBorder();
|
|
2985
3085
|
drawSelectionBorders();
|
|
2986
3086
|
drawScrollBars();
|