UNPKG

vega-functions

Version:

Custom functions for the Vega expression language.

375 lines (334 loc) 7 kB
import { codegenExpression, constants, functions } from 'vega-expression'; import { isTuple } from 'vega-dataflow'; import { selectionIdTest, selectionResolve, selectionTest, selectionTuples, selectionVisitor } from 'vega-selections'; import { cumulativeLogNormal, cumulativeNormal, cumulativeUniform, densityLogNormal, densityNormal, densityUniform, quantileLogNormal, quantileNormal, quantileUniform, random, sampleLogNormal, sampleNormal, sampleUniform } from 'vega-statistics'; import { dayofyear, timeOffset, timeSequence, timeUnitSpecifier, utcOffset, utcSequence, utcdayofyear, utcweek, week } from 'vega-time'; import { clampRange, extend, extent, flush, inrange, isArray, isBoolean, isDate, isNumber, isObject, isRegExp, isString, lerp, pad, panLinear, panLog, panPow, panSymlog, peek, quarter, span, stringValue, toBoolean, toDate, toNumber, toString, truncate, utcquarter, zoomLinear, zoomLog, zoomPow, zoomSymlog } from 'vega-util'; import { range as sequence } from 'd3-array'; import { hcl, hsl, lab, rgb } from 'd3-color'; import { contrast, luminance } from './functions/luminance'; import { data, indata, setdata } from './functions/data'; import encode from './functions/encode'; import { dayAbbrevFormat, dayFormat, format, monthAbbrevFormat, monthFormat, timeFormat, timeParse, utcFormat, utcParse } from './functions/format'; import { geoArea, geoBounds, geoCentroid, geoScale } from './functions/geo'; import inScope from './functions/inscope'; import intersect from './functions/intersect'; import { debug, info, warn } from './functions/log'; import merge from './functions/merge'; import modify from './functions/modify'; import { pinchAngle, pinchDistance } from './functions/pinch'; import pluck from './functions/pluck'; import { indexof, join, lastindexof, replace, reverse, slice, sort } from './functions/sequence'; import { intersectLasso, lassoAppend, lassoPath } from './functions/lasso'; import { bandspace, bandwidth, copy, domain, invert, range, scale } from './functions/scale'; import scaleGradient from './functions/scale-gradient'; import { geoShape, pathShape } from './functions/shape'; import { treeAncestors, treePath } from './functions/tree'; import { containerSize, screen, windowSize } from './functions/window'; import { SignalPrefix } from './constants'; import { internalScaleFunctions } from './scales'; import { dataVisitor, indataVisitor, scaleVisitor } from './visitors'; // Expression function context object export const functionContext = { random() { return random(); }, // override default cumulativeNormal, cumulativeLogNormal, cumulativeUniform, densityNormal, densityLogNormal, densityUniform, quantileNormal, quantileLogNormal, quantileUniform, sampleNormal, sampleLogNormal, sampleUniform, isArray, isBoolean, isDate, isDefined(_) { return _ !== undefined; }, isNumber, isObject, isRegExp, isString, isTuple, isValid(_) { return _ != null && _ === _; }, toBoolean, toDate(_) { return toDate(_); }, // suppress extra arguments toNumber, toString, indexof, join, lastindexof, replace, reverse, sort, slice, flush, lerp, merge, pad, peek, pluck, span, inrange, truncate, rgb, lab, hcl, hsl, luminance, contrast, sequence, format, utcFormat, utcParse, utcOffset, utcSequence, timeFormat, timeParse, timeOffset, timeSequence, timeUnitSpecifier, monthFormat, monthAbbrevFormat, dayFormat, dayAbbrevFormat, quarter, utcquarter, week, utcweek, dayofyear, utcdayofyear, warn, info, debug, extent(_) { return extent(_); }, // suppress extra arguments inScope, intersect, clampRange, pinchDistance, pinchAngle, screen, containerSize, windowSize, bandspace, setdata, pathShape, panLinear, panLog, panPow, panSymlog, zoomLinear, zoomLog, zoomPow, zoomSymlog, encode, modify, lassoAppend, lassoPath, intersectLasso }; const eventFunctions = ['view', 'item', 'group', 'xy', 'x', 'y'], // event functions eventPrefix = 'event.vega.', // event function prefix thisPrefix = 'this.', // function context prefix astVisitors = {}; // AST visitors for dependency analysis // export code generator parameters export const codegenParams = { forbidden: ['_'], allowed: ['datum', 'event', 'item'], fieldvar: 'datum', globalvar: id => `_[${stringValue(SignalPrefix + id)}]`, functions: buildFunctions, constants: constants, visitors: astVisitors }; // export code generator export const codeGenerator = codegenExpression(codegenParams); // Build expression function registry function buildFunctions(codegen) { const fn = functions(codegen); eventFunctions.forEach(name => fn[name] = eventPrefix + name); for (const name in functionContext) { fn[name] = thisPrefix + name; } extend(fn, internalScaleFunctions(codegen, functionContext, astVisitors)); return fn; } // Register an expression function export function expressionFunction(name, fn, visitor) { if (arguments.length === 1) { return functionContext[name]; } // register with the functionContext functionContext[name] = fn; // if there is an astVisitor register that, too if (visitor) astVisitors[name] = visitor; // if the code generator has already been initialized, // we need to also register the function with it if (codeGenerator) codeGenerator.functions[name] = thisPrefix + name; return this; } // register expression functions with ast visitors expressionFunction('bandwidth', bandwidth, scaleVisitor); expressionFunction('copy', copy, scaleVisitor); expressionFunction('domain', domain, scaleVisitor); expressionFunction('range', range, scaleVisitor); expressionFunction('invert', invert, scaleVisitor); expressionFunction('scale', scale, scaleVisitor); expressionFunction('gradient', scaleGradient, scaleVisitor); expressionFunction('geoArea', geoArea, scaleVisitor); expressionFunction('geoBounds', geoBounds, scaleVisitor); expressionFunction('geoCentroid', geoCentroid, scaleVisitor); expressionFunction('geoShape', geoShape, scaleVisitor); expressionFunction('geoScale', geoScale, scaleVisitor); expressionFunction('indata', indata, indataVisitor); expressionFunction('data', data, dataVisitor); expressionFunction('treePath', treePath, dataVisitor); expressionFunction('treeAncestors', treeAncestors, dataVisitor); // register Vega-Lite selection functions expressionFunction('vlSelectionTest', selectionTest, selectionVisitor); expressionFunction('vlSelectionIdTest', selectionIdTest, selectionVisitor); expressionFunction('vlSelectionResolve', selectionResolve, selectionVisitor); expressionFunction('vlSelectionTuples', selectionTuples);