diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js index 9f550a07..b8bd86c4 100644 --- a/src/timeline/Timeline.js +++ b/src/timeline/Timeline.js @@ -344,6 +344,7 @@ Timeline.prototype.setGroups = function(groups) { this.itemSet.hide(); // TODO: not so nice having to hide here this.contentPanel.removeChild(this.itemSet); this.itemSet.setItems(); // disconnect from items + this.itemSet = null; } // create new GroupSet @@ -359,6 +360,7 @@ Timeline.prototype.setGroups = function(groups) { this.groupSet.hide(); // TODO: not so nice having to hide here this.contentPanel.removeChild(this.groupSet); this.groupSet.setItems(); // disconnect from items + this.groupSet = null; } // create new items diff --git a/src/timeline/component/Group.js b/src/timeline/component/Group.js index 16637887..87c3029b 100644 --- a/src/timeline/component/Group.js +++ b/src/timeline/component/Group.js @@ -1,17 +1,19 @@ /** * @constructor Group - * @param {GroupSet} parent + * @param {Panel} contentPanel + * @param {Panel} labelPanel * @param {Number | String} groupId * @param {Object} [options] Options to set initial property values * // TODO: describe available options * @extends Component */ -function Group (parent, groupId, options) { +function Group (contentPanel, labelPanel, groupId, options) { this.id = util.randomUUID(); - this.parent = parent; + this.contentPanel = contentPanel; + this.labelPanel = labelPanel; this.groupId = groupId; - this.itemset = null; // ItemSet + this.itemSet = null; // ItemSet this.options = options || {}; this.options.top = 0; @@ -39,42 +41,50 @@ Group.prototype.setOptions = Component.prototype.setOptions; * @returns {HTMLElement} container */ Group.prototype.getContainer = function () { - return this.parent.getContainer(); + return null; }; /** - * Set item set for the group. The group will create a view on the itemset, + * Set item set for the group. The group will create a view on the itemSet, * filtered by the groups id. * @param {DataSet | DataView} items */ Group.prototype.setItems = function setItems(items) { - if (this.itemset) { + if (this.itemSet) { // remove current item set - this.itemset.hide(); - this.itemset.setItems(); - - this.parent.controller.remove(this.itemset); - this.itemset = null; + this.itemSet.hide(); + this.itemSet.setItems(); + this.contentPanel.removeChild(this.itemSet); + this.itemSet = null; } if (items) { var groupId = this.groupId; - var itemsetOptions = Object.create(this.options); - this.itemset = new ItemSet(this, null, itemsetOptions); - this.itemset.setRange(this.parent.range); + var itemSetOptions = Object.create(this.options); + this.itemSet = new ItemSet(itemSetOptions); + if (this.range) this.itemSet.setRange(this.range); + this.contentPanel.appendChild(this.itemSet); this.view = new DataView(items, { filter: function (item) { return item.group == groupId; } }); - this.itemset.setItems(this.view); - - this.parent.controller.add(this.itemset); + this.itemSet.setItems(this.view); } }; +/** + * Set range (start and end). + * @param {Range | Object} range A Range or an object containing start and end. + */ +Group.prototype.setRange = function (range) { + this.range = range; + + if (this.itemSet) this.itemSet.setRange(range); +}; + /** * Set selected items by their id. Replaces the current selection. * Unknown id's are silently ignored. @@ -83,7 +93,7 @@ Group.prototype.setItems = function setItems(items) { * unselected. */ Group.prototype.setSelection = function setSelection(ids) { - if (this.itemset) this.itemset.setSelection(ids); + if (this.itemSet) this.itemSet.setSelection(ids); }; /** @@ -91,7 +101,7 @@ Group.prototype.setSelection = function setSelection(ids) { * @return {Array} ids The ids of the selected items */ Group.prototype.getSelection = function getSelection() { - return this.itemset ? this.itemset.getSelection() : []; + return this.itemSet ? this.itemSet.getSelection() : []; }; /** @@ -99,8 +109,10 @@ Group.prototype.getSelection = function getSelection() { * @return {Boolean} changed */ Group.prototype.repaint = function repaint() { - this.top = this.itemset ? this.itemset.top : 0; - this.height = this.itemset ? this.itemset.height : 0; + this.itemSet.repaint(); + + 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 diff --git a/src/timeline/component/GroupSet.js b/src/timeline/component/GroupSet.js index bad77463..bfbaf904 100644 --- a/src/timeline/component/GroupSet.js +++ b/src/timeline/component/GroupSet.js @@ -1,18 +1,15 @@ /** * An GroupSet holds a set of groups - * @param {Component} parent - * @param {Component[]} [depends] Components on which this components depends - * (except for the parent) + * @param {Panel} labelPanel * @param {Object} [options] See GroupSet.setOptions for the available * options. * @constructor GroupSet * @extends Panel */ -function GroupSet(parent, depends, options) { +function GroupSet(labelPanel, options) { this.id = util.randomUUID(); - this.parent = parent; - this.depends = depends; + this.labelPanel = labelPanel; this.options = options || {}; this.range = null; // Range or Object {start: number, end: number} @@ -57,8 +54,18 @@ GroupSet.prototype = new Panel(); */ GroupSet.prototype.setOptions = Component.prototype.setOptions; +/** + * Set range (start and end). + * @param {Range | Object} range A Range or an object containing start and end. + */ GroupSet.prototype.setRange = function (range) { - // TODO: implement setRange + this.range = range; + + for (var id in this.groups) { + if (this.groups.hasOwnProperty(id)) { + this.groups[id].setRange(range); + } + } }; /** @@ -212,15 +219,16 @@ GroupSet.prototype.repaint = function repaint() { frame['timeline-groupset'] = this; this.dom.frame = frame; - if (!this.parent) throw new Error('Cannot repaint groupset: no parent attached'); + if (!this.parent) throw new Error('Cannot repaint GroupSet: no parent attached'); var parentContainer = this.parent.getContainer(); - if (!parentContainer) throw new Error('Cannot repaint groupset: parent has no container element'); + if (!parentContainer) throw new Error('Cannot repaint GroupSet: parent has no container element'); parentContainer.appendChild(frame); } // update classname frame.className = 'groupset' + (options.className ? (' ' + asString(options.className)) : ''); + /* TODO: labels // create labels var labelContainer = asElement(options.labelContainer); if (!labelContainer) { @@ -243,6 +251,7 @@ GroupSet.prototype.repaint = function repaint() { } labelContainer.appendChild(labels); } + */ var me = this, queue = this.queue, @@ -266,11 +275,10 @@ GroupSet.prototype.repaint = function repaint() { height: null }); - group = new Group(me, id, groupOptions); + group = new Group(me, me.labelPanel, id, groupOptions); + group.setRange(me.range); group.setItems(me.itemsData); // attach items data groups[id] = group; - - me.controller.add(group); } // TODO: update group data @@ -283,8 +291,6 @@ GroupSet.prototype.repaint = function repaint() { if (group) { group.setItems(); // detach items data delete groups[id]; - - me.controller.remove(group); } // update lists @@ -308,7 +314,6 @@ GroupSet.prototype.repaint = function repaint() { var top = 0; if (prevGroup) { top = function () { - // TODO: top must reckon with options.maxHeight return prevGroup.top + prevGroup.height; } } @@ -318,6 +323,7 @@ GroupSet.prototype.repaint = function repaint() { })(groups[orderedGroups[i]], groups[orderedGroups[i - 1]]); } + /* TODO // (re)create the labels while (labelSet.firstChild) { labelSet.removeChild(labelSet.firstChild); @@ -327,6 +333,14 @@ GroupSet.prototype.repaint = function repaint() { label = this._createLabel(id); labelSet.appendChild(label); } + */ + } + + // repaint all groups + for (id in groups) { + if (groups.hasOwnProperty(id)) { + group = groups[id].repaint(); + } } // reposition the labels and calculate the maximum label width @@ -346,7 +360,7 @@ GroupSet.prototype.repaint = function repaint() { } } } - this.props.labels.width = maxWidth; // TODO: force redraw when width is changed? + this.props.labels.width = maxWidth; // recalculate the height of the groupset var fixedHeight = (asSize(options.height) != null); @@ -364,7 +378,7 @@ GroupSet.prototype.repaint = function repaint() { } // reposition frame - frame.style.height = fixedHeight ? asSize(options.height) : this.height + 'px'; + frame.style.height = asSize((options.height != null) ? options.height : height); frame.style.top = asSize(options.top, '0'); frame.style.left = asSize(options.left, '0'); frame.style.width = asSize(options.width, '100%'); @@ -373,11 +387,13 @@ GroupSet.prototype.repaint = function repaint() { this.top = frame.offsetTop; this.left = frame.offsetLeft; this.width = frame.offsetWidth; - this.height = fixedHeight ? frame.offsetHeight : height; + this.height = frame.offsetHeight; + /* TODO // reposition labels labelSet.style.top = asSize(options.top, '0'); labelSet.style.height = fixedHeight ? asSize(options.height) : this.height + 'px'; + */ }; /** diff --git a/src/timeline/component/ItemSet.js b/src/timeline/component/ItemSet.js index 9cf2dbcf..4aaedd44 100644 --- a/src/timeline/component/ItemSet.js +++ b/src/timeline/component/ItemSet.js @@ -350,7 +350,7 @@ ItemSet.prototype.repaint = function repaint() { // reposition frame frame.style.left = asSize(options.left, '0'); frame.style.top = asSize(options.top, ''); - frame.style.bottom = asSize(options.bottom, ''); + //frame.style.bottom = asSize(options.bottom, ''); frame.style.width = asSize(options.width, '100%'); frame.style.height = fixedHeight ? asSize(options.height) : height + 'px'; @@ -364,7 +364,8 @@ ItemSet.prototype.repaint = function repaint() { this.dom.axis.style.left = asSize(options.left, '0'); this.dom.axis.style.width = asSize(options.width, '100%'); this.dom.axis.style.top = (orientation == 'top' ? this.top : this.top + this.height) + 'px'; - this.dom.axis.style.bottom = asSize(options.bottom, ''); + //this.dom.axis.style.top = asSize(options.top, ''); + //this.dom.axis.style.bottom = asSize(options.bottom, ''); return false; }; diff --git a/test/timeline.html b/test/timeline.html index c659501a..c6b405df 100644 --- a/test/timeline.html +++ b/test/timeline.html @@ -63,11 +63,12 @@ var container = document.getElementById('visualization'); var options = { + editable: true, //orientation: 'top', start: now.clone().add('days', -7), end: now.clone().add('days', 7), //maxHeight: 200, - height: 200, + //height: 200, showCurrentTime: true, showCustomTime: true, //start: moment('2013-01-01'), diff --git a/test/timeline_groups.html b/test/timeline_groups.html index 70ee8b3c..210fe45b 100644 --- a/test/timeline_groups.html +++ b/test/timeline_groups.html @@ -73,6 +73,7 @@ // create visualization var container = document.getElementById('visualization'); var options = { + editable: true, //height: 200, groupOrder: 'content' };