Browse Source

表格滚动性能优化

es6
guy 7 years ago
parent
commit
3c9175eb65
  1. 95
      bi/base.js
  2. 23
      bi/core.js
  3. 95
      docs/base.js
  4. 23
      docs/core.js
  5. 67
      src/base/collection/collection.js
  6. 28
      src/base/grid/grid.js
  7. 23
      src/core/base.js

95
bi/base.js

@ -2539,6 +2539,7 @@ BI.Collection = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -2588,12 +2589,10 @@ BI.Collection = BI.inherit(BI.Widget, {
for (var index = 0, len = o.items.length; index < len; index++) {
var cellMetadatum = o.cellSizeAndPositionGetter(index);
if (
cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
if (cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
cellMetadatum.width == null || isNaN(cellMetadatum.width) ||
cellMetadatum.x == null || isNaN(cellMetadatum.x) ||
cellMetadatum.y == null || isNaN(cellMetadatum.y)
) {
cellMetadatum.y == null || isNaN(cellMetadatum.y)) {
throw Error();
}
@ -2634,8 +2633,38 @@ BI.Collection = BI.inherit(BI.Widget, {
var top = Math.max(0, scrollTop - o.verticalOverscanSize);
var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize);
var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize);
if (right > 0 && bottom > 0) {
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
var renderedCells = [], renderedKeys = [];
//存储所有的left和top
var lefts = {}, tops = {};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
lefts[datum.x] = datum.x;
lefts[datum.x + datum.width] = datum.x + datum.width;
tops[datum.y] = datum.y;
tops[datum.y + datum.height] = datum.y + datum.height;
}
lefts = BI.toArray(lefts);
tops = BI.toArray(tops);
var leftMap = BI.invert(lefts);
var topMap = BI.invert(tops);
//存储上下左右四个边界
var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {};
var assertMinBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = Number.MAX_VALUE;
}
};
var assertMaxBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = 0;
}
};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
var index = BI.deepIndexOf(this.renderedKeys, datum.index);
@ -2673,6 +2702,25 @@ BI.Collection = BI.inherit(BI.Widget, {
_height: datum.height
});
}
var startTopIndex = topMap[datum.y] | 0;
var endTopIndex = topMap[datum.y + datum.height] | 0;
for (var k = startTopIndex; k <= endTopIndex; k++) {
var t = tops[k];
assertMinBorder(leftBorder, t);
assertMaxBorder(rightBorder, t);
leftBorder[t] = Math.min(leftBorder[t], datum.x);
rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width);
}
var startLeftIndex = leftMap[datum.x] | 0;
var endLeftIndex = leftMap[datum.x + datum.width] | 0;
for (var k = startLeftIndex; k <= endLeftIndex; k++) {
var l = lefts[k];
assertMinBorder(topBorder, l);
assertMaxBorder(bottomBorder, l);
topBorder[l] = Math.min(topBorder[l], datum.y);
bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height);
}
renderedKeys.push(datum.index);
}
//已存在的, 需要添加的和需要删除的
@ -2703,6 +2751,16 @@ BI.Collection = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
//Todo 左右比较特殊
var minX = BI.min(leftBorder);
var maxX = BI.max(rightBorder);
var minY = BI.max(topBorder);
var maxY = BI.min(bottomBorder);
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},
_getMaxScrollLeft: function () {
@ -2789,6 +2847,7 @@ BI.Collection = BI.inherit(BI.Widget, {
});
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
},
@ -14613,6 +14672,7 @@ BI.Grid = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -14661,13 +14721,17 @@ BI.Grid = BI.inherit(BI.Widget, {
_calculateChildrenToRender: function () {
var self = this, o = this.options;
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount;
if (height > 0 && width > 0) {
var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
if (BI.isEmpty(visibleColumnIndices) || BI.isEmpty(visibleRowIndices)) {
return;
}
var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft);
var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
@ -14685,8 +14749,22 @@ BI.Grid = BI.inherit(BI.Widget, {
var rowStartIndex = overscanRowIndices.overscanStartIndex;
var rowStopIndex = overscanRowIndices.overscanStopIndex;
var renderedCells = [], renderedKeys = [];
//算区间size
var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex);
var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex);
var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex);
var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex);
var top = minRowDatum.offset + verticalOffsetAdjustment;
var left = minColumnDatum.offset + horizontalOffsetAdjustment;
var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size;
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var renderedCells = [], renderedKeys = [];
var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0;
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
@ -14731,6 +14809,10 @@ BI.Grid = BI.inherit(BI.Widget, {
_height: rowDatum.size
});
}
minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment);
maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size);
minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment);
maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size);
renderedKeys.push(key);
}
}
@ -14762,6 +14844,7 @@ BI.Grid = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},

