diff --git a/HISTORY.md b/HISTORY.md index d3674871..029ef2a1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,12 +2,18 @@ http://visjs.org -## 2014-06-19, version 2.0.1 +## not yet released, version 2.1.0 ### Timeline - Fixed auto detected item type being preferred over the global item `type`. - Throws an error when constructing without new keyword. +- Removed the 'rangeoverflow' item type. Instead, one can use a regular range + and change css styling of the item contents to: + + .vis.timeline .item.range .content { + overflow: visible; + } ### Graph diff --git a/docs/timeline.html b/docs/timeline.html index 6907887d..07da66f4 100644 --- a/docs/timeline.html +++ b/docs/timeline.html @@ -202,8 +202,8 @@ var items = [
+ In case of ranges being spread over a wide range of time, it can be interesting to have the text contents of the ranges overflow the box. This can be achieved by changing the overflow property of the contents to visible with css: +
++.vis.timeline .item.range .content { + overflow: visible; +} ++ + + + + + \ No newline at end of file diff --git a/examples/timeline/index.html b/examples/timeline/index.html index 88ba04b7..79b67820 100644 --- a/examples/timeline/index.html +++ b/examples/timeline/index.html @@ -29,6 +29,7 @@ + diff --git a/src/timeline/component/ItemSet.js b/src/timeline/component/ItemSet.js index 92c45076..2eee85ea 100644 --- a/src/timeline/component/ItemSet.js +++ b/src/timeline/component/ItemSet.js @@ -13,7 +13,7 @@ function ItemSet(body, options) { this.body = body; this.defaultOptions = { - type: null, // 'box', 'point', 'range', 'rangeoverflow' + type: null, // 'box', 'point', 'range' orientation: 'bottom', // 'top' or 'bottom' align: 'center', // alignment of box items stack: true, @@ -114,7 +114,6 @@ ItemSet.prototype = new Component(); ItemSet.types = { box: ItemBox, range: ItemRange, - rangeoverflow: ItemRangeOverflow, point: ItemPoint }; @@ -696,6 +695,11 @@ ItemSet.prototype._onUpdate = function(ids) { item.id = id; // TODO: not so nice setting id afterwards me._addItem(item); } + else if (type == 'rangeoverflow') { + // TODO: deprecated since version 2.1.0 (or 3.0.0?). cleanup some day + throw new TypeError('Item type "rangeoverflow" is deprecated. Use css styling instead: ' + + '.vis.timeline .item.range .content {overflow: visible;}'); + } else { throw new TypeError('Unknown item type "' + type + '"'); } @@ -1205,7 +1209,7 @@ ItemSet.prototype._onAddItem = function (event) { }; // when default type is a range, add a default end date to the new item - if (this.options.type === 'range' || this.options.type == 'rangeoverflow') { + if (this.options.type === 'range') { var end = this.body.util.toTime(x + this.props.width / 5); newItem.end = snap ? snap(end) : end; } diff --git a/src/timeline/component/css/item.css b/src/timeline/component/css/item.css index 1291a49f..ea763ab2 100644 --- a/src/timeline/component/css/item.css +++ b/src/timeline/component/css/item.css @@ -41,15 +41,13 @@ border-radius: 4px; } -.vis.timeline .item.range, -.vis.timeline .item.rangeoverflow{ +.vis.timeline .item.range { border-style: solid; border-radius: 2px; box-sizing: border-box; } -.vis.timeline .item.range .content, -.vis.timeline .item.rangeoverflow .content { +.vis.timeline .item.range .content { position: relative; display: inline-block; } @@ -59,6 +57,10 @@ max-width: 100%; } +.vis.timeline .item.range.overflow .content { + overflow: visible; +} + .vis.timeline .item.line { padding: 0; position: absolute; @@ -82,8 +84,7 @@ cursor: pointer; } -.vis.timeline .item.range .drag-left, -.vis.timeline .item.rangeoverflow .drag-left { +.vis.timeline .item.range .drag-left { position: absolute; width: 24px; height: 100%; @@ -94,8 +95,7 @@ z-index: 10000; } -.vis.timeline .item.range .drag-right, -.vis.timeline .item.rangeoverflow .drag-right { +.vis.timeline .item.range .drag-right { position: absolute; width: 24px; height: 100%; diff --git a/src/timeline/component/item/ItemRange.js b/src/timeline/component/item/ItemRange.js index 00a2b241..98572557 100644 --- a/src/timeline/component/item/ItemRange.js +++ b/src/timeline/component/item/ItemRange.js @@ -14,6 +14,7 @@ function ItemRange (data, conversion, options) { width: 0 } }; + this.overflow = false; // if contents can overflow (css styling), this flag is set to true // validate data if (data) { @@ -107,6 +108,9 @@ ItemRange.prototype.redraw = function() { // recalculate size if (this.dirty) { + // determine from css whether this box has overflow + this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; + this.props.content.width = this.dom.content.offsetWidth; this.height = this.dom.box.offsetHeight; @@ -151,6 +155,7 @@ ItemRange.prototype.hide = function() { * Reposition the item horizontally * @Override */ +// TODO: delete the old function ItemRange.prototype.repositionX = function() { var props = this.props, parentWidth = this.parent.width, @@ -166,22 +171,35 @@ ItemRange.prototype.repositionX = function() { if (end > 2 * parentWidth) { end = 2 * parentWidth; } + var boxWidth = Math.max(end - start, 1); - // when range exceeds left of the window, position the contents at the left of the visible area - if (start < 0) { - contentLeft = Math.min(-start, - (end - start - props.content.width - 2 * padding)); - // TODO: remove the need for options.padding. it's terrible. - } - else { - contentLeft = 0; + if (this.overflow) { + // when range exceeds left of the window, position the contents at the left of the visible area + contentLeft = Math.max(-start, 0); + + this.left = start; + this.width = boxWidth + this.props.content.width; + // Note: The calculation of width is an optimistic calculation, giving + // a width which will not change when moving the Timeline + // So no restacking needed, which is nicer for the eye; } + else { // no overflow + // when range exceeds left of the window, position the contents at the left of the visible area + if (start < 0) { + contentLeft = Math.min(-start, + (end - start - props.content.width - 2 * padding)); + // TODO: remove the need for options.padding. it's terrible. + } + else { + contentLeft = 0; + } - this.left = start; - this.width = Math.max(end - start, 1); + this.left = start; + this.width = boxWidth; + } this.dom.box.style.left = this.left + 'px'; - this.dom.box.style.width = this.width + 'px'; + this.dom.box.style.width = boxWidth + 'px'; this.dom.content.style.left = contentLeft + 'px'; }; diff --git a/src/timeline/component/item/ItemRangeOverflow.js b/src/timeline/component/item/ItemRangeOverflow.js deleted file mode 100644 index 3d5d474e..00000000 --- a/src/timeline/component/item/ItemRangeOverflow.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @constructor ItemRangeOverflow - * @extends ItemRange - * @param {Object} data Object containing parameters start, end - * content, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} [options] Configuration options - * // TODO: describe options - */ -function ItemRangeOverflow (data, conversion, options) { - this.props = { - content: { - left: 0, - width: 0 - } - }; - - ItemRange.call(this, data, conversion, options); -} - -ItemRangeOverflow.prototype = new ItemRange (null, null, null); - -ItemRangeOverflow.prototype.baseClassName = 'item rangeoverflow'; - -/** - * Reposition the item horizontally - * @Override - */ -ItemRangeOverflow.prototype.repositionX = function() { - var parentWidth = this.parent.width, - start = this.conversion.toScreen(this.data.start), - end = this.conversion.toScreen(this.data.end), - contentLeft; - - // limit the width of the this, as browsers cannot draw very wide divs - if (start < -parentWidth) { - start = -parentWidth; - } - if (end > 2 * parentWidth) { - end = 2 * parentWidth; - } - - // when range exceeds left of the window, position the contents at the left of the visible area - contentLeft = Math.max(-start, 0); - - this.left = start; - var boxWidth = Math.max(end - start, 1); - this.width = boxWidth + this.props.content.width; - // Note: The calculation of width is an optimistic calculation, giving - // a width which will not change when moving the Timeline - // So no restacking needed, which is nicer for the eye - - this.dom.box.style.left = this.left + 'px'; - this.dom.box.style.width = boxWidth + 'px'; - this.dom.content.style.left = contentLeft + 'px'; -}; diff --git a/test/timeline.html b/test/timeline.html index 14ce8d91..b7fc9e59 100644 --- a/test/timeline.html +++ b/test/timeline.html @@ -15,6 +15,15 @@ #visualization .itemset { /*background: rgba(255, 255, 0, 0.5);*/ } + + /* + .vis.timeline .item.range .content { + overflow: hidden; + max-width: none; + } + */ + + @@ -70,7 +79,12 @@ {_id: 2, content: 'item 2', start: now.clone().add('days', -2).toDate() }, {_id: 3, content: 'item 3', start: now.clone().add('days', 2).toDate()}, { - _id: 4, content: 'item 4', + _id: 4, content: 'item 4 asdfjkadsf adksfk adskfadks aksdfk asdfkkadkskafdskdfs ', + start: now.clone().add('days', 0).toDate(), + end: now.clone().add('days', 7).toDate(), className: 'overflow' + }, + { + _id: 7, content: 'item 7 asdfjkadsf adksfk adskfadks aksdfk asdfkkadkskafdskdfs ', start: now.clone().add('days', 0).toDate(), end: now.clone().add('days', 7).toDate() },