canvas-datagrid 0.4.2 → 0.4.5
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 +29 -0
- package/dist/canvas-datagrid.debug.js +1567 -326
- 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 +59 -6
- package/lib/contextMenu.js +178 -49
- package/lib/defaults.js +21 -7
- package/lib/docs.js +48 -1
- package/lib/dom.js +29 -2
- package/lib/draw.js +497 -84
- package/lib/events/index.js +650 -161
- package/lib/groups/util.js +42 -0
- package/lib/intf.js +43 -3
- package/lib/main.js +1 -0
- package/lib/publicMethods.js +199 -41
- package/package.json +2 -2
package/lib/draw.js
CHANGED
|
@@ -110,8 +110,9 @@ export default function (self) {
|
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* @param {number[]} coords [x0,y0, x1,y1, x2,y2, ...]
|
|
113
|
+
* @param {boolean} [fill] fill the area that construct by these lines but not stroke
|
|
113
114
|
*/
|
|
114
|
-
function
|
|
115
|
+
function drawLines(coords, fill) {
|
|
115
116
|
if (coords.length < 4) return;
|
|
116
117
|
self.ctx.beginPath();
|
|
117
118
|
self.ctx.moveTo(
|
|
@@ -123,7 +124,8 @@ export default function (self) {
|
|
|
123
124
|
const y = coords[i + 1] + self.canvasOffsetTop;
|
|
124
125
|
self.ctx.lineTo(x, y);
|
|
125
126
|
}
|
|
126
|
-
self.ctx.
|
|
127
|
+
if (fill) self.ctx.fill();
|
|
128
|
+
else self.ctx.stroke();
|
|
127
129
|
}
|
|
128
130
|
/**
|
|
129
131
|
* @param {number} x based-X (left-top)
|
|
@@ -136,8 +138,67 @@ export default function (self) {
|
|
|
136
138
|
strokeRect(x, y, width, width);
|
|
137
139
|
const cx = x + width * 0.5;
|
|
138
140
|
const cy = y + width * 0.5;
|
|
139
|
-
|
|
140
|
-
if (collapsed)
|
|
141
|
+
drawLines([x + width * 0.2, cy, x + width * 0.78, cy]);
|
|
142
|
+
if (collapsed) drawLines([cx, y + width * 0.22, cx, y + width * 0.8]);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* @param {number} x
|
|
146
|
+
* @param {number} y
|
|
147
|
+
* @param {number} size
|
|
148
|
+
* @param {string} dir Direction of the triangle, one of the 't','b','l' and 'r'
|
|
149
|
+
* @param {boolean} [active]
|
|
150
|
+
*/
|
|
151
|
+
function drawUnhideIndicator(x, y, size, dir, active) {
|
|
152
|
+
const minPadding = size * 0.2;
|
|
153
|
+
const maxPadding = size * 0.3;
|
|
154
|
+
/** The long edge width of the triangle */
|
|
155
|
+
const longEdge = size - 2 * minPadding;
|
|
156
|
+
/** The median width of the triangle */
|
|
157
|
+
const median = size - 2 * maxPadding;
|
|
158
|
+
const halfLongEdge = longEdge * 0.5;
|
|
159
|
+
let x0, y0;
|
|
160
|
+
let coords, borderCoords;
|
|
161
|
+
switch (dir) {
|
|
162
|
+
case 'r':
|
|
163
|
+
x0 = x + maxPadding;
|
|
164
|
+
y0 = y + minPadding;
|
|
165
|
+
borderCoords = [x, y, x + size, y, x + size, y + size, x, y + size];
|
|
166
|
+
coords = [x0, y0, x0, y0 + longEdge, x0 + median, y0 + halfLongEdge];
|
|
167
|
+
break;
|
|
168
|
+
case 'l':
|
|
169
|
+
x0 = x + size - maxPadding;
|
|
170
|
+
y0 = y + minPadding;
|
|
171
|
+
borderCoords = [x + size, y, x, y, x, y + size, x + size, y + size];
|
|
172
|
+
coords = [x0, y0, x0, y0 + longEdge, x0 - median, y0 + halfLongEdge];
|
|
173
|
+
break;
|
|
174
|
+
case 't':
|
|
175
|
+
x0 = x + minPadding;
|
|
176
|
+
y0 = y + size - maxPadding;
|
|
177
|
+
borderCoords = [x, y + size, x, y, x + size, y, x + size, y + size];
|
|
178
|
+
coords = [x0, y0, x0 + longEdge, y0, x0 + halfLongEdge, y0 - median];
|
|
179
|
+
break;
|
|
180
|
+
case 'b':
|
|
181
|
+
x0 = x + minPadding;
|
|
182
|
+
y0 = y + maxPadding;
|
|
183
|
+
borderCoords = [x, y, x, y + size, x + size, y + size, x + size, y];
|
|
184
|
+
coords = [x0, y0, x0 + longEdge, y0, x0 + halfLongEdge, y0 + median];
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (active) {
|
|
189
|
+
self.ctx.strokeStyle = self.style.unhideIndicatorBorderColor;
|
|
190
|
+
self.ctx.lineWidth = 2;
|
|
191
|
+
drawLines(borderCoords);
|
|
192
|
+
|
|
193
|
+
self.ctx.fillStyle = self.style.unhideIndicatorBackgroundColor;
|
|
194
|
+
let offset = dir === 'r' || dir === 'b' ? 1 : 0;
|
|
195
|
+
if (dir === 'l' || dir === 'r')
|
|
196
|
+
fillRect(x - offset, y, size + offset, size);
|
|
197
|
+
else fillRect(x, y - offset, size, size + offset);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
self.ctx.fillStyle = self.style.unhideIndicatorColor;
|
|
201
|
+
drawLines(coords, true);
|
|
141
202
|
}
|
|
142
203
|
function drawOrderByArrow(x, y) {
|
|
143
204
|
var mt = self.style.columnHeaderOrderByArrowMarginTop * self.scale,
|
|
@@ -719,7 +780,15 @@ export default function (self) {
|
|
|
719
780
|
columnGroupsRectInfo = {},
|
|
720
781
|
collapsedColumnGroups = self.getCollapsedColumnGroups(),
|
|
721
782
|
collapsedRowGroups = self.getCollapsedRowGroups(),
|
|
722
|
-
cellHeight = self.style.cellHeight
|
|
783
|
+
cellHeight = self.style.cellHeight,
|
|
784
|
+
currentRowIndexOffset = 0,
|
|
785
|
+
/** @type {Array<{from:number,plus:number}>} */
|
|
786
|
+
rowIndexOffsetByHiddenRows = self.hiddenRowRanges
|
|
787
|
+
.map((range) => ({
|
|
788
|
+
from: range[0],
|
|
789
|
+
plus: range[1] - range[0] + 1,
|
|
790
|
+
}))
|
|
791
|
+
.sort((a, b) => a.from - b.from);
|
|
723
792
|
drawCount += 1;
|
|
724
793
|
p = performance.now();
|
|
725
794
|
self.visibleRowHeights = [];
|
|
@@ -874,13 +943,17 @@ export default function (self) {
|
|
|
874
943
|
selectionHandles.push([cell, 'tr']);
|
|
875
944
|
cell.selectionHandle = 'tr';
|
|
876
945
|
}
|
|
877
|
-
if (
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
946
|
+
if (cell.selectionBorderTop && cell.selectionBorderLeft) {
|
|
947
|
+
if (self.mobile) {
|
|
948
|
+
selectionHandles.push([cell, 'tl']);
|
|
949
|
+
cell.selectionHandle = 'tl';
|
|
950
|
+
}
|
|
951
|
+
if (self.fillOverlay.handle) {
|
|
952
|
+
self.fillOverlay.snapTo = {
|
|
953
|
+
x: cell.x,
|
|
954
|
+
y: cell.y,
|
|
955
|
+
};
|
|
956
|
+
}
|
|
884
957
|
}
|
|
885
958
|
if (
|
|
886
959
|
cell.selectionBorderBottom &&
|
|
@@ -897,6 +970,22 @@ export default function (self) {
|
|
|
897
970
|
) {
|
|
898
971
|
selectionHandles.push([cell, 'br']);
|
|
899
972
|
cell.selectionHandle = 'br';
|
|
973
|
+
|
|
974
|
+
if (self.fillOverlay.handle) {
|
|
975
|
+
self.fillOverlay.handle.x = cell.x + cell.width;
|
|
976
|
+
self.fillOverlay.handle.y = cell.y + cell.height;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (self.fillOverlay.handle) {
|
|
981
|
+
// Some corners may not be displaying, so we get at least
|
|
982
|
+
// one correct axis in order to display a fill overlay.
|
|
983
|
+
if (self.fillOverlay.snapTo.x === -1 && cell.selectionBorderLeft) {
|
|
984
|
+
self.fillOverlay.snapTo.x = cell.x;
|
|
985
|
+
}
|
|
986
|
+
if (self.fillOverlay.snapTo.y === -1 && cell.selectionBorderTop) {
|
|
987
|
+
self.fillOverlay.snapTo.y = cell.y;
|
|
988
|
+
}
|
|
900
989
|
}
|
|
901
990
|
}
|
|
902
991
|
}
|
|
@@ -995,8 +1084,10 @@ export default function (self) {
|
|
|
995
1084
|
isGrid = header.type === 'canvas-datagrid',
|
|
996
1085
|
activeHeader =
|
|
997
1086
|
(self.orders.rows[self.activeCell.rowIndex] === rowOrderIndex ||
|
|
1087
|
+
self.selectedRows.indexOf(rowOrderIndex) >= 0 ||
|
|
998
1088
|
self.orders.columns[self.activeCell.columnIndex] ===
|
|
999
|
-
headerIndex
|
|
1089
|
+
headerIndex ||
|
|
1090
|
+
self.selectedColumns.indexOf(headerIndex) >= 0) &&
|
|
1000
1091
|
(columnOrderIndex === -1 || rowOrderIndex === -1)
|
|
1001
1092
|
? isRowHeader
|
|
1002
1093
|
? 'activeRowHeaderCell'
|
|
@@ -1369,6 +1460,19 @@ export default function (self) {
|
|
|
1369
1460
|
group.to === cell.boundRowIndex,
|
|
1370
1461
|
) >= 0;
|
|
1371
1462
|
}
|
|
1463
|
+
// We don't treat the row index difference from hidden rows as the row gap.
|
|
1464
|
+
if (hasRowGap && self.hiddenRowRanges.length > 0) {
|
|
1465
|
+
for (let i = 0; i < self.hiddenRowRanges.length; i++) {
|
|
1466
|
+
const [beginRowIndex, endRowIndex] = self.hiddenRowRanges[i];
|
|
1467
|
+
if (
|
|
1468
|
+
cell.boundRowIndex === endRowIndex + 1 &&
|
|
1469
|
+
previousRowNumber === beginRowIndex - 1
|
|
1470
|
+
) {
|
|
1471
|
+
hasRowGap = false;
|
|
1472
|
+
break;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1372
1476
|
|
|
1373
1477
|
if (hasRowGap) {
|
|
1374
1478
|
const barHeight = self.style.rowHeaderCellRowNumberGapHeight;
|
|
@@ -1384,9 +1488,141 @@ export default function (self) {
|
|
|
1384
1488
|
}
|
|
1385
1489
|
}
|
|
1386
1490
|
|
|
1491
|
+
//#region draw unhide indicator for column headers
|
|
1492
|
+
if (isColumnHeader && self.attributes.showUnhideColumnsIndicator) {
|
|
1493
|
+
const hovered = self.hovers.unhideIndicator;
|
|
1494
|
+
const size = self.style.unhideIndicatorSize;
|
|
1495
|
+
const cellX = x;
|
|
1496
|
+
const topY = cell.y + Math.max(0.5 * (cell.height - size), 0);
|
|
1497
|
+
|
|
1498
|
+
const isActive = (orderIndex) =>
|
|
1499
|
+
hovered &&
|
|
1500
|
+
(hovered.dir === 'l' || hovered.dir === 'r') &&
|
|
1501
|
+
orderIndex >= hovered.orderIndex0 &&
|
|
1502
|
+
orderIndex <= hovered.orderIndex1;
|
|
1503
|
+
const isHiddenColumn = (columnIndex) =>
|
|
1504
|
+
columnIndex >= 0 &&
|
|
1505
|
+
schema[columnIndex] &&
|
|
1506
|
+
schema[columnIndex].hidden;
|
|
1507
|
+
|
|
1508
|
+
let orderIndex0, orderIndex1;
|
|
1509
|
+
const drawIndicator = (leftX, dir, active) => {
|
|
1510
|
+
self.visibleUnhideIndicators.push({
|
|
1511
|
+
x: leftX - 1,
|
|
1512
|
+
y: topY - 1,
|
|
1513
|
+
x2: leftX + size + 2,
|
|
1514
|
+
y2: topY + size + 2,
|
|
1515
|
+
orderIndex0,
|
|
1516
|
+
orderIndex1,
|
|
1517
|
+
dir,
|
|
1518
|
+
});
|
|
1519
|
+
if (!active) {
|
|
1520
|
+
const line = cell.text && cell.text.lines && cell.text.lines[0];
|
|
1521
|
+
if (line) {
|
|
1522
|
+
const iconsWidth = orderByArrowSize + treeArrowSize;
|
|
1523
|
+
const lineX0 = iconsWidth > 0 ? iconsWidth : line.x;
|
|
1524
|
+
const lineX1 = line.x + line.width;
|
|
1525
|
+
if (leftX + size >= lineX0 && leftX <= lineX1) return;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
drawUnhideIndicator(leftX, topY, size, dir, active);
|
|
1529
|
+
}; // end of drawIndicator
|
|
1530
|
+
|
|
1531
|
+
let orderIndexPtr = columnOrderIndex - 1;
|
|
1532
|
+
const prevColumnIndex = self.orders.columns[orderIndexPtr];
|
|
1533
|
+
if (isHiddenColumn(prevColumnIndex)) {
|
|
1534
|
+
const active = isActive(prevColumnIndex);
|
|
1535
|
+
orderIndex0 = orderIndexPtr;
|
|
1536
|
+
orderIndex1 = orderIndexPtr;
|
|
1537
|
+
while (--orderIndexPtr >= 0) {
|
|
1538
|
+
if (isHiddenColumn(self.orders.columns[orderIndexPtr]))
|
|
1539
|
+
orderIndex0 = orderIndexPtr;
|
|
1540
|
+
else break;
|
|
1541
|
+
}
|
|
1542
|
+
drawIndicator(cellX, 'r', active);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
orderIndexPtr = columnOrderIndex + 1;
|
|
1546
|
+
const nextColumnIndex = self.orders.columns[orderIndexPtr];
|
|
1547
|
+
if (isHiddenColumn(nextColumnIndex)) {
|
|
1548
|
+
const active = isActive(nextColumnIndex);
|
|
1549
|
+
orderIndex0 = orderIndexPtr;
|
|
1550
|
+
orderIndex1 = orderIndexPtr;
|
|
1551
|
+
while (++orderIndexPtr < self.orders.columns.length) {
|
|
1552
|
+
if (isHiddenColumn(self.orders.columns[orderIndexPtr]))
|
|
1553
|
+
orderIndex1 = orderIndexPtr;
|
|
1554
|
+
else break;
|
|
1555
|
+
}
|
|
1556
|
+
const indicatorX = x + cell.width - size;
|
|
1557
|
+
drawIndicator(indicatorX, 'l', active);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
//#endregion draw unhide indicator for column headers
|
|
1561
|
+
|
|
1562
|
+
//#region draw unhide indicator for row headers
|
|
1563
|
+
if (
|
|
1564
|
+
isRowHeader &&
|
|
1565
|
+
self.attributes.showUnhideRowsIndicator &&
|
|
1566
|
+
self.hiddenRowRanges.length > 0
|
|
1567
|
+
) {
|
|
1568
|
+
// Leo's comment:
|
|
1569
|
+
// from the first row to the last row, `rowIndex` is from 0 to the count of rows
|
|
1570
|
+
// but `boundRowIndex` can be disordered if there are any ordered columns or filtered columns
|
|
1571
|
+
// Like this statement:
|
|
1572
|
+
// console.log(rowIndex, cell.boundRowIndex, cell.formattedValue);
|
|
1573
|
+
// can output the result like this:
|
|
1574
|
+
// 0 1 '2'
|
|
1575
|
+
// 1 3 '4'
|
|
1576
|
+
const hovered = self.hovers.unhideIndicator;
|
|
1577
|
+
const size = self.style.unhideIndicatorSize;
|
|
1578
|
+
const leftX = cell.x + cell.width - size - 2;
|
|
1579
|
+
const cellY = y;
|
|
1580
|
+
const topIndicators = {};
|
|
1581
|
+
const bottomIndicators = {};
|
|
1582
|
+
self.hiddenRowRanges.forEach((it) => {
|
|
1583
|
+
topIndicators[it[0] - 1] = it;
|
|
1584
|
+
bottomIndicators[it[1] + 1] = it;
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
const rowIndex = cell.rowIndex + currentRowIndexOffset;
|
|
1588
|
+
const isActive = () =>
|
|
1589
|
+
hovered &&
|
|
1590
|
+
(hovered.dir === 't' || hovered.dir === 'b') &&
|
|
1591
|
+
rowIndex >= hovered.orderIndex0 - 1 &&
|
|
1592
|
+
rowIndex <= hovered.orderIndex1 + 1;
|
|
1593
|
+
|
|
1594
|
+
let orderIndex0, orderIndex1;
|
|
1595
|
+
const drawIndicator = (topY, dir, active) => {
|
|
1596
|
+
self.visibleUnhideIndicators.push({
|
|
1597
|
+
x: leftX - 1,
|
|
1598
|
+
y: topY - 1,
|
|
1599
|
+
x2: leftX + size + 2,
|
|
1600
|
+
y2: topY + size + 2,
|
|
1601
|
+
orderIndex0,
|
|
1602
|
+
orderIndex1,
|
|
1603
|
+
dir,
|
|
1604
|
+
});
|
|
1605
|
+
drawUnhideIndicator(leftX, topY, size, dir, active);
|
|
1606
|
+
}; // end of drawIndicator
|
|
1607
|
+
|
|
1608
|
+
let matched = topIndicators[rowIndex];
|
|
1609
|
+
if (matched) {
|
|
1610
|
+
const indicatorY = cellY + cell.height - size;
|
|
1611
|
+
[orderIndex0, orderIndex1] = matched;
|
|
1612
|
+
drawIndicator(indicatorY, 't', isActive());
|
|
1613
|
+
}
|
|
1614
|
+
matched = bottomIndicators[rowIndex];
|
|
1615
|
+
if (matched) {
|
|
1616
|
+
const indicatorY = cellY;
|
|
1617
|
+
[orderIndex0, orderIndex1] = matched;
|
|
1618
|
+
drawIndicator(indicatorY, 'b', isActive());
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
//#endregion draw unhide indicator for row headers
|
|
1622
|
+
|
|
1387
1623
|
x += cell.width + (bc ? 0 : self.style.cellBorderWidth);
|
|
1388
1624
|
return cell.width;
|
|
1389
|
-
};
|
|
1625
|
+
}; // end of drawEach
|
|
1390
1626
|
}
|
|
1391
1627
|
function drawFilterButton(cell, ev) {
|
|
1392
1628
|
var posX = cell.x + cell.width - self.style.filterButtonWidth - 1;
|
|
@@ -1424,17 +1660,20 @@ export default function (self) {
|
|
|
1424
1660
|
// as it is in the unfiltered data, instead of simply the viewed
|
|
1425
1661
|
// row index + 1. If rowIndex > viewData.length, it's a new row
|
|
1426
1662
|
// added to the end, and we want to render that new row's number
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1663
|
+
let filteredRowNumber;
|
|
1664
|
+
if (self.viewData && rowIndex < self.viewData.length)
|
|
1665
|
+
filteredRowNumber =
|
|
1666
|
+
self.getBoundRowIndexFromViewRowIndex(rowIndex) + 1;
|
|
1667
|
+
else
|
|
1668
|
+
filteredRowNumber = self.originalData
|
|
1431
1669
|
? self.originalData.length + 1
|
|
1432
1670
|
: rowOrderIndex + 1;
|
|
1433
1671
|
|
|
1434
|
-
|
|
1672
|
+
let rowHeaderValue =
|
|
1435
1673
|
self.hasActiveFilters() || self.hasCollapsedRowGroup()
|
|
1436
1674
|
? filteredRowNumber
|
|
1437
1675
|
: rowIndex + 1;
|
|
1676
|
+
rowHeaderValue += currentRowIndexOffset;
|
|
1438
1677
|
|
|
1439
1678
|
const rowHeaderCell = { rowHeaderCell: rowHeaderValue };
|
|
1440
1679
|
const headerDescription = {
|
|
@@ -1451,6 +1690,14 @@ export default function (self) {
|
|
|
1451
1690
|
-1,
|
|
1452
1691
|
-1,
|
|
1453
1692
|
);
|
|
1693
|
+
|
|
1694
|
+
if (
|
|
1695
|
+
rowIndexOffsetByHiddenRows[0] &&
|
|
1696
|
+
rowHeaderValue >= rowIndexOffsetByHiddenRows[0].from
|
|
1697
|
+
) {
|
|
1698
|
+
const { plus } = rowIndexOffsetByHiddenRows.shift();
|
|
1699
|
+
currentRowIndexOffset += plus;
|
|
1700
|
+
}
|
|
1454
1701
|
}
|
|
1455
1702
|
}
|
|
1456
1703
|
function drawHeaders() {
|
|
@@ -1593,7 +1840,7 @@ export default function (self) {
|
|
|
1593
1840
|
}
|
|
1594
1841
|
}
|
|
1595
1842
|
//draw frozen columns
|
|
1596
|
-
x =
|
|
1843
|
+
x = 1;
|
|
1597
1844
|
if (self.attributes.showRowHeaders) {
|
|
1598
1845
|
x += rowHeaderCellWidth;
|
|
1599
1846
|
}
|
|
@@ -1675,12 +1922,20 @@ export default function (self) {
|
|
|
1675
1922
|
schema = self.getSchema();
|
|
1676
1923
|
self.visibleCells = [];
|
|
1677
1924
|
self.visibleGroups = [];
|
|
1925
|
+
self.visibleUnhideIndicators = [];
|
|
1678
1926
|
self.canvasOffsetTop = self.isChildGrid ? self.parentNode.offsetTop : 0.5;
|
|
1679
1927
|
self.canvasOffsetLeft = self.isChildGrid
|
|
1680
1928
|
? self.parentNode.offsetLeft
|
|
1681
1929
|
: -0.5;
|
|
1682
1930
|
h = self.height;
|
|
1683
1931
|
w = self.width;
|
|
1932
|
+
|
|
1933
|
+
// patch for first row being hidden
|
|
1934
|
+
const firstRowIndexOffset = rowIndexOffsetByHiddenRows[0];
|
|
1935
|
+
if (firstRowIndexOffset && firstRowIndexOffset.from === 0) {
|
|
1936
|
+
currentRowIndexOffset = firstRowIndexOffset.plus;
|
|
1937
|
+
rowIndexOffsetByHiddenRows.shift();
|
|
1938
|
+
}
|
|
1684
1939
|
}
|
|
1685
1940
|
function drawBackground() {
|
|
1686
1941
|
radiusRect(0, 0, w, h, 0);
|
|
@@ -1876,7 +2131,7 @@ export default function (self) {
|
|
|
1876
2131
|
leftX -= toggleHandlePadding + 1;
|
|
1877
2132
|
if (containsEnd) rightX += toggleHandleSize;
|
|
1878
2133
|
}
|
|
1879
|
-
|
|
2134
|
+
drawLines(lineCoords);
|
|
1880
2135
|
ctx.restore();
|
|
1881
2136
|
pushToVisibleGroups(leftX, rightX);
|
|
1882
2137
|
}
|
|
@@ -2054,7 +2309,7 @@ export default function (self) {
|
|
|
2054
2309
|
// add more clickable area into `visibleGroups`
|
|
2055
2310
|
if (containsEnd) bottomY += toggleHandleSize;
|
|
2056
2311
|
}
|
|
2057
|
-
|
|
2312
|
+
drawLines(lineCoords);
|
|
2058
2313
|
ctx.restore();
|
|
2059
2314
|
pushToVisibleGroups(topY, bottomY);
|
|
2060
2315
|
}
|
|
@@ -2078,10 +2333,8 @@ export default function (self) {
|
|
|
2078
2333
|
if (self.attributes.allowFreezingRows) {
|
|
2079
2334
|
// HACK great, another stupid magic number.
|
|
2080
2335
|
// Background will appear as a 0.5px artifact behind the row freeze bar without this hack
|
|
2081
|
-
y +=
|
|
2082
|
-
|
|
2083
|
-
self.style.frozenMarkerWidth -
|
|
2084
|
-
0.4999999999;
|
|
2336
|
+
if (y > columnHeaderCellHeight) y += self.style.frozenMarkerWidth;
|
|
2337
|
+
y += self.style.frozenMarkerBorderWidth - 0.4999999999;
|
|
2085
2338
|
}
|
|
2086
2339
|
self.lastFrozenRowPixel = y;
|
|
2087
2340
|
}
|
|
@@ -2208,6 +2461,7 @@ export default function (self) {
|
|
|
2208
2461
|
self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;
|
|
2209
2462
|
self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;
|
|
2210
2463
|
if (
|
|
2464
|
+
self.selectedRows.indexOf(self.reorderTarget.sortRowIndex) === -1 &&
|
|
2211
2465
|
self.currentCell.rowIndex !== self.reorderObject.rowIndex &&
|
|
2212
2466
|
self.currentCell.rowIndex > -1 &&
|
|
2213
2467
|
self.currentCell.rowIndex < l
|
|
@@ -2221,10 +2475,12 @@ export default function (self) {
|
|
|
2221
2475
|
}
|
|
2222
2476
|
} else if (self.dragMode === 'column-reorder' && self.reorderObject) {
|
|
2223
2477
|
var selectedColumns = self.selections[0];
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
self.
|
|
2227
|
-
|
|
2478
|
+
if (selectedColumns) {
|
|
2479
|
+
for (var k = 1; k < selectedColumns.length; k++) {
|
|
2480
|
+
b.width += self.getColumnWidth(
|
|
2481
|
+
self.orders.columns[selectedColumns[k]],
|
|
2482
|
+
);
|
|
2483
|
+
}
|
|
2228
2484
|
}
|
|
2229
2485
|
b.height = h;
|
|
2230
2486
|
b.y = 0;
|
|
@@ -2237,8 +2493,11 @@ export default function (self) {
|
|
|
2237
2493
|
self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;
|
|
2238
2494
|
self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;
|
|
2239
2495
|
if (
|
|
2496
|
+
self.selectedColumns.indexOf(self.reorderTarget.sortColumnIndex) ===
|
|
2497
|
+
-1 &&
|
|
2240
2498
|
self.currentCell.sortColumnIndex !==
|
|
2241
2499
|
self.reorderObject.sortColumnIndex &&
|
|
2500
|
+
self.reorderTarget.columnIndex !== self.reorderObject.columnIndex &&
|
|
2242
2501
|
self.currentCell.sortColumnIndex > -1 &&
|
|
2243
2502
|
self.currentCell.sortColumnIndex < schema.length
|
|
2244
2503
|
) {
|
|
@@ -2257,10 +2516,12 @@ export default function (self) {
|
|
|
2257
2516
|
strokeRect(0, 0, self.width, self.height);
|
|
2258
2517
|
}
|
|
2259
2518
|
function drawSelectionBorders() {
|
|
2260
|
-
self.ctx.lineWidth = self.style.selectionOverlayBorderWidth;
|
|
2261
|
-
self.ctx.strokeStyle = self.style.selectionOverlayBorderColor;
|
|
2262
2519
|
function dsb(c) {
|
|
2263
|
-
|
|
2520
|
+
if (!self.fillOverlay.handle) {
|
|
2521
|
+
self.ctx.lineWidth = self.style.selectionOverlayBorderWidth;
|
|
2522
|
+
self.ctx.strokeStyle = self.style.selectionOverlayBorderColor;
|
|
2523
|
+
addBorderLine(c[0], c[1]);
|
|
2524
|
+
}
|
|
2264
2525
|
}
|
|
2265
2526
|
selectionBorders
|
|
2266
2527
|
.filter(function (c) {
|
|
@@ -2303,9 +2564,14 @@ export default function (self) {
|
|
|
2303
2564
|
})
|
|
2304
2565
|
.forEach(dsb);
|
|
2305
2566
|
self.ctx.restore();
|
|
2567
|
+
|
|
2568
|
+
drawFillOverlay();
|
|
2306
2569
|
}
|
|
2307
2570
|
function drawSelectionHandles() {
|
|
2308
|
-
if (
|
|
2571
|
+
if (
|
|
2572
|
+
(self.mobile || self.attributes.allowMovingSelection) &&
|
|
2573
|
+
self.attributes.editable
|
|
2574
|
+
) {
|
|
2309
2575
|
self.ctx.lineWidth = self.style.selectionHandleBorderWidth;
|
|
2310
2576
|
self.ctx.strokeStyle = self.style.selectionHandleBorderColor;
|
|
2311
2577
|
self.ctx.fillStyle = self.style.selectionHandleColor;
|
|
@@ -2326,6 +2592,62 @@ export default function (self) {
|
|
|
2326
2592
|
});
|
|
2327
2593
|
}
|
|
2328
2594
|
}
|
|
2595
|
+
function drawFillOverlay() {
|
|
2596
|
+
if (!self.fillOverlay.handle || !self.fillOverlay.snapTo) {
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
self.ctx.save();
|
|
2601
|
+
|
|
2602
|
+
const overlay = self.fillOverlay;
|
|
2603
|
+
const handle = overlay.handle;
|
|
2604
|
+
const toX = overlay.snapTo.x;
|
|
2605
|
+
const toY = overlay.snapTo.y;
|
|
2606
|
+
|
|
2607
|
+
// The cell that the cursor is moving over. This may be unavailable
|
|
2608
|
+
// when the cursor is outside the grid or is pointing to something else.
|
|
2609
|
+
//
|
|
2610
|
+
// When unavailable, we use the actual position of the cursor to draw
|
|
2611
|
+
// the overlay.
|
|
2612
|
+
const snap = overlay.snap;
|
|
2613
|
+
|
|
2614
|
+
// Calculate the X, Y coordinates of the cursor with snap positions and
|
|
2615
|
+
// the direction of the movement in mind.
|
|
2616
|
+
//
|
|
2617
|
+
// When the movement is horizontal, we get the Y coordinate from the handle,
|
|
2618
|
+
// and vice-versa.
|
|
2619
|
+
const cursorX =
|
|
2620
|
+
overlay.direction === 'x'
|
|
2621
|
+
? snap
|
|
2622
|
+
? snap.x + (overlay.x < toX ? 0 : snap.width)
|
|
2623
|
+
: overlay.x
|
|
2624
|
+
: handle.x;
|
|
2625
|
+
const cursorY =
|
|
2626
|
+
overlay.direction === undefined || overlay.direction === 'y'
|
|
2627
|
+
? snap
|
|
2628
|
+
? snap.y + (overlay.y < toY ? 0 : snap.height)
|
|
2629
|
+
: overlay.y
|
|
2630
|
+
: handle.y;
|
|
2631
|
+
|
|
2632
|
+
// The final coordinates of the rect. We use 'minX' and 'minY' to avoid
|
|
2633
|
+
// drawing on the frozen area.
|
|
2634
|
+
const x = Math.max(Math.min(toX, cursorX), overlay.minX);
|
|
2635
|
+
const y = Math.max(Math.min(toY, cursorY), overlay.minY);
|
|
2636
|
+
|
|
2637
|
+
// Width and height of the rect are the difference between the
|
|
2638
|
+
// coordinates of both the rect and the cursor. The user may be pointing
|
|
2639
|
+
// behind and/or upwards of the rect, so we need to take that into
|
|
2640
|
+
// account.
|
|
2641
|
+
const width = Math.max(toX, cursorX) - x;
|
|
2642
|
+
const height = Math.max(toY, cursorY) - y;
|
|
2643
|
+
|
|
2644
|
+
self.ctx.strokeStyle = self.style.fillOverlayBorderColor;
|
|
2645
|
+
self.ctx.lineWidth = self.style.fillOverlayBorderWidth;
|
|
2646
|
+
self.ctx.setLineDash([3, 3]);
|
|
2647
|
+
strokeRect(x, y, width, height);
|
|
2648
|
+
self.ctx.setLineDash([]);
|
|
2649
|
+
self.ctx.restore();
|
|
2650
|
+
}
|
|
2329
2651
|
function drawActiveCell() {
|
|
2330
2652
|
if (!aCell) {
|
|
2331
2653
|
return;
|
|
@@ -2359,81 +2681,172 @@ export default function (self) {
|
|
|
2359
2681
|
self.ctx.restore();
|
|
2360
2682
|
}
|
|
2361
2683
|
function drawFrozenMarkers() {
|
|
2362
|
-
if (self.dragStartObject !== undefined) return;
|
|
2363
2684
|
var my = self.lastFrozenRowPixel - self.style.frozenMarkerWidth,
|
|
2364
|
-
mx = self.lastFrozenColumnPixel - self.style.
|
|
2685
|
+
mx = self.lastFrozenColumnPixel - self.style.frozenMarkerWidth,
|
|
2365
2686
|
xHover =
|
|
2366
2687
|
self.currentCell && self.currentCell.style === 'frozen-row-marker',
|
|
2367
2688
|
yHover =
|
|
2368
2689
|
self.currentCell && self.currentCell.style === 'frozen-column-marker';
|
|
2690
|
+
let rowHeaderCellWidth = self.getRowHeaderCellWidth();
|
|
2369
2691
|
self.ctx.lineWidth = self.style.frozenMarkerBorderWidth;
|
|
2370
2692
|
if (self.attributes.allowFreezingColumns) {
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2693
|
+
if (
|
|
2694
|
+
!self.freezeMarkerPosition ||
|
|
2695
|
+
(self.freezeMarkerPosition && self.dragMode === 'frozen-row-marker')
|
|
2696
|
+
) {
|
|
2697
|
+
if (mx > self.style.rowHeaderCellWidth) {
|
|
2698
|
+
self.ctx.fillStyle = self.style.frozenMarkerColor;
|
|
2699
|
+
self.ctx.strokeStyle = self.style.frozenMarkerBorderColor;
|
|
2700
|
+
fillRect(mx, 0, self.style.frozenMarkerWidth, self.height);
|
|
2701
|
+
strokeRect(mx, 0, self.style.frozenMarkerWidth, self.height);
|
|
2702
|
+
}
|
|
2703
|
+
self.ctx.fillStyle = yHover
|
|
2704
|
+
? self.style.frozenMarkerHoverColor
|
|
2705
|
+
: self.style.frozenMarkerHeaderColor;
|
|
2706
|
+
self.ctx.strokeStyle = yHover
|
|
2707
|
+
? self.style.frozenMarkerHoverBorderColor
|
|
2708
|
+
: self.style.frozenMarkerHeaderColor;
|
|
2709
|
+
fillRect(
|
|
2710
|
+
mx,
|
|
2711
|
+
0,
|
|
2712
|
+
self.style.frozenMarkerWidth,
|
|
2713
|
+
self.style.columnHeaderCellHeight,
|
|
2714
|
+
);
|
|
2715
|
+
strokeRect(
|
|
2716
|
+
mx,
|
|
2717
|
+
0,
|
|
2718
|
+
self.style.frozenMarkerWidth,
|
|
2719
|
+
self.style.columnHeaderCellHeight,
|
|
2720
|
+
);
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
if (
|
|
2724
|
+
!self.dragStartObject ||
|
|
2725
|
+
(self.dragStartObject &&
|
|
2726
|
+
self.dragStartObject.style !== 'rowHeaderCell')
|
|
2727
|
+
) {
|
|
2728
|
+
self.visibleCells.unshift({
|
|
2729
|
+
x: mx,
|
|
2730
|
+
y: 0,
|
|
2731
|
+
height: self.height,
|
|
2732
|
+
width: self.style.frozenMarkerWidth, // + self.style.frozenMarkerBorderWidth,
|
|
2733
|
+
style: 'frozen-column-marker',
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2387
2736
|
}
|
|
2388
2737
|
if (self.attributes.allowFreezingRows) {
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2738
|
+
if (
|
|
2739
|
+
!self.freezeMarkerPosition ||
|
|
2740
|
+
(self.freezeMarkerPosition &&
|
|
2741
|
+
self.dragMode === 'frozen-column-marker')
|
|
2742
|
+
) {
|
|
2743
|
+
if (my > rowHeaderCellWidth) {
|
|
2744
|
+
self.ctx.fillStyle = self.style.frozenMarkerColor;
|
|
2745
|
+
self.ctx.strokeStyle = self.style.frozenMarkerBorderColor;
|
|
2746
|
+
fillRect(0, my, self.width, self.style.frozenMarkerWidth);
|
|
2747
|
+
strokeRect(0, my, self.width, self.style.frozenMarkerWidth);
|
|
2748
|
+
}
|
|
2749
|
+
self.ctx.fillStyle = xHover
|
|
2750
|
+
? self.style.frozenMarkerHoverColor
|
|
2751
|
+
: self.style.frozenMarkerHeaderColor;
|
|
2752
|
+
self.ctx.strokeStyle = xHover
|
|
2753
|
+
? self.style.frozenMarkerHoverBorderColor
|
|
2754
|
+
: self.style.frozenMarkerHeaderColor;
|
|
2755
|
+
fillRect(0, my, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2756
|
+
strokeRect(0, my, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2757
|
+
}
|
|
2758
|
+
var height =
|
|
2398
2759
|
self.style.frozenMarkerWidth + self.style.frozenMarkerBorderWidth;
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2760
|
+
if (
|
|
2761
|
+
!self.dragStartObject ||
|
|
2762
|
+
(self.dragStartObject &&
|
|
2763
|
+
self.dragStartObject.style !== 'columnHeaderCell')
|
|
2764
|
+
) {
|
|
2765
|
+
self.visibleCells.unshift({
|
|
2766
|
+
x: 0,
|
|
2767
|
+
y: my,
|
|
2768
|
+
height: height,
|
|
2769
|
+
width: self.width,
|
|
2770
|
+
style: 'frozen-row-marker',
|
|
2771
|
+
});
|
|
2772
|
+
}
|
|
2406
2773
|
rowGroupsFrozenInfo = { y: my, h: height };
|
|
2407
2774
|
}
|
|
2408
2775
|
if (self.freezeMarkerPosition) {
|
|
2409
2776
|
self.ctx.fillStyle = self.style.frozenMarkerActiveColor;
|
|
2410
2777
|
self.ctx.strokeStyle = self.style.frozenMarkerActiveBorderColor;
|
|
2411
2778
|
if (self.dragMode === 'frozen-column-marker') {
|
|
2779
|
+
let posX = self.freezeMarkerPosition.x;
|
|
2780
|
+
let nearCell = self.getCellAt(posX, 0);
|
|
2781
|
+
if (self.freezeMarkerPosition.isGrab) posX = mx;
|
|
2782
|
+
if (posX > rowHeaderCellWidth) {
|
|
2783
|
+
let x =
|
|
2784
|
+
nearCell.x -
|
|
2785
|
+
self.style.frozenMarkerWidth -
|
|
2786
|
+
self.style.frozenMarkerBorderWidth;
|
|
2787
|
+
if (posX > x + nearCell.width / 2) x = x + nearCell.width;
|
|
2788
|
+
self.ctx.fillStyle = self.style.frozenMarkerColor;
|
|
2789
|
+
self.ctx.strokeStyle = self.style.frozenMarkerBorderColor;
|
|
2790
|
+
fillRect(x, 0, self.style.frozenMarkerWidth, self.height);
|
|
2791
|
+
strokeRect(x, 0, self.style.frozenMarkerWidth, self.height);
|
|
2792
|
+
self.ctx.fillStyle = self.style.frozenMarkerHeaderColor;
|
|
2793
|
+
self.ctx.strokeStyle = self.style.frozenMarkerHeaderColor;
|
|
2794
|
+
fillRect(
|
|
2795
|
+
x,
|
|
2796
|
+
0,
|
|
2797
|
+
self.style.frozenMarkerWidth,
|
|
2798
|
+
self.style.columnHeaderCellHeight,
|
|
2799
|
+
);
|
|
2800
|
+
strokeRect(
|
|
2801
|
+
x,
|
|
2802
|
+
0,
|
|
2803
|
+
self.style.frozenMarkerWidth,
|
|
2804
|
+
self.style.columnHeaderCellHeight,
|
|
2805
|
+
);
|
|
2806
|
+
}
|
|
2807
|
+
self.ctx.fillStyle = self.style.frozenMarkerActiveHeaderColor;
|
|
2808
|
+
self.ctx.strokeStyle = self.style.frozenMarkerActiveBorderColor;
|
|
2412
2809
|
fillRect(
|
|
2413
|
-
|
|
2810
|
+
posX,
|
|
2414
2811
|
0,
|
|
2415
2812
|
self.style.frozenMarkerWidth,
|
|
2416
|
-
self.
|
|
2813
|
+
self.style.columnHeaderCellHeight,
|
|
2417
2814
|
);
|
|
2418
2815
|
strokeRect(
|
|
2419
|
-
|
|
2816
|
+
posX,
|
|
2420
2817
|
0,
|
|
2421
2818
|
self.style.frozenMarkerWidth,
|
|
2422
|
-
self.
|
|
2819
|
+
self.style.columnHeaderCellHeight,
|
|
2423
2820
|
);
|
|
2821
|
+
self.ctx.fillStyle = self.style.frozenMarkerActiveColor;
|
|
2822
|
+
fillRect(posX, 0, self.style.frozenMarkerWidth, self.height);
|
|
2823
|
+
strokeRect(posX, 0, self.style.frozenMarkerWidth, self.height);
|
|
2424
2824
|
} else {
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
self.
|
|
2435
|
-
self.style.
|
|
2436
|
-
|
|
2825
|
+
let posY = self.freezeMarkerPosition.y;
|
|
2826
|
+
let nearCell = self.getCellAt(0, posY);
|
|
2827
|
+
if (self.freezeMarkerPosition.isGrab) posY = my;
|
|
2828
|
+
if (posY > self.style.columnHeaderCellHeight) {
|
|
2829
|
+
let y =
|
|
2830
|
+
nearCell.y -
|
|
2831
|
+
self.style.frozenMarkerWidth -
|
|
2832
|
+
self.style.frozenMarkerBorderWidth;
|
|
2833
|
+
if (posY > y + nearCell.height / 2) y = y + nearCell.height;
|
|
2834
|
+
self.ctx.fillStyle = self.style.frozenMarkerColor;
|
|
2835
|
+
self.ctx.strokeStyle = self.style.frozenMarkerBorderColor;
|
|
2836
|
+
fillRect(0, y, self.width, self.style.frozenMarkerWidth);
|
|
2837
|
+
strokeRect(0, y, self.width, self.style.frozenMarkerWidth);
|
|
2838
|
+
self.ctx.fillStyle = self.style.frozenMarkerHeaderColor;
|
|
2839
|
+
self.ctx.strokeStyle = self.style.frozenMarkerHeaderColor;
|
|
2840
|
+
fillRect(0, y, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2841
|
+
strokeRect(0, y, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2842
|
+
}
|
|
2843
|
+
self.ctx.fillStyle = self.style.frozenMarkerActiveHeaderColor;
|
|
2844
|
+
self.ctx.strokeStyle = self.style.frozenMarkerActiveBorderColor;
|
|
2845
|
+
fillRect(0, posY, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2846
|
+
strokeRect(0, posY, rowHeaderCellWidth, self.style.frozenMarkerWidth);
|
|
2847
|
+
self.ctx.fillStyle = self.style.frozenMarkerActiveColor;
|
|
2848
|
+
fillRect(0, posY, self.width, self.style.frozenMarkerWidth);
|
|
2849
|
+
strokeRect(0, posY, self.width, self.style.frozenMarkerWidth);
|
|
2437
2850
|
}
|
|
2438
2851
|
}
|
|
2439
2852
|
}
|