From 6afc095d6300d63201835ba277b4b8693a4aed0b Mon Sep 17 00:00:00 2001 From: Yotam Berkowitz Date: Sat, 7 Oct 2017 18:59:45 +0300 Subject: [PATCH] On timeline loaded (#3530) * initial trial * Add onInitialDrawComplete * Add docs * Add to eventListeners examples * Keeping things DRY * Remove callback insertion * Remove call * Fix initial real first draw complete and fix comments from review * remove all --- docs/timeline/index.html | 50 +++++++++++-------- .../timeline/interaction/eventListeners.html | 3 +- lib/timeline/Core.js | 7 ++- lib/timeline/Timeline.js | 30 +++++++---- lib/timeline/optionsTimeline.js | 1 + 5 files changed, 59 insertions(+), 32 deletions(-) diff --git a/docs/timeline/index.html b/docs/timeline/index.html index f30ddbe2..0b6f46c0 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -579,7 +579,7 @@ function (option, path) { editable boolean or Object false - If true, the items in the timeline can be manipulated. Only applicable when option selectable is true. See also the callbacks onAdd, onUpdate, onMove, and onRemove. When editable is an object, one can enable or disable individual manipulation actions. + If true, the items in the timeline can be manipulated. Only applicable when option selectable is true. See also the callbacks onAdd, onUpdate, onMove, and onRemove. When editable is an object, one can enable or disable individual manipulation actions. See section Editing Items for a detailed explanation. @@ -901,10 +901,10 @@ function (option, path) { onAdd function none - Callback function triggered when an item is about to be added: when the user double taps an empty space in the Timeline. See section Editing Items for more information. Only applicable when both options selectable and editable.add are set true. + Callback function triggered when an item is about to be added: when the user double taps an empty space in the Timeline. See section Editing Items for more information. Only applicable when both options selectable and editable.add are set true. - + onAddGroup function @@ -912,31 +912,31 @@ function (option, path) { Callback function triggered when a group is about to be added. The signature and semantics are the same as for onAdd. - + onDropObjectOnItem function none Callback function triggered when an object containing target:'item' in its drag data is dropped in to a timeline item. - + - onUpdate + onInitialDrawComplete function none - Callback function triggered when an item is about to be updated, when the user double taps an item in the Timeline. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. + Callback function triggered when the timeline is initially drawn. This function fires once per timeline creation. - + onMove function none - Callback function triggered when an item has been moved: after the user has dragged the item to an other position. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. + Callback function triggered when an item has been moved: after the user has dragged the item to an other position. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. - + onMoveGroup function @@ -944,23 +944,23 @@ function (option, path) { Callback function triggered when a group has been moved: after the user has dragged the group to an other position. The signature and semantics are the same as for onMove. - + onMoving function none - Callback function triggered repeatedly when an item is being moved. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. + Callback function triggered repeatedly when an item is being moved. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. - + onRemove function none - Callback function triggered when an item is about to be removed: when the user tapped the delete button on the top right of a selected item. See section Editing Items for more information. Only applicable when both options selectable and editable.remove are set true. + Callback function triggered when an item is about to be removed: when the user tapped the delete button on the top right of a selected item. See section Editing Items for more information. Only applicable when both options selectable and editable.remove are set true. - + onRemoveGroup function @@ -968,7 +968,15 @@ function (option, path) { Callback function triggered when a group is about to be removed. The signature and semantics are the same as for onRemove. - + + + onUpdate + function + none + Callback function triggered when an item is about to be updated, when the user double taps an item in the Timeline. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true. + + + order function @@ -1054,7 +1062,7 @@ function (option, path) { By default, the timeline shows both minor and major date labels on the time axis. For example the minor labels show minutes and the major labels show hours. - When showMajorLabels is false, no major labels + When showMajorLabels is false, no major labels are shown. @@ -1065,7 +1073,7 @@ function (option, path) { By default, the timeline shows both minor and major date labels on the time axis. For example the minor labels show minutes and the major labels show hours. - When showMinorLabels is false, no minor labels + When showMinorLabels is false, no minor labels are shown. When both showMajorLabels and showMinorLabels are false, no horizontal axis will be visible. @@ -1225,7 +1233,7 @@ function (option, path) { true Specifies whether the Timeline can be zoomed by pinching or scrolling in the window. - Only applicable when option moveable is set true. + Only applicable when option moveable is set true. @@ -1235,7 +1243,7 @@ function (option, path) { '' Specifies whether the Timeline is only zoomed when an additional key is down. Available values are '' (does not apply), 'altKey', 'ctrlKey', or 'metaKey'. - Only applicable when option moveable is set true. + Only applicable when option moveable is set true. @@ -1776,7 +1784,7 @@ timeline.off('select', onSelect);

Editing Items

- When the Timeline is configured to be editable (both options selectable and editable are true), the user can: + When the Timeline is configured to be editable (both options selectable and editable are true), the user can:

  • Select an item by clicking it, and use ctrl+click to or shift+click to select multiple items (when multiselect: true).
  • diff --git a/examples/timeline/interaction/eventListeners.html b/examples/timeline/interaction/eventListeners.html index ae16dc67..6b07d5b6 100644 --- a/examples/timeline/interaction/eventListeners.html +++ b/examples/timeline/interaction/eventListeners.html @@ -34,7 +34,8 @@ var container = document.getElementById('visualization'); var options = { - editable: true + editable: true, + onInitialDrawComplete: function() { logEvent('Timeline initial draw completed', {}); }, }; var timeline = new vis.Timeline(container, items, options); diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index b266ef7d..134c1580 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -111,6 +111,11 @@ Core.prototype._create = function (container) { this._redraw(); } }.bind(this)); + this.on('rangechanged', function () { + if (!this.initialRangeChangeDone) { + this.initialRangeChangeDone = true; + } + }.bind(this)); this.on('touch', this._onTouch.bind(this)); this.on('panmove', this._onDrag.bind(this)); @@ -324,6 +329,7 @@ Core.prototype._create = function (container) { this.redrawCount = 0; this.initialDrawDone = false; + this.initialRangeChangeDone = false; // attach the root panel to the provided container if (!container) throw new Error('No container provided'); @@ -1008,7 +1014,6 @@ Core.prototype._redraw = function() { } else { this.redrawCount = 0; } - this.initialDrawDone = true; //Emit public 'changed' event for UI updates, see issue #1592 this.body.emitter.emit("changed"); diff --git a/lib/timeline/Timeline.js b/lib/timeline/Timeline.js index 3484b22a..60974393 100644 --- a/lib/timeline/Timeline.js +++ b/lib/timeline/Timeline.js @@ -58,13 +58,14 @@ function Timeline (container, items, groups, options) { width: null, height: null, maxHeight: null, - minHeight: null + minHeight: null, }; this.options = util.deepExtend({}, this.defaultOptions); // Create the DOM, props, and emitter this._create(container); if (!options || (options && typeof options.rtl == "undefined")) { + this.dom.root.style.visibility = 'hidden'; var directionFromDom, domNode = this.dom.root; while (!directionFromDom && domNode) { directionFromDom = window.getComputedStyle(domNode, null).direction; @@ -76,6 +77,7 @@ function Timeline (container, items, groups, options) { } this.options.rollingMode = options && options.rollingMode; + this.options.onInitialDrawComplete = options && options.onInitialDrawComplete; // all components listed here will be repainted automatically this.components = []; @@ -160,11 +162,11 @@ function Timeline (container, items, groups, options) { } //Single time autoscale/fit - this.fitDone = false; + this.initialFitDone = false; this.on('changed', function (){ if (this.itemsData == null || this.options.rollingMode) return; - if (!me.fitDone) { - me.fitDone = true; + if (!me.initialFitDone) { + me.initialFitDone = true; if (me.options.start != undefined || me.options.end != undefined) { if (me.options.start == undefined || me.options.end == undefined) { var range = me.getItemRange(); @@ -173,11 +175,20 @@ function Timeline (container, items, groups, options) { var start = me.options.start != undefined ? me.options.start : range.min; var end = me.options.end != undefined ? me.options.end : range.max; me.setWindow(start, end, {animation: false}); - } - else { + } else { me.fit({animation: false}); } } + + if (!me.initialDrawDone && me.initialRangeChangeDone) { + me.initialDrawDone = true; + me.dom.root.style.visibility = 'visible'; + if (me.options.onInitialDrawComplete) { + setTimeout(() => { + return me.options.onInitialDrawComplete(); + }, 0) + } + } }); // apply options @@ -472,8 +483,9 @@ Timeline.prototype.focus = function(id, options) { * provided to specify duration and easing function. * Default duration is 500 ms, and default easing * function is 'easeInOutQuad'. + * @param {function} [callback] */ -Timeline.prototype.fit = function (options) { +Timeline.prototype.fit = function (options, callback) { var animation = (options && options.animation !== undefined) ? options.animation : true; var range; @@ -481,12 +493,12 @@ Timeline.prototype.fit = function (options) { if (dataset.length === 1 && dataset.get()[0].end === undefined) { // a single item -> don't fit, just show a range around the item from -4 to +3 days range = this.getDataRange(); - this.moveTo(range.min.valueOf(), {animation}); + this.moveTo(range.min.valueOf(), {animation}, callback); } else { // exactly fit the items (plus a small margin) range = this.getItemRange(); - this.range.setRange(range.min, range.max, { animation: animation }); + this.range.setRange(range.min, range.max, { animation: animation }, callback); } }; diff --git a/lib/timeline/optionsTimeline.js b/lib/timeline/optionsTimeline.js index 928bb43f..820b6b3e 100644 --- a/lib/timeline/optionsTimeline.js +++ b/lib/timeline/optionsTimeline.js @@ -126,6 +126,7 @@ let allOptions = { onAddGroup: {'function': 'function'}, onMoveGroup: {'function': 'function'}, onRemoveGroup: {'function': 'function'}, + onInitialDrawComplete: {'function': 'function'}, order: {'function': 'function'}, orientation: { axis: {string,'undefined': 'undefined'},