vega-functions
Version:
Custom functions for the Vega expression language.
94 lines (80 loc) • 2.31 kB
JavaScript
import {isTuple} from 'vega-dataflow';
import {isArray, isFunction, isObject, truthy} from 'vega-util';
function equal(a, b) {
return a === b || a !== a && b !== b ? true
: isArray(a) ? (
isArray(b) && a.length === b.length ? equalArray(a, b) : false
)
: isObject(a) && isObject(b) ? equalObject(a, b)
: false;
}
function equalArray(a, b) {
for (let i=0, n=a.length; i<n; ++i) {
if (!equal(a[i], b[i])) return false;
}
return true;
}
function equalObject(a, b) {
for (const key in a) {
if (!equal(a[key], b[key])) return false;
}
return true;
}
function removePredicate(props) {
return _ => equalObject(props, _);
}
/**
* Modify data in a dataset.
* @param {string} name - Dataset name
* @param {Array|Object} insert - Data to insert
* @param {boolean|Array|Object} remove - true to remove all, array/tuple to remove, or object to match
* @param {Object} toggle - Data to toggle
* @param {Object|Array} modify - Tuple or array of tuples to modify
* @param {Object} values - Field values to update
*/
export default function(name, insert, remove, toggle, modify, values) {
const df = this.context.dataflow,
data = this.context.data[name],
input = data.input,
stamp = df.stamp();
let changes = data.changes,
predicate, key;
if (df._trigger === false || !(input.value.length || insert || toggle)) {
// nothing to do!
return 0;
}
if (!changes || changes.stamp < stamp) {
data.changes = (changes = df.changeset());
changes.stamp = stamp;
df.runAfter(() => {
data.modified = true;
df.pulse(input, changes).run();
}, true, 1);
}
if (remove) {
predicate = remove === true ? truthy
: (isArray(remove) || isTuple(remove)) ? remove
: removePredicate(remove);
changes.remove(predicate);
}
if (insert) {
changes.insert(insert);
}
if (toggle) {
predicate = removePredicate(toggle);
if (input.value.some(predicate)) {
changes.remove(predicate);
} else {
changes.insert(toggle);
}
}
if (modify) {
if (isFunction(modify)) {
throw Error('modify parameter must be a data tuple, not a function');
}
for (key in values) {
changes.modify(modify, key, values[key]);
}
}
return 1;
}