You've already forked wakapi-readme-stats
Bar graph added.
This commit is contained in:
735
node_modules/vega-functions/build/vega-functions.js
generated
vendored
Normal file
735
node_modules/vega-functions/build/vega-functions.js
generated
vendored
Normal file
@@ -0,0 +1,735 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vega-util'), require('vega-expression'), require('d3-geo'), require('d3-color'), require('vega-dataflow'), require('vega-scale'), require('vega-scenegraph'), require('vega-selections'), require('vega-statistics'), require('vega-time'), require('d3-array')) :
|
||||
typeof define === 'function' && define.amd ? define(['exports', 'vega-util', 'vega-expression', 'd3-geo', 'd3-color', 'vega-dataflow', 'vega-scale', 'vega-scenegraph', 'vega-selections', 'vega-statistics', 'vega-time', 'd3-array'], factory) :
|
||||
(global = global || self, factory(global.vega = {}, global.vega, global.vega, global.d3, global.d3, global.vega, global.vega, global.vega, global.vega, global.vega, global.vega, global.d3));
|
||||
}(this, (function (exports, vegaUtil, vegaExpression, d3Geo, d3Color, vegaDataflow, vegaScale, vegaScenegraph, vegaSelections, vegaStatistics, vegaTime, d3Array) { 'use strict';
|
||||
|
||||
function data(name) {
|
||||
const data = this.context.data[name];
|
||||
return data ? data.values.value : [];
|
||||
}
|
||||
|
||||
function indata(name, field, value) {
|
||||
const index = this.context.data[name]['index:' + field],
|
||||
entry = index ? index.value.get(value) : undefined;
|
||||
return entry ? entry.count : entry;
|
||||
}
|
||||
|
||||
function setdata(name, tuples) {
|
||||
const df = this.context.dataflow,
|
||||
data = this.context.data[name],
|
||||
input = data.input;
|
||||
|
||||
df.pulse(input, df.changeset().remove(vegaUtil.truthy).insert(tuples));
|
||||
return 1;
|
||||
}
|
||||
|
||||
function encode(item, name, retval) {
|
||||
if (item) {
|
||||
const df = this.context.dataflow,
|
||||
target = item.mark.source;
|
||||
df.pulse(target, df.changeset().encode(item, name));
|
||||
}
|
||||
return retval !== undefined ? retval : item;
|
||||
}
|
||||
|
||||
const wrap = method => function(value, spec) {
|
||||
const locale = this.context.dataflow.locale();
|
||||
return locale[method](spec)(value);
|
||||
};
|
||||
|
||||
const format = wrap('format');
|
||||
const timeFormat = wrap('timeFormat');
|
||||
const utcFormat = wrap('utcFormat');
|
||||
const timeParse = wrap('timeParse');
|
||||
const utcParse = wrap('utcParse');
|
||||
|
||||
var dateObj = new Date(2000, 0, 1);
|
||||
|
||||
function time(month, day, specifier) {
|
||||
if (!Number.isInteger(month) || !Number.isInteger(day)) return '';
|
||||
dateObj.setYear(2000);
|
||||
dateObj.setMonth(month);
|
||||
dateObj.setDate(day);
|
||||
return timeFormat.call(this, dateObj, specifier);
|
||||
}
|
||||
|
||||
function monthFormat(month) {
|
||||
return time.call(this, month, 1, '%B');
|
||||
}
|
||||
|
||||
function monthAbbrevFormat(month) {
|
||||
return time.call(this, month, 1, '%b');
|
||||
}
|
||||
|
||||
function dayFormat(day) {
|
||||
return time.call(this, 0, 2 + day, '%A');
|
||||
}
|
||||
|
||||
function dayAbbrevFormat(day) {
|
||||
return time.call(this, 0, 2 + day, '%a');
|
||||
}
|
||||
|
||||
const DataPrefix = ':';
|
||||
const IndexPrefix = '@';
|
||||
const ScalePrefix = '%';
|
||||
const SignalPrefix = '$';
|
||||
|
||||
function dataVisitor(name, args, scope, params) {
|
||||
if (args[0].type !== vegaExpression.Literal) {
|
||||
vegaUtil.error('First argument to data functions must be a string literal.');
|
||||
}
|
||||
|
||||
const data = args[0].value,
|
||||
dataName = DataPrefix + data;
|
||||
|
||||
if (!vegaUtil.hasOwnProperty(dataName, params)) {
|
||||
try {
|
||||
params[dataName] = scope.getData(data).tuplesRef();
|
||||
} catch (err) {
|
||||
// if data set does not exist, there's nothing to track
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function indataVisitor(name, args, scope, params) {
|
||||
if (args[0].type !== vegaExpression.Literal) vegaUtil.error('First argument to indata must be a string literal.');
|
||||
if (args[1].type !== vegaExpression.Literal) vegaUtil.error('Second argument to indata must be a string literal.');
|
||||
|
||||
const data = args[0].value,
|
||||
field = args[1].value,
|
||||
indexName = IndexPrefix + field;
|
||||
|
||||
if (!vegaUtil.hasOwnProperty(indexName, params)) {
|
||||
params[indexName] = scope.getData(data).indataRef(scope, field);
|
||||
}
|
||||
}
|
||||
|
||||
function scaleVisitor(name, args, scope, params) {
|
||||
if (args[0].type === vegaExpression.Literal) {
|
||||
// add scale dependency
|
||||
addScaleDependency(scope, params, args[0].value);
|
||||
} else {
|
||||
// indirect scale lookup; add all scales as parameters
|
||||
for (name in scope.scales) {
|
||||
addScaleDependency(scope, params, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addScaleDependency(scope, params, name) {
|
||||
const scaleName = ScalePrefix + name;
|
||||
if (!vegaUtil.hasOwnProperty(params, scaleName)) {
|
||||
try {
|
||||
params[scaleName] = scope.scaleRef(name);
|
||||
} catch (err) {
|
||||
// TODO: error handling? warning?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getScale(name, ctx) {
|
||||
let s;
|
||||
return vegaUtil.isFunction(name) ? name
|
||||
: vegaUtil.isString(name) ? (s = ctx.scales[name]) && s.value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function internalScaleFunctions(codegen, fnctx, visitors) {
|
||||
// add helper method to the 'this' expression function context
|
||||
fnctx.__bandwidth = s => s && s.bandwidth ? s.bandwidth() : 0;
|
||||
|
||||
// register AST visitors for internal scale functions
|
||||
visitors._bandwidth = scaleVisitor;
|
||||
visitors._range = scaleVisitor;
|
||||
visitors._scale = scaleVisitor;
|
||||
|
||||
// resolve scale reference directly to the signal hash argument
|
||||
const ref = arg => '_[' + (
|
||||
arg.type === vegaExpression.Literal
|
||||
? vegaUtil.stringValue(ScalePrefix + arg.value)
|
||||
: vegaUtil.stringValue(ScalePrefix) + '+' + codegen(arg)
|
||||
) + ']';
|
||||
|
||||
// define and return internal scale function code generators
|
||||
// these internal functions are called by mark encoders
|
||||
return {
|
||||
_bandwidth: args => `this.__bandwidth(${ref(args[0])})`,
|
||||
_range: args => `${ref(args[0])}.range()`,
|
||||
_scale: args => `${ref(args[0])}(${codegen(args[1])})`
|
||||
};
|
||||
}
|
||||
|
||||
function geoMethod(methodName, globalMethod) {
|
||||
return function(projection, geojson, group) {
|
||||
if (projection) {
|
||||
// projection defined, use it
|
||||
const p = getScale(projection, (group || this).context);
|
||||
return p && p.path[methodName](geojson);
|
||||
} else {
|
||||
// projection undefined, use global method
|
||||
return globalMethod(geojson);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const geoArea = geoMethod('area', d3Geo.geoArea);
|
||||
const geoBounds = geoMethod('bounds', d3Geo.geoBounds);
|
||||
const geoCentroid = geoMethod('centroid', d3Geo.geoCentroid);
|
||||
|
||||
function inScope(item) {
|
||||
let group = this.context.group,
|
||||
value = false;
|
||||
|
||||
if (group) while (item) {
|
||||
if (item === group) { value = true; break; }
|
||||
item = item.mark.group;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function log(df, method, args) {
|
||||
try {
|
||||
df[method].apply(df, ['EXPRESSION'].concat([].slice.call(args)));
|
||||
} catch (err) {
|
||||
df.warn(err);
|
||||
}
|
||||
return args[args.length-1];
|
||||
}
|
||||
|
||||
function warn() {
|
||||
return log(this.context.dataflow, 'warn', arguments);
|
||||
}
|
||||
|
||||
function info() {
|
||||
return log(this.context.dataflow, 'info', arguments);
|
||||
}
|
||||
|
||||
function debug() {
|
||||
return log(this.context.dataflow, 'debug', arguments);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
function channel_luminance_value(channelValue) {
|
||||
const val = channelValue / 255;
|
||||
if (val <= 0.03928) {
|
||||
return val / 12.92;
|
||||
}
|
||||
return Math.pow((val + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
function luminance(color) {
|
||||
const c = d3Color.rgb(color),
|
||||
r = channel_luminance_value(c.r),
|
||||
g = channel_luminance_value(c.g),
|
||||
b = channel_luminance_value(c.b);
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
||||
function contrast(color1, color2) {
|
||||
const lum1 = luminance(color1),
|
||||
lum2 = luminance(color2),
|
||||
lumL = Math.max(lum1, lum2),
|
||||
lumD = Math.min(lum1, lum2);
|
||||
return (lumL + 0.05) / (lumD + 0.05);
|
||||
}
|
||||
|
||||
function merge() {
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift({});
|
||||
return vegaUtil.extend.apply(null, args);
|
||||
}
|
||||
|
||||
function equal(a, b) {
|
||||
return a === b || a !== a && b !== b ? true
|
||||
: vegaUtil.isArray(a) ? (
|
||||
vegaUtil.isArray(b) && a.length === b.length ? equalArray(a, b) : false
|
||||
)
|
||||
: vegaUtil.isObject(a) && vegaUtil.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 (let key in a) {
|
||||
if (!equal(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function removePredicate(props) {
|
||||
return _ => equalObject(props, _);
|
||||
}
|
||||
|
||||
function modify(name, insert, remove, toggle, modify, values) {
|
||||
let df = this.context.dataflow,
|
||||
data = this.context.data[name],
|
||||
input = data.input,
|
||||
changes = data.changes,
|
||||
stamp = df.stamp(),
|
||||
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(function() {
|
||||
data.modified = true;
|
||||
df.pulse(input, changes).run();
|
||||
}, true, 1);
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
predicate = remove === true ? vegaUtil.truthy
|
||||
: (vegaUtil.isArray(remove) || vegaDataflow.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) {
|
||||
for (key in values) {
|
||||
changes.modify(modify, key, values[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
function pinchDistance(event) {
|
||||
const t = event.touches,
|
||||
dx = t[0].clientX - t[1].clientX,
|
||||
dy = t[0].clientY - t[1].clientY;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
function pinchAngle(event) {
|
||||
const t = event.touches;
|
||||
return Math.atan2(
|
||||
t[0].clientY - t[1].clientY,
|
||||
t[0].clientX - t[1].clientX
|
||||
);
|
||||
}
|
||||
|
||||
function bandspace(count, paddingInner, paddingOuter) {
|
||||
return vegaScale.bandSpace(count || 0, paddingInner || 0, paddingOuter || 0);
|
||||
}
|
||||
|
||||
function bandwidth(name, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return s && s.bandwidth ? s.bandwidth() : 0;
|
||||
}
|
||||
|
||||
function copy(name, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return s ? s.copy() : undefined;
|
||||
}
|
||||
|
||||
function domain(name, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return s ? s.domain() : [];
|
||||
}
|
||||
|
||||
function invert(name, range, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return !s ? undefined
|
||||
: vegaUtil.isArray(range) ? (s.invertRange || s.invert)(range)
|
||||
: (s.invert || s.invertExtent)(range);
|
||||
}
|
||||
|
||||
function range(name, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return s && s.range ? s.range() : [];
|
||||
}
|
||||
|
||||
function scale(name, value, group) {
|
||||
const s = getScale(name, (group || this).context);
|
||||
return s ? s(value) : undefined;
|
||||
}
|
||||
|
||||
function scaleGradient(scale, p0, p1, count, group) {
|
||||
scale = getScale(scale, (group || this).context);
|
||||
|
||||
const gradient = vegaScenegraph.Gradient(p0, p1);
|
||||
|
||||
let stops = scale.domain(),
|
||||
min = stops[0],
|
||||
max = vegaUtil.peek(stops),
|
||||
fraction = vegaUtil.identity;
|
||||
|
||||
if (!(max - min)) {
|
||||
// expand scale if domain has zero span, fix #1479
|
||||
scale = (scale.interpolator
|
||||
? vegaScale.scale('sequential')().interpolator(scale.interpolator())
|
||||
: vegaScale.scale('linear')().interpolate(scale.interpolate()).range(scale.range())
|
||||
).domain([min=0, max=1]);
|
||||
} else {
|
||||
fraction = vegaScale.scaleFraction(scale, min, max);
|
||||
}
|
||||
|
||||
if (scale.ticks) {
|
||||
stops = scale.ticks(+count || 15);
|
||||
if (min !== stops[0]) stops.unshift(min);
|
||||
if (max !== vegaUtil.peek(stops)) stops.push(max);
|
||||
}
|
||||
|
||||
stops.forEach(_ => gradient.stop(fraction(_), scale(_)));
|
||||
|
||||
return gradient;
|
||||
}
|
||||
|
||||
function geoShape(projection, geojson, group) {
|
||||
const p = getScale(projection, (group || this).context);
|
||||
return function(context) {
|
||||
return p ? p.path.context(context)(geojson) : '';
|
||||
};
|
||||
}
|
||||
|
||||
function pathShape(path) {
|
||||
let p = null;
|
||||
return function(context) {
|
||||
return context
|
||||
? vegaScenegraph.pathRender(context, (p = p || vegaScenegraph.pathParse(path)))
|
||||
: path;
|
||||
};
|
||||
}
|
||||
|
||||
const datum = d => d.data;
|
||||
|
||||
function treeNodes(name, context) {
|
||||
const tree = data.call(context, name);
|
||||
return tree.root && tree.root.lookup || {};
|
||||
}
|
||||
|
||||
function treePath(name, source, target) {
|
||||
const nodes = treeNodes(name, this),
|
||||
s = nodes[source],
|
||||
t = nodes[target];
|
||||
return s && t ? s.path(t).map(datum) : undefined;
|
||||
}
|
||||
|
||||
function treeAncestors(name, node) {
|
||||
const n = treeNodes(name, this)[node];
|
||||
return n ? n.ancestors().map(datum) : undefined;
|
||||
}
|
||||
|
||||
const _window = () => (typeof window !== 'undefined' && window) || null;
|
||||
|
||||
function screen() {
|
||||
const w = _window();
|
||||
return w ? w.screen : {};
|
||||
}
|
||||
|
||||
function windowSize() {
|
||||
const w = _window();
|
||||
return w
|
||||
? [w.innerWidth, w.innerHeight]
|
||||
: [undefined, undefined];
|
||||
}
|
||||
|
||||
function containerSize() {
|
||||
const view = this.context.dataflow,
|
||||
el = view.container && view.container();
|
||||
return el
|
||||
? [el.clientWidth, el.clientHeight]
|
||||
: [undefined, undefined];
|
||||
}
|
||||
|
||||
function intersect(b, opt, group) {
|
||||
if (!b) return [];
|
||||
|
||||
const [u, v] = b,
|
||||
box = new vegaScenegraph.Bounds().set(u[0], u[1], v[0], v[1]),
|
||||
scene = group || this.context.dataflow.scenegraph().root;
|
||||
|
||||
return vegaScenegraph.intersect(scene, box, filter(opt));
|
||||
}
|
||||
|
||||
function filter(opt) {
|
||||
let p = null;
|
||||
|
||||
if (opt) {
|
||||
const types = vegaUtil.array(opt.marktype),
|
||||
names = vegaUtil.array(opt.markname);
|
||||
p = _ => (!types.length || types.some(t => _.marktype === t))
|
||||
&& (!names.length || names.some(s => _.name === s));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Expression function context object
|
||||
const functionContext = {
|
||||
random: function() { return vegaStatistics.random(); }, // override default
|
||||
cumulativeNormal: vegaStatistics.cumulativeNormal,
|
||||
cumulativeLogNormal: vegaStatistics.cumulativeLogNormal,
|
||||
cumulativeUniform: vegaStatistics.cumulativeUniform,
|
||||
densityNormal: vegaStatistics.densityNormal,
|
||||
densityLogNormal: vegaStatistics.densityLogNormal,
|
||||
densityUniform: vegaStatistics.densityUniform,
|
||||
quantileNormal: vegaStatistics.quantileNormal,
|
||||
quantileLogNormal: vegaStatistics.quantileLogNormal,
|
||||
quantileUniform: vegaStatistics.quantileUniform,
|
||||
sampleNormal: vegaStatistics.sampleNormal,
|
||||
sampleLogNormal: vegaStatistics.sampleLogNormal,
|
||||
sampleUniform: vegaStatistics.sampleUniform,
|
||||
isArray: vegaUtil.isArray,
|
||||
isBoolean: vegaUtil.isBoolean,
|
||||
isDate: vegaUtil.isDate,
|
||||
isDefined: function(_) { return _ !== undefined; },
|
||||
isNumber: vegaUtil.isNumber,
|
||||
isObject: vegaUtil.isObject,
|
||||
isRegExp: vegaUtil.isRegExp,
|
||||
isString: vegaUtil.isString,
|
||||
isTuple: vegaDataflow.isTuple,
|
||||
isValid: function(_) { return _ != null && _ === _; },
|
||||
toBoolean: vegaUtil.toBoolean,
|
||||
toDate: vegaUtil.toDate,
|
||||
toNumber: vegaUtil.toNumber,
|
||||
toString: vegaUtil.toString,
|
||||
flush: vegaUtil.flush,
|
||||
lerp: vegaUtil.lerp,
|
||||
merge,
|
||||
pad: vegaUtil.pad,
|
||||
peek: vegaUtil.peek,
|
||||
span: vegaUtil.span,
|
||||
inrange: vegaUtil.inrange,
|
||||
truncate: vegaUtil.truncate,
|
||||
rgb: d3Color.rgb,
|
||||
lab: d3Color.lab,
|
||||
hcl: d3Color.hcl,
|
||||
hsl: d3Color.hsl,
|
||||
luminance,
|
||||
contrast,
|
||||
sequence: d3Array.range,
|
||||
format,
|
||||
utcFormat,
|
||||
utcParse,
|
||||
utcOffset: vegaTime.utcOffset,
|
||||
utcSequence: vegaTime.utcSequence,
|
||||
timeFormat,
|
||||
timeParse,
|
||||
timeOffset: vegaTime.timeOffset,
|
||||
timeSequence: vegaTime.timeSequence,
|
||||
timeUnitSpecifier: vegaTime.timeUnitSpecifier,
|
||||
monthFormat,
|
||||
monthAbbrevFormat,
|
||||
dayFormat,
|
||||
dayAbbrevFormat,
|
||||
quarter: vegaUtil.quarter,
|
||||
utcquarter: vegaUtil.utcquarter,
|
||||
week: vegaTime.week,
|
||||
utcweek: vegaTime.utcweek,
|
||||
dayofyear: vegaTime.dayofyear,
|
||||
utcdayofyear: vegaTime.utcdayofyear,
|
||||
warn,
|
||||
info,
|
||||
debug,
|
||||
extent: vegaUtil.extent,
|
||||
inScope,
|
||||
intersect,
|
||||
clampRange: vegaUtil.clampRange,
|
||||
pinchDistance,
|
||||
pinchAngle,
|
||||
screen,
|
||||
containerSize,
|
||||
windowSize,
|
||||
bandspace,
|
||||
setdata,
|
||||
pathShape,
|
||||
panLinear: vegaUtil.panLinear,
|
||||
panLog: vegaUtil.panLog,
|
||||
panPow: vegaUtil.panPow,
|
||||
panSymlog: vegaUtil.panSymlog,
|
||||
zoomLinear: vegaUtil.zoomLinear,
|
||||
zoomLog: vegaUtil.zoomLog,
|
||||
zoomPow: vegaUtil.zoomPow,
|
||||
zoomSymlog: vegaUtil.zoomSymlog,
|
||||
encode,
|
||||
modify
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
// Build expression function registry
|
||||
function buildFunctions(codegen) {
|
||||
const fn = vegaExpression.functions(codegen);
|
||||
eventFunctions.forEach(name => fn[name] = eventPrefix + name);
|
||||
for (let name in functionContext) { fn[name] = thisPrefix + name; }
|
||||
vegaUtil.extend(fn, internalScaleFunctions(codegen, functionContext, astVisitors));
|
||||
return fn;
|
||||
}
|
||||
|
||||
// Register an expression function
|
||||
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('indata', indata, indataVisitor);
|
||||
expressionFunction('data', data, dataVisitor);
|
||||
expressionFunction('treePath', treePath, dataVisitor);
|
||||
expressionFunction('treeAncestors', treeAncestors, dataVisitor);
|
||||
|
||||
// register Vega-Lite selection functions
|
||||
expressionFunction('vlSelectionTest', vegaSelections.selectionTest, vegaSelections.selectionVisitor);
|
||||
expressionFunction('vlSelectionResolve', vegaSelections.selectionResolve, vegaSelections.selectionVisitor);
|
||||
|
||||
// Export code generator and parameters
|
||||
const codegenParams = {
|
||||
blacklist: ['_'],
|
||||
whitelist: ['datum', 'event', 'item'],
|
||||
fieldvar: 'datum',
|
||||
globalvar: id => '_[' + vegaUtil.stringValue(SignalPrefix + id) + ']',
|
||||
functions: buildFunctions,
|
||||
constants: vegaExpression.constants,
|
||||
visitors: astVisitors
|
||||
};
|
||||
|
||||
var codeGenerator = vegaExpression.codegen(codegenParams);
|
||||
|
||||
function parser(expr, scope) {
|
||||
var params = {}, ast, gen;
|
||||
|
||||
// parse the expression to an abstract syntax tree (ast)
|
||||
try {
|
||||
expr = vegaUtil.isString(expr) ? expr : (vegaUtil.stringValue(expr) + '');
|
||||
ast = vegaExpression.parse(expr);
|
||||
} catch (err) {
|
||||
vegaUtil.error('Expression parse error: ' + expr);
|
||||
}
|
||||
|
||||
// analyze ast function calls for dependencies
|
||||
ast.visit(node => {
|
||||
if (node.type !== vegaExpression.CallExpression) return;
|
||||
var name = node.callee.name,
|
||||
visit = codegenParams.visitors[name];
|
||||
if (visit) visit(name, node.arguments, scope, params);
|
||||
});
|
||||
|
||||
// perform code generation
|
||||
gen = codeGenerator(ast);
|
||||
|
||||
// collect signal dependencies
|
||||
gen.globals.forEach(name => {
|
||||
var signalName = SignalPrefix + name;
|
||||
if (!vegaUtil.hasOwnProperty(params, signalName) && scope.getSignal(name)) {
|
||||
params[signalName] = scope.signalRef(name);
|
||||
}
|
||||
});
|
||||
|
||||
// return generated expression code and dependencies
|
||||
return {
|
||||
$expr: vegaUtil.extend({code: gen.code}, scope.options.ast ? {ast} : null),
|
||||
$fields: gen.fields,
|
||||
$params: params
|
||||
};
|
||||
}
|
||||
|
||||
exports.DataPrefix = DataPrefix;
|
||||
exports.IndexPrefix = IndexPrefix;
|
||||
exports.ScalePrefix = ScalePrefix;
|
||||
exports.SignalPrefix = SignalPrefix;
|
||||
exports.bandspace = bandspace;
|
||||
exports.bandwidth = bandwidth;
|
||||
exports.codeGenerator = codeGenerator;
|
||||
exports.codegenParams = codegenParams;
|
||||
exports.containerSize = containerSize;
|
||||
exports.contrast = contrast;
|
||||
exports.copy = copy;
|
||||
exports.data = data;
|
||||
exports.dataVisitor = dataVisitor;
|
||||
exports.dayAbbrevFormat = dayAbbrevFormat;
|
||||
exports.dayFormat = dayFormat;
|
||||
exports.debug = debug;
|
||||
exports.domain = domain;
|
||||
exports.encode = encode;
|
||||
exports.expressionFunction = expressionFunction;
|
||||
exports.format = format;
|
||||
exports.functionContext = functionContext;
|
||||
exports.geoArea = geoArea;
|
||||
exports.geoBounds = geoBounds;
|
||||
exports.geoCentroid = geoCentroid;
|
||||
exports.geoShape = geoShape;
|
||||
exports.inScope = inScope;
|
||||
exports.indata = indata;
|
||||
exports.indataVisitor = indataVisitor;
|
||||
exports.info = info;
|
||||
exports.invert = invert;
|
||||
exports.luminance = luminance;
|
||||
exports.merge = merge;
|
||||
exports.modify = modify;
|
||||
exports.monthAbbrevFormat = monthAbbrevFormat;
|
||||
exports.monthFormat = monthFormat;
|
||||
exports.parseExpression = parser;
|
||||
exports.pathShape = pathShape;
|
||||
exports.pinchAngle = pinchAngle;
|
||||
exports.pinchDistance = pinchDistance;
|
||||
exports.range = range;
|
||||
exports.scale = scale;
|
||||
exports.scaleGradient = scaleGradient;
|
||||
exports.scaleVisitor = scaleVisitor;
|
||||
exports.screen = screen;
|
||||
exports.setdata = setdata;
|
||||
exports.timeFormat = timeFormat;
|
||||
exports.timeParse = timeParse;
|
||||
exports.treeAncestors = treeAncestors;
|
||||
exports.treePath = treePath;
|
||||
exports.utcFormat = utcFormat;
|
||||
exports.utcParse = utcParse;
|
||||
exports.warn = warn;
|
||||
exports.windowSize = windowSize;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
})));
|
||||
Reference in New Issue
Block a user