Browse Source

Add callback functions to moveTo, zoomIn, zoomOut and setWindow (#2870)

* Fix redraw order

* Fix error when option is not defined

* Allow template labels

* Add .travis.yml file

* Add experiment travis code

* Fix react example

* Add callback functions to moveTo, zoomIn, zoomOut and setWindow
gemini
yotamberk 7 years ago
committed by Brad Hards
parent
commit
3d1e8a3296
4 changed files with 98 additions and 35 deletions
  1. +8
    -4
      docs/timeline/index.html
  2. +38
    -11
      lib/timeline/Core.js
  3. +50
    -18
      lib/timeline/Range.js
  4. +2
    -2
      lib/timeline/Timeline.js

+ 8
- 4
docs/timeline/index.html View File

@ -1308,12 +1308,13 @@ document.getElementById('myTimeline').onclick = function (event) {
</tr> </tr>
<tr> <tr>
<td>moveTo(time [, options])</td>
<td>moveTo(time [, options, callback])</td>
<td>none</td> <td>none</td>
<td>Move the window such that given time is centered on screen. Parameter <code>time</code> can be a <code>Date</code>, <code>Number</code>, or <code>String</code>. Available options: <td>Move the window such that given time is centered on screen. Parameter <code>time</code> can be a <code>Date</code>, <code>Number</code>, or <code>String</code>. Available options:
<ul> <ul>
<li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li> <li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li>
</ul> </ul>
A callback <code>function</code> can be passed as an optional parameter. This function will be called at the end of moveTo function.
</td> </td>
</tr> </tr>
@ -1422,12 +1423,13 @@ document.getElementById('myTimeline').onclick = function (event) {
</tr> </tr>
<tr> <tr>
<td>setWindow(start, end [, options])</td>
<td>setWindow(start, end [, options, callback])</td>
<td>none</td> <td>none</td>
<td>Set the current visible window. The parameters <code>start</code> and <code>end</code> can be a <code>Date</code>, <code>Number</code>, or <code>String</code>. If the parameter value of <code>start</code> or <code>end</code> is null, the parameter will be left unchanged. Available options: <td>Set the current visible window. The parameters <code>start</code> and <code>end</code> can be a <code>Date</code>, <code>Number</code>, or <code>String</code>. If the parameter value of <code>start</code> or <code>end</code> is null, the parameter will be left unchanged. Available options:
<ul> <ul>
<li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li> <li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li>
</ul> </ul>
A callback <code>function</code> can be passed as an optional parameter. This function will be called at the end of setWindow function.
</td> </td>
</tr> </tr>
@ -1439,21 +1441,23 @@ document.getElementById('myTimeline').onclick = function (event) {
</tr> </tr>
<tr> <tr>
<td>zoomIn(percentage [, options])</td>
<td>zoomIn(percentage [, options, callback])</td>
<td>none</td> <td>none</td>
<td>Zoom in the current visible window. The parameter <code>percentage</code> can be a <code>Number</code> and must be between 0 and 1. If the parameter value of <code>percentage</code> is null, the window will be left unchanged. Available options: <td>Zoom in the current visible window. The parameter <code>percentage</code> can be a <code>Number</code> and must be between 0 and 1. If the parameter value of <code>percentage</code> is null, the window will be left unchanged. Available options:
<ul> <ul>
<li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li> <li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li>
</ul> </ul>
A callback <code>function</code> can be passed as an optional parameter. This function will be called at the end of zoomIn function.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>zoomOut(percentage [, options])</td>
<td>zoomOut(percentage [, options, callback])</td>
<td>none</td> <td>none</td>
<td>Zoom out the current visible window. The parameter <code>percentage</code> can be a <code>Number</code> and must be between 0 and 1. If the parameter value of <code>percentage</code> is null, the window will be left unchanged. Available options: <td>Zoom out the current visible window. The parameter <code>percentage</code> can be a <code>Number</code> and must be between 0 and 1. If the parameter value of <code>percentage</code> is null, the window will be left unchanged. Available options:
<ul> <ul>
<li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li> <li><code>animation: boolean or {duration: number, easingFunction: string}</code><br>If true (default) or an Object, the range is animated smoothly to the new window. An object can be provided to specify duration and easing function. Default duration is 500 ms, and default easing function is <code>'easeInOutQuad'</code>. Available easing functions: <code>"linear"</code>, <code>"easeInQuad"</code>, <code>"easeOutQuad"</code>, <code>"easeInOutQuad"</code>, <code>"easeInCubic"</code>, <code>"easeOutCubic"</code>, <code>"easeInOutCubic"</code>, <code>"easeInQuart"</code>, <code>"easeOutQuart"</code>, <code>"easeInOutQuart"</code>, <code>"easeInQuint"</code>, <code>"easeOutQuint"</code>, <code>"easeInOutQuint"</code>.</li>
</ul> </ul>
A callback <code>function</code> can be passed as an optional parameter. This function will be called at the end of zoomOut function.
</td> </td>
</tr> </tr>

+ 38
- 11
lib/timeline/Core.js View File

@ -613,8 +613,9 @@ Core.prototype.getVisibleItems = function() {
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Function} a callback funtion to be executed at the end of this function
*/ */
Core.prototype.fit = function(options) {
Core.prototype.fit = function(options, callback) {
var range = this.getDataRange(); var range = this.getDataRange();
// skip range set if there is no min and max date // skip range set if there is no min and max date
@ -627,7 +628,7 @@ Core.prototype.fit = function(options) {
var min = new Date(range.min.valueOf() - interval * 0.01); var min = new Date(range.min.valueOf() - interval * 0.01);
var max = new Date(range.max.valueOf() + interval * 0.01); var max = new Date(range.max.valueOf() + interval * 0.01);
var animation = (options && options.animation !== undefined) ? options.animation : true; var animation = (options && options.animation !== undefined) ? options.animation : true;
this.range.setRange(min, max, animation);
this.range.setRange(min, max, { animation: animation }, callback);
}; };
/** /**
@ -660,17 +661,28 @@ Core.prototype.getDataRange = function() {
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Function} a callback funtion to be executed at the end of this function
*/ */
Core.prototype.setWindow = function(start, end, options) {
Core.prototype.setWindow = function(start, end, options, callback) {
if (typeof arguments[2] == "function") {
callback = arguments[2]
options = {};
}
var animation; var animation;
if (arguments.length == 1) { if (arguments.length == 1) {
var range = arguments[0]; var range = arguments[0];
animation = (range.animation !== undefined) ? range.animation : true; animation = (range.animation !== undefined) ? range.animation : true;
this.range.setRange(range.start, range.end, animation);
this.range.setRange(range.start, range.end, { animation: animation });
}
else if (arguments.length == 2 && typeof arguments[1] == "function") {
var range = arguments[0];
callback = arguments[1];
animation = (range.animation !== undefined) ? range.animation : true;
this.range.setRange(range.start, range.end, { animation: animation }, callback);
} }
else { else {
animation = (options && options.animation !== undefined) ? options.animation : true; animation = (options && options.animation !== undefined) ? options.animation : true;
this.range.setRange(start, end, animation);
this.range.setRange(start, end, { animation: animation }, callback);
} }
}; };
@ -684,8 +696,13 @@ Core.prototype.setWindow = function(start, end, options) {
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Function} a callback funtion to be executed at the end of this function
*/ */
Core.prototype.moveTo = function(time, options) {
Core.prototype.moveTo = function(time, options, callback) {
if (typeof arguments[1] == "function") {
callback = arguments[1]
options = {};
}
var interval = this.range.end - this.range.start; var interval = this.range.end - this.range.start;
var t = util.convert(time, 'Date').valueOf(); var t = util.convert(time, 'Date').valueOf();
@ -693,7 +710,7 @@ Core.prototype.moveTo = function(time, options) {
var end = t + interval / 2; var end = t + interval / 2;
var animation = (options && options.animation !== undefined) ? options.animation : true; var animation = (options && options.animation !== undefined) ? options.animation : true;
this.range.setRange(start, end, animation);
this.range.setRange(start, end, { animation: animation }, callback);
}; };
/** /**
@ -718,9 +735,14 @@ Core.prototype.getWindow = function() {
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Function} a callback funtion to be executed at the end of this function
*/ */
Core.prototype.zoomIn = function(percentage, options) {
Core.prototype.zoomIn = function(percentage, options, callback) {
if (!percentage || percentage < 0 || percentage > 1) return if (!percentage || percentage < 0 || percentage > 1) return
if (typeof arguments[1] == "function") {
callback = arguments[1]
options = {};
}
var range = this.getWindow(); var range = this.getWindow();
var start = range.start.valueOf(); var start = range.start.valueOf();
var end = range.end.valueOf(); var end = range.end.valueOf();
@ -730,7 +752,7 @@ Core.prototype.zoomIn = function(percentage, options) {
var newStart = start + distance; var newStart = start + distance;
var newEnd = end - distance; var newEnd = end - distance;
this.setWindow(newStart, newEnd, options);
this.setWindow(newStart, newEnd, options, callback);
}; };
/** /**
@ -743,9 +765,14 @@ Core.prototype.zoomIn = function(percentage, options) {
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Function} a callback funtion to be executed at the end of this function
*/ */
Core.prototype.zoomOut = function(percentage, options) {
Core.prototype.zoomOut = function(percentage, options, callback) {
if (!percentage || percentage < 0 || percentage > 1) return if (!percentage || percentage < 0 || percentage > 1) return
if (typeof arguments[1] == "function") {
callback = arguments[1]
options = {};
}
var range = this.getWindow(); var range = this.getWindow();
var start = range.start.valueOf(); var start = range.start.valueOf();
var end = range.end.valueOf(); var end = range.end.valueOf();
@ -753,7 +780,7 @@ Core.prototype.zoomOut = function(percentage, options) {
var newStart = start - interval * percentage / 2; var newStart = start - interval * percentage / 2;
var newEnd = end + interval * percentage / 2; var newEnd = end + interval * percentage / 2;
this.setWindow(newStart, newEnd, options);
this.setWindow(newStart, newEnd, options, callback);
}; };
/** /**

+ 50
- 18
lib/timeline/Range.js View File

@ -138,7 +138,10 @@ Range.prototype.startRolling = function() {
var end = t + interval / 2; var end = t + interval / 2;
var animation = (me.options && me.options.animation !== undefined) ? me.options.animation : true; var animation = (me.options && me.options.animation !== undefined) ? me.options.animation : true;
me.setRange(start, end, false);
var options = {
animation: false
};
me.setRange(start, end, options);
// determine interval to refresh // determine interval to refresh
var scale = me.conversion(me.body.domProps.center.width).scale; var scale = me.conversion(me.body.domProps.center.width).scale;
@ -169,29 +172,36 @@ Range.prototype.stopRolling = function() {
* Set a new start and end range * Set a new start and end range
* @param {Date | Number | String} [start] * @param {Date | Number | String} [start]
* @param {Date | Number | String} [end] * @param {Date | Number | String} [end]
* @param {boolean | {duration: number, easingFunction: string}} [animation=false]
* If true (default), the range is animated
* @param {Object} options Available options:
* {Boolean | {duration: number, easingFunction: string}} [animation=false]
* If true, the range is animated
* smoothly to the new window. An object can be * smoothly to the new window. An object can be
* provided to specify duration and easing function. * provided to specify duration and easing function.
* Default duration is 500 ms, and default easing * Default duration is 500 ms, and default easing
* function is 'easeInOutQuad'. * function is 'easeInOutQuad'.
* @param {Boolean} [byUser=false]
* {Boolean} [byUser=false]
* {Event} event Mouse event
* {Function} a callback funtion to be executed at the end of this function
* *
*/ */
Range.prototype.setRange = function(start, end, animation, byUser, event) {
if (byUser !== true) {
byUser = false;
Range.prototype.setRange = function(start, end, options, callback) {
if (!options) {
options = {};
}
if (options.byUser !== true) {
options.byUser = false;
} }
var finalStart = start != undefined ? util.convert(start, 'Date').valueOf() : null; var finalStart = start != undefined ? util.convert(start, 'Date').valueOf() : null;
var finalEnd = end != undefined ? util.convert(end, 'Date').valueOf() : null; var finalEnd = end != undefined ? util.convert(end, 'Date').valueOf() : null;
this._cancelAnimation(); this._cancelAnimation();
if (animation) { // true or an Object
if (options.animation) { // true or an Object
var me = this; var me = this;
var initStart = this.start; var initStart = this.start;
var initEnd = this.end; var initEnd = this.end;
var duration = (typeof animation === 'object' && 'duration' in animation) ? animation.duration : 500;
var easingName = (typeof animation === 'object' && 'easingFunction' in animation) ? animation.easingFunction : 'easeInOutQuad';
var duration = (typeof options.animation === 'object' && 'duration' in options.animation) ? options.animation.duration : 500;
var easingName = (typeof options.animation === 'object' && 'easingFunction' in options.animation) ? options.animation.easingFunction : 'easeInOutQuad';
var easingFunction = util.easingFunctions[easingName]; var easingFunction = util.easingFunctions[easingName];
if (!easingFunction) { if (!easingFunction) {
throw new Error('Unknown easing function ' + JSON.stringify(easingName) + '. ' + throw new Error('Unknown easing function ' + JSON.stringify(easingName) + '. ' +
@ -217,8 +227,8 @@ Range.prototype.setRange = function(start, end, animation, byUser, event) {
var params = { var params = {
start: new Date(me.start), start: new Date(me.start),
end: new Date(me.end), end: new Date(me.end),
byUser:byUser,
event: event
byUser: options.byUser,
event: options.event
} }
if (changed) { if (changed) {
@ -228,6 +238,7 @@ Range.prototype.setRange = function(start, end, animation, byUser, event) {
if (done) { if (done) {
if (anyChanged) { if (anyChanged) {
me.body.emitter.emit('rangechanged', params); me.body.emitter.emit('rangechanged', params);
if (callback) { return callback() }
} }
} }
else { else {
@ -247,11 +258,12 @@ Range.prototype.setRange = function(start, end, animation, byUser, event) {
var params = { var params = {
start: new Date(this.start), start: new Date(this.start),
end: new Date(this.end), end: new Date(this.end),
byUser:byUser,
event: event
byUser: options.byUser,
event: options.event
}; };
this.body.emitter.emit('rangechange', params); this.body.emitter.emit('rangechange', params);
this.body.emitter.emit('rangechanged', params); this.body.emitter.emit('rangechanged', params);
if (callback) { return callback() }
} }
} }
}; };
@ -600,7 +612,12 @@ Range.prototype._onMouseWheel = function(event) {
var newStart = this.start - diff; var newStart = this.start - diff;
var newEnd = this.end - diff; var newEnd = this.end - diff;
this.setRange(newStart, newEnd, false, true, event);
var options = {
animation: false,
byUser: true,
event: event
}
this.setRange(newStart, newEnd, options);
} }
return; return;
} }
@ -698,7 +715,12 @@ Range.prototype._onPinch = function (event) {
newEnd = safeEnd; newEnd = safeEnd;
} }
this.setRange(newStart, newEnd, false, true, event);
var options = {
animation: false,
byUser: true,
event: event
}
this.setRange(newStart, newEnd, options);
this.startToFront = false; // revert to default this.startToFront = false; // revert to default
this.endToFront = true; // revert to default this.endToFront = true; // revert to default
@ -802,7 +824,12 @@ Range.prototype.zoom = function(scale, center, delta, event) {
newEnd = safeEnd; newEnd = safeEnd;
} }
this.setRange(newStart, newEnd, false, true, event);
var options = {
animation: false,
byUser: true,
event: event
}
this.setRange(newStart, newEnd, options);
this.startToFront = false; // revert to default this.startToFront = false; // revert to default
this.endToFront = true; // revert to default this.endToFront = true; // revert to default
@ -843,7 +870,12 @@ Range.prototype.moveTo = function(moveTo) {
var newStart = this.start - diff; var newStart = this.start - diff;
var newEnd = this.end - diff; var newEnd = this.end - diff;
this.setRange(newStart, newEnd, false, true, null);
var options = {
animation: false,
byUser: true,
event: null
}
this.setRange(newStart, newEnd, options);
}; };
module.exports = Range; module.exports = Range;

+ 2
- 2
lib/timeline/Timeline.js View File

@ -382,7 +382,7 @@ Timeline.prototype.focus = function(id, options) {
var interval = Math.max((this.range.end - this.range.start), (end - start) * 1.1); var interval = Math.max((this.range.end - this.range.start), (end - start) * 1.1);
var animation = (options && options.animation !== undefined) ? options.animation : true; var animation = (options && options.animation !== undefined) ? options.animation : true;
this.range.setRange(middle - interval / 2, middle + interval / 2, animation);
this.range.setRange(middle - interval / 2, middle + interval / 2, { animation: animation });
} }
}; };
@ -409,7 +409,7 @@ Timeline.prototype.fit = function (options) {
else { else {
// exactly fit the items (plus a small margin) // exactly fit the items (plus a small margin)
range = this.getItemRange(); range = this.getItemRange();
this.range.setRange(range.min, range.max, animation);
this.range.setRange(range.min, range.max, { animation: animation });
} }
}; };

Loading…
Cancel
Save