Skip to content

Commit

Permalink
drastically improved draw time, fixed minor bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Tony Germaneri committed Nov 30, 2016
1 parent 5efe034 commit 7e43f2e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 83 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ canvas-grid

Lightweight canvas based data grid.

[Demo][https://tonygermaneri.github.io/canvas-datagrid/sample/index.html]
[Demo](https://tonygermaneri.github.io/canvas-datagrid/sample/index.html)

Instantiation
=============
Expand Down
175 changes: 95 additions & 80 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,15 @@ define([], function context() {
originalData,
changes = [],
scrollEdit,
scrollIndexTop = 0,
scrollPixelTop = 0,
dragStart;
function setStorageData() {
if (!attributes.saveAppearance) { return; }
localStorage.setItem(storageName + '-' + args.name, JSON.stringify({
sizes: sizes
}));
}
function getVisibleSchema() {
return (schema || tempSchema).filter(function (col) { return !col.hidden; });
}
Expand Down Expand Up @@ -279,19 +287,6 @@ define([], function context() {
}
fire('selectionchanged', [getSelectedData(), selections, selectionBounds], intf);
}
function setScrollAreaHeight() {
scrollHeight = data.reduce(function reduceData(accumulator, row) {
return accumulator + (sizes.rows[row[uniqueId]] || style.cellHeight);
}, 0) || 0;
scrollWidth = (schema || tempSchema).reduce(function reduceSchema(accumulator, column) {
return accumulator + column.width;
}, 0) || 0;
if (attributes.showNewRow) {
scrollHeight += style.cellHeight;
}
scrollArea.style.height = style.headerCellHeight + scrollHeight + 'px';
scrollArea.style.width = scrollWidth + 'px';
}
function drawOrderByArrow(x, y) {
ctx.fillStyle = style.headerOrderByArrowColor;
ctx.strokeStyle = style.headerOrderByArrowBorderColor;
Expand Down Expand Up @@ -321,7 +316,7 @@ define([], function context() {
|| !container.offsetWidth) {
return;
}
var newRow, rowHeaderCell, p, cx, cy, cellHeight, cornerCell, y, x, c, h, w, s, end;
var newRow, rowHeaderCell, p, cx, cy, cellHeight, cornerCell, y, x, c, h, w, s, r, rd, l = data.length;
if (attributes.showPerformance) {
p = performance.now();
}
Expand All @@ -330,7 +325,7 @@ define([], function context() {
visibleCells = [];
cellHeight = sizes.rows[data[uniqueId]] || style.cellHeight;
x = 0;
y = scrollBox.scrollTop * -1 + style.headerCellHeight;
y = scrollBox.scrollTop * -1 + style.headerCellHeight + scrollPixelTop;
h = canvas.height = height;
w = canvas.width = width;
ctx.textBaseline = 'alphabetic';
Expand All @@ -351,11 +346,6 @@ define([], function context() {
if (active) {
cellStyle = 'activeCell';
}
if (y < cellHeight * -1) { return; }
if (y - cellHeight > h) {
end = true;
return;
}
if (visibleRows.indexOf(rowIndex) === -1
&& ['headerCell', 'cornerCell'].indexOf(cellStyle) === -1) {
visibleRows.push(rowIndex);
Expand Down Expand Up @@ -458,19 +448,22 @@ define([], function context() {
drawCell(rowHeaderCell, index)(a, -1);
}
}
data.forEach(function (d, index) {
if (end) {
return;
for (r = scrollIndexTop; r < l; r += 1) {
rd = data[r];
if ((y - cellHeight > h)
|| (r < scrollIndexTop)
|| (y < cellHeight * -1)) {
break;
}
cellHeight = sizes.rows[d[uniqueId]] || style.cellHeight;
cellHeight = sizes.rows[rd[uniqueId]] || style.cellHeight;
if (attributes.showRowHeaders) {
x = sizes.columns.cornerCell || style.headerRowWidth;
}
s.forEach(drawCell(d, index));
drawRowHeader(d, index);
s.forEach(drawCell(rd, r));
drawRowHeader(rd, r);
y += cellHeight;
x = 0;
});
}
if (attributes.showNewRow) {
newRow = {};
newRow[uniqueId] = uId;
Expand Down Expand Up @@ -529,6 +522,75 @@ define([], function context() {
ctx.strokeText(p, w - 200, h - 50);
}
}
function scroll() {
scrollIndexTop = 0;
scrollPixelTop = style.cellHeight * -1;
while (scrollPixelTop < scrollBox.scrollTop) {
scrollPixelTop += sizes.rows[data[scrollIndexTop][uniqueId]] || style.cellHeight;
scrollIndexTop += 1;
}
scrollIndexTop = Math.max(scrollIndexTop - 1, 0);
scrollPixelTop = Math.max(scrollPixelTop - style.cellHeight, 0);
draw();
if (textarea) {
textarea.style.top = scrollEdit.textareaTop
+ (scrollEdit.scrollTop - scrollBox.scrollTop) + 'px';
textarea.style.left = scrollEdit.textareaLeft
+ (scrollEdit.scrollLeft - scrollBox.scrollLeft) + 'px';
}
}
function getHeaderByName(name) {
var x, i = (schema || tempSchema);
for (x = 0; x < i.length; x += 1) {
if (i[x].name === name) {
return i[x];
}
}
}
function findColumnMaxTextLength(name) {
var m = -Infinity;
if (name === 'cornerCell') {
ctx.font = style.headerRowCellFont;
return ctx.measureText(data.length.toString()).width
+ style.headerRowCellPaddingRight
+ style.headerRowCellPaddingLeft;
}
(schema || tempSchema).forEach(function (col) {
if (col.name !== name) { return; }
ctx.font = style.headerCellFont;
var t = ctx.measureText(col.title || col.name).width
+ style.headerCellPaddingRight
+ style.headerCellPaddingLeft;
m = t > m ? t : m;
});
data.forEach(function (row) {
ctx.font = style.cellFont;
var t = ctx.measureText(row[name]).width
+ style.cellPaddingRight
+ style.cellPaddingLeft;
m = t > m ? t : m;
});
return m;
}
function fitColumnToValues(name) {
sizes.columns[name === 'cornerCell' ? name : getHeaderByName(name)[uniqueId]]
= findColumnMaxTextLength(name);
draw();
}
function setScrollAreaHeight() {
scrollHeight = data.reduce(function reduceData(accumulator, row) {
return accumulator + (sizes.rows[row[uniqueId]] || style.cellHeight);
}, 0) || 0;
scrollWidth = (schema || tempSchema).reduce(function reduceSchema(accumulator, column) {
return accumulator + column.width;
}, 0) || 0;
if (attributes.showNewRow) {
scrollHeight += style.cellHeight;
}
style.headerRowWidth = findColumnMaxTextLength('cornerCell');
scrollArea.style.height = style.headerCellHeight + scrollHeight + 'px';
scrollArea.style.width = scrollWidth + 'px';
}
function order(columnName, direction) {
var asc = direction === 'asc',
f,
Expand Down Expand Up @@ -664,14 +726,6 @@ define([], function context() {
document.body.addEventListener('mousedown', disp);
}
}
function getHeaderByName(name) {
var x, i = (schema || tempSchema);
for (x = 0; x < i.length; x += 1) {
if (i[x].name === name) {
return i[x];
}
}
}
function refreshFromOrigialData() {
data = originalData.filter(function (row) {
return true;
Expand Down Expand Up @@ -737,6 +791,7 @@ define([], function context() {
e.preventDefault();
setFilter();
disposeContextMenu();
controlInput.focus();
}
});
}
Expand All @@ -752,8 +807,10 @@ define([], function context() {
rows: {},
columns: {},
};
setStorageData();
draw();
disposeContextMenu();
controlInput.focus();
}
});
}
Expand All @@ -764,6 +821,7 @@ define([], function context() {
e.preventDefault();
order(contextObject.item.header.name, 'asc');
disposeContextMenu();
controlInput.focus();
}
});
menuItems.push({
Expand All @@ -772,6 +830,7 @@ define([], function context() {
e.preventDefault();
order(contextObject.item.header.name, 'desc');
disposeContextMenu();
controlInput.focus();
}
});
}
Expand All @@ -793,6 +852,7 @@ define([], function context() {
item.onclick.apply(this, [e, contextObject, disposeContextMenu]);
e.preventDefault();
e.stopPropagation();
controlInput.focus();
});
}
});
Expand All @@ -815,36 +875,6 @@ define([], function context() {
container.appendChild(contextMenu);
e.preventDefault();
}
function findColumnMaxTextLength(name) {
var m = -Infinity;
if (name === 'cornerCell') {
ctx.font = style.headerRowCellFont;
return ctx.measureText(data.length.toString()).width
+ style.headerRowCellPaddingRight
+ style.headerRowCellPaddingLeft;
}
(schema || tempSchema).forEach(function (col) {
if (col.name !== name) { return; }
ctx.font = style.headerCellFont;
var t = ctx.measureText(col.title || col.name).width
+ style.headerCellPaddingRight
+ style.headerCellPaddingLeft;
m = t > m ? t : m;
});
data.forEach(function (row) {
ctx.font = style.cellFont;
var t = ctx.measureText(row[name]).width
+ style.cellPaddingRight
+ style.cellPaddingLeft;
m = t > m ? t : m;
});
return m;
}
function fitColumnToValues(name) {
sizes.columns[name === 'cornerCell' ? name : getHeaderByName(name)[uniqueId]]
= findColumnMaxTextLength(name);
draw();
}
function getSelectionBounds() {
var low = {x: Infinity, y: Infinity},
high = {x: -Infinity, y: -Infinity};
Expand Down Expand Up @@ -1123,12 +1153,6 @@ define([], function context() {
return;
}
}
function setStorageData() {
if (!attributes.saveAppearance) { return; }
localStorage.setItem(storageName + '-' + args.name, JSON.stringify({
sizes: sizes
}));
}
function stopDragResize() {
setScrollAreaHeight();
document.body.removeEventListener('mousemove', dragResizeColumn, false);
Expand Down Expand Up @@ -1328,15 +1352,6 @@ define([], function context() {
}
styleSheet.href = 'data:text/css;base64,' + btoa(style.contextMenuStyleSheet || css);
}
function scroll() {
draw();
if (textarea) {
textarea.style.top = scrollEdit.textareaTop
+ (scrollEdit.scrollTop - scrollBox.scrollTop) + 'px';
textarea.style.left = scrollEdit.textareaLeft
+ (scrollEdit.scrollLeft - scrollBox.scrollLeft) + 'px';
}
}
function setDom() {
controlInput = document.createElement('input');
container = document.createElement('div');
Expand Down
4 changes: 2 additions & 2 deletions sample/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
document.addEventListener('DOMContentLoaded', function () {
'use strict';
function createRandomSampleData() {
var rows = 10000, x, data = [], d, i, c,
var rows = 99999, x, data = [], d, i, c,
r = 'Elend, eam, animal omittam an, has in, explicari principes. Elit, causae eleifend mea cu. No sed adipisci accusata, ei mea everti melius periculis. Ei quot audire pericula mea, qui ubique offendit no. Sint mazim mandamus duo ei. Sumo maiestatis id has, at animal reprehendunt definitionem cum, mei ne adhuc theophrastus.';
c = r.split(' ');
r = r.split(',');
Expand All @@ -19,7 +19,7 @@ document.addEventListener('DOMContentLoaded', function () {
function createSampleData() {
var x,
data = [],
rows = 10000,
rows = 99999,
cols = ['Alpha', 'Beta', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', 'Indigo', 'Juliet', 'Kilo', 'Lima', 'Mike', 'November', 'Oscar', 'Pappa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform', 'Victor', 'Whiskey', 'X-Ray', 'Yak', 'Zulu'];
function addRow(col, index) {
data[x][col] = x + ':' + index;
Expand Down

0 comments on commit 7e43f2e

Please sign in to comment.