Browse Source

Implemented DataSet.setOptions

v3_develop
jos 9 years ago
parent
commit
6ec184e737
7 changed files with 196 additions and 16 deletions
  1. +1
    -0
      HISTORY.md
  2. +35
    -1
      docs/dataset.html
  3. +1
    -0
      index.js
  4. +34
    -8
      lib/DataSet.js
  5. +83
    -7
      lib/Queue.js
  6. +38
    -0
      test/DataSet.test.js
  7. +4
    -0
      test/Queue.test.js

+ 1
- 0
HISTORY.md View File

@ -17,6 +17,7 @@ http://visjs.org
### DataSet
- Support for queueing of changes, and flushing them at once.
- Implemented `DataSet.setOptions`. Only applicable for the `queue` options.
## 2014-10-24, version 3.6.2

+ 35
- 1
docs/dataset.html View File

@ -185,7 +185,6 @@ var data = new vis.DataSet([data] [, options])
Default value is <code>Infinity</code>.
</li>
</ul>
</td>
</tr>
</table>
@ -326,6 +325,41 @@ var data = new vis.DataSet([data] [, options])
</td>
</tr>
<tr>
<td>
setOptions(options)
</td>
<td>none</td>
<td>
Set options for the DataSet. Available options:
<ul>
<li>
<code>queue</code><br>
Queue data changes ('add', 'update', 'remove') and flush them at once.
The queue can be flushed manually by calling
<code>DataSet.flush()</code>, or can be flushed after a configured delay
or maximum number of entries.
<br>
<br>
When <code>queue</code> is true, a queue is created with default options.
When <code>queue</code> is false, an existing queue will be flushed and removed.
Options can be specified by providing an object:
<ul>
<li><code>delay: number</code><br>
The queue will be flushed automatically after an inactivity of this
delay in milliseconds. Default value is <code>null</code>.
<li><code>max: number</code><br>
When the queue exceeds the given maximum number
of entries, the queue is flushed automatically.
Default value is <code>Infinity</code>.
</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td>
update(data [, senderId])

+ 1
- 0
index.js View File

@ -5,6 +5,7 @@ exports.DOMutil = require('./lib/DOMutil');
// data
exports.DataSet = require('./lib/DataSet');
exports.DataView = require('./lib/DataView');
exports.Queue = require('./lib/Queue');
// Graph3d
exports.Graph3d = require('./lib/graph3d/Graph3d');

+ 34
- 8
lib/DataSet.js View File

