diff --git a/README.md b/README.md index 7d35b959..2d397abb 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ Install via bower: bower install vis +Link via cdnjs: + + http://cdnjs.com + Or download the library from the github project: [https://github.com/almende/vis.git](https://github.com/almende/vis.git). diff --git a/docs/timeline.html b/docs/timeline.html index 96a7c333..26fcefd9 100644 --- a/docs/timeline.html +++ b/docs/timeline.html @@ -854,6 +854,15 @@ var options = { Description + + addCustomTime(time[, id]) + Number | String + + Only applicable when the option showCustomTime is true.
+ Add new vertical bar representing custom time that can be dragged by the user. Parameter time can be a Date, Number, or String. Parameter id can be Number or String. If id is provided, it will be used as ID for the new vertical bar, otherwise the ID will be auto generated.
+ Returns ID of the newly created bar. + + clear([what]) none @@ -903,9 +912,9 @@ timeline.clear({options: true}); // clear options only - getCustomTime() + getCustomTime([id]) Date - Retrieve the custom time. Only applicable when the option showCustomTime is true. + Retrieve the custom time. Only applicable when the option showCustomTime is true. If parameter id is provided, time of the custom time bar under that ID is returned. @@ -958,6 +967,14 @@ timeline.clear({options: true}); // clear options only + + removeCustomTime(id) + none + + Remove vertical bars previously added to the timeline via addCustomTime method. Parameter id is the ID of the custom vertical bar returned by addCustomTime method. + + + setCurrentTime(time) none @@ -967,9 +984,9 @@ timeline.clear({options: true}); // clear options only - setCustomTime(time) + setCustomTime(time [, id]) none - Adjust the custom time bar. Only applicable when the option showCustomTime is true. time can be a Date object, numeric timestamp, or ISO date string. + Adjust the custom time bar. Only applicable when the option showCustomTime is true. Parameter time can be a Date object, numeric timestamp, or ISO date string. Parameter id represents ID of the custom time bar, provided by addCustomTime method and can be a Number or String. @@ -1130,6 +1147,7 @@ timeline.off('select', onSelect); @@ -1142,6 +1160,7 @@ timeline.off('select', onSelect); diff --git a/examples/timeline/34_add_custom_timebar.html b/examples/timeline/34_add_custom_timebar.html new file mode 100644 index 00000000..894d2881 --- /dev/null +++ b/examples/timeline/34_add_custom_timebar.html @@ -0,0 +1,74 @@ + + + + Timeline | Show current and custom time bars + + + + + + + + +

+ + +

+

+ + +

+

+ timechange bar index: . Time: +

+

+ timechanged bar index: . Time: +


+ +
+ + + + \ No newline at end of file diff --git a/examples/timeline/index.html b/examples/timeline/index.html index c21533dc..82526bd7 100644 --- a/examples/timeline/index.html +++ b/examples/timeline/index.html @@ -44,7 +44,7 @@

31_background_areas_with_groups.html

32_grid_styling.html

33_custom_snapping.html

- +

34_add_custom_timebar.html

requirejs_example.html

diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index 9ca3c209..2edab7f5 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -7,6 +7,7 @@ var Range = require('./Range'); var ItemSet = require('./component/ItemSet'); var Activator = require('../shared/Activator'); var DateUtil = require('./DateUtil'); +var CustomTime = require('./component/CustomTime'); /** * Create a timeline visualization @@ -277,25 +278,123 @@ Core.prototype.destroy = function () { /** * Set a custom time bar * @param {Date} time + * @param {int} id */ -Core.prototype.setCustomTime = function (time) { +Core.prototype.setCustomTime = function (time, id) { if (!this.customTime) { throw new Error('Cannot get custom time: Custom time bar is not enabled'); } - this.customTime.setCustomTime(time); + var barId = id || 0; + + this.components.forEach(function (element, index, components) { + if (element instanceof CustomTime && element.options.id === barId) { + element.setCustomTime(time); + } + }); }; /** * Retrieve the current custom time. * @return {Date} customTime + * @param {int} id */ -Core.prototype.getCustomTime = function() { +Core.prototype.getCustomTime = function(id) { if (!this.customTime) { throw new Error('Cannot get custom time: Custom time bar is not enabled'); } - return this.customTime.getCustomTime(); + var barId = id || 0, + customTime = this.customTime.getCustomTime(); + + this.components.forEach(function (element, index, components) { + if (element instanceof CustomTime && element.options.id === barId) { + customTime = element.getCustomTime(); + } + }); + + return customTime; +}; + +/** + * Add custom vertical bar + * @param {Date | String | Number} time A Date, unix timestamp, or + * ISO date string. Time point where the new bar should be placed + * @param {Number | String} ID of the new bar + * @return {Number | String} ID of the new bar + */ +Core.prototype.addCustomTime = function (time, id) { + if (!this.currentTime) { + throw new Error('Option showCurrentTime must be true'); + } + + if (time === undefined) { + throw new Error('Time parameter for the custom bar must be provided'); + } + + var ts = util.convert(time, 'Date').valueOf(), + numIds, customTime, customBarId; + + // All bar IDs are kept in 1 array, mixed types + // Bar with ID 0 is the default bar. + if (!this.customBarIds || this.customBarIds.constructor !== Array) { + this.customBarIds = [0]; + } + + // If the ID is not provided, generate one, otherwise just use it + if (id === undefined) { + + numIds = this.customBarIds.filter(function (element) { + return util.isNumber(element); + }); + + customBarId = numIds.length > 0 ? Math.max.apply(null, numIds) + 1 : 1; + + } else { + + // Check for duplicates + this.customBarIds.forEach(function (element) { + if (element === id) { + throw new Error('Custom time ID already exists'); + } + }); + + customBarId = id; + } + + this.customBarIds.push(customBarId); + + customTime = new CustomTime(this.body, { + showCustomTime : true, + time : ts, + id : customBarId + }); + + this.components.push(customTime); + this.redraw(); + + return customBarId; +}; + +/** + * Remove previously added custom bar + * @param {int} id ID of the custom bar to be removed + * @return {boolean} True if the bar exists and is removed, false otherwise + */ +Core.prototype.removeCustomTime = function (id) { + + var me = this; + + this.components.forEach(function (bar, index, components) { + if (bar instanceof CustomTime && bar.options.id === id) { + // Only the lines added by the user will be removed + if (bar.options.id !== 0) { + me.customBarIds.splice(me.customBarIds.indexOf(id), 1); + components.splice(index, 1); + bar.destroy(); + } + } + }); }; diff --git a/lib/timeline/component/CustomTime.js b/lib/timeline/component/CustomTime.js index 44c2a4da..eea21450 100644 --- a/lib/timeline/component/CustomTime.js +++ b/lib/timeline/component/CustomTime.js @@ -20,11 +20,17 @@ function CustomTime (body, options) { this.defaultOptions = { showCustomTime: false, locales: locales, - locale: 'en' + locale: 'en', + id: 0 }; this.options = util.extend({}, this.defaultOptions); - this.customTime = new Date(); + if (options && options.time) { + this.customTime = options.time; + } else { + this.customTime = new Date(); + } + this.eventParams = {}; // stores state parameters while dragging the bar // create the DOM @@ -43,7 +49,12 @@ CustomTime.prototype = new Component(); CustomTime.prototype.setOptions = function(options) { if (options) { // copy all options that we know - util.selectiveExtend(['showCustomTime', 'locale', 'locales'], this.options, options); + util.selectiveExtend(['showCustomTime', 'locale', 'locales', 'id'], this.options, options); + + // Triggered by addCustomTimeBar, redraw to add new bar + if (this.options.id) { + this.redraw(); + } } }; @@ -169,6 +180,7 @@ CustomTime.prototype._onDrag = function (event) { // fire a timechange event this.body.emitter.emit('timechange', { + id: this.options.id, time: new Date(this.customTime.valueOf()) }); @@ -186,6 +198,7 @@ CustomTime.prototype._onDragEnd = function (event) { // fire a timechanged event this.body.emitter.emit('timechanged', { + id: this.options.id, time: new Date(this.customTime.valueOf()) });