Utilities API

Vega uses a set of JavaScript utilities throughout its implementation, including function generators, type checkers, log messages, and additional utilities for Object, Array and String values. These methods are bound to the top-level vega object, and can also be used in a stand-alone fashion by using the vega-util package. For additional utility methods for date-time values, see the Time Utilities API reference.

Utilities API Reference

Functions

Functions and function generators for accessing and comparing values.

# vega.accessor(function[, fields, name]) <>

Annotates a function instance with a string array of dependent data fields and a string name, and returns the input function. Assumes the input function takes an object (data tuple) as input, and that strings in the fields array correspond to object properties accessed by the function. Once annotated, Vega dataflows can track data field dependencies and generate appropriate output names (e.g., when computing aggregations) if the function is used as an accessor.

Internally, this method assigns the field array to the fields property of the input function, and the name to the fname property. To be future-proof, clients should not access these properties directly. Instead, use the accessorFields and accessorName methods.

# vega.accessorFields(accessor) <>

Returns the array of dependent field names for a given accessor function. Returns null if no field names have been set.

# vega.accessorName(accessor) <>

Returns the name string for a given accessor function. Returns null if no name has been set.

# vega.ascending(a, b) <>

A comparator function for sorting primitive and Date values in ascending order.

# vega.compare(fields[, orders]) <>

Generates a comparator function for sorting data values, based on the given set of fields and optional sort orders. The fields argument must be either a string, an accessor function, or an array of either. Strings indicate the name of object properties to sort by, in precedence order. Field strings may include nested properties (e.g., foo.bar.baz). The orders argument must be either a string or an array of strings; the valid string values are 'ascending' (for ascending sort order of the corresponding field) or 'descending' (for descending sort order of the corresponding field). If the orders argument is omitted, is shorter than the fields array, or includes values other than 'ascending' or 'descending', corresponding fields will default to ascending order.

# vega.constant(value) <>

Given an input value, returns a function that simply returns that value. If the input value is itself a function, that function is returned directly.

# vega.debounce(delay, func) <>

Generates a “debounced” function that delays invoking func until after delay milliseconds have elapsed since the last time the debounced function was invoked. Invocation passes up to one argument from the debounced function to func and does not preserve the this context.

# vega.field(field[, name]) <>

Generates an accessor function for retrieving the specified field value. The input field string may include nested properties (e.g., foo.bar.baz). An optional name argument indicates the accessor name for the generated function; if excluded the field string will be used as the name (see the accessor method for more details).

var fooField = vega.field('foo');
fooField({foo: 5}); // 5
vega.accessorName(fooField); // 'foo'
vega.accessorFields(fooField); // ['foo']

var pathField = vega.field('foo.bar', 'path');
pathField({foo: {bar: 'vega'}}); // 'vega'
pathField({foo: 5}); // undefined
vega.accessorName(pathField); // 'path'
vega.accessorFields(pathField); // ['foo.bar']

# vega.id(object) <>

An accessor function that returns the value of the id property of an input object.

# vega.identity(value) <>

An accessor function that simply returns its value argument.

# vega.key(fields[, flat]) <>

Generates an accessor function that returns a key string (suitable for using as an object property name) for a set of object fields. The fields argument must be either a string or string array, with each entry indicating a property of an input object to be used to produce representative key values. The resulting key function is an accessor instance with the accessor name 'key'. The optional flat argument is a boolean flag indicating if the field names should be treated as flat property names, side-stepping nested field lookups normally indicated by dot or bracket notation. By default, flat is false and nested property lookup is performed.

var keyf = vega.key(['foo', 'bar']);
keyf({foo:'hi', bar:5}); // 'hi|5'
vega.accessorName(keyf); // 'key'
vega.accessorFields(keyf); // ['foo', 'bar']

# vega.one() <>

An accessor function that simply returns the value one (1).

# vega.zero() <>

An accessor function that simply returns the value zero (0).

# vega.truthy() <>

An accessor function that simply returns the boolean true value.

# vega.falsy() <>

An accessor function that simply returns the boolean false value.

Type Checkers

Functions for checking the type of JavaScript values.

# vega.isArray(value) <>

Returns true if the input value is an Array instance, false otherwise.

# vega.isBoolean(value) <>

Returns true if the input value is a Boolean instance, false otherwise.

# vega.isDate(value) <>

Returns true if the input value is a Date instance, false otherwise.

# vega.isFunction(value) <>

Returns true if the input value is a Function instance, false otherwise.

# vega.isIterable(value) <>

Returns true if the input value supports the iterable protocol, false otherwise.

# vega.isNumber(value) <>

Returns true if the input value is a Number instance, false otherwise.

# vega.isObject(value) <>

Returns true if the input value is an Object instance, false otherwise.

# vega.isRegExp(value) <>