@ -84,16 +84,42 @@ function DataSet (data, options) {
this.add(data);
}
// change the dataset in a queued one
if (this._options.queue) {
var queue = {
replace: ['add', 'update', 'remove']
};
if (typeof this._options.queue === 'object') util.extend(queue, this._options.queue);
Queue.extend(this, queue);
}
this.setOptions(options);
}
/**
* @param {Object} [options] Available options:
* {Object} queue Queue changes to the DataSet,
* flush them all at once.
* Queue options:
* - {number} delay Delay in ms, null by default
* - {number} max Maximum number of entries in the queue, Infinity by default
* @param options
*/
DataSet.prototype.setOptions = function(options) {
if (options && options.queue !== undefined) {
if (options.queue === false) {
// delete queue if loaded
if (this._queue) {
this._queue.destroy();
delete this._queue;
}
}
else {
// create queue and update its options
if (!this._queue) {
this._queue = Queue.extend(this, {
replace: ['add', 'update', 'remove']
});
}
if (typeof options.queue === 'object') {
this._queue.setOptions(options.queue);
}
}
}
};
/**
* Subscribe to an event, add an event listener
* @param {String} event Event name. Available events: 'put', 'update',

+ 83
- 7
lib/Queue.js View File

@ -2,7 +2,7 @@
* A queue
* @param {Object} options
* Available options:
* - delay: number When a number, the queue will be flushed
* - delay: number When provided, the queue will be flushed
* automatically after an inactivity of this delay
* in milliseconds.
* Default value is null.
@ -13,14 +13,41 @@
*/
function Queue(options) {
// options
this.delay = options && typeof options.delay === 'number' ? options.delay : null;
this.max = options && typeof options.max === 'number' ? options.max : Infinity;
this.delay = null;
this.max = Infinity;
// properties
this._queue = [];
this._timeout = null;
this._extended = null;
this.setOptions(options);
}
/**
* Update the configuration of the queue
* @param {Object} options
* Available options:
* - delay: number When provided, the queue will be flushed
* automatically after an inactivity of this delay
* in milliseconds.
* Default value is null.
* - max: number When the queue exceeds the given maximum number
* of entries, the queue is flushed automatically.
* Default value of max is Infinity.
* @param options
*/
Queue.prototype.setOptions = function (options) {
if (options && typeof options.delay !== 'undefined') {
this.delay = options.delay;
}
if (options && typeof options.max !== 'undefined') {
this.max = options.max;
}
this._flushIfNeeded();
};
/**
* Extend an object with queuing functionality.
* The object will be extended with a function flush, and the methods provided
@ -31,13 +58,14 @@ function Queue(options) {
* - replace: Array.<string>
* A list with method names of the methods
* on the object to be replaced with queued ones.
* - delay: number When a number, the queue will be flushed
* - delay: number When provided, the queue will be flushed
* automatically after an inactivity of this delay
* in milliseconds.
* Default value is null.
* - max: number When the queue exceeds the given maximum number
* of entries, the queue is flushed automatically.
* Default value of max is Infinity.
* @return {Queue} Returns the created queue
*/
Queue.extend = function (object, options) {
var queue = new Queue(options);
@ -49,11 +77,51 @@ Queue.extend = function (object, options) {
queue.flush();
};
var methods = [{
name: 'flush',
original: undefined
}];
if (options && options.replace) {
for (var i = 0; i < options.replace.length; i++) {
queue.replace(object, options.replace[i]);
var name = options.replace[i];
methods.push({
name: name,
original: object[name]
});
queue.replace(object, name);
}
}
queue._extended = {
object: object,
methods: methods
};
return queue;
};
/**
* Destroy the queue. The queue will first flush all queued actions, and in
* case it has extended an object, will restore the original object.
*/
Queue.prototype.destroy = function () {
this.flush();
if (this._extended) {
var object = this._extended.object;
var methods = this._extended.methods;
for (var i = 0; i < methods.length; i++) {
var method = methods[i];
if (method.original) {
object[method.name] = method.original;
}
else {
delete object[method.name];
}
}
this._extended = null;
}
};
/**
@ -96,15 +164,23 @@ Queue.prototype.queue = function(entry) {
this._queue.push(entry);
}
this._flushIfNeeded();
};
/**
* Check whether the queue needs to be flushed
* @private
*/
Queue.prototype._flushIfNeeded = function () {
// flush when the maximum is exceeded.
if (this._queue.length > this.max) {
this.flush();
}
// flush after a period of inactivity when a delay is configured
if (typeof this.delay === 'number') {
clearTimeout(this._timeout);
if (this.queue.length > 0 && typeof this.delay === 'number') {
var me = this;
clearTimeout(this._timeout);
this._timeout = setTimeout(function () {
me.flush();
}, this.delay);

+ 38
- 0
test/DataSet.test.js View File

@ -236,4 +236,42 @@ describe('DataSet', function () {
}, 200)
});
it('should remove a queue from the dataset', function () {
var options = {queue: true};
var dataset = new DataSet([
{id: 1, content: 'Item 1'},
{id: 2, content: 'Item 2'}
], options);
assert.deepEqual(dataset.get(), [
{id: 1, content: 'Item 1'},
{id: 2, content: 'Item 2'}
]);
dataset.add({id: 3, content: 'Item 3'});
dataset.update({id: 1, content: 'Item 1 (updated)'});
dataset.remove(2);
assert.deepEqual(dataset.get(), [
{id: 1, content: 'Item 1'},
{id: 2, content: 'Item 2'}
]);
dataset.setOptions({queue: false}); // remove queue, should flush changes
assert.deepEqual(dataset.get(), [
{id: 1, content: 'Item 1 (updated)'},
{id: 3, content: 'Item 3'}
]);
dataset.add({id: 4, content: 'Item 4'});
assert.deepEqual(dataset.get(), [
{id: 1, content: 'Item 1 (updated)'},
{id: 3, content: 'Item 3'},
{id: 4, content: 'Item 4'}
]);
});
});

+ 4
- 0
test/Queue.test.js View File

@ -153,4 +153,8 @@ describe('Queue', function () {
assert.equal(obj.count, 2);
});
// TODO: test Queue.setOptions
// TODO: test Queue.destroy
});

Loading…
Cancel
Save