canvas-datagrid 0.3.24 → 0.4.2
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 +35 -0
- package/dist/canvas-datagrid.debug.js +2283 -120
- 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 +116 -0
- package/lib/contextMenu.js +289 -1
- package/lib/defaults.js +36 -0
- package/lib/docs.js +18 -0
- package/lib/dom.js +27 -5
- package/lib/draw.js +627 -30
- package/lib/events/index.js +175 -24
- package/lib/events/util.js +3 -2
- package/lib/intf.js +573 -1
- package/lib/publicMethods.js +394 -14
- package/package.json +1 -1
package/lib/events/index.js
CHANGED
|
@@ -130,6 +130,8 @@ export default function (self) {
|
|
|
130
130
|
l = (self.viewData || []).length,
|
|
131
131
|
columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
|
|
132
132
|
rowHeaderCellWidth = self.getRowHeaderCellWidth(),
|
|
133
|
+
topGroupAreaHeight = self.getColumnGroupAreaHeight(),
|
|
134
|
+
leftGroupAreaWidth = self.getRowGroupAreaWidth(),
|
|
133
135
|
ch = self.style.cellHeight,
|
|
134
136
|
s = self.getSchema();
|
|
135
137
|
// sets actual DOM canvas element
|
|
@@ -148,8 +150,10 @@ export default function (self) {
|
|
|
148
150
|
self.scrollBox.verticalBoxVisible = dataHeight > self.scrollBox.height;
|
|
149
151
|
}
|
|
150
152
|
function setScrollBoxSize() {
|
|
151
|
-
self.scrollBox.width =
|
|
152
|
-
|
|
153
|
+
self.scrollBox.width =
|
|
154
|
+
self.width - rowHeaderCellWidth - leftGroupAreaWidth;
|
|
155
|
+
self.scrollBox.height =
|
|
156
|
+
self.height - columnHeaderCellHeight - topGroupAreaHeight;
|
|
153
157
|
}
|
|
154
158
|
function setCanvasSize() {
|
|
155
159
|
if (self.isChildGrid) {
|
|
@@ -157,8 +161,13 @@ export default function (self) {
|
|
|
157
161
|
}
|
|
158
162
|
dims = {
|
|
159
163
|
// HACK +1 ? maybe it's a magic cell border? Required to line up properly in auto height mode.
|
|
160
|
-
height:
|
|
161
|
-
|
|
164
|
+
height:
|
|
165
|
+
columnHeaderCellHeight +
|
|
166
|
+
topGroupAreaHeight +
|
|
167
|
+
dataHeight +
|
|
168
|
+
cellBorder +
|
|
169
|
+
1,
|
|
170
|
+
width: dataWidth + rowHeaderCellWidth + cellBorder + leftGroupAreaWidth,
|
|
162
171
|
};
|
|
163
172
|
['width', 'height'].forEach(function (dim) {
|
|
164
173
|
//TODO: support inherit
|
|
@@ -190,18 +199,31 @@ export default function (self) {
|
|
|
190
199
|
if (l > 1) {
|
|
191
200
|
self.scrollCache.y[x] = dataHeight;
|
|
192
201
|
}
|
|
202
|
+
const collapsedColumnGroups = self.getCollapsedColumnGroups();
|
|
203
|
+
const isColumnCollapsed = (columnIndex) =>
|
|
204
|
+
collapsedColumnGroups.findIndex(
|
|
205
|
+
(group) => columnIndex >= group.from && columnIndex <= group.to,
|
|
206
|
+
) >= 0;
|
|
207
|
+
/** @type {number} it will be used in `reduceSchema` only */
|
|
208
|
+
let frozenWidth = 0;
|
|
193
209
|
dataWidth =
|
|
194
210
|
s.reduce(function reduceSchema(accumulator, column, columnIndex) {
|
|
195
211
|
// intentional redefintion of column. This causes scrollCache to be in the correct order
|
|
196
|
-
|
|
197
|
-
|
|
212
|
+
const schemaIndex = self.orders.columns[columnIndex];
|
|
213
|
+
const columnWidth = self.getColumnWidth(schemaIndex);
|
|
214
|
+
column = s[schemaIndex];
|
|
215
|
+
if (!column.hidden && !isColumnCollapsed(columnIndex))
|
|
216
|
+
accumulator += columnWidth;
|
|
217
|
+
if (columnIndex < self.frozenColumn) {
|
|
198
218
|
self.scrollCache.x[columnIndex] = accumulator;
|
|
199
|
-
|
|
219
|
+
frozenWidth = accumulator;
|
|
220
|
+
} else {
|
|
221
|
+
self.scrollCache.x[columnIndex] = Math.max(
|
|
222
|
+
frozenWidth + columnWidth,
|
|
223
|
+
accumulator,
|
|
224
|
+
);
|
|
200
225
|
}
|
|
201
|
-
|
|
202
|
-
accumulator + self.getColumnWidth(self.orders.columns[columnIndex]);
|
|
203
|
-
self.scrollCache.x[columnIndex] = va;
|
|
204
|
-
return va;
|
|
226
|
+
return accumulator;
|
|
205
227
|
}, 0) || 0;
|
|
206
228
|
if (self.attributes.showNewRow) {
|
|
207
229
|
dataHeight += ch;
|
|
@@ -224,8 +246,9 @@ export default function (self) {
|
|
|
224
246
|
}
|
|
225
247
|
/// calculate scroll bar dimensions
|
|
226
248
|
// non-controversial
|
|
227
|
-
self.scrollBox.top =
|
|
228
|
-
|
|
249
|
+
self.scrollBox.top =
|
|
250
|
+
columnHeaderCellHeight + topGroupAreaHeight + columnHeaderCellBorder;
|
|
251
|
+
self.scrollBox.left = rowHeaderCellWidth + leftGroupAreaWidth;
|
|
229
252
|
// width and height of scroll box
|
|
230
253
|
setScrollBoxSize();
|
|
231
254
|
// is the data larger than the scroll box
|
|
@@ -274,6 +297,7 @@ export default function (self) {
|
|
|
274
297
|
self.scrollBox.heightBoxRatio =
|
|
275
298
|
(self.scrollBox.height -
|
|
276
299
|
columnHeaderCellHeight -
|
|
300
|
+
topGroupAreaHeight -
|
|
277
301
|
self.scrollCache.y[self.frozenRow]) /
|
|
278
302
|
dataHeight;
|
|
279
303
|
self.scrollBox.scrollBoxHeight =
|
|
@@ -291,9 +315,14 @@ export default function (self) {
|
|
|
291
315
|
);
|
|
292
316
|
// horizontal
|
|
293
317
|
n.x += rowHeaderCellWidth;
|
|
294
|
-
n.y += self.height - self.style.scrollBarWidth - d;
|
|
318
|
+
n.y += self.height - self.style.scrollBarWidth - d - topGroupAreaHeight;
|
|
295
319
|
n.width =
|
|
296
|
-
self.width -
|
|
320
|
+
self.width -
|
|
321
|
+
self.style.scrollBarWidth -
|
|
322
|
+
rowHeaderCellWidth -
|
|
323
|
+
leftGroupAreaWidth -
|
|
324
|
+
d -
|
|
325
|
+
m;
|
|
297
326
|
n.height = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
|
|
298
327
|
// horizontal box
|
|
299
328
|
nb.y = n.y + self.style.scrollBarBoxMargin;
|
|
@@ -302,13 +331,19 @@ export default function (self) {
|
|
|
302
331
|
// vertical
|
|
303
332
|
v.x +=
|
|
304
333
|
self.width -
|
|
334
|
+
leftGroupAreaWidth -
|
|
305
335
|
self.style.scrollBarWidth -
|
|
306
336
|
self.style.scrollBarBorderWidth -
|
|
307
337
|
d;
|
|
308
338
|
v.y += columnHeaderCellHeight + self.scrollCache.y[self.frozenRow];
|
|
309
339
|
v.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
|
|
310
340
|
v.height =
|
|
311
|
-
self.height -
|
|
341
|
+
self.height -
|
|
342
|
+
columnHeaderCellHeight -
|
|
343
|
+
topGroupAreaHeight -
|
|
344
|
+
self.style.scrollBarWidth -
|
|
345
|
+
d -
|
|
346
|
+
m;
|
|
312
347
|
// vertical box
|
|
313
348
|
vb.x = v.x + self.style.scrollBarBoxMargin;
|
|
314
349
|
vb.y += self.scrollCache.y[self.frozenRow];
|
|
@@ -420,6 +455,14 @@ export default function (self) {
|
|
|
420
455
|
if (self.contextMenu || self.input) {
|
|
421
456
|
return;
|
|
422
457
|
}
|
|
458
|
+
|
|
459
|
+
// Cancel dragging action if user ventures outside grid
|
|
460
|
+
if (self.draggingItem && e.which === 0) {
|
|
461
|
+
self.stopFreezeMove(e);
|
|
462
|
+
self.mouseup(e);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
423
466
|
self.mouse = overridePos || self.getLayerPos(e);
|
|
424
467
|
var ctrl =
|
|
425
468
|
(e.ctrlKey || e.metaKey || self.attributes.persistantSelectionMode) &&
|
|
@@ -469,6 +512,7 @@ export default function (self) {
|
|
|
469
512
|
rowIndex: cell.rowIndex,
|
|
470
513
|
columnIndex: cell.columnIndex,
|
|
471
514
|
onFilterButton: false,
|
|
515
|
+
onCellTreeIcon: false,
|
|
472
516
|
};
|
|
473
517
|
if (
|
|
474
518
|
cell.isFilterable &&
|
|
@@ -488,6 +532,26 @@ export default function (self) {
|
|
|
488
532
|
self.hovers.onFilterButton = true;
|
|
489
533
|
self.draw();
|
|
490
534
|
}
|
|
535
|
+
if (cell.isRowTree || cell.isColumnTree) {
|
|
536
|
+
const pc = cell.isRowTree
|
|
537
|
+
? self.cellTree.rows[cell.rowIndex].parentCount
|
|
538
|
+
: 0;
|
|
539
|
+
const rc = self.style.cellTreeIconWidth * self.scale,
|
|
540
|
+
rx =
|
|
541
|
+
cell.x +
|
|
542
|
+
cell.paddingLeft +
|
|
543
|
+
self.canvasOffsetLeft +
|
|
544
|
+
self.style.cellTreeIconMarginLeft +
|
|
545
|
+
pc * (rc + cell.paddingLeft),
|
|
546
|
+
ry =
|
|
547
|
+
cell.y +
|
|
548
|
+
self.canvasOffsetTop +
|
|
549
|
+
self.style.cellTreeIconMarginTop * self.scale;
|
|
550
|
+
if (x >= rx && x <= rx + rc && y >= ry && y < ry + rc) {
|
|
551
|
+
self.hovers.onCellTreeIcon = true;
|
|
552
|
+
self.draw();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
491
555
|
}
|
|
492
556
|
if (self.selecting || self.reorderObject) {
|
|
493
557
|
delta = {
|
|
@@ -512,7 +576,24 @@ export default function (self) {
|
|
|
512
576
|
dragBounds.right = s.length - 1;
|
|
513
577
|
dragBounds.top = Math.min(sBounds.top, cell.rowIndex);
|
|
514
578
|
dragBounds.bottom = Math.max(sBounds.bottom, cell.rowIndex);
|
|
579
|
+
if (dragBounds.top < 0) dragBounds.top = 0;
|
|
515
580
|
}
|
|
581
|
+
|
|
582
|
+
if (self.dragStartObject.rowIndex === -1) {
|
|
583
|
+
sBounds = self.getSelectionBounds();
|
|
584
|
+
dragBounds.left =
|
|
585
|
+
cell.columnIndex === undefined
|
|
586
|
+
? sBounds.left
|
|
587
|
+
: Math.min(sBounds.left, cell.columnIndex);
|
|
588
|
+
dragBounds.right =
|
|
589
|
+
cell.columnIndex === undefined
|
|
590
|
+
? sBounds.right
|
|
591
|
+
: Math.max(sBounds.right, cell.columnIndex);
|
|
592
|
+
dragBounds.top = -1;
|
|
593
|
+
dragBounds.bottom = self.viewData.length - 1;
|
|
594
|
+
if (dragBounds.left < 0) dragBounds.left = 0;
|
|
595
|
+
}
|
|
596
|
+
|
|
516
597
|
if (
|
|
517
598
|
self.dragStartObject.rowIndex !== cell.rowIndex ||
|
|
518
599
|
self.dragStartObject.columnIndex !== cell.columnIndex
|
|
@@ -525,11 +606,31 @@ export default function (self) {
|
|
|
525
606
|
self.attributes.selectionMode === 'row'
|
|
526
607
|
) {
|
|
527
608
|
if (
|
|
609
|
+
cell.rowIndex !== undefined &&
|
|
528
610
|
(self.attributes.selectionMode === 'row' ||
|
|
529
611
|
self.dragStartObject.columnIndex === -1) &&
|
|
530
612
|
self.rowBoundaryCrossed
|
|
531
613
|
) {
|
|
532
|
-
self.
|
|
614
|
+
if (self.dragStartObject.rowIndex < cell.rowIndex) {
|
|
615
|
+
dragBounds.top = self.dragStartObject.rowIndex;
|
|
616
|
+
dragBounds.bottom = cell.rowIndex;
|
|
617
|
+
} else {
|
|
618
|
+
dragBounds.top = cell.rowIndex;
|
|
619
|
+
dragBounds.bottom = self.dragStartObject.rowIndex;
|
|
620
|
+
}
|
|
621
|
+
} else if (
|
|
622
|
+
cell.rowIndex !== undefined &&
|
|
623
|
+
(self.attributes.selectionMode === 'column' ||
|
|
624
|
+
self.dragStartObject.rowIndex === -1) &&
|
|
625
|
+
self.columnBoundaryCrossed
|
|
626
|
+
) {
|
|
627
|
+
if (self.dragStartObject.columnIndex < cell.columnIndex) {
|
|
628
|
+
dragBounds.left = self.dragStartObject.columnIndex;
|
|
629
|
+
dragBounds.right = cell.columnIndex;
|
|
630
|
+
} else {
|
|
631
|
+
dragBounds.left = cell.columnIndex;
|
|
632
|
+
dragBounds.right = self.dragStartObject.columnIndex;
|
|
633
|
+
}
|
|
533
634
|
} else if (self.attributes.selectionMode !== 'row') {
|
|
534
635
|
if (cell.hovered && self.hovers.onFilterButton) {
|
|
535
636
|
if (cell.openedFilter) {
|
|
@@ -549,12 +650,20 @@ export default function (self) {
|
|
|
549
650
|
}
|
|
550
651
|
self.draw();
|
|
551
652
|
return;
|
|
653
|
+
} else if (
|
|
654
|
+
cell.hovered &&
|
|
655
|
+
self.hovers.onCellTreeIcon &&
|
|
656
|
+
e.type == 'mousedown'
|
|
657
|
+
) {
|
|
658
|
+
self.toggleCollapseTree(cell.rowIndex, cell.columnIndex);
|
|
659
|
+
return;
|
|
552
660
|
} else {
|
|
553
661
|
self.selectedFilterButton = {
|
|
554
662
|
columnIndex: -1,
|
|
555
663
|
rowIndex: -1,
|
|
556
664
|
};
|
|
557
665
|
if (self.hovers.onFilterButton) return;
|
|
666
|
+
if (self.hovers.onCellTreeIcon) return;
|
|
558
667
|
if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
|
|
559
668
|
if (
|
|
560
669
|
self.selections[cell.rowIndex] &&
|
|
@@ -627,6 +736,12 @@ export default function (self) {
|
|
|
627
736
|
}
|
|
628
737
|
}
|
|
629
738
|
}
|
|
739
|
+
const columnGroup = self.getColumnGroupAt(self.mouse.x, self.mouse.y);
|
|
740
|
+
if (columnGroup) self.cursor = 'pointer';
|
|
741
|
+
|
|
742
|
+
const rowGroup = self.getRowGroupAt(self.mouse.x, self.mouse.y);
|
|
743
|
+
if (rowGroup) self.cursor = 'pointer';
|
|
744
|
+
|
|
630
745
|
self.cellBoundaryCrossed = false;
|
|
631
746
|
self.rowBoundaryCrossed = false;
|
|
632
747
|
self.columnBoundaryCrossed = false;
|
|
@@ -675,9 +790,25 @@ export default function (self) {
|
|
|
675
790
|
) {
|
|
676
791
|
return;
|
|
677
792
|
}
|
|
793
|
+
|
|
794
|
+
let group = self.getColumnGroupAt(pos.x, pos.y);
|
|
795
|
+
if (!group) group = self.getRowGroupAt(pos.x, pos.y);
|
|
796
|
+
if (group) {
|
|
797
|
+
if (self.toggleGroup(group)) {
|
|
798
|
+
self.setStorageData();
|
|
799
|
+
self.refresh();
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
678
804
|
if (!self.hasFocus) {
|
|
679
805
|
return;
|
|
680
806
|
}
|
|
807
|
+
|
|
808
|
+
const leftOffset = self.getRowGroupAreaWidth();
|
|
809
|
+
const topOffset = self.getColumnGroupAreaHeight();
|
|
810
|
+
const xInGrid = pos.x - leftOffset;
|
|
811
|
+
const yInGrid = pos.y - topOffset;
|
|
681
812
|
if (
|
|
682
813
|
['rowHeaderCell', 'columnHeaderCell'].indexOf(self.currentCell.style) ===
|
|
683
814
|
-1 &&
|
|
@@ -715,17 +846,17 @@ export default function (self) {
|
|
|
715
846
|
if (
|
|
716
847
|
self.currentCell.style === 'rowHeaderCell' &&
|
|
717
848
|
self.attributes.tree &&
|
|
718
|
-
|
|
719
|
-
|
|
849
|
+
xInGrid > 0 &&
|
|
850
|
+
xInGrid - self.currentCell.x <
|
|
720
851
|
self.style.treeArrowWidth +
|
|
721
852
|
self.style.treeArrowMarginLeft +
|
|
722
853
|
self.style.treeArrowMarginRight +
|
|
723
854
|
self.style.treeArrowClickRadius &&
|
|
724
|
-
|
|
855
|
+
yInGrid - self.currentCell.y <
|
|
725
856
|
self.style.treeArrowHeight +
|
|
726
857
|
self.style.treeArrowMarginTop +
|
|
727
858
|
self.style.treeArrowClickRadius &&
|
|
728
|
-
|
|
859
|
+
yInGrid > 0
|
|
729
860
|
) {
|
|
730
861
|
self.toggleTree(i.rowIndex);
|
|
731
862
|
return;
|
|
@@ -765,7 +896,6 @@ export default function (self) {
|
|
|
765
896
|
self.dragMode === 'ew-resize'
|
|
766
897
|
) {
|
|
767
898
|
self.resize(true);
|
|
768
|
-
self.scrollBox.scrollLeft += x;
|
|
769
899
|
}
|
|
770
900
|
if (self.dragMode === 'ew-resize') {
|
|
771
901
|
self.sizes.columns[
|
|
@@ -975,6 +1105,7 @@ export default function (self) {
|
|
|
975
1105
|
-1,
|
|
976
1106
|
self.activeCell.rowIndex,
|
|
977
1107
|
);
|
|
1108
|
+
if (!self.reorderObject) return;
|
|
978
1109
|
self.reorderTarget = self.currentCell;
|
|
979
1110
|
self.reorderObject.dragOffset = {
|
|
980
1111
|
x: x,
|
|
@@ -1126,6 +1257,8 @@ export default function (self) {
|
|
|
1126
1257
|
|
|
1127
1258
|
self.ignoreNextClick = true;
|
|
1128
1259
|
self.freezeMarkerPosition = pos;
|
|
1260
|
+
pos.x -= self.getRowGroupAreaWidth();
|
|
1261
|
+
pos.y -= self.getColumnGroupAreaHeight();
|
|
1129
1262
|
if (
|
|
1130
1263
|
self.currentCell &&
|
|
1131
1264
|
self.currentCell.rowIndex !== undefined &&
|
|
@@ -1284,6 +1417,12 @@ export default function (self) {
|
|
|
1284
1417
|
self.dragStartObject.rowIndex > -1
|
|
1285
1418
|
) {
|
|
1286
1419
|
self.selectRow(self.dragStartObject.rowIndex, ctrl, null);
|
|
1420
|
+
} else if (
|
|
1421
|
+
(self.attributes.selectionMode === 'column' ||
|
|
1422
|
+
self.dragStartObject.rowIndex === -1) &&
|
|
1423
|
+
self.dragStartObject.columnIndex > -1
|
|
1424
|
+
) {
|
|
1425
|
+
self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
|
|
1287
1426
|
} else if (self.attributes.selectionMode !== 'row') {
|
|
1288
1427
|
self.mousemove(e);
|
|
1289
1428
|
}
|
|
@@ -1646,9 +1785,21 @@ export default function (self) {
|
|
|
1646
1785
|
self.autosize();
|
|
1647
1786
|
} else if (
|
|
1648
1787
|
['cell', 'activeCell'].includes(self.currentCell.style) &&
|
|
1649
|
-
!self.hovers.onFilterButton
|
|
1788
|
+
!self.hovers.onFilterButton &&
|
|
1789
|
+
!self.hovers.onCellTreeIcon
|
|
1650
1790
|
) {
|
|
1651
|
-
|
|
1791
|
+
if (self.currentCell.isRowTree || self.currentCell.isColumnTree) {
|
|
1792
|
+
self.cellTreeExpandCollapse(
|
|
1793
|
+
self.currentCell.rowIndex,
|
|
1794
|
+
self.currentCell.columnIndex,
|
|
1795
|
+
);
|
|
1796
|
+
self.draw();
|
|
1797
|
+
} else {
|
|
1798
|
+
self.beginEditAt(
|
|
1799
|
+
self.currentCell.columnIndex,
|
|
1800
|
+
self.currentCell.rowIndex,
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1652
1803
|
}
|
|
1653
1804
|
};
|
|
1654
1805
|
self.scrollWheel = function (e) {
|
package/lib/events/util.js
CHANGED
|
@@ -87,7 +87,8 @@ const parseData = function (data, mimeType) {
|
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
const htmlSafe = function (value) {
|
|
90
|
-
if (typeof value
|
|
90
|
+
if (typeof value !== 'string') return value;
|
|
91
|
+
|
|
91
92
|
return value.replace(/</g, '<').replace(/>/g, '>');
|
|
92
93
|
};
|
|
93
94
|
|
|
@@ -111,7 +112,7 @@ const createHTMLString = function (selectedData, isNeat) {
|
|
|
111
112
|
(row) =>
|
|
112
113
|
'<tr>' +
|
|
113
114
|
Object.values(row)
|
|
114
|
-
.map((value) => '<td>'
|
|
115
|
+
.map((value) => ['<td>', htmlSafe(value), '</td>'].join(''))
|
|
115
116
|
.join('') +
|
|
116
117
|
'</tr>',
|
|
117
118
|
)
|