Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Revert "Group redraw performance" #3451

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 51 additions & 108 deletions lib/timeline/component/Group.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,30 +206,47 @@ Group.prototype.getLabelWidth = function() {
return this.props.label.width;
};

Group.prototype._didMarkerHeightChange = function() {

/**
* Repaint this group
* @param {{start: number, end: number}} range
* @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
* @param {boolean} [forceRestack=false] Force restacking of all items
* @return {boolean} Returns true if the group is resized
*/
Group.prototype.redraw = function(range, margin, forceRestack) {
var resized = false;

// force recalculation of the height of the items when the marker height changed
// (due to the Timeline being attached to the DOM or changed from display:none to visible)
var markerHeight = this.dom.marker.clientHeight;
if (markerHeight != this.lastMarkerHeight) {
this.lastMarkerHeight = markerHeight;
util.forEach(this.items, function (item) {
item.dirty = true;
if (item.displayed) item.redraw();
});
return true;
}
}

Group.prototype._calculateGroupSizeAndPosition = function() {
forceRestack = true;
}

// recalculate the height of the subgroups
this._calculateSubGroupHeights(margin);

// calculate actual size and position
var foreground = this.dom.foreground;
this.top = foreground.offsetTop;
this.right = foreground.offsetLeft;
this.width = foreground.offsetWidth;
}

