From 284013c3e3bb0753419fc870bca42b0fb3263991 Mon Sep 17 00:00:00 2001 From: jos Date: Thu, 1 May 2014 17:11:32 +0200 Subject: [PATCH] Implemented option `stack` to enable/disable stacking of items. --- HISTORY.md | 1 + dist/vis.js | 32 ++++++++++++++++++++++++++++---- docs/timeline.html | 7 +++++++ src/timeline/Timeline.js | 1 + src/timeline/component/Group.js | 7 ++++++- src/timeline/stack.js | 22 +++++++++++++++++++--- test/timeline_groups.html | 1 + 7 files changed, 63 insertions(+), 8 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 1dbc2f4f..5e6955ca 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -10,6 +10,7 @@ http://visjs.org - Great performance improvements. - Improved layout of box-items inside groups. - Items can now be dragged from one group to another. +- Implemented option `stack` to enable/disable stacking of items. - Option `editable` can now be used to enable/disable individual manipulation actions (`add`, `updateTime`, `updateGroup`, `remove`). - Function `setWindow` now accepts an object with properties `start` and `end`. diff --git a/dist/vis.js b/dist/vis.js index b8487024..f6cf32e1 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -2488,14 +2488,14 @@ stack.orderByEnd = function orderByEnd(items) { }; /** - * Adjust vertical positions of the events such that they don't overlap each + * Adjust vertical positions of the items such that they don't overlap each * other. * @param {Item[]} items * All visible items * @param {{item: number, axis: number}} margin * Margins between items and between items and the axis. * @param {boolean} [force=false] - * If true, all items will be re-stacked. If false (default), only + * If true, all items will be repositioned. If false (default), only * items having a top===null will be re-stacked */ stack.stack = function _stack (items, margin, force) { @@ -2528,7 +2528,7 @@ stack.stack = function _stack (items, margin, force) { } if (collidingItem != null) { - // There is a collision. Reposition the event above the colliding element + // There is a collision. Reposition the items above the colliding element item.top = collidingItem.top + collidingItem.height + margin.item; } } while (collidingItem); @@ -2536,6 +2536,22 @@ stack.stack = function _stack (items, margin, force) { } }; +/** + * Adjust vertical positions of the items without stacking them + * @param {Item[]} items + * All visible items + * @param {{item: number, axis: number}} margin + * Margins between items and between items and the axis. + */ +stack.nostack = function nostack (items, margin) { + var i, iMax; + + // reset top position of all items + for (i = 0, iMax = items.length; i < iMax; i++) { + items[i].top = margin.axis; + } +}; + /** * Test if the two provided items collide * The items must have parameters left, width, top, and height. @@ -5405,6 +5421,8 @@ ItemSet.prototype._onRemoveGroups = function _onRemoveGroups(ids) { } }); + this.markDirty(); + this.emit('change'); }; @@ -6795,7 +6813,12 @@ Group.prototype.repaint = function repaint(range, margin, restack) { this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); // reposition visible items vertically - stack.stack(this.visibleItems, margin, restack); + if (this.itemSet.options.stack) { // TODO: ugly way to access options... + stack.stack(this.visibleItems, margin, restack); + } + else { // no stacking + stack.nostack(this.visibleItems, margin); + } this.stackDirty = false; for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { var item = this.visibleItems[i]; @@ -7135,6 +7158,7 @@ function Timeline (container, items, options) { orientation: 'bottom', direction: 'horizontal', // 'horizontal' or 'vertical' autoResize: true, + stacking: true, editable: { updateTime: false, diff --git a/docs/timeline.html b/docs/timeline.html index a08c8c56..26c12b91 100644 --- a/docs/timeline.html +++ b/docs/timeline.html @@ -564,6 +564,13 @@ var options = { visible. + + stack + Boolean + true + If true (default), items will be stacked on top of each other such that they are not overlapping. + + start Date | Number | String diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js index 983e5924..edcf0411 100644 --- a/src/timeline/Timeline.js +++ b/src/timeline/Timeline.js @@ -15,6 +15,7 @@ function Timeline (container, items, options) { orientation: 'bottom', direction: 'horizontal', // 'horizontal' or 'vertical' autoResize: true, + stacking: true, editable: { updateTime: false, diff --git a/src/timeline/component/Group.js b/src/timeline/component/Group.js index de95c9fa..f1fa1791 100644 --- a/src/timeline/component/Group.js +++ b/src/timeline/component/Group.js @@ -123,7 +123,12 @@ Group.prototype.repaint = function repaint(range, margin, restack) { this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); // reposition visible items vertically - stack.stack(this.visibleItems, margin, restack); + if (this.itemSet.options.stack) { // TODO: ugly way to access options... + stack.stack(this.visibleItems, margin, restack); + } + else { // no stacking + stack.nostack(this.visibleItems, margin); + } this.stackDirty = false; for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { var item = this.visibleItems[i]; diff --git a/src/timeline/stack.js b/src/timeline/stack.js index 06050f43..97cee61c 100644 --- a/src/timeline/stack.js +++ b/src/timeline/stack.js @@ -28,14 +28,14 @@ stack.orderByEnd = function orderByEnd(items) { }; /** - * Adjust vertical positions of the events such that they don't overlap each + * Adjust vertical positions of the items such that they don't overlap each * other. * @param {Item[]} items * All visible items * @param {{item: number, axis: number}} margin * Margins between items and between items and the axis. * @param {boolean} [force=false] - * If true, all items will be re-stacked. If false (default), only + * If true, all items will be repositioned. If false (default), only * items having a top===null will be re-stacked */ stack.stack = function _stack (items, margin, force) { @@ -68,7 +68,7 @@ stack.stack = function _stack (items, margin, force) { } if (collidingItem != null) { - // There is a collision. Reposition the event above the colliding element + // There is a collision. Reposition the items above the colliding element item.top = collidingItem.top + collidingItem.height + margin.item; } } while (collidingItem); @@ -76,6 +76,22 @@ stack.stack = function _stack (items, margin, force) { } }; +/** + * Adjust vertical positions of the items without stacking them + * @param {Item[]} items + * All visible items + * @param {{item: number, axis: number}} margin + * Margins between items and between items and the axis. + */ +stack.nostack = function nostack (items, margin) { + var i, iMax; + + // reset top position of all items + for (i = 0, iMax = items.length; i < iMax; i++) { + items[i].top = margin.axis; + } +}; + /** * Test if the two provided items collide * The items must have parameters left, width, top, and height. diff --git a/test/timeline_groups.html b/test/timeline_groups.html index f37d7195..6dff9219 100644 --- a/test/timeline_groups.html +++ b/test/timeline_groups.html @@ -78,6 +78,7 @@ updateTime: true, updateGroup: true }, + stack: false, //height: 200, groupOrder: 'content' };