vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
5.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /**
  2. * A queue
  3. * @param {Object} options
  4. * Available options:
  5. * - delay: number When provided, the queue will be flushed
  6. * automatically after an inactivity of this delay
  7. * in milliseconds.
  8. * Default value is null.
  9. * - max: number When the queue exceeds the given maximum number
  10. * of entries, the queue is flushed automatically.
  11. * Default value of max is Infinity.
  12. * @constructor
  13. */
  14. function Queue(options) {
  15. // options
  16. this.delay = null;
  17. this.max = Infinity;
  18. // properties
  19. this._queue = [];
  20. this._timeout = null;
  21. this._extended = null;
  22. this.setOptions(options);
  23. }
  24. /**
  25. * Update the configuration of the queue
  26. * @param {Object} options
  27. * Available options:
  28. * - delay: number When provided, the queue will be flushed
  29. * automatically after an inactivity of this delay
  30. * in milliseconds.
  31. * Default value is null.
  32. * - max: number When the queue exceeds the given maximum number
  33. * of entries, the queue is flushed automatically.
  34. * Default value of max is Infinity.
  35. * @param options
  36. */
  37. Queue.prototype.setOptions = function (options) {
  38. if (options && typeof options.delay !== 'undefined') {
  39. this.delay = options.delay;
  40. }
  41. if (options && typeof options.max !== 'undefined') {
  42. this.max = options.max;
  43. }
  44. this._flushIfNeeded();
  45. };
  46. /**
  47. * Extend an object with queuing functionality.
  48. * The object will be extended with a function flush, and the methods provided
  49. * in options.replace will be replaced with queued ones.
  50. * @param {Object} object
  51. * @param {Object} options
  52. * Available options:
  53. * - replace: Array.<string>
  54. * A list with method names of the methods
  55. * on the object to be replaced with queued ones.
  56. * - delay: number When provided, the queue will be flushed
  57. * automatically after an inactivity of this delay
  58. * in milliseconds.
  59. * Default value is null.
  60. * - max: number When the queue exceeds the given maximum number
  61. * of entries, the queue is flushed automatically.
  62. * Default value of max is Infinity.
  63. * @return {Queue} Returns the created queue
  64. */
  65. Queue.extend = function (object, options) {
  66. var queue = new Queue(options);
  67. if (object.flush !== undefined) {
  68. throw new Error('Target object already has a property flush');
  69. }
  70. object.flush = function () {
  71. queue.flush();
  72. };
  73. var methods = [{
  74. name: 'flush',
  75. original: undefined
  76. }];
  77. if (options && options.replace) {
  78. for (var i = 0; i < options.replace.length; i++) {
  79. var name = options.replace[i];
  80. methods.push({
  81. name: name,
  82. original: object[name]
  83. });
  84. queue.replace(object, name);
  85. }
  86. }
  87. queue._extended = {
  88. object: object,
  89. methods: methods
  90. };
  91. return queue;
  92. };
  93. /**
  94. * Destroy the queue. The queue will first flush all queued actions, and in
  95. * case it has extended an object, will restore the original object.
  96. */
  97. Queue.prototype.destroy = function () {
  98. this.flush();
  99. if (this._extended) {
  100. var object = this._extended.object;
  101. var methods = this._extended.methods;
  102. for (var i = 0; i < methods.length; i++) {
  103. var method = methods[i];
  104. if (method.original) {
  105. object[method.name] = method.original;
  106. }
  107. else {
  108. delete object[method.name];
  109. }
  110. }
  111. this._extended = null;
  112. }
  113. };
  114. /**
  115. * Replace a method on an object with a queued version
  116. * @param {Object} object Object having the method
  117. * @param {string} method The method name
  118. */
  119. Queue.prototype.replace = function(object, method) {
  120. var me = this;
  121. var original = object[method];
  122. if (!original) {
  123. throw new Error('Method ' + method + ' undefined');
  124. }
  125. object[method] = function () {
  126. // create an Array with the arguments
  127. var args = [];
  128. for (var i = 0; i < arguments.length; i++) {
  129. args[i] = arguments[i];
  130. }
  131. // add this call to the queue
  132. me.queue({
  133. args: args,
  134. fn: original,
  135. context: this
  136. });
  137. };
  138. };
  139. /**
  140. * Queue a call
  141. * @param {function | {fn: function, args: Array} | {fn: function, args: Array, context: Object}} entry
  142. */
  143. Queue.prototype.queue = function(entry) {
  144. if (typeof entry === 'function') {
  145. this._queue.push({fn: entry});
  146. }
  147. else {
  148. this._queue.push(entry);
  149. }
  150. this._flushIfNeeded();
  151. };
  152. /**
  153. * Check whether the queue needs to be flushed
  154. * @private
  155. */
  156. Queue.prototype._flushIfNeeded = function () {
  157. // flush when the maximum is exceeded.
  158. if (this._queue.length > this.max) {
  159. this.flush();
  160. }
  161. // flush after a period of inactivity when a delay is configured
  162. clearTimeout(this._timeout);
  163. if (this.queue.length > 0 && typeof this.delay === 'number') {
  164. var me = this;
  165. this._timeout = setTimeout(function () {
  166. me.flush();
  167. }, this.delay);
  168. }
  169. };
  170. /**
  171. * Flush all queued calls
  172. */
  173. Queue.prototype.flush = function () {
  174. while (this._queue.length > 0) {
  175. var entry = this._queue.shift();
  176. entry.fn.apply(entry.context || entry.fn, entry.args || []);
  177. }
  178. };
  179. module.exports = Queue;