Returns true if the input value is a RegExp instance, false otherwise.

# vega.isString(value) <>

Returns true if the input value is a String instance, false otherwise.

Type Coercion

Functions for coercing values to a desired type.

# vega.toBoolean(value) <>

Coerces the input value to a boolean. The strings "true" and "1" map to true; the strings "false" and "0" map to false. Null values and empty strings are mapped to null.

# vega.toDate(value[, parser]) <>

Coerces the input value to a Date timestamp. Null values and empty strings are mapped to null. Date objects are passed through unchanged. If an optional parser function is provided, it is used to perform date parsing. By default, numbers (timestamps) are passed through unchanged and otherwise Date.parse is used. Be aware that Date.parse has different implementations across browsers!

# vega.toNumber(value) <>

Coerces the input value to a number. Null values and empty strings are mapped to null.

# vega.toString(value) <>

Coerces the input value to a string. Null values and empty strings are mapped to null.

Objects

Functions for manipulating JavaScript Object values.

# vega.extend(target[, source1, source2, …]) <>

Extends a target object by copying (in order) all enumerable properties of the input source objects.

# vega.hasOwnProperty(object, property) <>

Returns true if the input object has a named property defined on it, otherwise false. This method concerns the input object only, ignoring properties defined up the prototype chain. The method is equivalent to Object.hasOwnProperty, but improves security by guarding against overridden Object prototype built-ins.

# vega.inherits(child, parent[, members]) <>

A convenience method for setting up object-oriented inheritance. Assigns the prototype property of the input child function, such that the child inherits the properties of the parent function’s prototype via prototypal inheritance. The optional members argument is an object containing methods or properties to add to the new child prototype. Returns the new child prototype object.

# vega.lruCache([maxsize]) <>

Provides a key/value cache, keyed by string, that evicts least recently used (LRU) entries. Supports has, get, set, and clear methods. The optional maxsize argument (default 10,000) determines the maximum number of elements that can be added before items are evicted.

In the internal implementation two caches are used: a current cache and a previous cache. When then current cache fills, it becomes the previous cache and a new, empty current cache is created. Subsequent get calls will promote elements in the previous cache to the current cache. Once the current cache fills, the caches are again turned over and all LRU items still residing in the previous cache are dropped.

var cache = vega.lruCache(1); // use 1-element cache to demonstrate
cache.set('a', 1); // current cache has a->1
cache.set('b', 2); // current cache has b->2, previous cache has a->1
cache.get('a');    // -> 1 (a now in current cache, b in previous cache)
cache.set('c', 3); // current cache has c->3, previous cache has a->1
cache.has('c');    // -> true  (c is in the current cache)
cache.has('b');    // -> false (b has been evicted)
cache.has('a');    // -> true  (a is in the previous cache)
cache.get('c');    // -> 3
cache.clear();

# vega.fastmap([object]) <>

Provides a key/value map data structure, keyed by string. Supports a subset of the ES6 Map API, including has, get, set, delete and clear methods and a size property. If the optional object argument is provided, all key/values on the input object will be added to the new map instance.

var map = vega.fastmap({foo:1, bar:2});
map.has('foo'); // -> true
map.get('foo'); // -> 1
map.delete('bar');
map.has('bar'); // -> false
map.set('baz', 0);
map.get('baz'); // -> 0
map.size; // -> 2
map.empty; // -> 1 (number of empty entries)
map.clean(); // invoke garbage collection, clears empty entries

By using basic JavaScript objects to hash values and avoiding calls to the built-in JavaScript delete operator, fastmaps provide good performance. However, this speed comes at the cost of some object bloat, requiring periodic garbage collection in the case of many deletions. The fastmap object provides a clean method for requesting garbage collection of empty map entries. The test method is a getter/setter for providing an optional boolean-valued function that indicates additional objects (not just empty entries from deleted keys) that should be removed during garbage collection.

# vega.mergeConfig(…config) <>

Merges a collection of Vega configuration objects into a single combined object. Configuration objects with higher index positions in the arguments list have higher precedence, and so may override settings provided by earlier objects.

# vega.writeConfig(config, key, value[, recurse]) <>

Writes a value to a Vega configuration object. Given a config object and a configuration property key and value, appropriately assign the value to the config object. The recurse parameter controls if recursive merging (as opposed to overwriting) is performed: if false or undefined, no recursion is performed; if true one level of recursive merge is performed; if recurse is object-valued, one level of recursive merge is performed for keys that the recurse object maps to a truthy value. This method is a helper method used within mergeConfig.

Arrays

Functions for manipulating JavaScript Array values.

# vega.array(value) <>

Ensures that the input value is an Array instance. If so, the value is simply returned. If not, the value is wrapped within a new single-element an array, returning [value].

# vega.clampRange(range, min, max) <>

