diff --git a/src/timeline/component/Group.js b/src/timeline/component/Group.js index 46779a0f..7e78e5ee 100644 --- a/src/timeline/component/Group.js +++ b/src/timeline/component/Group.js @@ -24,10 +24,14 @@ function Group (contentPanel, labelPanel, groupId, options) { } }; + this.dom = {}; + this.top = 0; this.left = 0; this.width = 0; this.height = 0; + + this._create(); } Group.prototype = new Component(); @@ -35,6 +39,53 @@ Group.prototype = new Component(); // TODO: comment Group.prototype.setOptions = Component.prototype.setOptions; +/** + * Create DOM elements for the group + * @private + */ +Group.prototype._create = function() { + var label = document.createElement('div'); + label.className = 'vlabel'; + this.dom.label = label; + + var inner = document.createElement('div'); + inner.className = 'inner'; + label.appendChild(inner); + this.dom.inner = inner; +}; + +/** + * Get the HTML DOM label of this group + * @returns {Element} label + */ +Group.prototype.getLabel = function getLabel() { + return this.dom.label; +}; + +/** + * Set the group data for this group + * @param {Object} data Group data, can contain properties content and className + */ +Group.prototype.setData = function setData(data) { + // update contents + var content = data && data.content; + if (content instanceof Element) { + this.dom.inner.appendChild(content); + } + else if (content != undefined) { + this.dom.inner.innerHTML = content; + } + else { + this.dom.inner.innerHTML = this.groupId; + } + + // update className + var className = data && data.className; + if (className) { + util.addClassName(this.dom.label, className); + } +}; + /** * Set item set for the group. The group will create a view on the itemSet, * filtered by the groups id. @@ -111,21 +162,15 @@ Group.prototype.getSelection = function getSelection() { Group.prototype.repaint = function repaint() { var resized = this.itemSet.repaint(); + // TODO: top is redundant, cleanup this.top = this.itemSet ? this.itemSet.top : 0; this.height = this.itemSet ? this.itemSet.height : 0; - // TODO: reckon with the height of the group label + this.dom.label.style.height = this.height + 'px'; - if (this.label) { - // TODO: only update the labels width/height when the label is changed - var inner = this.label.firstChild; - this.props.label.width = inner.clientWidth; - this.props.label.height = inner.clientHeight; - } - else { - this.props.label.width = 0; - this.props.label.height = 0; - } + // calculate inner size of the label + resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized; + resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized; return resized; }; diff --git a/src/timeline/component/GroupSet.js b/src/timeline/component/GroupSet.js index d1981858..c720abc8 100644 --- a/src/timeline/component/GroupSet.js +++ b/src/timeline/component/GroupSet.js @@ -271,6 +271,8 @@ GroupSet.prototype.repaint = function repaint() { height: null }); + // TODO: do not recreate the group with every update + group = new Group(me.contentPanel, me.labelPanel, id, groupOptions); group.on('change', me.emit.bind(me, 'change')); // propagate change event group.setRange(me.range); @@ -282,8 +284,8 @@ GroupSet.prototype.repaint = function repaint() { // as this call will already trigger a repaint } - // TODO: update group data - group.data = groupsData.get(id); + // update group data + group.setData(groupsData.get(id)); break; case 'remove': @@ -311,7 +313,7 @@ GroupSet.prototype.repaint = function repaint() { } for (i = 0; i < this.groupIds.length; i++) { id = this.groupIds[i]; - label = this._createLabel(id); + label = this.groups[id].getLabel(); labelSet.frame.appendChild(label); } @@ -338,19 +340,10 @@ GroupSet.prototype.repaint = function repaint() { for (id in groups) { if (groups.hasOwnProperty(id)) { group = groups[id]; - label = group.label; - if (label) { - label.style.height = group.height + 'px'; - - console.log('label height groupId=', id, ' height', group.height) - - var width = label.firstChild && label.firstChild.clientWidth || 0; - maxWidth = Math.max(maxWidth, width); - } + maxWidth = Math.max(maxWidth, group.props.label.width); } } - if (this.props.labels.width != maxWidth) resized = true; - this.props.labels.width = maxWidth; + resized = util.updateProperty(this.props.labels, 'width', maxWidth) || resized; // recalculate the height of the groupset var fixedHeight = (asSize(options.height) != null); @@ -384,43 +377,9 @@ GroupSet.prototype.repaint = function repaint() { this.width = groupSet.offsetWidth; this.height = height; - console.log('groupset.repaint resized=', resized) - return resized; }; -/** - * Create a label for group with given id - * @param {Number} id - * @return {Element} label - * @private - */ -GroupSet.prototype._createLabel = function(id) { - var group = this.groups[id]; - var label = document.createElement('div'); - label.className = 'vlabel'; - var inner = document.createElement('div'); - inner.className = 'inner'; - label.appendChild(inner); - - var content = group.data && group.data.content; - if (content instanceof Element) { - inner.appendChild(content); - } - else if (content != undefined) { - inner.innerHTML = content; - } - - var className = group.data && group.data.className; - if (className) { - util.addClassName(label, className); - } - - group.label = label; // TODO: not so nice, parking labels in the group this way!!! - - return label; -}; - /** * Get the width of the group labels * @return {Number} width diff --git a/src/util.js b/src/util.js index 46bbb8b9..788cea5e 100644 --- a/src/util.js +++ b/src/util.js @@ -463,7 +463,7 @@ util.toArray = function toArray(object) { * @param {*} value * @return {Boolean} changed */ -util.updateProperty = function updateProp (object, key, value) { +util.updateProperty = function updateProperty (object, key, value) { if (object[key] !== value) { object[key] = value; return true;