From 15a4ac52658c7fe2cb0b6abe5cbb66e6bc9f9023 Mon Sep 17 00:00:00 2001 From: josdejong Date: Wed, 30 Oct 2013 14:22:41 +0100 Subject: [PATCH] Fixed #6: options `min` and `max` are broken. --- HISTORY.md | 2 + src/timeline/Range.js | 97 ++++++++++++++++-------------- src/timeline/TimeStep.js | 3 +- src/timeline/Timeline.js | 37 ++++++------ src/timeline/component/TimeAxis.js | 13 ++-- test/timeline.html | 11 ++-- 6 files changed, 88 insertions(+), 75 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0d6a30a2..e6175fff 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ http://visjs.org - Implemented option `showCurrentTime`, displaying a red, vertical bar at current time. Thanks fi0dor. +- Fixed broken Timeline options `min` and `max`. +- Fixed not being able to load vis.js in node.js. ## 2013-09-20, version 0.2.0 diff --git a/src/timeline/Range.js b/src/timeline/Range.js index 2215ea36..ef9c4ce3 100644 --- a/src/timeline/Range.js +++ b/src/timeline/Range.js @@ -8,16 +8,10 @@ */ function Range(options) { this.id = util.randomUUID(); - this.start = 0; // Number - this.end = 0; // Number - - // this.options = options || {}; // TODO: fix range options - this.options = { - min: null, - max: null, - zoomMin: null, - zoomMax: null - }; + this.start = null; // Number + this.end = null; // Number + + this.options = options || {}; this.listeners = []; @@ -27,8 +21,6 @@ function Range(options) { /** * Set options for the range controller * @param {Object} options Available options: - * {Number} start Set start value of the range - * {Number} end Set end value of the range * {Number} min Minimum value for start * {Number} max Maximum value for end * {Number} zoomMin Set a minimum value for @@ -39,8 +31,9 @@ function Range(options) { Range.prototype.setOptions = function (options) { util.extend(this.options, options); - if (options.start != null || options.end != null) { - this.setRange(options.start, options.end); + // re-apply range with new limitations + if (this.start !== null && this.end !== null) { + this.setRange(this.start, this.end); } }; @@ -119,8 +112,8 @@ Range.prototype._trigger = function (event) { /** * Set a new start and end range - * @param {Number} start - * @param {Number} end + * @param {Number} [start] + * @param {Number} [end] */ Range.prototype.setRange = function(start, end) { var changed = this._applyRange(start, end); @@ -134,21 +127,23 @@ Range.prototype.setRange = function(start, end) { * Set a new start and end range. This method is the same as setRange, but * does not trigger a range change and range changed event, and it returns * true when the range is changed - * @param {Number} start - * @param {Number} end + * @param {Number} [start] + * @param {Number} [end] * @return {Boolean} changed * @private */ Range.prototype._applyRange = function(start, end) { - var newStart = (start != null) ? util.convert(start, 'Number') : this.start; - var newEnd = (end != null) ? util.convert(end, 'Number') : this.end; - var diff; + var newStart = (start != null) ? util.convert(start, 'Number') : this.start, + newEnd = (end != null) ? util.convert(end, 'Number') : this.end, + max = (this.options.max != null) ? util.convert(this.options.max, 'Date').valueOf() : null, + min = (this.options.min != null) ? util.convert(this.options.min, 'Date').valueOf() : null, + diff; // check for valid number - if (isNaN(newStart)) { + if (isNaN(newStart) || newStart === null) { throw new Error('Invalid start "' + start + '"'); } - if (isNaN(newEnd)) { + if (isNaN(newEnd) || newEnd === null) { throw new Error('Invalid end "' + end + '"'); } @@ -158,64 +153,76 @@ Range.prototype._applyRange = function(start, end) { } // prevent start < min - if (this.options.min != null) { - var min = this.options.min.valueOf(); + if (min !== null) { if (newStart < min) { diff = (min - newStart); newStart += diff; newEnd += diff; + + // prevent end > max + if (max != null) { + if (newEnd > max) { + newEnd = max; + } + } } } // prevent end > max - if (this.options.max != null) { - var max = this.options.max.valueOf(); + if (max !== null) { if (newEnd > max) { diff = (newEnd - max); newStart -= diff; newEnd -= diff; + + // prevent start < min + if (min != null) { + if (newStart < min) { + newStart = min; + } + } } } - // prevent (end-start) > zoomMin - if (this.options.zoomMin != null) { - var zoomMin = this.options.zoomMin.valueOf(); + // prevent (end-start) < zoomMin + if (this.options.zoomMin !== null) { + var zoomMin = parseFloat(this.options.zoomMin); if (zoomMin < 0) { zoomMin = 0; } if ((newEnd - newStart) < zoomMin) { - if ((this.end - this.start) > zoomMin) { + if ((this.end - this.start) === zoomMin) { + // ignore this action, we are already zoomed to the minimum + newStart = this.start; + newEnd = this.end; + } + else { // zoom to the minimum diff = (zoomMin - (newEnd - newStart)); newStart -= diff / 2; newEnd += diff / 2; } - else { - // ingore this action, we are already zoomed to the minimum - newStart = this.start; - newEnd = this.end; - } } } - // prevent (end-start) > zoomMin - if (this.options.zoomMax != null) { - var zoomMax = this.options.zoomMax.valueOf(); + // prevent (end-start) > zoomMax + if (this.options.zoomMax !== null) { + var zoomMax = parseFloat(this.options.zoomMax); if (zoomMax < 0) { zoomMax = 0; } if ((newEnd - newStart) > zoomMax) { - if ((this.end - this.start) < zoomMax) { + if ((this.end - this.start) === zoomMax) { + // ignore this action, we are already zoomed to the maximum + newStart = this.start; + newEnd = this.end; + } + else { // zoom to the maximum diff = ((newEnd - newStart) - zoomMax); newStart += diff / 2; newEnd -= diff / 2; } - else { - // ingore this action, we are already zoomed to the maximum - newStart = this.start; - newEnd = this.end; - } } } diff --git a/src/timeline/TimeStep.js b/src/timeline/TimeStep.js index 4823b9f7..ccbc6c9f 100644 --- a/src/timeline/TimeStep.js +++ b/src/timeline/TimeStep.js @@ -63,8 +63,7 @@ TimeStep.SCALE = { */ TimeStep.prototype.setRange = function(start, end, minimumStep) { if (!(start instanceof Date) || !(end instanceof Date)) { - //throw "No legal start or end date in method setRange"; - return; + throw "No legal start or end date in method setRange"; } this._start = (start != undefined) ? new Date(start.valueOf()) : new Date(); diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js index 27c62282..125499af 100644 --- a/src/timeline/Timeline.js +++ b/src/timeline/Timeline.js @@ -7,11 +7,12 @@ */ function Timeline (container, items, options) { var me = this; - this.options = util.extend({ + var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); + this.options = { orientation: 'bottom', min: null, max: null, - zoomMin: 10, // milliseconds + zoomMin: 10, // milliseconds zoomMax: 1000 * 60 * 60 * 24 * 365 * 10000, // milliseconds // moveable: true, // TODO: option moveable // zoomable: true, // TODO: option zoomable @@ -19,7 +20,7 @@ function Timeline (container, items, options) { showMajorLabels: true, showCurrentTime: false, autoResize: false - }, options); + }; // controller this.controller = new Controller(); @@ -72,19 +73,13 @@ function Timeline (container, items, options) { this.controller.add(this.labelPanel); // range - var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); - this.range = new Range({ - start: now.clone().add('days', -3).valueOf(), - end: now.clone().add('days', 4).valueOf() - }); - /* TODO: fix range options var rangeOptions = Object.create(this.options); this.range = new Range(rangeOptions); this.range.setRange( now.clone().add('days', -3).valueOf(), now.clone().add('days', 4).valueOf() ); - */ + // TODO: reckon with options moveable and zoomable this.range.subscribe(this.rootPanel, 'move', 'horizontal'); this.range.subscribe(this.rootPanel, 'zoom', 'horizontal'); @@ -120,7 +115,12 @@ function Timeline (container, items, options) { this.itemsData = null; // DataSet this.groupsData = null; // DataSet - // set data + // apply options + if (options) { + this.setOptions(options); + } + + // set data (must be after options are applied) if (items) { this.setItems(items); } @@ -131,11 +131,12 @@ function Timeline (container, items, options) { * @param {Object} options TODO: describe the available options */ Timeline.prototype.setOptions = function (options) { - if (options) { - util.extend(this.options, options); - } + util.extend(this.options, options); - // TODO: apply range min,max + // force update of range + // options.start and options.end can be undefined + //this.range.setRange(options.start, options.end); + this.range.setRange(); this.controller.reflow(); this.controller.repaint(); @@ -174,7 +175,7 @@ Timeline.prototype.setItems = function(items) { // apply the data range as range var dataRange = this.getItemRange(); - // add 5% on both sides + // add 5% space on both sides var min = dataRange.min; var max = dataRange.max; if (min != null && max != null) { @@ -189,10 +190,10 @@ Timeline.prototype.setItems = function(items) { // override specified start and/or end date if (this.options.start != undefined) { - min = new Date(this.options.start.valueOf()); + min = util.convert(this.options.start, 'Date'); } if (this.options.end != undefined) { - max = new Date(this.options.end.valueOf()); + max = util.convert(this.options.end, 'Date'); } // apply range if there is a min or max available diff --git a/src/timeline/component/TimeAxis.js b/src/timeline/component/TimeAxis.js index 7b8a3535..ec976939 100644 --- a/src/timeline/component/TimeAxis.js +++ b/src/timeline/component/TimeAxis.js @@ -487,12 +487,13 @@ TimeAxis.prototype.reflow = function () { // calculate range and step this._updateConversion(); - var start = util.convert(range.start, 'Date'), - end = util.convert(range.end, 'Date'), - minimumStep = this.toTime((props.minorCharWidth || 10) * 5) - this.toTime(0); - this.step = new TimeStep(start, end, minimumStep); - changed += update(props.range, 'start', start.valueOf()); - changed += update(props.range, 'end', end.valueOf()); + var start = util.convert(range.start, 'Number'), + end = util.convert(range.end, 'Number'), + minimumStep = this.toTime((props.minorCharWidth || 10) * 5).valueOf() + -this.toTime(0).valueOf(); + this.step = new TimeStep(new Date(start), new Date(end), minimumStep); + changed += update(props.range, 'start', start); + changed += update(props.range, 'end', end); changed += update(props.range, 'minimumStep', minimumStep.valueOf()); } diff --git a/test/timeline.html b/test/timeline.html index 33829560..8b725a7b 100644 --- a/test/timeline.html +++ b/test/timeline.html @@ -2,6 +2,7 @@ +