23
bi/core.js

@ -2163,6 +2163,29 @@ if (!window.BI) {
return true;
},
backFindKey: function (obj, predicate, context) {
predicate = BI.iteratee(predicate, context);
var keys = _.keys(obj), key;
for (var i = keys.length - 1; i >= 0; i--) {
key = keys[i];
if (predicate(obj[key], key, obj)) {
return key;
}
}
},
backFind: function (obj, predicate, context) {
var key;
if (BI.isArray(obj)) {
key = BI.findLastIndex(obj, predicate, context);
} else {
key = BI.backFindKey(obj, predicate, context);
}
if (key !== void 0 && key !== -1) {
return obj[key];
}
},
remove: function (obj, target, context) {
var isFunction = BI.isFunction(target);
target = isFunction || BI.isArray(target) ? target : [target];

95
docs/base.js

@ -2539,6 +2539,7 @@ BI.Collection = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -2588,12 +2589,10 @@ BI.Collection = BI.inherit(BI.Widget, {
for (var index = 0, len = o.items.length; index < len; index++) {
var cellMetadatum = o.cellSizeAndPositionGetter(index);
if (
cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
if (cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
cellMetadatum.width == null || isNaN(cellMetadatum.width) ||
cellMetadatum.x == null || isNaN(cellMetadatum.x) ||
cellMetadatum.y == null || isNaN(cellMetadatum.y)
) {
cellMetadatum.y == null || isNaN(cellMetadatum.y)) {
throw Error();
}
@ -2634,8 +2633,38 @@ BI.Collection = BI.inherit(BI.Widget, {
var top = Math.max(0, scrollTop - o.verticalOverscanSize);
var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize);
var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize);
if (right > 0 && bottom > 0) {
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
var renderedCells = [], renderedKeys = [];
//存储所有的left和top
var lefts = {}, tops = {};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
lefts[datum.x] = datum.x;
lefts[datum.x + datum.width] = datum.x + datum.width;
tops[datum.y] = datum.y;
tops[datum.y + datum.height] = datum.y + datum.height;
}
lefts = BI.toArray(lefts);
tops = BI.toArray(tops);
var leftMap = BI.invert(lefts);
var topMap = BI.invert(tops);
//存储上下左右四个边界
var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {};
var assertMinBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = Number.MAX_VALUE;
}
};
var assertMaxBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = 0;
}
};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
var index = BI.deepIndexOf(this.renderedKeys, datum.index);
@ -2673,6 +2702,25 @@ BI.Collection = BI.inherit(BI.Widget, {
_height: datum.height
});
}
var startTopIndex = topMap[datum.y] | 0;
var endTopIndex = topMap[datum.y + datum.height] | 0;
for (var k = startTopIndex; k <= endTopIndex; k++) {
var t = tops[k];
assertMinBorder(leftBorder, t);
assertMaxBorder(rightBorder, t);
leftBorder[t] = Math.min(leftBorder[t], datum.x);
rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width);
}
var startLeftIndex = leftMap[datum.x] | 0;
var endLeftIndex = leftMap[datum.x + datum.width] | 0;
for (var k = startLeftIndex; k <= endLeftIndex; k++) {
var l = lefts[k];
assertMinBorder(topBorder, l);
assertMaxBorder(bottomBorder, l);
topBorder[l] = Math.min(topBorder[l], datum.y);
bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height);
}
renderedKeys.push(datum.index);
}
//已存在的, 需要添加的和需要删除的
@ -2703,6 +2751,16 @@ BI.Collection = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
//Todo 左右比较特殊
var minX = BI.min(leftBorder);
var maxX = BI.max(rightBorder);
var minY = BI.max(topBorder);
var maxY = BI.min(bottomBorder);
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},
_getMaxScrollLeft: function () {
@ -2789,6 +2847,7 @@ BI.Collection = BI.inherit(BI.Widget, {
});
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
},
@ -14613,6 +14672,7 @@ BI.Grid = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -14661,13 +14721,17 @@ BI.Grid = BI.inherit(BI.Widget, {
_calculateChildrenToRender: function () {
var self = this, o = this.options;
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount;
if (height > 0 && width > 0) {
var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
if (BI.isEmpty(visibleColumnIndices) || BI.isEmpty(visibleRowIndices)) {
return;
}
var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft);
var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
@ -14685,8 +14749,22 @@ BI.Grid = BI.inherit(BI.Widget, {
var rowStartIndex = overscanRowIndices.overscanStartIndex;
var rowStopIndex = overscanRowIndices.overscanStopIndex;
var renderedCells = [], renderedKeys = [];
//算区间size
var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex);
var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex);
var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex);
var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex);
var top = minRowDatum.offset + verticalOffsetAdjustment;
var left = minColumnDatum.offset + horizontalOffsetAdjustment;
var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size;
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var renderedCells = [], renderedKeys = [];
var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0;
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
@ -14731,6 +14809,10 @@ BI.Grid = BI.inherit(BI.Widget, {
_height: rowDatum.size
});
}
minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment);
maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size);
minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment);
maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size);
renderedKeys.push(key);
}
}
@ -14762,6 +14844,7 @@ BI.Grid = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},

