Browse Source

Smarter check whether data changed when redrawing items. (See also #290)

v3_develop
jos 10 years ago
parent
commit
b7a67920d5
8 changed files with 8915 additions and 8895 deletions
  1. +8795
    -8771
      dist/vis.js
  2. +1
    -1
      dist/vis.map
  3. +10
    -10
      dist/vis.min.js
  4. +2
    -4
      lib/timeline/component/ItemSet.js
  5. +57
    -11
      lib/timeline/component/item/Item.js
  6. +17
    -34
      lib/timeline/component/item/ItemBox.js
  7. +17
    -32
      lib/timeline/component/item/ItemPoint.js
  8. +16
    -32
      lib/timeline/component/item/ItemRange.js

+ 8795
- 8771
dist/vis.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/vis.map
File diff suppressed because it is too large
View File


+ 10
- 10
dist/vis.min.js
File diff suppressed because it is too large
View File


+ 2
- 4
lib/timeline/component/ItemSet.js View File

@ -949,10 +949,8 @@ ItemSet.prototype._addItem = function(item) {
ItemSet.prototype._updateItem = function(item, itemData) { ItemSet.prototype._updateItem = function(item, itemData) {
var oldGroupId = item.data.group; var oldGroupId = item.data.group;
item.data = itemData;
if (item.displayed) {
item.redraw();
}
// update the items data (will redraw the item when displayed)
item.setData(itemData);
// update group // update group
if (oldGroupId != item.data.group) { if (oldGroupId != item.data.group) {

+ 57
- 11
lib/timeline/component/item/Item.js View File

@ -32,6 +32,7 @@ function Item (data, conversion, options) {
*/ */
Item.prototype.select = function() { Item.prototype.select = function() {
this.selected = true; this.selected = true;
this.dirty = true;
if (this.displayed) this.redraw(); if (this.displayed) this.redraw();
}; };
@ -40,6 +41,18 @@ Item.prototype.select = function() {
*/ */
Item.prototype.unselect = function() { Item.prototype.unselect = function() {
this.selected = false; this.selected = false;
this.dirty = true;
if (this.displayed) this.redraw();
};
/**
* Set data for the item. Existing data will be updated. The id should not
* be changed. When the item is displayed, it will be redrawn immediately.
* @param {Object} data
*/
Item.prototype.setData = function(data) {
this.data = data;
this.dirty = true;
if (this.displayed) this.redraw(); if (this.displayed) this.redraw();
}; };
@ -140,24 +153,57 @@ Item.prototype._repaintDeleteButton = function (anchor) {
} }
}; };
/**
* Set HTML contents for the item
* @param {Element} element HTML element to fill with the contents
* @private
*/
Item.prototype._updateContents = function (element) {
if (this.data.content instanceof Element) {
element.innerHTML = '';
element.appendChild(this.data.content);
}
else if (this.data.content != undefined) {
element.innerHTML = this.data.content;
}
else {
throw new Error('Property "content" missing in item ' + this.data.id);
}
};
/**
* Set HTML contents for the item
* @param {Element} element HTML element to fill with the contents
* @private
*/
Item.prototype._updateTitle = function (element) {
if (this.data.title != null) {
element.title = this.data.title || '';
}
else {
element.removeAttribute('title');
}
};
/** /**
* Process dataAttributes timeline option and set as data- attributes on dom.content * Process dataAttributes timeline option and set as data- attributes on dom.content
* @param {Element} element HTML element to which the attributes will be attached
* @private
*/ */
Item.prototype._attachDataAttributes = function() {
Item.prototype._updateDataAttributes = function(element) {
if (this.options.dataAttributes && this.options.dataAttributes.length > 0) { if (this.options.dataAttributes && this.options.dataAttributes.length > 0) {
var auxiliaryData = Object.keys(this.data);
for (var i = 0; i < this.options.dataAttributes.length; i++) {
var name = this.options.dataAttributes[i];
var value = this.data[name];
for (var i in this.options.dataAttributes) {
var c = this.options.dataAttributes[i];
if (auxiliaryData.indexOf(c) >= 0) {
this.dom.content.setAttribute('data-' + c, this.data[c]);
if (value != null) {
element.setAttribute('data-' + name, value);
}
else {
element.removeAttribute('data-' + name);
} }
} }
} }
};
};
module.exports = Item; module.exports = Item;

+ 17
- 34
lib/timeline/component/item/ItemBox.js View File

@ -74,6 +74,8 @@ ItemBox.prototype.redraw = function() {
// attach this item as attribute // attach this item as attribute
dom.box['timeline-item'] = this; dom.box['timeline-item'] = this;
this.dirty = true;
} }
// append DOM to parent DOM // append DOM to parent DOM
@ -97,47 +99,28 @@ ItemBox.prototype.redraw = function() {
} }
this.displayed = true; this.displayed = true;
// update contents
if (this.data.content != this.content) {
this.content = this.data.content;
if (this.content instanceof Element) {
dom.content.innerHTML = '';
dom.content.appendChild(this.content);
}
else if (this.data.content != undefined) {
dom.content.innerHTML = this.content;
}
else {
throw new Error('Property "content" missing in item ' + this.data.id);
}
this.dirty = true;
}
// Update DOM when item is marked dirty. An item is marked dirty when:
// - the item is not yet rendered
// - the item's data is changed
// - the item is selected/deselected
if (this.dirty) {
// update contents
this._updateContents(this.dom.content);
// update title
if (this.data.title != this.title) {
dom.box.title = this.data.title;
this.title = this.data.title;
}
// update title
this._updateTitle(this.dom.box);
// update class
var className = (this.data.className? ' ' + this.data.className : '') +
(this.selected ? ' selected' : '');
if (this.className != className) {
this.className = className;
// update class
var className = (this.data.className? ' ' + this.data.className : '') +
(this.selected ? ' selected' : '');
dom.box.className = 'item box' + className; dom.box.className = 'item box' + className;
dom.line.className = 'item line' + className; dom.line.className = 'item line' + className;
dom.dot.className = 'item dot' + className; dom.dot.className = 'item dot' + className;
this.dirty = true;
}
this._attachDataAttributes();
// update data attributes
this._updateDataAttributes(this.dom.box);
// recalculate size
if (this.dirty) {
// recalculate size
this.props.dot.height = dom.dot.offsetHeight; this.props.dot.height = dom.dot.offsetHeight;
this.props.dot.width = dom.dot.offsetWidth; this.props.dot.width = dom.dot.offsetWidth;
this.props.line.width = dom.line.offsetWidth; this.props.line.width = dom.line.offsetWidth;

+ 17
- 32
lib/timeline/component/item/ItemPoint.js View File

@ -72,6 +72,8 @@ ItemPoint.prototype.redraw = function() {
// attach this item as attribute // attach this item as attribute
dom.point['timeline-item'] = this; dom.point['timeline-item'] = this;
this.dirty = true;
} }
// append DOM to parent DOM // append DOM to parent DOM
@ -87,44 +89,27 @@ ItemPoint.prototype.redraw = function() {
} }
this.displayed = true; this.displayed = true;
// update contents
if (this.data.content != this.content) {
this.content = this.data.content;
if (this.content instanceof Element) {
dom.content.innerHTML = '';
dom.content.appendChild(this.content);
}
else if (this.data.content != undefined) {
dom.content.innerHTML = this.content;
}
else {
throw new Error('Property "content" missing in item ' + this.data.id);
}
this.dirty = true;
}
// Update DOM when item is marked dirty. An item is marked dirty when:
// - the item is not yet rendered
// - the item's data is changed
// - the item is selected/deselected
if (this.dirty) {
// update contents
this._updateContents(this.dom.content);
// update title
if (this.data.title != this.title) {
dom.point.title = this.data.title;
this.title = this.data.title;
}
// update title
this._updateTitle(this.dom.point);
// update class
var className = (this.data.className? ' ' + this.data.className : '') +
(this.selected ? ' selected' : '');
if (this.className != className) {
this.className = className;
// update class
var className = (this.data.className? ' ' + this.data.className : '') +
(this.selected ? ' selected' : '');
dom.point.className = 'item point' + className; dom.point.className = 'item point' + className;
dom.dot.className = 'item dot' + className; dom.dot.className = 'item dot' + className;
this.dirty = true;
}
this._attachDataAttributes();
// attach HTML attributes
this._updateDataAttributes(this.dom.point);
// recalculate size
if (this.dirty) {
// recalculate size
this.width = dom.point.offsetWidth; this.width = dom.point.offsetWidth;
this.height = dom.point.offsetHeight; this.height = dom.point.offsetHeight;
this.props.dot.width = dom.dot.offsetWidth; this.props.dot.width = dom.dot.offsetWidth;

+ 16
- 32
lib/timeline/component/item/ItemRange.js View File

@ -67,6 +67,8 @@ ItemRange.prototype.redraw = function() {
// attach this item as attribute // attach this item as attribute
dom.box['timeline-item'] = this; dom.box['timeline-item'] = this;
this.dirty = true;
} }
// append DOM to parent DOM // append DOM to parent DOM
@ -82,46 +84,28 @@ ItemRange.prototype.redraw = function() {
} }
this.displayed = true; this.displayed = true;
// update contents
if (this.data.content != this.content) {
this.content = this.data.content;
if (this.content instanceof Element) {
dom.content.innerHTML = '';
dom.content.appendChild(this.content);
}
else if (this.data.content != undefined) {
dom.content.innerHTML = this.content;
}
else {
throw new Error('Property "content" missing in item ' + this.data.id);
}
this.dirty = true;
}
// Update DOM when item is marked dirty. An item is marked dirty when:
// - the item is not yet rendered
// - the item's data is changed
// - the item is selected/deselected
if (this.dirty) {
// update contents
this._updateContents(this.dom.content);
// update title
if (this.data.title != this.title) {
dom.box.title = this.data.title;
this.title = this.data.title;
}
// update title
this._updateTitle(this.dom.box);
// update class
var className = (this.data.className ? (' ' + this.data.className) : '') +
(this.selected ? ' selected' : '');
if (this.className != className) {
this.className = className;
// update class
var className = (this.data.className ? (' ' + this.data.className) : '') +
(this.selected ? ' selected' : '');
dom.box.className = this.baseClassName + className; dom.box.className = this.baseClassName + className;
this.dirty = true;
}
this._attachDataAttributes();
this._updateDataAttributes(this.dom.box);
// recalculate size
if (this.dirty) {
// determine from css whether this box has overflow // determine from css whether this box has overflow
this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden';
// recalculate size
this.props.content.width = this.dom.content.offsetWidth; this.props.content.width = this.dom.content.offsetWidth;
this.height = this.dom.box.offsetHeight; this.height = this.dom.box.offsetHeight;

Loading…
Cancel
Save