diff --git a/lib/timeline/Range.js b/lib/timeline/Range.js index e49951d4..e2ef0bbb 100644 --- a/lib/timeline/Range.js +++ b/lib/timeline/Range.js @@ -15,7 +15,7 @@ var DateUtil = require('./DateUtil'); function Range(body, options) { var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); var start = now.clone().add(-3, 'days').valueOf(); - var end = now.clone().add(-3, 'days').valueOf(); + var end = now.clone().add(3, 'days').valueOf(); if(options === undefined) { this.start = start; @@ -256,6 +256,13 @@ Range.prototype.setRange = function(start, end, animation, byUser, event) { } }; +/** + * Get the number of milliseconds per pixel. + */ +Range.prototype.getMillisecondsPerPixel = function() { + return (this.end - this.start) / this.body.dom.center.clientWidth; +} + /** * Stop an animation * @private @@ -291,7 +298,7 @@ Range.prototype._applyRange = function(start, end) { throw new Error('Invalid end "' + end + '"'); } - // prevent start < end + // prevent end < start if (newEnd < newStart) { newEnd = newStart; } diff --git a/lib/timeline/component/item/BoxItem.js b/lib/timeline/component/item/BoxItem.js index 02e35937..377b2e06 100644 --- a/lib/timeline/component/item/BoxItem.js +++ b/lib/timeline/component/item/BoxItem.js @@ -37,15 +37,14 @@ BoxItem.prototype = new Item (null, null, null); /** * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @param {{start: Number, end: Number}} range with a timestamp for start and end * @returns {boolean} True if visible */ BoxItem.prototype.isVisible = function(range) { // determine visibility var isVisible; var align = this.options.align; - var msPerPixel = (range.end - range.start) / range.body.dom.center.clientWidth; - var widthInMs = this.width * msPerPixel; + var widthInMs = this.width * range.getMillisecondsPerPixel(); if (align == 'right') { isVisible = (this.data.start.getTime() > range.start ) && (this.data.start.getTime() - widthInMs < range.end); diff --git a/lib/timeline/component/item/PointItem.js b/lib/timeline/component/item/PointItem.js index c4c14c91..83c4e67b 100644 --- a/lib/timeline/component/item/PointItem.js +++ b/lib/timeline/component/item/PointItem.js @@ -38,13 +38,12 @@ PointItem.prototype = new Item (null, null, null); /** * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @param {{start: Number, end: Number}} range with a timestamp for start and end * @returns {boolean} True if visible */ PointItem.prototype.isVisible = function(range) { // determine visibility - var msPerPixel = (range.end - range.start) / range.body.dom.center.clientWidth; - var widthInMs = this.width * msPerPixel; + var widthInMs = this.width * range.getMillisecondsPerPixel(); return (this.data.start.getTime() + widthInMs > range.start ) && (this.data.start < range.end); }; diff --git a/package.json b/package.json index 9cd86986..aa585ef8 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,9 @@ "gulp-concat": "^2.6.0", "gulp-rename": "^1.2.2", "gulp-util": "^3.0.7", + "jsdom": "9.9.1", "mocha": "^3.1.2", + "mocha-jsdom": "^1.1.0", "rimraf": "^2.5.2", "uglify-js": "^2.6.2", "uuid": "^3.0.1", diff --git a/test/TimelineRange.test.js b/test/TimelineRange.test.js new file mode 100644 index 00000000..ba79142d --- /dev/null +++ b/test/TimelineRange.test.js @@ -0,0 +1,61 @@ +var assert = require('assert'); +var vis = require('../dist/vis'); +var jsdom = require('mocha-jsdom') +var moment = vis.moment; +var timeline = vis.timeline; +var Range = timeline.Range; + +function buildSimpleBody() { + var body = { + dom: { + center: { + clientWidth: 1000 + } + }, + domProps: this.props, + emitter: { + on: function() {}, + off: function() {}, + emit: function() {} + }, + hiddenDates: [], + util: {} + }; + body.dom.rollingModeBtn = document.createElement('div'); + return body; +} + +describe('Timeline Range', function () { + + jsdom(); + + it('should have start default before now', function () { + var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0).valueOf(); + var range = new Range(buildSimpleBody()); + assert(range.start < now, "Default start is before now"); + }); + + it('should have end default after now', function () { + var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0).valueOf(); + var range = new Range(buildSimpleBody()); + assert(range.end > now, "Default end is after now"); + }); + + it('should support custom start and end dates', function () { + var range = new Range(buildSimpleBody()); + range.setRange(new Date(2017, 0, 26, 13, 26, 3, 320), new Date(2017, 3, 11, 0, 23, 35, 0), false, false, null); + assert.equal(range.start, new Date(2017, 0, 26, 13, 26, 3, 320).valueOf(), "start is as expected"); + assert.equal(range.end, new Date(2017, 3, 11, 0, 23, 35, 0).valueOf(), "end is as expected"); + }); + + it('should calculate milliseconds per pixel', function () { + var range = new Range(buildSimpleBody()); + assert(range.getMillisecondsPerPixel() > 0, "positive value for milliseconds per pixel"); + }); + + it('should calculate 1 millisecond per pixel for simple range', function () { + var range = new Range(buildSimpleBody()); + range.setRange(new Date(2017, 0, 26, 13, 26, 3, 320), new Date(2017, 0, 26, 13, 26, 4, 320), false, false, null); + assert.equal(range.getMillisecondsPerPixel(), 1, "one second over 1000 pixels"); + }); +}); \ No newline at end of file