23
docs/core.js

@ -13305,6 +13305,29 @@ if (!window.BI) {
return true;
},
backFindKey: function (obj, predicate, context) {
predicate = BI.iteratee(predicate, context);
var keys = _.keys(obj), key;
for (var i = keys.length - 1; i >= 0; i--) {
key = keys[i];
if (predicate(obj[key], key, obj)) {
return key;
}
}
},
backFind: function (obj, predicate, context) {
var key;
if (BI.isArray(obj)) {
key = BI.findLastIndex(obj, predicate, context);
} else {
key = BI.backFindKey(obj, predicate, context);
}
if (key !== void 0 && key !== -1) {
return obj[key];
}
},
remove: function (obj, target, context) {
var isFunction = BI.isFunction(target);
target = isFunction || BI.isArray(target) ? target : [target];

67
src/base/collection/collection.js

@ -27,6 +27,7 @@ BI.Collection = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -76,12 +77,10 @@ BI.Collection = BI.inherit(BI.Widget, {
for (var index = 0, len = o.items.length; index < len; index++) {
var cellMetadatum = o.cellSizeAndPositionGetter(index);
if (
cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
if (cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
cellMetadatum.width == null || isNaN(cellMetadatum.width) ||
cellMetadatum.x == null || isNaN(cellMetadatum.x) ||
cellMetadatum.y == null || isNaN(cellMetadatum.y)
) {
cellMetadatum.y == null || isNaN(cellMetadatum.y)) {
throw Error();
}
@ -122,8 +121,38 @@ BI.Collection = BI.inherit(BI.Widget, {
var top = Math.max(0, scrollTop - o.verticalOverscanSize);
var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize);
var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize);
if (right > 0 && bottom > 0) {
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
var renderedCells = [], renderedKeys = [];
//存储所有的left和top
var lefts = {}, tops = {};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
lefts[datum.x] = datum.x;
lefts[datum.x + datum.width] = datum.x + datum.width;
tops[datum.y] = datum.y;
tops[datum.y + datum.height] = datum.y + datum.height;
}
lefts = BI.toArray(lefts);
tops = BI.toArray(tops);
var leftMap = BI.invert(lefts);
var topMap = BI.invert(tops);
//存储上下左右四个边界
var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {};
var assertMinBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = Number.MAX_VALUE;
}
};
var assertMaxBorder = function (border, offset) {
if (border[offset] == null) {
border[offset] = 0;
}
};
for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
var datum = childrenToDisplay[i];
var index = BI.deepIndexOf(this.renderedKeys, datum.index);
@ -161,6 +190,25 @@ BI.Collection = BI.inherit(BI.Widget, {
_height: datum.height
});
}
var startTopIndex = topMap[datum.y] | 0;
var endTopIndex = topMap[datum.y + datum.height] | 0;
for (var k = startTopIndex; k <= endTopIndex; k++) {
var t = tops[k];
assertMinBorder(leftBorder, t);
assertMaxBorder(rightBorder, t);
leftBorder[t] = Math.min(leftBorder[t], datum.x);
rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width);
}
var startLeftIndex = leftMap[datum.x] | 0;
var endLeftIndex = leftMap[datum.x + datum.width] | 0;
for (var k = startLeftIndex; k <= endLeftIndex; k++) {
var l = lefts[k];
assertMinBorder(topBorder, l);
assertMaxBorder(bottomBorder, l);
topBorder[l] = Math.min(topBorder[l], datum.y);
bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height);
}
renderedKeys.push(datum.index);
}
//已存在的, 需要添加的和需要删除的
@ -191,6 +239,16 @@ BI.Collection = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
//Todo 左右比较特殊
var minX = BI.min(leftBorder);
var maxX = BI.max(rightBorder);
var minY = BI.max(topBorder);
var maxY = BI.min(bottomBorder);
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},
_getMaxScrollLeft: function () {
@ -277,6 +335,7 @@ BI.Collection = BI.inherit(BI.Widget, {
});
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
},

