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 f30ddbe29..0b6f46c0e 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -579,7 +579,7 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

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 @@

Configuration Options

'' 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 @@

Events

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 ae16dc678..6b07d5b63 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 b266ef7de..134c1580b 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 3484b22a1..609743931 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 928bb43f4..820b6b3ef 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'},