Group.prototype._redrawItems = function(forceRestack, lastIsVisible, margin, range) {
var restack = forceRestack || this.stackDirty || this.isVisible && !lastIsVisible;
var lastIsVisible = this.isVisible;
this.isVisible = this._isGroupVisible(range, margin);

var restack = forceRestack || this.stackDirty || (this.isVisible && !lastIsVisible);

// if restacking, reposition visible items vertically
if (restack) {
this._updateSubgroupsSizes();
// if restacking, reposition visible items vertically
if(restack) {
if (typeof this.itemSet.options.order === 'function') {
// a custom order function
// brute force restack of all items
Expand All @@ -238,7 +255,7 @@ Group.prototype._redrawItems = function(forceRestack, lastIsVisible, margin, ran
var me = this;
var limitSize = false;
util.forEach(this.items, function (item) {
if (!item.displayed) {
if (!item.dom) { // If this item has never been displayed then the dom property will not be defined, this means we need to measure the size
item.redraw();
me.visibleItems.push(item);
}
Expand All @@ -251,41 +268,41 @@ Group.prototype._redrawItems = function(forceRestack, lastIsVisible, margin, ran
});
stack.stack(customOrderedItems, margin, true /* restack=true */);
this.visibleItems = this._updateItemsInRange(this.orderedItems, this.visibleItems, range);
} else {

}
else {
// no custom order function, lazy stacking
this.visibleItems = this._updateItemsInRange(this.orderedItems, this.visibleItems, range);

if (this.itemSet.options.stack) {
// TODO: ugly way to access options...
stack.stack(this.visibleItems, margin, true /* restack=true */);
} else {
// no stacking
if (this.itemSet.options.stack) { // TODO: ugly way to access options...
stack.stack(this.visibleItems, margin, true /* restack=true */);
}
else { // no stacking
stack.nostack(this.visibleItems, margin, this.subgroups, this.itemSet.options.stackSubgroups);
}
}

this.stackDirty = false;
}
}
// recalculate the height of the group
var height = this._calculateHeight(margin);

Group.prototype._didResize = function(resized, height) {
// calculate actual size and position
foreground = this.dom.foreground;
this.top = foreground.offsetTop;
this.right = foreground.offsetLeft;
this.width = foreground.offsetWidth;
resized = util.updateProperty(this, 'height', height) || resized;
// recalculate size of label
var labelWidth = this.dom.inner.clientWidth;
var labelHeight = this.dom.inner.clientHeight;
resized = util.updateProperty(this.props.label, 'width', labelWidth) || resized;
resized = util.updateProperty(this.props.label, 'height', labelHeight) || resized;
return resized;
}
resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized;
resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized;

Group.prototype._applyGroupHeight = function(height) {
this.dom.background.style.height = height + 'px';
this.dom.foreground.style.height = height + 'px';
// apply new height
this.dom.background.style.height = height + 'px';
this.dom.foreground.style.height = height + 'px';
this.dom.label.style.height = height + 'px';
}

// update vertical position of items after they are re-stacked and the height of the group is calculated
Group.prototype._updateItemsVerticalPosition = function(resized, margin) {
// update vertical position of items after they are re-stacked and the height of the group is calculated
for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
var item = this.visibleItems[i];
item.repositionY(margin);
Expand All @@ -295,84 +312,10 @@ Group.prototype._updateItemsVerticalPosition = function(resized, margin) {
}

if (!this.isVisible && this.height) {
return false;
return resized = false;
}

return resized;
}

/**
* Repaint this group
* @param {{start: number, end: number}} range
* @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
* @param {boolean} [forceRestack=false] Force restacking of all items
* @param {boolean} [returnQueue=false] return the queue or if the group resized
* @return {boolean} Returns true if the group is resized or the redraw queue if returnQueue=true
*/
Group.prototype.redraw = function(range, margin, forceRestack, returnQueue) {
var resized = false;
var lastIsVisible = this.isVisible;
var height;

var queue = [
// force recalculation of the height of the items when the marker height changed
// (due to the Timeline being attached to the DOM or changed from display:none to visible)
(function () {
forceRestack = this._didMarkerHeightChange.bind(this);
}).bind(this),

// recalculate the height of the subgroups
this._updateSubGroupHeights.bind(this, margin),

// calculate actual size and position
this._calculateGroupSizeAndPosition.bind(this),

// check if group is visible
(function() {
this.isVisible = this._isGroupVisible.bind(this)(range, margin);
}).bind(this),

// redraw Items if needed
(function() {
this._redrawItems.bind(this)(forceRestack, lastIsVisible, margin, range)
}).bind(this),

// update subgroups
this._updateSubgroupsSizes.bind(this),

// recalculate the height of the group
(function() {
height = this._calculateHeight.bind(this)(margin);
}).bind(this),

// calculate actual size and position again
this._calculateGroupSizeAndPosition.bind(this),

// check if resized
(function() {
resized = this._didResize.bind(this)(resized, height)
}).bind(this),

// apply group height
(function() {
this._applyGroupHeight.bind(this)(height)
}).bind(this),

// update vertical position of items after they are re-stacked and the height of the group is calculated
(function() {
return resized = this._updateItemsVerticalPosition.bind(this)(resized, margin)
}).bind(this)
]

if (returnQueue) {
return queue;
} else {
var result;
queue.forEach(function (fn) {
result = fn();
});
return result;
}
};

/**
Expand All @@ -381,7 +324,7 @@ Group.prototype.redraw = function(range, margin, forceRestack, returnQueue) {
* @param {{item: vis.Item}} margin
* @private
*/
Group.prototype._updateSubGroupHeights = function (margin) {
Group.prototype._calculateSubGroupHeights = function (margin) {
if (Object.keys(this.subgroups).length > 0) {
var me = this;

Expand Down
36 changes: 6 additions & 30 deletions lib/timeline/component/ItemSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -681,37 +681,13 @@ ItemSet.prototype.redraw = function() {
// redraw the background group
this.groups[BACKGROUND].redraw(range, nonFirstMargin, forceRestack);

var redrawQueue = {};
var redrawQueueLength = 0;

// collect redraw functions
util.forEach(this.groups, function (group, key) {
if (key === BACKGROUND) return;
var groupMargin = group == firstGroup ? firstMargin : nonFirstMargin;
var returnQueue = true;
redrawQueue[key] = group.redraw(range, groupMargin, forceRestack, returnQueue);
redrawQueueLength = redrawQueue[key].length;
// redraw all regular groups
util.forEach(this.groups, function (group) {
var groupMargin = (group == firstGroup) ? firstMargin : nonFirstMargin;
var groupResized = group.redraw(range, groupMargin, forceRestack);
resized = groupResized || resized;
height += group.height;
});

if (redrawQueueLength) {
var redrawResults = {};

for (var i = 0; i < redrawQueueLength; i++) {
util.forEach(redrawQueue, function (fns, key) {
redrawResults[key] = fns[i]();
});
}

// redraw all regular groups
util.forEach(this.groups, function (group, key) {
if (key === BACKGROUND) return;
var groupResized = redrawResults[key];
resized = groupResized || resized;
height += group.height;
});
height = Math.max(height, minHeight);
}

height = Math.max(height, minHeight);

// update frame height
Expand Down