Span-preserving range clamp. If the span of the input range is less than (max - min) and an endpoint exceeds either the min or max value, the range is translated such that the span is preserved and one endpoint touches the boundary of the min/max range. If the span exceeds (max - min), returns the range [min, max].

# vega.extent(array[, accessor]) <>

Returns an array with the minimum and maximum values in the input array, in the form [min, max]. Ignores null, undefined, and NaN values. The optional accessor argument provides a function that is first applied to each array value prior to comparison.

# vega.extentIndex(array[, accessor]) <>

Returns the array indices for the minimum and maximum values in the input array (as a [minIndex, maxIndex] array), according to natural ordering. The optional accessor argument provides a function that is first applied to each array value prior to comparison.

vega.extentIndex([1,5,3,0,4,2]); // [3, 1]
vega.extentIndex([
  {a: 3, b:2},
  {a: 2, b:1},
  {a: 1, b:3}
], vega.field('b')); // [1, 2]

# vega.flush(range, value, threshold, left, right, center) <>

Selects among potential return values if the provided value is flush with the input numeric range. Returns left if value is within the *threshold distance of the minimum element of the range. Returns right if value is within the *threshold distance of the maximum element of the range. Otherwise, returns center.

# vega.inrange(value, range[, left, right]) <>

Returns true if the input value lies within the span of the given range array. The left and right boolean flags control the use of inclusive (true) or exclusive (false) comparisons; if unspecified, inclusive tests are used.

# vega.lerp(array, fraction) <>

Returns the linearly interpolated value between the first and last entries in the array for the provided interpolation fraction (typically between 0 and 1). For example, lerp([0, 50], 0.5) returns 25.

# vega.merge(compare, array1, array2[, output]) <>

Merge two sorted arrays into a single sorted array. The input compare function is a comparator for sorting elements and should correspond to the pre-sorted orders of the array1 and array2 source arrays. The merged array contents are written to the output array, if provided. If output is not specified, a new array is generated and returned.

# vega.panLinear(domain, delta) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that translates the domain by a delta using a linear transform. The delta value is expressed as a fraction of the current domain span, and may be positive or negative to indicate the translation direction. The return value is a two-element array indicating the starting and ending value of the translated (panned) domain.

# vega.panLog(domain, delta) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that translates the domain by a delta using a logarithmic transform. The delta value is expressed as a fraction of the current domain span, and may be positive or negative to indicate the translation direction. The return value is a two-element array indicating the starting and ending value of the translated (panned) domain.

# vega.panPow(domain, delta, exponent) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that translates the domain by a delta using a power scale transform parameterized by the provided exponent. The delta value is expressed as a fraction of the current domain span, and may be positive or negative to indicate the translation direction. The return value is a two-element array indicating the starting and ending value of the translated (panned) domain.

# vega.panSymlog(domain, delta, constant) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that translates the domain by a delta using a symlog (symmetric log) scale transform parameterized by the provided constant. The delta value is expressed as a fraction of the current domain span, and may be positive or negative to indicate the translation direction. The return value is a two-element array indicating the starting and ending value of the translated (panned) domain.

# vega.peek(array) <>

Returns the last element in the input array. Similar to the built-in Array.pop method, except that it does not remove the last element. This method is a convenient shorthand for array[array.length - 1].

# vega.span(array) <>

Returns the numerical span of the input array: the difference between the last and first values.

# vega.toSet(array) <>

Given an input array of values, returns a new Object instance whose property keys are the values in array, each assigned a property value of 1. Each value in array is coerced to a String value and so should map to a reasonable string key value.

vega.toSet([1, 2, 3]); // {'1':1, '2':1, '3':1}

# vega.visitArray(array, [filter,] visitor) <>

Vists the values in an input array, invoking the visitor function for each array value that passes an optional filter. If specified, the filter function is called with each individual array value. If the filter function return value is truthy, the returned value is then passed as input to the visitor function. Thus, the filter not only performs filtering, it can serve as a value transformer. If the filter function is not specified, all values in the array are passed to the visitor function. Similar to the built-in Array.forEach method, the visitor function is invoked with three arguments: the value to visit, the current index into the source array, and a reference to the soure array.

// console output: 1 0; 3 2
vega.visitArray([0, -1, 2],
  function(x) { return x + 1; },
  function(v, i, array) { console.log(v, i); });

# vega.zoomLinear(domain, anchor, scale) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that scales (zooms) the domain by a scale factor using a linear transform, centered on the given anchor value. If anchor is null, the midpoint of the domain is used instead. The return value is a two-element array indicating the starting and ending value of the scaled (zoomed) domain.

# vega.zoomLog(domain, anchor, scale) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that scales (zooms) the domain by a scale factor using a logarithmic transform, centered on the given anchor value. If anchor is null, the midpoint of the domain is used instead. The return value is a two-element array indicating the starting and ending value of the scaled (zoomed) domain.

