Browse Source

Use requestAnimationFrame to throttle redraws

codeClimate
Greg Kubisa 8 years ago
parent
commit
ff3948f85c
7 changed files with 25 additions and 47 deletions
  1. +9
    -16
      docs/timeline/index.html
  2. +1
    -1
      index-timeline-graph2d.js
  3. +3
    -4
      lib/timeline/Core.js
  4. +2
    -3
      lib/timeline/Timeline.js
  5. +0
    -2
      lib/timeline/optionsGraph2d.js
  6. +1
    -3
      lib/timeline/optionsTimeline.js
  7. +9
    -18
      lib/util.js

+ 9
- 16
docs/timeline/index.html View File

@ -31,13 +31,13 @@
<script language="JavaScript"> <script language="JavaScript">
smoothScroll.init(); smoothScroll.init();
</script> </script>
<!-- Tipue vendor css --> <!-- Tipue vendor css -->
<link href="../css/tipuesearch.css" rel="stylesheet"> <link href="../css/tipuesearch.css" rel="stylesheet">
<!-- Tipue vendor css --> <!-- Tipue vendor css -->
<link href="../css/tipuesearch.css" rel="stylesheet"> <link href="../css/tipuesearch.css" rel="stylesheet">
<script type="text/javascript" src="../js/toggleTable.js"></script> <script type="text/javascript" src="../js/toggleTable.js"></script>
</head> </head>
<body onload="prettyPrint();"> <body onload="prettyPrint();">
@ -213,7 +213,7 @@
or a DataView (offering 1 way data binding). or a DataView (offering 1 way data binding).
Items are regular objects and can contain the properties <code>start</code>, Items are regular objects and can contain the properties <code>start</code>,
<code>end</code> (optional), <code>content</code>, <code>end</code> (optional), <code>content</code>,
<code>group</code> (optional), <code>className</code> (optional),
<code>group</code> (optional), <code>className</code> (optional),
<code>editable</code> (optional), and <code>style</code> (optional). <code>editable</code> (optional), and <code>style</code> (optional).
</p> </p>
@ -624,7 +624,7 @@ function (option, path) {
If no <code>order</code> properties are provided, the order will be undetermined. If no <code>order</code> properties are provided, the order will be undetermined.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>groupOrderSwap</td> <td>groupOrderSwap</td>
<td>Function</td> <td>Function</td>
@ -787,7 +787,7 @@ function (option, path) {
Only applicable when option <code>selectable</code> is <code>true</code>. Only applicable when option <code>selectable</code> is <code>true</code>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="font-size: 0.9em">multiselectPerGroup</td> <td style="font-size: 0.9em">multiselectPerGroup</td>
<td>boolean</td> <td>boolean</td>
@ -805,7 +805,7 @@ function (option, path) {
<td>Callback function triggered when an item is about to be added: when the user double taps an empty space in the Timeline. See section <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.add</code> are set <code><code>true</code></code>. <td>Callback function triggered when an item is about to be added: when the user double taps an empty space in the Timeline. See section <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.add</code> are set <code><code>true</code></code>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>onAddGroup</td> <td>onAddGroup</td>
<td>function</td> <td>function</td>
@ -829,7 +829,7 @@ function (option, path) {
<td>Callback function triggered when an item has been moved: after the user has dragged the item to an other position. See section <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.updateTime</code> or <code>editable.updateGroup</code> are set <code><code>true</code></code>. <td>Callback function triggered when an item has been moved: after the user has dragged the item to an other position. See section <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.updateTime</code> or <code>editable.updateGroup</code> are set <code><code>true</code></code>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>onMoveGroup</td> <td>onMoveGroup</td>
<td>function</td> <td>function</td>
@ -853,7 +853,7 @@ function (option, path) {
<td>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 <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.remove</code> are set <code><code>true</code></code>. <td>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 <a href="#Editing_Items">Editing Items</a> for more information. Only applicable when both options <code>selectable</code> and <code>editable.remove</code> are set <code><code>true</code></code>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>onRemoveGroup</td> <td>onRemoveGroup</td>
<td>function</td> <td>function</td>
@ -967,13 +967,6 @@ function (option, path) {
<td>A template function used to generate the contents of the items. The function is called by the Timeline with an items data as argument, and must return HTML code as result. When the option template is specified, the items do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td> <td>A template function used to generate the contents of the items. The function is called by the Timeline with an items data as argument, and must return HTML code as result. When the option template is specified, the items do not need to have a field <code>content</code>. See section <a href="#Templates">Templates</a> for a detailed explanation.</td>
</tr> </tr>
<tr>
<td>throttleRedraw</td>
<td>number</td>
<td><code>0</code></td>
<td>Limit the maximum number of redraws to once every x milliseconds. For example setting throttleRedraw to `100` milliseconds will limit the number of redraws to 10 times per second.</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','timeAxis', this);"> <tr class='toggle collapsible' onclick="toggleTable('optionTable','timeAxis', this);">
<td><span parent="timeAxis" class="right-caret"></span> timeAxis</td> <td><span parent="timeAxis" class="right-caret"></span> timeAxis</td>
<td>Object</td> <td>Object</td>

+ 1
- 1
index-timeline-graph2d.js View File

@ -44,4 +44,4 @@ exports.timeline = {
// bundled external libraries // bundled external libraries
exports.moment = require('./lib/module/moment'); exports.moment = require('./lib/module/moment');
exports.Hammer = require('./lib/module/hammer'); exports.Hammer = require('./lib/module/hammer');
exports.keycharm = require('keycharm');
exports.keycharm = require('keycharm');

+ 3
- 4
lib/timeline/Core.js View File

@ -222,8 +222,7 @@ Core.prototype.setOptions = function (options) {
var fields = [ var fields = [
'width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'width', 'height', 'minHeight', 'maxHeight', 'autoResize',
'start', 'end', 'clickToUse', 'dataAttributes', 'hiddenDates', 'start', 'end', 'clickToUse', 'dataAttributes', 'hiddenDates',
'locale', 'locales', 'moment', 'rtl',
'throttleRedraw'
'locale', 'locales', 'moment', 'rtl'
]; ];
util.selectiveExtend(fields, this.options, options); util.selectiveExtend(fields, this.options, options);
@ -233,7 +232,7 @@ Core.prototype.setOptions = function (options) {
this.dom.leftContainer = this.dom.rightContainer; this.dom.leftContainer = this.dom.rightContainer;
this.dom.rightContainer = contentContainer; this.dom.rightContainer = contentContainer;
this.dom.container.style.direction = "rtl"; this.dom.container.style.direction = "rtl";
this.dom.backgroundVertical.className = 'vis-panel vis-background vis-vertical-rtl'; }
this.dom.backgroundVertical.className = 'vis-panel vis-background vis-vertical-rtl'; }
this.options.orientation = {item:undefined,axis:undefined}; this.options.orientation = {item:undefined,axis:undefined};
if ('orientation' in options) { if ('orientation' in options) {
@ -330,7 +329,7 @@ Core.prototype.setOptions = function (options) {
// override redraw with a throttled version // override redraw with a throttled version
if (!this._origRedraw) { if (!this._origRedraw) {
this._origRedraw = this._redraw.bind(this); this._origRedraw = this._redraw.bind(this);
this._redraw = util.throttle(this._origRedraw, this.options.throttleRedraw);
this._redraw = util.throttle(this._origRedraw);
} else { } else {
// Not the initial run: redraw everything // Not the initial run: redraw everything
this._redraw(); this._redraw();

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

@ -47,7 +47,6 @@ function Timeline (container, items, groups, options) {
end: null, end: null,
autoResize: true, autoResize: true,
throttleRedraw: 0, // ms
orientation: { orientation: {
axis: 'bottom', // axis orientation: 'bottom', 'top', or 'both' axis: 'bottom', // axis orientation: 'bottom', 'top', or 'both'
@ -426,7 +425,7 @@ Timeline.prototype.getItemRange = function () {
var start = getStart(item); var start = getStart(item);
var end = getEnd(item); var end = getEnd(item);
if (this.options.rtl) { if (this.options.rtl) {
var startSide = start - (item.getWidthRight() + 10) * factor; var startSide = start - (item.getWidthRight() + 10) * factor;
var endSide = end + (item.getWidthLeft() + 10) * factor; var endSide = end + (item.getWidthLeft() + 10) * factor;
@ -434,7 +433,7 @@ Timeline.prototype.getItemRange = function () {
var startSide = start - (item.getWidthLeft() + 10) * factor; var startSide = start - (item.getWidthLeft() + 10) * factor;
var endSide = end + (item.getWidthRight() + 10) * factor; var endSide = end + (item.getWidthRight() + 10) * factor;
} }
if (startSide < min) { if (startSide < min) {
min = startSide; min = startSide;

+ 0
- 2
lib/timeline/optionsGraph2d.js View File

@ -100,7 +100,6 @@ let allOptions = {
}, },
autoResize: {boolean}, autoResize: {boolean},
throttleRedraw: {number},
clickToUse: {boolean}, clickToUse: {boolean},
end: {number, date, string, moment}, end: {number, date, string, moment},
format: { format: {
@ -225,7 +224,6 @@ let configureOptions = {
}, },
autoResize: true, autoResize: true,
throttleRedraw: [10, 0, 1000, 10],
clickToUse: false, clickToUse: false,
end: '', end: '',
format: { format: {

+ 1
- 3
lib/timeline/optionsTimeline.js View File

@ -27,7 +27,6 @@ let allOptions = {
align: {string}, align: {string},
rtl: {boolean, 'undefined': 'undefined'}, rtl: {boolean, 'undefined': 'undefined'},
autoResize: {boolean}, autoResize: {boolean},
throttleRedraw: {number},
clickToUse: {boolean}, clickToUse: {boolean},
dataAttributes: {string, array}, dataAttributes: {string, array},
editable: { editable: {
@ -145,7 +144,6 @@ let configureOptions = {
align: ['center', 'left', 'right'], align: ['center', 'left', 'right'],
direction: false, direction: false,
autoResize: true, autoResize: true,
throttleRedraw: [10, 0, 1000, 10],
clickToUse: false, clickToUse: false,
// dataAttributes: ['all'], // FIXME: can be 'all' or string[] // dataAttributes: ['all'], // FIXME: can be 'all' or string[]
editable: { editable: {
@ -229,4 +227,4 @@ let configureOptions = {
} }
}; };
export {allOptions, configureOptions};
export {allOptions, configureOptions};

+ 9
- 18
lib/util.js View File

@ -702,29 +702,20 @@ exports.updateProperty = function (object, key, value) {
}; };
/** /**
* Throttle the given function to be only executed once every `wait` milliseconds
* Throttle the given function to be only executed once per animation frame
* @param {function} fn * @param {function} fn
* @param {number} wait Time in milliseconds
* @returns {function} Returns the throttled function * @returns {function} Returns the throttled function
*/ */
exports.throttle = function (fn, wait) {
var timeout = null;
var needExecution = false;
exports.throttle = function (fn) {
var scheduled = false;
return function throttled () { return function throttled () {
if (!timeout) {
needExecution = false;
fn();
timeout = setTimeout(function() {
timeout = null;
if (needExecution) {
throttled();
}
}, wait)
}
else {
needExecution = true;
if (!scheduled) {
scheduled = true;
requestAnimationFrame(function () {
scheduled = false;
fn();
});
} }
} }
}; };

Loading…
Cancel
Save