Skip to content

Commit

Permalink
Implemented DataSet.setOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong committed Oct 28, 2014
1 parent eb4f3c4 commit 6ec184e
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 16 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 35 additions & 1 deletion docs/dataset.html
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ <h2 id="Construction">Construction</h2>
Default value is <code>Infinity</code>.
</li>
</ul>

</td>
</tr>
</table>
Expand Down Expand Up @@ -326,6 +325,41 @@ <h2 id="Methods">Methods</h2>
</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])
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
42 changes: 34 additions & 8 deletions lib/DataSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
90 changes: 83 additions & 7 deletions lib/Queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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;
}
};

/**
Expand Down Expand Up @@ -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);
Expand Down
38 changes: 38 additions & 0 deletions test/DataSet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 4 additions & 0 deletions test/Queue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,8 @@ describe('Queue', function () {
assert.equal(obj.count, 2);
});

// TODO: test Queue.setOptions

// TODO: test Queue.destroy

});

0 comments on commit 6ec184e

Please sign in to comment.