28
src/base/grid/grid.js

@ -30,6 +30,7 @@ BI.Grid = BI.inherit(BI.Widget, {
var self = this, o = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
@ -78,13 +79,17 @@ BI.Grid = BI.inherit(BI.Widget, {
_calculateChildrenToRender: function () {
var self = this, o = this.options;
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()), scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount;
if (height > 0 && width > 0) {
var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
if (BI.isEmpty(visibleColumnIndices) || BI.isEmpty(visibleRowIndices)) {
return;
}
var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft);
var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
@ -102,8 +107,22 @@ BI.Grid = BI.inherit(BI.Widget, {
var rowStartIndex = overscanRowIndices.overscanStartIndex;
var rowStopIndex = overscanRowIndices.overscanStopIndex;
var renderedCells = [], renderedKeys = [];
//算区间size
var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex);
var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex);
var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex);
var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex);
var top = minRowDatum.offset + verticalOffsetAdjustment;
var left = minColumnDatum.offset + horizontalOffsetAdjustment;
var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size;
//如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var renderedCells = [], renderedKeys = [];
var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0;
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
@ -148,6 +167,10 @@ BI.Grid = BI.inherit(BI.Widget, {
_height: rowDatum.size
});
}
minX = Math.min(minX, columnDatum.offset + horizontalOffsetAdjustment);
maxX = Math.max(maxX, columnDatum.offset + horizontalOffsetAdjustment + columnDatum.size);
minY = Math.min(minY, rowDatum.offset + verticalOffsetAdjustment);
maxY = Math.max(maxY, rowDatum.offset + verticalOffsetAdjustment + rowDatum.size);
renderedKeys.push(key);
}
}
@ -179,6 +202,7 @@ BI.Grid = BI.inherit(BI.Widget, {
this.container.addItems(addedItems);
this.renderedCells = renderedCells;
this.renderedKeys = renderedKeys;
this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
}
},

23
src/core/base.js

@ -268,6 +268,29 @@ if (!window.BI) {
return true;
},
backFindKey: function (obj, predicate, context) {
predicate = BI.iteratee(predicate, context);
var keys = _.keys(obj), key;
for (var i = keys.length - 1; i >= 0; i--) {
key = keys[i];
if (predicate(obj[key], key, obj)) {
return key;
}
}
},
backFind: function (obj, predicate, context) {
var key;
if (BI.isArray(obj)) {
key = BI.findLastIndex(obj, predicate, context);
} else {
key = BI.backFindKey(obj, predicate, context);
}
if (key !== void 0 && key !== -1) {
return obj[key];
}
},
remove: function (obj, target, context) {
var isFunction = BI.isFunction(target);
target = isFunction || BI.isArray(target) ? target : [target];

Loading…
Cancel
Save