canvas-datagrid 0.3.19 → 0.3.20
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 +6 -0
- package/dist/canvas-datagrid.debug.js +661 -35
- 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 +9 -0
- package/lib/button.js +325 -0
- package/lib/contextMenu.js +47 -8
- package/lib/defaults.js +27 -0
- package/lib/dom.js +90 -0
- package/lib/draw.js +68 -0
- package/lib/events/index.js +79 -27
- package/lib/intf.js +17 -0
- package/lib/main.js +2 -0
- package/lib/publicMethods.js +37 -0
- package/package.json +1 -1
package/lib/draw.js
CHANGED
|
@@ -164,6 +164,34 @@ export default function (self) {
|
|
|
164
164
|
self.ctx.fill();
|
|
165
165
|
return ml + aw + mr;
|
|
166
166
|
}
|
|
167
|
+
function drawFilterButtonArrow(x, y) {
|
|
168
|
+
var mt =
|
|
169
|
+
((self.style.filterButtonHeight - self.style.filterButtonArrowHeight) /
|
|
170
|
+
2) *
|
|
171
|
+
self.scale,
|
|
172
|
+
ml =
|
|
173
|
+
((self.style.filterButtonWidth - self.style.filterButtonArrowWidth) /
|
|
174
|
+
2) *
|
|
175
|
+
self.scale,
|
|
176
|
+
aw = self.style.filterButtonArrowWidth * self.scale,
|
|
177
|
+
ah = self.style.filterButtonArrowHeight * self.scale;
|
|
178
|
+
x += self.canvasOffsetLeft;
|
|
179
|
+
y += self.canvasOffsetTop;
|
|
180
|
+
self.ctx.fillStyle = self.style.filterButtonArrowColor;
|
|
181
|
+
self.ctx.strokeStyle = self.style.filterButtonArrowBorderColor;
|
|
182
|
+
self.ctx.beginPath();
|
|
183
|
+
x = x + ml;
|
|
184
|
+
y = y + mt;
|
|
185
|
+
|
|
186
|
+
self.ctx.moveTo(x, y);
|
|
187
|
+
self.ctx.lineTo(x + aw, y);
|
|
188
|
+
self.ctx.lineTo(x + aw * 0.5, y + ah);
|
|
189
|
+
self.ctx.moveTo(x, y);
|
|
190
|
+
|
|
191
|
+
self.ctx.stroke();
|
|
192
|
+
self.ctx.fill();
|
|
193
|
+
return ml + aw;
|
|
194
|
+
}
|
|
167
195
|
function radiusRect(x, y, w, h, radius) {
|
|
168
196
|
x += self.canvasOffsetLeft;
|
|
169
197
|
y += self.canvasOffsetTop;
|
|
@@ -816,6 +844,9 @@ export default function (self) {
|
|
|
816
844
|
isCorner = /cornerCell/.test(cellStyle),
|
|
817
845
|
isRowHeader = 'rowHeaderCell' === cellStyle,
|
|
818
846
|
isColumnHeader = 'columnHeaderCell' === cellStyle,
|
|
847
|
+
isFilterable =
|
|
848
|
+
self.filterable.rows.includes(rowIndex) &&
|
|
849
|
+
self.filterable.columns.includes(headerIndex),
|
|
819
850
|
wrap = self.style.cellWhiteSpace !== 'nowrap',
|
|
820
851
|
selected =
|
|
821
852
|
self.selections[rowOrderIndex] &&
|
|
@@ -824,6 +855,9 @@ export default function (self) {
|
|
|
824
855
|
self.hovers.rowIndex === rowOrderIndex &&
|
|
825
856
|
(self.attributes.hoverMode === 'row' ||
|
|
826
857
|
self.hovers.columnIndex === columnOrderIndex),
|
|
858
|
+
openedFilter =
|
|
859
|
+
self.selectedFilterButton.rowIndex == rowIndex &&
|
|
860
|
+
self.selectedFilterButton.columnIndex == headerIndex,
|
|
827
861
|
active =
|
|
828
862
|
self.activeCell.rowIndex === rowOrderIndex &&
|
|
829
863
|
self.activeCell.columnIndex === columnOrderIndex,
|
|
@@ -915,6 +949,8 @@ export default function (self) {
|
|
|
915
949
|
isColumnHeader: isColumnHeader,
|
|
916
950
|
isColumnHeaderCellCap: isColumnHeaderCellCap,
|
|
917
951
|
isRowHeader: isRowHeader,
|
|
952
|
+
isFilterable: isFilterable,
|
|
953
|
+
openedFilter: openedFilter,
|
|
918
954
|
rowOpen: rowOpen,
|
|
919
955
|
header: header,
|
|
920
956
|
|
|
@@ -1114,6 +1150,10 @@ export default function (self) {
|
|
|
1114
1150
|
}
|
|
1115
1151
|
self.ctx.restore();
|
|
1116
1152
|
|
|
1153
|
+
if (isFilterable) {
|
|
1154
|
+
drawFilterButton(cell);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1117
1157
|
// Gaps may occur in row numbers between consecutively rendered rows
|
|
1118
1158
|
// when we are filtering. We draw attention to this by drawing a thick
|
|
1119
1159
|
// border overlapping the two consecutive row headers. If sorting, visible
|
|
@@ -1154,6 +1194,34 @@ export default function (self) {
|
|
|
1154
1194
|
return cell.width;
|
|
1155
1195
|
};
|
|
1156
1196
|
}
|
|
1197
|
+
function drawFilterButton(cell, ev) {
|
|
1198
|
+
var posX = cell.x + cell.width - self.style.filterButtonWidth - 1;
|
|
1199
|
+
var posY = cell.y + cell.height - self.style.filterButtonHeight - 2;
|
|
1200
|
+
if (self.dispatchEvent('beforerenderfilterbutton', ev)) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
self.ctx.save();
|
|
1204
|
+
self.ctx.strokeStyle = self.style.filterButtonBorderColor;
|
|
1205
|
+
self.ctx.fillStyle = self.style.filterButtonBackgroundColor;
|
|
1206
|
+
if (cell.openedFilter) {
|
|
1207
|
+
self.ctx.fillStyle = self.style.filterButtonActiveBackgroundColor;
|
|
1208
|
+
} else if (cell.hovered && self.hovers.onFilterButton) {
|
|
1209
|
+
self.ctx.fillStyle = self.style.filterButtonHoverBackgroundColor;
|
|
1210
|
+
}
|
|
1211
|
+
radiusRect(
|
|
1212
|
+
posX,
|
|
1213
|
+
posY,
|
|
1214
|
+
self.style.filterButtonWidth,
|
|
1215
|
+
self.style.filterButtonHeight,
|
|
1216
|
+
self.style.filterButtonBorderRadius,
|
|
1217
|
+
);
|
|
1218
|
+
self.ctx.stroke();
|
|
1219
|
+
self.ctx.fill();
|
|
1220
|
+
drawFilterButtonArrow(posX, posY);
|
|
1221
|
+
self.ctx.clip();
|
|
1222
|
+
self.dispatchEvent('afterrenderfilterbutton', ev);
|
|
1223
|
+
self.ctx.restore();
|
|
1224
|
+
}
|
|
1157
1225
|
function drawRowHeader(rowData, rowIndex, rowOrderIndex) {
|
|
1158
1226
|
if (self.attributes.showRowHeaders) {
|
|
1159
1227
|
x = 0;
|
package/lib/events/index.js
CHANGED
|
@@ -468,7 +468,18 @@ export default function (self) {
|
|
|
468
468
|
self.hovers = {
|
|
469
469
|
rowIndex: cell.rowIndex,
|
|
470
470
|
columnIndex: cell.columnIndex,
|
|
471
|
+
onFilterButton: false,
|
|
471
472
|
};
|
|
473
|
+
if (
|
|
474
|
+
cell.isFilterable &&
|
|
475
|
+
x > cell.x + cell.width - self.style.filterButtonWidth &&
|
|
476
|
+
x < cell.x + cell.width &&
|
|
477
|
+
y > cell.y + cell.height - self.style.filterButtonHeight &&
|
|
478
|
+
y < cell.y + cell.height
|
|
479
|
+
) {
|
|
480
|
+
self.hovers.onFilterButton = true;
|
|
481
|
+
self.draw();
|
|
482
|
+
}
|
|
472
483
|
}
|
|
473
484
|
if (self.selecting || self.reorderObject) {
|
|
474
485
|
delta = {
|
|
@@ -512,30 +523,57 @@ export default function (self) {
|
|
|
512
523
|
) {
|
|
513
524
|
self.selectRow(cell.rowIndex, ctrl, null, true);
|
|
514
525
|
} else if (self.attributes.selectionMode !== 'row') {
|
|
515
|
-
if (
|
|
516
|
-
if (
|
|
517
|
-
|
|
518
|
-
self.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
526
|
+
if (cell.hovered && self.hovers.onFilterButton) {
|
|
527
|
+
if (cell.openedFilter) {
|
|
528
|
+
cell.openedFilter = false;
|
|
529
|
+
self.selectedFilterButton = {
|
|
530
|
+
columnIndex: -1,
|
|
531
|
+
rowIndex: -1,
|
|
532
|
+
};
|
|
533
|
+
} else {
|
|
534
|
+
self.selectedFilterButton.rowIndex = cell.rowIndex;
|
|
535
|
+
self.selectedFilterButton.columnIndex = cell.columnIndex;
|
|
536
|
+
self.contextmenuEvent(e, {
|
|
537
|
+
x: cell.x + cell.width - self.style.filterButtonWidth,
|
|
538
|
+
y: cell.y + cell.height,
|
|
539
|
+
rect: { left: 0, top: 0 },
|
|
540
|
+
});
|
|
524
541
|
}
|
|
542
|
+
self.draw();
|
|
543
|
+
return;
|
|
525
544
|
} else {
|
|
526
|
-
self.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
545
|
+
self.selectedFilterButton = {
|
|
546
|
+
columnIndex: -1,
|
|
547
|
+
rowIndex: -1,
|
|
548
|
+
};
|
|
549
|
+
if (self.hovers.onFilterButton) return;
|
|
550
|
+
if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
|
|
551
|
+
if (
|
|
552
|
+
self.selections[cell.rowIndex] &&
|
|
553
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex) !==
|
|
554
|
+
-1
|
|
555
|
+
) {
|
|
556
|
+
self.selections[cell.rowIndex].splice(
|
|
557
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex),
|
|
558
|
+
1,
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
} else {
|
|
562
|
+
self.selections[cell.rowIndex] =
|
|
563
|
+
self.selections[cell.rowIndex] || [];
|
|
564
|
+
if (
|
|
565
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex) ===
|
|
566
|
+
-1
|
|
567
|
+
) {
|
|
568
|
+
self.selections[cell.rowIndex].push(cell.columnIndex);
|
|
569
|
+
var event = {
|
|
570
|
+
selections: self.selections,
|
|
571
|
+
selectedData: self.getSelectedData(),
|
|
572
|
+
selectedCells: self.getSelectedCells(),
|
|
573
|
+
selectionBounds: self.getSelectionBounds(),
|
|
574
|
+
};
|
|
575
|
+
self.dispatchEvent('selectionchanged', event);
|
|
576
|
+
}
|
|
539
577
|
}
|
|
540
578
|
}
|
|
541
579
|
}
|
|
@@ -548,13 +586,18 @@ export default function (self) {
|
|
|
548
586
|
dragBounds.right !== self.selectionBounds.right) &&
|
|
549
587
|
!ctrl
|
|
550
588
|
) {
|
|
551
|
-
self.
|
|
589
|
+
if (!(cell.hovered && self.hovers.onFilterButton)) {
|
|
590
|
+
self.selections = [];
|
|
591
|
+
}
|
|
592
|
+
if (dragBounds.top === -1) {
|
|
593
|
+
dragBounds.top = 0;
|
|
594
|
+
}
|
|
552
595
|
sBounds = dragBounds;
|
|
553
596
|
if (self.attributes.selectionMode === 'row') {
|
|
554
597
|
for (i = sBounds.top; i <= sBounds.bottom; i += 1) {
|
|
555
598
|
self.selectRow(i, true, null, true);
|
|
556
599
|
}
|
|
557
|
-
} else
|
|
600
|
+
} else {
|
|
558
601
|
self.selectArea(sBounds, true);
|
|
559
602
|
if (sBounds.left == -1 && sBounds.top !== sBounds.bottom)
|
|
560
603
|
self.isMultiRowsSelected = true;
|
|
@@ -632,7 +675,9 @@ export default function (self) {
|
|
|
632
675
|
-1 &&
|
|
633
676
|
!ctrl
|
|
634
677
|
) {
|
|
635
|
-
self.
|
|
678
|
+
if (!self.hovers.onFilterButton) {
|
|
679
|
+
self.setActiveCell(i.columnIndex, i.rowIndex);
|
|
680
|
+
}
|
|
636
681
|
}
|
|
637
682
|
if (self.currentCell.context === 'cell') {
|
|
638
683
|
if (self.currentCell.style === 'cornerCell') {
|
|
@@ -1173,8 +1218,12 @@ export default function (self) {
|
|
|
1173
1218
|
!freeze &&
|
|
1174
1219
|
!resize
|
|
1175
1220
|
) {
|
|
1176
|
-
if (
|
|
1221
|
+
if (
|
|
1222
|
+
!(self.dragMode == 'row-reorder' && self.isMultiRowsSelected) &&
|
|
1223
|
+
!(self.currentCell.hovered && self.hovers.onFilterButton)
|
|
1224
|
+
) {
|
|
1177
1225
|
self.selections = [];
|
|
1226
|
+
}
|
|
1178
1227
|
}
|
|
1179
1228
|
if (self.dragStartObject.isGrid) {
|
|
1180
1229
|
return;
|
|
@@ -1556,7 +1605,10 @@ export default function (self) {
|
|
|
1556
1605
|
self.currentCell.style === 'cornerCell'
|
|
1557
1606
|
) {
|
|
1558
1607
|
self.autosize();
|
|
1559
|
-
} else if (
|
|
1608
|
+
} else if (
|
|
1609
|
+
['cell', 'activeCell'].includes(self.currentCell.style) &&
|
|
1610
|
+
!self.hovers.onFilterButton
|
|
1611
|
+
) {
|
|
1560
1612
|
self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
|
|
1561
1613
|
}
|
|
1562
1614
|
};
|
package/lib/intf.js
CHANGED
|
@@ -61,6 +61,14 @@ export default function (self, ctor) {
|
|
|
61
61
|
trees: {},
|
|
62
62
|
};
|
|
63
63
|
self.selections = [];
|
|
64
|
+
self.filterable = {
|
|
65
|
+
rows: [],
|
|
66
|
+
columns: [],
|
|
67
|
+
};
|
|
68
|
+
self.selectedFilterButton = {
|
|
69
|
+
columnIndex: -1,
|
|
70
|
+
rowIndex: -1,
|
|
71
|
+
};
|
|
64
72
|
self.hovers = {};
|
|
65
73
|
self.attributes = {};
|
|
66
74
|
self.style = {};
|
|
@@ -88,6 +96,7 @@ export default function (self, ctor) {
|
|
|
88
96
|
self.eventNames = [
|
|
89
97
|
'afterdraw',
|
|
90
98
|
'afterrendercell',
|
|
99
|
+
'afterrenderfilterbutton',
|
|
91
100
|
'attributechanged',
|
|
92
101
|
'beforebeginedit',
|
|
93
102
|
'beforecreatecellgrid',
|
|
@@ -95,6 +104,7 @@ export default function (self, ctor) {
|
|
|
95
104
|
'beforeendedit',
|
|
96
105
|
'beforerendercell',
|
|
97
106
|
'beforerendercellgrid',
|
|
107
|
+
'beforerenderfilterbutton',
|
|
98
108
|
'beginedit',
|
|
99
109
|
'cellmouseout',
|
|
100
110
|
'cellmouseover',
|
|
@@ -755,6 +765,7 @@ export default function (self, ctor) {
|
|
|
755
765
|
self.intf.clearChangeLog = self.clearChangeLog;
|
|
756
766
|
self.intf.gotoCell = self.gotoCell;
|
|
757
767
|
self.intf.gotoRow = self.gotoRow;
|
|
768
|
+
self.intf.addButton = self.addButton;
|
|
758
769
|
self.intf.getHeaderByName = self.getHeaderByName;
|
|
759
770
|
self.intf.findColumnScrollLeft = self.findColumnScrollLeft;
|
|
760
771
|
self.intf.findRowScrollTop = self.findRowScrollTop;
|
|
@@ -1534,6 +1545,9 @@ export default function (self, ctor) {
|
|
|
1534
1545
|
if (!preventScrollEvent) {
|
|
1535
1546
|
self.scroll();
|
|
1536
1547
|
}
|
|
1548
|
+
if (self.button) {
|
|
1549
|
+
self.moveButtonPos();
|
|
1550
|
+
}
|
|
1537
1551
|
}
|
|
1538
1552
|
function setScrollLeft(value, preventScrollEvent) {
|
|
1539
1553
|
if (isNaN(value)) {
|
|
@@ -1552,6 +1566,9 @@ export default function (self, ctor) {
|
|
|
1552
1566
|
if (!preventScrollEvent) {
|
|
1553
1567
|
self.scroll();
|
|
1554
1568
|
}
|
|
1569
|
+
if (self.button) {
|
|
1570
|
+
self.moveButtonPos();
|
|
1571
|
+
}
|
|
1555
1572
|
}
|
|
1556
1573
|
self.scrollBox.toString = function () {
|
|
1557
1574
|
return (
|
package/lib/main.js
CHANGED
|
@@ -9,6 +9,7 @@ import events from './events';
|
|
|
9
9
|
import touch from './touch';
|
|
10
10
|
import intf from './intf';
|
|
11
11
|
import contextMenu from './contextMenu';
|
|
12
|
+
import button from './button';
|
|
12
13
|
import dom from './dom';
|
|
13
14
|
import publicMethods from './publicMethods';
|
|
14
15
|
|
|
@@ -21,6 +22,7 @@ var modules = [
|
|
|
21
22
|
touch,
|
|
22
23
|
intf,
|
|
23
24
|
contextMenu,
|
|
25
|
+
button,
|
|
24
26
|
dom,
|
|
25
27
|
publicMethods,
|
|
26
28
|
];
|
package/lib/publicMethods.js
CHANGED
|
@@ -206,6 +206,18 @@ export default function (self) {
|
|
|
206
206
|
delete self.columnFilters[column];
|
|
207
207
|
} else {
|
|
208
208
|
self.columnFilters[column] = value;
|
|
209
|
+
if (self.attributes.showFilterInCell) {
|
|
210
|
+
self.filterable.rows.push(0);
|
|
211
|
+
self.orders.columns.forEach(function (value, index) {
|
|
212
|
+
self.filterable.columns.push(index);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (!Object.keys(self.columnFilters).length) {
|
|
217
|
+
self.filterable = {
|
|
218
|
+
rows: [],
|
|
219
|
+
columns: [],
|
|
220
|
+
};
|
|
209
221
|
}
|
|
210
222
|
self.refresh();
|
|
211
223
|
};
|
|
@@ -294,6 +306,31 @@ export default function (self) {
|
|
|
294
306
|
self.gotoRow = function (y) {
|
|
295
307
|
self.gotoCell(0, y);
|
|
296
308
|
};
|
|
309
|
+
/**
|
|
310
|
+
* Add a button into the cell.
|
|
311
|
+
* @memberof canvasDatagrid
|
|
312
|
+
* @name addButton
|
|
313
|
+
* @method
|
|
314
|
+
* @param {number} columnIndex The column index of the cell to to add a button.
|
|
315
|
+
* @param {number} rowIndex The row index of the cell to to add a button.
|
|
316
|
+
* @param {object} offset Offset how far go away from cell.
|
|
317
|
+
* @param {object} items a list of items to add into button menu.
|
|
318
|
+
* @param {string} imgSrc icon path to add into button.
|
|
319
|
+
*/
|
|
320
|
+
self.addButton = function (columnIndex, rowIndex, offset, items, imgSrc) {
|
|
321
|
+
var cells = self.visibleCells.filter(function (c) {
|
|
322
|
+
return c.sortColumnIndex === columnIndex && c.sortRowIndex === rowIndex;
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
self.attachButton(
|
|
326
|
+
{
|
|
327
|
+
top: cells[0].y + cells[0].height + offset.y,
|
|
328
|
+
left: cells[0].x + cells[0].width + offset.x,
|
|
329
|
+
},
|
|
330
|
+
items,
|
|
331
|
+
imgSrc,
|
|
332
|
+
);
|
|
333
|
+
};
|
|
297
334
|
/**
|
|
298
335
|
* Scrolls the cell at cell x, row y into view if it is not already.
|
|
299
336
|
* @memberof canvasDatagrid
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvas-datagrid",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.20",
|
|
4
4
|
"description": "Canvas based data grid web component. Capable of displaying millions of contiguous hierarchical rows and columns without paging or loading, on a single canvas element.",
|
|
5
5
|
"main": "./dist/canvas-datagrid.js",
|
|
6
6
|
"module": "./dist/canvas-datagrid.module.js",
|