diff --git a/HISTORY.md b/HISTORY.md
index 74cf8c49..cfb0404a 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -13,6 +13,7 @@ http://visjs.org
- Added property `length` holding the total number of items to the `DataSet`
and `DataView`.
+- Added a method `refresh()` to the `DataView`, to update filter results.
### Timeline
diff --git a/docs/dataview.html b/docs/dataview.html
index 159ad720..316da77a 100644
--- a/docs/dataview.html
+++ b/docs/dataview.html
@@ -219,6 +219,22 @@ var data = new vis.DataView(dataset, options)
+
+ refresh() |
+ none |
+
+ Refresh the filter results of a DataView. Useful when the filter function contains dynamic properties, like:
+
+ var data = new vis.DataSet(...);
+var view = new vis.DataView(data, {
+ filter: function (item) {
+ return item.value > threshold;
+ }
+});
+ In this example, threshold is an external parameter. When the value of threshold changes, the DataView must be notified that the filter results may have changed by calling DataView.refresh() .
+ |
+
+
setDataSet(data)
diff --git a/lib/DataView.js b/lib/DataView.js
index c5fbdfb8..cc4e04bd 100644
--- a/lib/DataView.js
+++ b/lib/DataView.js
@@ -79,6 +79,48 @@ DataView.prototype.setData = function (data) {
}
};
+/**
+ * Refresh the DataView. Useful when the DataView has a filter function
+ * containing a variable parameter.
+ */
+DataView.prototype.refresh = function () {
+ var id;
+ var ids = this._data.getIds({filter: this._options && this._options.filter});
+ var newIds = {};
+ var added = [];
+ var removed = [];
+
+ // check for additions
+ for (var i = 0; i < ids.length; i++) {
+ id = ids[i];
+ newIds[id] = true;
+ if (!this._ids[id]) {
+ added.push(id);
+ this._ids[id] = true;
+ this.length++;
+ }
+ }
+
+ // check for removals
+ for (id in this._ids) {
+ if (this._ids.hasOwnProperty(id)) {
+ if (!newIds[id]) {
+ removed.push(id);
+ delete this._ids[id];
+ this.length--;
+ }
+ }
+ }
+
+ // trigger events
+ if (added.length) {
+ this._trigger('add', {items: added});
+ }
+ if (removed.length) {
+ this._trigger('remove', {items: removed});
+ }
+};
+
/**
* Get data from the data view
*
diff --git a/test/DataView.test.js b/test/DataView.test.js
index 43110ba2..bb8ff1f9 100644
--- a/test/DataView.test.js
+++ b/test/DataView.test.js
@@ -94,4 +94,57 @@ describe('DataView', function () {
assert.equal(group2.length, 0);
});
+
+ it('should refresh a DataView with filter', function () {
+ var data = new DataSet([
+ {id:1, value:2},
+ {id:2, value:4},
+ {id:3, value:7}
+ ]);
+
+ var threshold = 5;
+
+ // create a view. The view has a filter with a dynamic property `threshold`
+ var view = new DataView(data, {
+ filter: function (item) {
+ return item.value < threshold;
+ }
+ });
+
+ var added, updated, removed;
+ view.on('add', function (event, props) {added = added.concat(props.items)});
+ view.on('update', function (event, props) {updated = updated.concat(props.items)});
+ view.on('remove', function (event, props) {removed = removed.concat(props.items)});
+
+ assert.deepEqual(view.get(), [
+ {id:1, value:2},
+ {id:2, value:4}
+ ]);
+
+ // change the threshold to 3
+ added = [];
+ updated = [];
+ removed = [];
+ threshold = 3;
+ view.refresh();
+ assert.deepEqual(view.get(), [{id:1, value:2}]);
+ assert.deepEqual(added, []);
+ assert.deepEqual(updated, []);
+ assert.deepEqual(removed, [2]);
+
+ // change threshold to 8
+ added = [];
+ updated = [];
+ removed = [];
+ threshold = 8;
+ view.refresh();
+ assert.deepEqual(view.get(), [
+ {id:1, value:2},
+ {id:2, value:4},
+ {id:3, value:7}
+ ]);
+ assert.deepEqual(added, [2, 3]);
+ assert.deepEqual(updated, []);
+ assert.deepEqual(removed, []);
+ })
});
|