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.

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