# vega.zoomPow(domain, anchor, scale, exponent) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that scales (zooms) the domain by a scale factor using a power scale transform parameterized by the provided exponent, centered on the given anchor value. If anchor is null, the midpoint of the domain is used instead. The return value is a two-element array indicating the starting and ending value of the scaled (zoomed) domain.

# vega.zoomSymlog(domain, anchor, scale, constant) <>

Given an input numeric domain (sorted in increasing order), returns a new domain array that scales (zooms) the domain by a scale factor using a symlog (symmetric log) scale transform parameterized by the provided constant, centered on the given anchor value. If anchor is null, the midpoint of the domain is used instead. The return value is a two-element array indicating the starting and ending value of the scaled (zoomed) domain.

Dates

Functions for manipulating JavaScript Date values.

# vega.quarter(date) <>

Returns the quarter of the year (an integer between 1 and 4) for an input date object or timestamp for the local timezone.

# vega.utcquarter(date) <>

Returns the quarter of the year (an integer between 1 and 4) for an input date object or timestamp for Coordinated Universal Time (UTC).

Strings

Functions for generating and manipulating JavaScript String values.

# vega.pad(string, length[, character, align]) <>

Pads a string value with repeated instances of a character up to a specified length. If character is not specified, a space (' ') is used. By default, padding is added to the end of a string. An optional align parameter specifies if padding should be added to the 'left' (beginning), 'center', or 'right' (end) of the input string.

vega.pad('15', 5, '0', 'left'); // '00015'

# vega.repeat(string, count) <>

Given an input string, returns a new string that repeats the input count times.

vega.repeat('0', 5); // '00000'

# vega.splitAccessPath(path) <>

Splits an input string representing an access path for JavaScript object properties into an array of constituent path elements.

vega.splitAccessPath('foo'); // ['foo']
vega.splitAccessPath('foo.bar'); // ['foo', 'bar']
vega.splitAccessPath('foo["bar"]'); // ['foo', 'bar']
vega.splitAccessPath('foo[0].bar'); // ['foo', '0', 'bar']

# vega.stringValue(value) <>

Returns an output representation of an input value that is both JSON and JavaScript compliant. For Object and String values, JSON.stringify is used to generate the output string. Primitive types such as Number or Boolean are returned as-is. This method can be used to generate values that can then be included in runtime-compiled code snippets (for example, via the Function constructor).

# vega.truncate(string, length[, align, ellipsis]) <>

Truncates an input string to a target length. The optional align argument indicates what part of the string should be truncated: 'left' (the beginning), 'center', or 'right' (the end). By default, the 'right' end of the string is truncated. The optional ellipsis argument indicates the string to use to indicate truncated content; by default the ellipsis character (, same as \u2026) is used.

Logging

# vega.logger([level, method]) <>

Generates a new logger instance for selectively writing log messages to the JavaScript console. The optional level argument indicates the initial log level to use (one of None, Warn, Info, or Debug), and defaults to None if not specified.

The generated logger instance provides the following methods:

  • level(value): Sets the current logging level. Only messages with a log level less than or equal to value will be written to the console.
  • error(message1[, message2, …]): Logs an error message. The messages will be written to the console using the console.error method if the current log level is Error or higher.
  • warn(message1[, message2, …]): Logs a warning message. The messages will be written to the console using the console.warn method if the current log level is Warn or higher.
  • info(message1[, message2, …]): Logs an informative message. The messages will be written to the console using the console.log method if the current log level is Info or higher.
  • debug(message1[, message2, …]): Logs a debugging message. The messages will be written to the console using the console.log method if the current log level is Debug or higher.

To override the choice of console method invoked (console.log, console.warn, or console.error), use the optional method argument (one of "log", "warn", or "error") to route all log messages through the same method.

# vega.None <>

Constant value indicating a log level of ‘None’. If set as the log level of a logger instance, all log messages will be suppressed.

# vega.Error <>

Constant value indicating a log level of ‘Error’. If set as the log level of a logger instance, only error messages will be presented.

# vega.Warn <>

Constant value indicating a log level of ‘Warn’. If set as the log level of a logger instance, both error and warning messages will be presented.

# vega.Info <>

Constant value indicating a log level of ‘Info’. If set as the log level of a logger instance, error, warning and info messages will be presented.

# vega.Debug <>

Constant value indicating a log level of ‘Debug’. If set as the log level of a logger instance, all log messages (error, warning, info and debug) will be presented.

Errors

# vega.error(message) <>

Throws a new error with the provided error message. This is a convenience method adding a layer of indirection for error handling, for example allowing error conditions to be included in expression chains.

vega.error('Uh oh'); // equivalent to: throw Error('Uh oh')

// embed error in an expression
return isOk ? returnValue : vega.error('Not OK');