vendor/assets/javascripts/vega.js in vega-0.1.1 vs vendor/assets/javascripts/vega.js in vega-0.1.2
- old
+ new
@@ -2,10 +2,92 @@
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vega = {}));
}(this, (function (exports) { 'use strict';
+ var name = "vega";
+ var version = "5.19.1";
+ var description = "The Vega visualization grammar.";
+ var keywords = [
+ "vega",
+ "visualization",
+ "interaction",
+ "dataflow",
+ "library",
+ "data",
+ "d3"
+ ];
+ var license = "BSD-3-Clause";
+ var author = "UW Interactive Data Lab (http://idl.cs.washington.edu)";
+ var main = "build/vega-node.js";
+ var module = "build/vega.module.js";
+ var unpkg = "build/vega.min.js";
+ var jsdelivr = "build/vega.min.js";
+ var types = "index.d.ts";
+ var repository = "vega/vega";
+ var scripts = {
+ bundle: "rollup -c --config-bundle",
+ prebuild: "rimraf build && rimraf build-es5",
+ build: "rollup -c --config-core --config-bundle --config-ie",
+ postbuild: "node schema-copy",
+ pretest: "yarn build --config-test",
+ test: "TZ=America/Los_Angeles tape 'test/**/*-test.js'",
+ prepublishOnly: "yarn test && yarn build",
+ postpublish: "./schema-deploy.sh"
+ };
+ var dependencies = {
+ "vega-crossfilter": "~4.0.5",
+ "vega-dataflow": "~5.7.3",
+ "vega-encode": "~4.8.3",
+ "vega-event-selector": "~2.0.6",
+ "vega-expression": "~4.0.1",
+ "vega-force": "~4.0.7",
+ "vega-format": "~1.0.4",
+ "vega-functions": "~5.12.0",
+ "vega-geo": "~4.3.8",
+ "vega-hierarchy": "~4.0.9",
+ "vega-label": "~1.0.0",
+ "vega-loader": "~4.4.0",
+ "vega-parser": "~6.1.3",
+ "vega-projection": "~1.4.5",
+ "vega-regression": "~1.0.9",
+ "vega-runtime": "~6.1.3",
+ "vega-scale": "~7.1.1",
+ "vega-scenegraph": "~4.9.3",
+ "vega-statistics": "~1.7.9",
+ "vega-time": "~2.0.4",
+ "vega-transforms": "~4.9.3",
+ "vega-typings": "~0.19.2",
+ "vega-util": "~1.16.0",
+ "vega-view": "~5.9.2",
+ "vega-view-transforms": "~4.5.8",
+ "vega-voronoi": "~4.1.5",
+ "vega-wordcloud": "~4.1.3"
+ };
+ var devDependencies = {
+ "vega-schema": "*"
+ };
+ var gitHead = "f112ee55fc5ddd025df8820fce371803106a3968";
+ var pkg = {
+ name: name,
+ version: version,
+ description: description,
+ keywords: keywords,
+ license: license,
+ author: author,
+ main: main,
+ module: module,
+ unpkg: unpkg,
+ jsdelivr: jsdelivr,
+ types: types,
+ repository: repository,
+ scripts: scripts,
+ dependencies: dependencies,
+ devDependencies: devDependencies,
+ gitHead: gitHead
+ };
+
function accessor(fn, fields, name) {
fn.fields = fields || [];
fn.fname = name;
return fn;
}
@@ -660,10 +742,14 @@
function isDate(_) {
return Object.prototype.toString.call(_) === '[object Date]';
}
+ function isIterable(_) {
+ return _ && isFunction(_[Symbol.iterator]);
+ }
+
function isNumber(_) {
return typeof _ === 'number';
}
function isRegExp(_) {
@@ -849,10 +935,235 @@
array.forEach(visitor);
}
}
}
+ // https://... file://... //...
+
+ const protocol_re = /^([A-Za-z]+:)?\/\//; // Matches allowed URIs. From https://github.com/cure53/DOMPurify/blob/master/src/regexp.js with added file://
+
+ const allowed_re = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file|data):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape
+
+ const whitespace_re = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g; // eslint-disable-line no-control-regex
+ // Special treatment in node.js for the file: protocol
+
+ const fileProtocol = 'file://';
+ /**
+ * Factory for a loader constructor that provides methods for requesting
+ * files from either the network or disk, and for sanitizing request URIs.
+ * @param {function} fetch - The Fetch API for HTTP network requests.
+ * If null or undefined, HTTP loading will be disabled.
+ * @param {object} fs - The file system interface for file loading.
+ * If null or undefined, local file loading will be disabled.
+ * @return {function} A loader constructor with the following signature:
+ * param {object} [options] - Optional default loading options to use.
+ * return {object} - A new loader instance.
+ */
+
+ function loaderFactory (fetch, fs) {
+ return options => ({
+ options: options || {},
+ sanitize: sanitize,
+ load: load,
+ fileAccess: !!fs,
+ file: fileLoader(fs),
+ http: httpLoader(fetch)
+ });
+ }
+ /**
+ * Load an external resource, typically either from the web or from the local
+ * filesystem. This function uses {@link sanitize} to first sanitize the uri,
+ * then calls either {@link http} (for web requests) or {@link file} (for
+ * filesystem loading).
+ * @param {string} uri - The resource indicator (e.g., URL or filename).
+ * @param {object} [options] - Optional loading options. These options will
+ * override any existing default options.
+ * @return {Promise} - A promise that resolves to the loaded content.
+ */
+
+ async function load(uri, options) {
+ const opt = await this.sanitize(uri, options),
+ url = opt.href;
+ return opt.localFile ? this.file(url) : this.http(url, options);
+ }
+ /**
+ * URI sanitizer function.
+ * @param {string} uri - The uri (url or filename) to check.
+ * @param {object} options - An options hash.
+ * @return {Promise} - A promise that resolves to an object containing
+ * sanitized uri data, or rejects it the input uri is deemed invalid.
+ * The properties of the resolved object are assumed to be
+ * valid attributes for an HTML 'a' tag. The sanitized uri *must* be
+ * provided by the 'href' property of the returned object.
+ */
+
+
+ async function sanitize(uri, options) {
+ options = extend({}, this.options, options);
+ const fileAccess = this.fileAccess,
+ result = {
+ href: null
+ };
+ let isFile, loadFile, base;
+ const isAllowed = allowed_re.test(uri.replace(whitespace_re, ''));
+
+ if (uri == null || typeof uri !== 'string' || !isAllowed) {
+ error('Sanitize failure, invalid URI: ' + $(uri));
+ }
+
+ const hasProtocol = protocol_re.test(uri); // if relative url (no protocol/host), prepend baseURL
+
+ if ((base = options.baseURL) && !hasProtocol) {
+ // Ensure that there is a slash between the baseURL (e.g. hostname) and url
+ if (!uri.startsWith('/') && base[base.length - 1] !== '/') {
+ uri = '/' + uri;
+ }
+
+ uri = base + uri;
+ } // should we load from file system?
+
+
+ loadFile = (isFile = uri.startsWith(fileProtocol)) || options.mode === 'file' || options.mode !== 'http' && !hasProtocol && fileAccess;
+
+ if (isFile) {
+ // strip file protocol
+ uri = uri.slice(fileProtocol.length);
+ } else if (uri.startsWith('//')) {
+ if (options.defaultProtocol === 'file') {
+ // if is file, strip protocol and set loadFile flag
+ uri = uri.slice(2);
+ loadFile = true;
+ } else {
+ // if relative protocol (starts with '//'), prepend default protocol
+ uri = (options.defaultProtocol || 'http') + ':' + uri;
+ }
+ } // set non-enumerable mode flag to indicate local file load
+
+
+ Object.defineProperty(result, 'localFile', {
+ value: !!loadFile
+ }); // set uri
+
+ result.href = uri; // set default result target, if specified
+
+ if (options.target) {
+ result.target = options.target + '';
+ } // set default result rel, if specified (#1542)
+
+
+ if (options.rel) {
+ result.rel = options.rel + '';
+ } // provide control over cross-origin image handling (#2238)
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
+
+
+ if (options.context === 'image' && options.crossOrigin) {
+ result.crossOrigin = options.crossOrigin + '';
+ } // return
+
+
+ return result;
+ }
+ /**
+ * File system loader factory.
+ * @param {object} fs - The file system interface.
+ * @return {function} - A file loader with the following signature:
+ * param {string} filename - The file system path to load.
+ * param {string} filename - The file system path to load.
+ * return {Promise} A promise that resolves to the file contents.
+ */
+
+
+ function fileLoader(fs) {
+ return fs ? filename => new Promise((accept, reject) => {
+ fs.readFile(filename, (error, data) => {
+ if (error) reject(error);else accept(data);
+ });
+ }) : fileReject;
+ }
+ /**
+ * Default file system loader that simply rejects.
+ */
+
+
+ async function fileReject() {
+ error('No file system access.');
+ }
+ /**
+ * HTTP request handler factory.
+ * @param {function} fetch - The Fetch API method.
+ * @return {function} - An http loader with the following signature:
+ * param {string} url - The url to request.
+ * param {object} options - An options hash.
+ * return {Promise} - A promise that resolves to the file contents.
+ */
+
+
+ function httpLoader(fetch) {
+ return fetch ? async function (url, options) {
+ const opt = extend({}, this.options.http, options),
+ type = options && options.response,
+ response = await fetch(url, opt);
+ return !response.ok ? error(response.status + '' + response.statusText) : isFunction(response[type]) ? response[type]() : response.text();
+ } : httpReject;
+ }
+ /**
+ * Default http request handler that simply rejects.
+ */
+
+
+ async function httpReject() {
+ error('No HTTP fetch method available.');
+ }
+
+ const isValid = _ => _ != null && _ === _;
+
+ const isBoolean$1 = _ => _ === 'true' || _ === 'false' || _ === true || _ === false;
+
+ const isDate$1 = _ => !Number.isNaN(Date.parse(_));
+
+ const isNumber$1 = _ => !Number.isNaN(+_) && !(_ instanceof Date);
+
+ const isInteger = _ => isNumber$1(_) && Number.isInteger(+_);
+
+ const typeParsers = {
+ boolean: toBoolean,
+ integer: toNumber,
+ number: toNumber,
+ date: toDate,
+ string: toString,
+ unknown: identity
+ };
+ const typeTests = [isBoolean$1, isInteger, isNumber$1, isDate$1];
+ const typeList = ['boolean', 'integer', 'number', 'date'];
+ function inferType(values, field) {
+ if (!values || !values.length) return 'unknown';
+ const n = values.length,
+ m = typeTests.length,
+ a = typeTests.map((_, i) => i + 1);
+
+ for (let i = 0, t = 0, j, value; i < n; ++i) {
+ value = field ? values[i][field] : values[i];
+
+ for (j = 0; j < m; ++j) {
+ if (a[j] && isValid(value) && !typeTests[j](value)) {
+ a[j] = 0;
+ ++t;
+ if (t === typeTests.length) return 'string';
+ }
+ }
+ }
+
+ return typeList[a.reduce((u, v) => u === 0 ? v : u, 0) - 1];
+ }
+ function inferTypes(data, fields) {
+ return fields.reduce((types, field) => {
+ types[field] = inferType(data, field);
+ return types;
+ }, {});
+ }
+
var EOL = {},
EOF = {},
QUOTE = 34,
NEWLINE = 10,
RETURN = 13;
@@ -1017,10 +1328,48 @@
formatRow: formatRow,
formatValue: formatValue
};
}
+ function delimitedFormat(delimiter) {
+ const parse = function (data, format) {
+ const delim = {
+ delimiter: delimiter
+ };
+ return dsv(data, format ? extend(format, delim) : delim);
+ };
+
+ parse.responseType = 'text';
+ return parse;
+ }
+ function dsv(data, format) {
+ if (format.header) {
+ data = format.header.map($).join(format.delimiter) + '\n' + data;
+ }
+
+ return dsvFormat(format.delimiter).parse(data + '');
+ }
+ dsv.responseType = 'text';
+
+ function isBuffer(_) {
+ return typeof Buffer === 'function' && isFunction(Buffer.isBuffer) ? Buffer.isBuffer(_) : false;
+ }
+
+ function json(data, format) {
+ const prop = format && format.property ? field(format.property) : identity;
+ return isObject(data) && !isBuffer(data) ? parseJSON(prop(data), format) : prop(JSON.parse(data));
+ }
+ json.responseType = 'json';
+
+ function parseJSON(data, format) {
+ if (!isArray(data) && isIterable(data)) {
+ data = [...data];
+ }
+
+ return format && format.copy ? JSON.parse(JSON.stringify(data)) : data;
+ }
+
function identity$1 (x) {
return x;
}
function transform (transform) {
@@ -1323,10 +1672,54 @@
if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i);
});
return arcs;
}
+ const filters = {
+ interior: (a, b) => a !== b,
+ exterior: (a, b) => a === b
+ };
+ function topojson(data, format) {
+ let method, object, property, filter;
+ data = json(data, format);
+
+ if (format && format.feature) {
+ method = feature;
+ property = format.feature;
+ } else if (format && format.mesh) {
+ method = mesh;
+ property = format.mesh;
+ filter = filters[format.filter];
+ } else {
+ error('Missing TopoJSON feature or mesh parameter.');
+ }
+
+ object = (object = data.objects[property]) ? method(data, object, filter) : error('Invalid TopoJSON object: ' + property);
+ return object && object.features || [object];
+ }
+ topojson.responseType = 'json';
+
+ const format = {
+ dsv: dsv,
+ csv: delimitedFormat(','),
+ tsv: delimitedFormat('\t'),
+ json: json,
+ topojson: topojson
+ };
+ function formats(name, reader) {
+ if (arguments.length > 1) {
+ format[name] = reader;
+ return this;
+ } else {
+ return has(format, name) ? format[name] : null;
+ }
+ }
+ function responseType(type) {
+ const f = formats(type);
+ return f && f.responseType || 'text';
+ }
+
function ascending$1 (a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function bisector (f) {
@@ -2008,20 +2401,20 @@
formatPrefix: formatPrefix
};
}
var locale;
- var format;
+ var format$1;
var formatPrefix;
defaultLocale({
thousands: ",",
grouping: [3],
currency: ["$", ""]
});
function defaultLocale(definition) {
locale = formatLocale(definition);
- format = locale.format;
+ format$1 = locale.format;
formatPrefix = locale.formatPrefix;
return locale;
}
function precisionFixed (step) {
@@ -3478,11 +3871,11 @@
let defaultNumberLocale;
resetNumberFormatDefaultLocale();
function resetNumberFormatDefaultLocale() {
return defaultNumberLocale = numberLocale({
- format: format,
+ format: format$1,
formatPrefix: formatPrefix
});
}
function numberFormatLocale(definition) {
@@ -3573,321 +3966,11 @@
resetNumberFormatDefaultLocale();
resetTimeFormatDefaultLocale();
return defaultLocale$2();
}
- const protocol_re = /^([A-Za-z]+:)?\/\//; // Matches allowed URIs. From https://github.com/cure53/DOMPurify/blob/master/src/regexp.js with added file://
-
- const allowed_re = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file|data):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape
-
- const whitespace_re = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g; // eslint-disable-line no-control-regex
- // Special treatment in node.js for the file: protocol
-
- const fileProtocol = 'file://';
- /**
- * Factory for a loader constructor that provides methods for requesting
- * files from either the network or disk, and for sanitizing request URIs.
- * @param {function} fetch - The Fetch API for HTTP network requests.
- * If null or undefined, HTTP loading will be disabled.
- * @param {object} fs - The file system interface for file loading.
- * If null or undefined, local file loading will be disabled.
- * @return {function} A loader constructor with the following signature:
- * param {object} [options] - Optional default loading options to use.
- * return {object} - A new loader instance.
- */
-
- function loaderFactory(fetch, fs) {
- return options => ({
- options: options || {},
- sanitize: sanitize,
- load: load,
- fileAccess: !!fs,
- file: fileLoader(fs),
- http: httpLoader(fetch)
- });
- }
- /**
- * Load an external resource, typically either from the web or from the local
- * filesystem. This function uses {@link sanitize} to first sanitize the uri,
- * then calls either {@link http} (for web requests) or {@link file} (for
- * filesystem loading).
- * @param {string} uri - The resource indicator (e.g., URL or filename).
- * @param {object} [options] - Optional loading options. These options will
- * override any existing default options.
- * @return {Promise} - A promise that resolves to the loaded content.
- */
-
-
- async function load(uri, options) {
- const opt = await this.sanitize(uri, options),
- url = opt.href;
- return opt.localFile ? this.file(url) : this.http(url, options);
- }
- /**
- * URI sanitizer function.
- * @param {string} uri - The uri (url or filename) to sanity check.
- * @param {object} options - An options hash.
- * @return {Promise} - A promise that resolves to an object containing
- * sanitized uri data, or rejects it the input uri is deemed invalid.
- * The properties of the resolved object are assumed to be
- * valid attributes for an HTML 'a' tag. The sanitized uri *must* be
- * provided by the 'href' property of the returned object.
- */
-
-
- async function sanitize(uri, options) {
- options = extend({}, this.options, options);
- const fileAccess = this.fileAccess,
- result = {
- href: null
- };
- let isFile, loadFile, base;
- const isAllowed = allowed_re.test(uri.replace(whitespace_re, ''));
-
- if (uri == null || typeof uri !== 'string' || !isAllowed) {
- error('Sanitize failure, invalid URI: ' + $(uri));
- }
-
- const hasProtocol = protocol_re.test(uri); // if relative url (no protocol/host), prepend baseURL
-
- if ((base = options.baseURL) && !hasProtocol) {
- // Ensure that there is a slash between the baseURL (e.g. hostname) and url
- if (!uri.startsWith('/') && base[base.length - 1] !== '/') {
- uri = '/' + uri;
- }
-
- uri = base + uri;
- } // should we load from file system?
-
-
- loadFile = (isFile = uri.startsWith(fileProtocol)) || options.mode === 'file' || options.mode !== 'http' && !hasProtocol && fileAccess;
-
- if (isFile) {
- // strip file protocol
- uri = uri.slice(fileProtocol.length);
- } else if (uri.startsWith('//')) {
- if (options.defaultProtocol === 'file') {
- // if is file, strip protocol and set loadFile flag
- uri = uri.slice(2);
- loadFile = true;
- } else {
- // if relative protocol (starts with '//'), prepend default protocol
- uri = (options.defaultProtocol || 'http') + ':' + uri;
- }
- } // set non-enumerable mode flag to indicate local file load
-
-
- Object.defineProperty(result, 'localFile', {
- value: !!loadFile
- }); // set uri
-
- result.href = uri; // set default result target, if specified
-
- if (options.target) {
- result.target = options.target + '';
- } // set default result rel, if specified (#1542)
-
-
- if (options.rel) {
- result.rel = options.rel + '';
- } // provide control over cross-origin image handling (#2238)
- // https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
-
-
- if (options.context === 'image' && options.crossOrigin) {
- result.crossOrigin = options.crossOrigin + '';
- } // return
-
-
- return result;
- }
- /**
- * File system loader factory.
- * @param {object} fs - The file system interface.
- * @return {function} - A file loader with the following signature:
- * param {string} filename - The file system path to load.
- * param {string} filename - The file system path to load.
- * return {Promise} A promise that resolves to the file contents.
- */
-
-
- function fileLoader(fs) {
- return fs ? filename => new Promise((accept, reject) => {
- fs.readFile(filename, (error, data) => {
- if (error) reject(error);else accept(data);
- });
- }) : fileReject;
- }
- /**
- * Default file system loader that simply rejects.
- */
-
-
- async function fileReject() {
- error('No file system access.');
- }
- /**
- * HTTP request handler factory.
- * @param {function} fetch - The Fetch API method.
- * @return {function} - An http loader with the following signature:
- * param {string} url - The url to request.
- * param {object} options - An options hash.
- * return {Promise} - A promise that resolves to the file contents.
- */
-
-
- function httpLoader(fetch) {
- return fetch ? async function (url, options) {
- const opt = extend({}, this.options.http, options),
- type = options && options.response,
- response = await fetch(url, opt);
- return !response.ok ? error(response.status + '' + response.statusText) : isFunction(response[type]) ? response[type]() : response.text();
- } : httpReject;
- }
- /**
- * Default http request handler that simply rejects.
- */
-
-
- async function httpReject() {
- error('No HTTP fetch method available.');
- }
-
- const isValid = _ => _ != null && _ === _;
-
- const isBoolean$1 = _ => _ === 'true' || _ === 'false' || _ === true || _ === false;
-
- const isDate$1 = _ => !Number.isNaN(Date.parse(_));
-
- const isNumber$1 = _ => !Number.isNaN(+_) && !(_ instanceof Date);
-
- const isInteger = _ => isNumber$1(_) && Number.isInteger(+_);
-
- const typeParsers = {
- boolean: toBoolean,
- integer: toNumber,
- number: toNumber,
- date: toDate,
- string: toString,
- unknown: identity
- };
- const typeTests = [isBoolean$1, isInteger, isNumber$1, isDate$1];
- const typeList = ['boolean', 'integer', 'number', 'date'];
-
- function inferType(values, field) {
- if (!values || !values.length) return 'unknown';
- const n = values.length,
- m = typeTests.length,
- a = typeTests.map((_, i) => i + 1);
-
- for (let i = 0, t = 0, j, value; i < n; ++i) {
- value = field ? values[i][field] : values[i];
-
- for (j = 0; j < m; ++j) {
- if (a[j] && isValid(value) && !typeTests[j](value)) {
- a[j] = 0;
- ++t;
- if (t === typeTests.length) return 'string';
- }
- }
- }
-
- return typeList[a.reduce((u, v) => u === 0 ? v : u, 0) - 1];
- }
-
- function inferTypes(data, fields) {
- return fields.reduce((types, field) => {
- types[field] = inferType(data, field);
- return types;
- }, {});
- }
-
- function delimitedFormat(delimiter) {
- const parse = function (data, format) {
- const delim = {
- delimiter: delimiter
- };
- return dsv(data, format ? extend(format, delim) : delim);
- };
-
- parse.responseType = 'text';
- return parse;
- }
-
- function dsv(data, format) {
- if (format.header) {
- data = format.header.map($).join(format.delimiter) + '\n' + data;
- }
-
- return dsvFormat(format.delimiter).parse(data + '');
- }
-
- dsv.responseType = 'text';
-
- function isBuffer(_) {
- return typeof Buffer === 'function' && isFunction(Buffer.isBuffer) ? Buffer.isBuffer(_) : false;
- }
-
- function json(data, format) {
- const prop = format && format.property ? field(format.property) : identity;
- return isObject(data) && !isBuffer(data) ? parseJSON(prop(data), format) : prop(JSON.parse(data));
- }
-
- json.responseType = 'json';
-
- function parseJSON(data, format) {
- return format && format.copy ? JSON.parse(JSON.stringify(data)) : data;
- }
-
- const filters = {
- interior: (a, b) => a !== b,
- exterior: (a, b) => a === b
- };
-
- function topojson(data, format) {
- let method, object, property, filter;
- data = json(data, format);
-
- if (format && format.feature) {
- method = feature;
- property = format.feature;
- } else if (format && format.mesh) {
- method = mesh;
- property = format.mesh;
- filter = filters[format.filter];
- } else {
- error('Missing TopoJSON feature or mesh parameter.');
- }
-
- object = (object = data.objects[property]) ? method(data, object, filter) : error('Invalid TopoJSON object: ' + property);
- return object && object.features || [object];
- }
-
- topojson.responseType = 'json';
- const format$1 = {
- dsv: dsv,
- csv: delimitedFormat(','),
- tsv: delimitedFormat('\t'),
- json: json,
- topojson: topojson
- };
-
- function formats(name, reader) {
- if (arguments.length > 1) {
- format$1[name] = reader;
- return this;
- } else {
- return has(format$1, name) ? format$1[name] : null;
- }
- }
-
- function responseType(type) {
- const f = formats(type);
- return f && f.responseType || 'text';
- }
-
- function read(data, schema, timeParser, utcParser) {
+ function read (data, schema, timeParser, utcParser) {
schema = schema || {};
const reader = formats(schema.type || 'json');
if (!reader) error('Unknown data format type: ' + schema.type);
data = reader(data, schema);
if (schema.parse) parse(data, schema.parse, timeParser, utcParser);
@@ -13292,11 +13375,10 @@
}
}
return null;
}
-
const domImage = () => typeof Image !== 'undefined' ? Image : null;
function initRange(domain, range) {
switch (arguments.length) {
case 0:
@@ -14660,11 +14742,11 @@
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
- return format(specifier);
+ return format$1(specifier);
}
function linearish(scale) {
var domain = scale.domain;
@@ -14878,11 +14960,11 @@
return r ? z.reverse() : z;
};
scale.tickFormat = function (count, specifier) {
if (specifier == null) specifier = base === 10 ? ".0e" : ",";
- if (typeof specifier !== "function") specifier = format(specifier);
+ if (typeof specifier !== "function") specifier = format$1(specifier);
if (count === Infinity) return specifier;
if (count == null) count = 10;
var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
return function (d) {
@@ -18695,11 +18777,11 @@
};
useCanvas(true);
function useCanvas(use) {
textMetrics.width = use && context$1 ? measureWidth : estimateWidth;
- } // make dumb, simple estimate if no canvas is available
+ } // make simple estimate if no canvas is available
function estimateWidth(item, text) {
return _estimateWidth(textValue(item, text), fontSize(item));
}
@@ -20299,11 +20381,12 @@
const rootAttributes = {
'fill': 'none',
'stroke-miterlimit': 10
};
const RootIndex = 0,
- ns = metadata.xmlns;
+ xmlns = 'http://www.w3.org/2000/xmlns/',
+ svgns = metadata.xmlns;
function SVGRenderer(loader) {
Renderer.call(this, loader);
this._dirtyID = 0;
this._dirty = [];
@@ -20330,18 +20413,23 @@
this._defs = {};
this._clearDefs();
if (el) {
- this._svg = domChild(el, 0, 'svg', ns);
- setAttributes(this._svg, metadata);
+ this._svg = domChild(el, 0, 'svg', svgns);
+ this._svg.setAttributeNS(xmlns, 'xmlns', svgns);
+
+ this._svg.setAttributeNS(xmlns, 'xmlns:xlink', metadata['xmlns:xlink']);
+
+ this._svg.setAttribute('version', metadata['version']);
+
this._svg.setAttribute('class', 'marks');
domClear(el, 1); // set the svg root group
- this._root = domChild(this._svg, RootIndex, 'g', ns);
+ this._root = domChild(this._svg, RootIndex, 'g', svgns);
setAttributes(this._root, rootAttributes); // ensure no additional child elements
domClear(this._svg, RootIndex + 1);
} // set background color if defined
@@ -20406,11 +20494,11 @@
if (!svg) return null;
let node;
if (bg) {
svg.removeAttribute('style');
- node = domChild(svg, RootIndex, 'rect', ns);
+ node = domChild(svg, RootIndex, 'rect', svgns);
setAttributes(node, {
width: this._width,
height: this._height,
fill: bg
});
@@ -20645,16 +20733,16 @@
defs = this._defs;
let el = defs.el,
index = 0;
for (const id in defs.gradient) {
- if (!el) defs.el = el = domChild(svg, RootIndex + 1, 'defs', ns);
+ if (!el) defs.el = el = domChild(svg, RootIndex + 1, 'defs', svgns);
index = updateGradient(el, defs.gradient[id], index);
}
for (const id in defs.clipping) {
- if (!el) defs.el = el = domChild(svg, RootIndex + 1, 'defs', ns);
+ if (!el) defs.el = el = domChild(svg, RootIndex + 1, 'defs', svgns);
index = updateClipping(el, defs.clipping[id], index);
} // clean-up
if (el) {
@@ -20690,47 +20778,47 @@
if (grad.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
- let pt = domChild(el, index++, 'pattern', ns);
+ let pt = domChild(el, index++, 'pattern', svgns);
setAttributes(pt, {
id: patternPrefix + grad.id,
viewBox: '0,0,1,1',
width: '100%',
height: '100%',
preserveAspectRatio: 'xMidYMid slice'
});
- pt = domChild(pt, 0, 'rect', ns);
+ pt = domChild(pt, 0, 'rect', svgns);
setAttributes(pt, {
width: 1,
height: 1,
fill: "url(".concat(href(), "#").concat(grad.id, ")")
});
- el = domChild(el, index++, 'radialGradient', ns);
+ el = domChild(el, index++, 'radialGradient', svgns);
setAttributes(el, {
id: grad.id,
fx: grad.x1,
fy: grad.y1,
fr: grad.r1,
cx: grad.x2,
cy: grad.y2,
r: grad.r2
});
} else {
- el = domChild(el, index++, 'linearGradient', ns);
+ el = domChild(el, index++, 'linearGradient', svgns);
setAttributes(el, {
id: grad.id,
x1: grad.x1,
x2: grad.x2,
y1: grad.y1,
y2: grad.y2
});
}
for (i = 0, n = grad.stops.length; i < n; ++i) {
- stop = domChild(el, i, 'stop', ns);
+ stop = domChild(el, i, 'stop', svgns);
stop.setAttribute('offset', grad.stops[i].offset);
stop.setAttribute('stop-color', grad.stops[i].color);
}
domClear(el, i);
@@ -20738,18 +20826,18 @@
} // update clipping path definitions
function updateClipping(el, clip, index) {
let mask;
- el = domChild(el, index, 'clipPath', ns);
+ el = domChild(el, index, 'clipPath', svgns);
el.setAttribute('id', clip.id);
if (clip.path) {
- mask = domChild(el, 0, 'path', ns);
+ mask = domChild(el, 0, 'path', svgns);
mask.setAttribute('d', clip.path);
} else {
- mask = domChild(el, 0, 'rect', ns);
+ mask = domChild(el, 0, 'rect', svgns);
setAttributes(mask, {
x: 0,
y: 0,
width: clip.width,
height: clip.height
@@ -20779,27 +20867,27 @@
let node = item._svg,
doc; // create a new dom node if needed
if (!node) {
doc = el.ownerDocument;
- node = domCreate(doc, tag, ns);
+ node = domCreate(doc, tag, svgns);
item._svg = node;
if (item.mark) {
node.__data__ = item;
node.__values__ = {
fill: 'default'
}; // if group, create background, content, and foreground elements
if (tag === 'g') {
- const bg = domCreate(doc, 'path', ns);
+ const bg = domCreate(doc, 'path', svgns);
node.appendChild(bg);
bg.__data__ = item;
- const cg = domCreate(doc, 'g', ns);
+ const cg = domCreate(doc, 'g', svgns);
node.appendChild(cg);
cg.__data__ = item;
- const fg = domCreate(doc, 'path', ns);
+ const fg = domCreate(doc, 'path', svgns);
node.appendChild(fg);
fg.__data__ = item;
fg.__values__ = {
fill: 'default'
};
@@ -20885,11 +20973,11 @@
if (key !== values.text) {
domClear(el, 0);
doc = el.ownerDocument;
lh = lineHeight(item);
value.forEach((t, i) => {
- const ts = domCreate(doc, 'tspan', ns);
+ const ts = domCreate(doc, 'tspan', svgns);
ts.__data__ = item; // data binding
ts.textContent = t;
if (i) {
@@ -27173,11 +27261,11 @@
var ex = extent(values),
start = zero ? Math.min(ex[0], 0) : ex[0],
stop = ex[1],
span = stop - start,
step = nice ? tickStep(start, stop, k) : span / (k + 1);
- return range$1(step, stop, step);
+ return range$1(start + step, stop, step);
};
}
/**
* Generate isocontours (level sets) based on input raster grid data.
* @constructor
@@ -35886,12 +35974,10 @@
__proto__: null,
crossfilter: CrossFilter,
resolvefilter: ResolveFilter
});
- var version = "5.16.1";
-
const RawCode = 'RawCode';
const Literal = 'Literal';
const Property = 'Property';
const Identifier$1 = 'Identifier';
const ArrayExpression = 'ArrayExpression';
@@ -36085,11 +36171,11 @@
ch === 0x5C || // \ (backslash)
ch >= 0x80 && RegexNonAsciiIdentifierPart.test(String.fromCharCode(ch));
} // 7.6.1.1 Keywords
- const keywords = {
+ const keywords$1 = {
'if': 1,
'in': 1,
'do': 1,
'var': 1,
'for': 1,
@@ -36277,11 +36363,11 @@
id = source$1.charCodeAt(index$1) === 0x5C ? getEscapedIdentifier() : getIdentifier(); // There is no keyword or literal with only one character.
// Thus, it must be an identifier.
if (id.length === 1) {
type = TokenIdentifier;
- } else if (keywords.hasOwnProperty(id)) {
+ } else if (keywords$1.hasOwnProperty(id)) {
// eslint-disable-line no-prototype-builtins
type = TokenKeyword;
} else if (id === 'null') {
type = TokenNullLiteral;
} else if (id === 'true' || id === 'false') {
@@ -36431,10 +36517,14 @@
type: TokenPunctuator,
value: ch2,
start: start,
end: index$1
};
+ }
+
+ if (ch2 === '//') {
+ throwError({}, MessageUnexpectedToken, ILLEGAL);
} // 1-character punctuators: < > = ! + - * % & | ^ /
if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
++index$1;
@@ -37533,25 +37623,17 @@
utcminutes: fn('getUTCMinutes', DATE, 0),
utcseconds: fn('getUTCSeconds', DATE, 0),
utcmilliseconds: fn('getUTCMilliseconds', DATE, 0),
// sequence functions
length: fn('length', null, -1),
- join: fn('join', null),
- indexof: fn('indexOf', null),
- lastindexof: fn('lastIndexOf', null),
- slice: fn('slice', null),
- reverse: function (args) {
- return '(' + codegen(args[0]) + ').slice().reverse()';
- },
// STRING functions
parseFloat: 'parseFloat',
parseInt: 'parseInt',
upper: fn('toUpperCase', STRING, 0),
lower: fn('toLowerCase', STRING, 0),
substring: fn('substring', STRING),
split: fn('split', STRING),
- replace: fn('replace', STRING),
trim: fn('trim', STRING, 0),
// REGEXP functions
regexp: REGEXP,
test: fn('test', REGEXP),
// Control Flow functions
@@ -37631,11 +37713,11 @@
fn = has(functions, callee) && functions[callee];
if (!fn) error('Unrecognized function: ' + callee);
return isFunction(fn) ? fn(args) : fn + '(' + args.map(visit).join(',') + ')';
},
ArrayExpression: n => '[' + n.elements.map(visit).join(',') + ']',
- BinaryExpression: n => '(' + visit(n.left) + n.operator + visit(n.right) + ')',
+ BinaryExpression: n => '(' + visit(n.left) + ' ' + n.operator + ' ' + visit(n.right) + ')',
UnaryExpression: n => '(' + n.operator + visit(n.argument) + ')',
ConditionalExpression: n => '(' + visit(n.test) + '?' + visit(n.consequent) + ':' + visit(n.alternate) + ')',
LogicalExpression: n => '(' + visit(n.left) + n.operator + visit(n.right) + ')',
ObjectExpression: n => '{' + n.properties.map(visit).join(',') + '}',
Property: n => {
@@ -37660,21 +37742,79 @@
codegen.functions = functions;
codegen.constants = constants;
return codegen;
}
+ function ascending$3(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+ }
+
+ function bisector$1(f) {
+ let delta = f;
+ let compare = f;
+
+ if (f.length === 1) {
+ delta = (d, x) => f(d) - x;
+
+ compare = ascendingComparator$1(f);
+ }
+
+ function left(a, x, lo, hi) {
+ if (lo == null) lo = 0;
+ if (hi == null) hi = a.length;
+
+ while (lo < hi) {
+ const mid = lo + hi >>> 1;
+ if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid;
+ }
+
+ return lo;
+ }
+
+ function right(a, x, lo, hi) {
+ if (lo == null) lo = 0;
+ if (hi == null) hi = a.length;
+
+ while (lo < hi) {
+ const mid = lo + hi >>> 1;
+ if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1;
+ }
+
+ return lo;
+ }
+
+ function center(a, x, lo, hi) {
+ if (lo == null) lo = 0;
+ if (hi == null) hi = a.length;
+ const i = left(a, x, lo, hi - 1);
+ return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;
+ }
+
+ return {
+ left,
+ center,
+ right
+ };
+ }
+
+ function ascendingComparator$1(f) {
+ return (d, x) => ascending$3(f(d), x);
+ }
+
const Intersect = 'intersect';
const Union = 'union';
const VlMulti = 'vlMulti';
+ const VlPoint = 'vlPoint';
const Or = 'or';
const And = 'and';
- var TYPE_ENUM = 'E',
- TYPE_RANGE_INC = 'R',
- TYPE_RANGE_EXC = 'R-E',
- TYPE_RANGE_LE = 'R-LE',
- TYPE_RANGE_RE = 'R-RE',
- UNIT_INDEX = 'index:unit'; // TODO: revisit date coercion?
+ const SELECTION_ID = '_vgsid_',
+ TYPE_ENUM = 'E',
+ TYPE_RANGE_INC = 'R',
+ TYPE_RANGE_EXC = 'R-E',
+ TYPE_RANGE_LE = 'R-LE',
+ TYPE_RANGE_RE = 'R-RE',
+ UNIT_INDEX = 'index:unit'; // TODO: revisit date coercion?
function testPoint(datum, entry) {
var fields = entry.fields,
values = entry.values,
n = fields.length,
@@ -37768,20 +37908,63 @@
// if no active selections, return false
return n && intersect;
}
+
+ const selectionId = field(SELECTION_ID),
+ bisect = bisector$1(selectionId),
+ bisectLeft$1 = bisect.left,
+ bisectRight$1 = bisect.right;
+
+ function selectionIdTest(name, datum, op) {
+ const data = this.context.data[name],
+ entries = data ? data.values.value : [],
+ unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined,
+ intersect = op === Intersect,
+ value = selectionId(datum),
+ index = bisectLeft$1(entries, value);
+ if (index === entries.length) return false;
+ if (selectionId(entries[index]) !== value) return false;
+
+ if (unitIdx && intersect) {
+ if (unitIdx.size === 1) return true;
+ if (bisectRight$1(entries, value) - index < unitIdx.size) return false;
+ }
+
+ return true;
+ }
/**
+ * Maps an array of scene graph items to an array of selection tuples.
+ * @param {string} name - The name of the dataset representing the selection.
+ * @param {string} unit - The name of the unit view.
+ *
+ * @returns {array} An array of selection entries for the given unit.
+ */
+
+
+ function selectionTuples(array, base) {
+ return array.map(x => extend({
+ values: base.fields.map(f => (f.getter || (f.getter = field(f.field)))(x.datum))
+ }, base));
+ }
+ /**
* Resolves selection for use as a scale domain or reads via the API.
* @param {string} name - The name of the dataset representing the selection
* @param {string} [op='union'] - The set operation for combining selections.
* One of 'intersect' or 'union' (default).
+ * @param {boolean} isMulti - Identifies a "multi" selection to perform more
+ * expensive resolution computation.
+ * @param {boolean} vl5 - With Vega-Lite v5, "multi" selections are now called "point"
+ * selections, and thus the resolved tuple should reflect this name.
+ * This parameter allows us to reflect this change without triggering
+ * a major version bump for Vega.
* @returns {object} An object of selected fields and values.
*/
- function selectionResolve(name, op, isMulti) {
+ function selectionResolve(name, op, isMulti, vl5) {
var data = this.context.data[name],
entries = data ? data.values.value : [],
resolved = {},
multiRes = {},
types = {},
@@ -37832,11 +38015,12 @@
resolved[field] = Object.keys(resolved[field]).map(unit => resolved[field][unit]).reduce((acc, curr) => acc === undefined ? curr : ops[types[field] + '_' + op](acc, curr));
});
entries = Object.keys(multiRes);
if (isMulti && entries.length) {
- resolved[VlMulti] = op === Union ? {
+ const key = vl5 ? VlPoint : VlMulti;
+ resolved[key] = op === Union ? {
[Or]: entries.reduce((acc, k) => (acc.push(...multiRes[k]), acc), [])
} : {
[And]: entries.map(k => ({
[Or]: multiRes[k]
}))
@@ -38232,10 +38416,50 @@
function pinchAngle(event) {
const t = event.touches;
return Math.atan2(t[0].clientY - t[1].clientY, t[0].clientX - t[1].clientX);
}
+ const accessors = {};
+
+ function pluck(data, name) {
+ const accessor = accessors[name] || (accessors[name] = field(name));
+ return isArray(data) ? data.map(accessor) : accessor(data);
+ }
+
+ function array$5(seq) {
+ return isArray(seq) || ArrayBuffer.isView(seq) ? seq : null;
+ }
+
+ function sequence$1(seq) {
+ return array$5(seq) || (isString(seq) ? seq : null);
+ }
+
+ function join$1(seq, ...args) {
+ return array$5(seq).join(...args);
+ }
+
+ function indexof(seq, ...args) {
+ return sequence$1(seq).indexOf(...args);
+ }
+
+ function lastindexof(seq, ...args) {
+ return sequence$1(seq).lastIndexOf(...args);
+ }
+
+ function slice$1(seq, ...args) {
+ return sequence$1(seq).slice(...args);
+ }
+
+ function replace$1(str, pattern, repl) {
+ if (isFunction(repl)) error('Function argument passed to replace.');
+ return String(str).replace(pattern, repl);
+ }
+
+ function reverse$1(seq) {
+ return array$5(seq).slice().reverse();
+ }
+
function bandspace(count, paddingInner, paddingOuter) {
return bandSpace(count || 0, paddingInner || 0, paddingOuter || 0);
}
function bandwidth(name, group) {
@@ -38405,15 +38629,22 @@
toBoolean,
toDate,
toNumber,
toString,
+ indexof,
+ join: join$1,
+ lastindexof,
+ replace: replace$1,
+ reverse: reverse$1,
+ slice: slice$1,
flush,
lerp,
merge: merge$3,
pad,
peek,
+ pluck,
span,
inrange,
truncate,
rgb,
lab,
@@ -38533,11 +38764,13 @@
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);
function parser$1(expr, scope) {
const params = {}; // parse the expression to an abstract syntax tree (ast)
let ast;
@@ -39471,16 +39704,12 @@
return {
view: constant(view),
item: constant(item || {}),
group: group,
xy: xy,
- x: function (item) {
- return xy(item)[0];
- },
- y: function (item) {
- return xy(item)[1];
- }
+ x: item => xy(item)[0],
+ y: item => xy(item)[1]
};
}
const VIEW = 'view',
TIMER = 'timer',
@@ -43387,12 +43616,12 @@
t,
m;
if (data.values) {
// hard-wired input data set
- if (hasSignal(data.values) || hasSignal(data.format)) {
- // if either values or format has signal, use dynamic loader
+ if (isSignal(data.values) || hasSignal(data.format)) {
+ // if either values is signal or format has signal, use dynamic loader
output.push(load$1(scope, data));
output.push(source = collect());
} else {
// otherwise, ingest upon dataflow init
output.push(source = collect({
@@ -44917,10 +45146,12 @@
}
// -- Transforms -----
extend(transforms, tx, vtx, encode, geo, force, label, tree$1, reg, voronoi, wordcloud, xf); // -- Exports -----
+ const version$1 = pkg.version;
+
exports.Bounds = Bounds;
exports.CanvasHandler = CanvasHandler;
exports.CanvasRenderer = CanvasRenderer;
exports.DATE = DATE;
exports.DAY = DAY;
@@ -45001,11 +45232,11 @@
exports.field = field;
exports.flush = flush;
exports.font = font;
exports.fontFamily = fontFamily;
exports.fontSize = fontSize;
- exports.format = format$1;
+ exports.format = format;
exports.formatLocale = numberFormatDefaultLocale;
exports.formats = formats;
exports.hasOwnProperty = has;
exports.id = id;
exports.identity = identity;
@@ -45024,10 +45255,11 @@
exports.intersectRule = intersectRule;
exports.isArray = isArray;
exports.isBoolean = isBoolean;
exports.isDate = isDate;
exports.isFunction = isFunction;
+ exports.isIterable = isIterable;
exports.isNumber = isNumber;
exports.isObject = isObject;
exports.isRegExp = isRegExp;
exports.isString = isString;
exports.isTuple = isTuple;
@@ -45130,10 +45362,10 @@
exports.utcOffset = utcOffset;
exports.utcSequence = utcSequence;
exports.utcdayofyear = utcdayofyear;
exports.utcquarter = utcquarter;
exports.utcweek = utcweek;
- exports.version = version;
+ exports.version = version$1;
exports.visitArray = visitArray;
exports.week = week;
exports.writeConfig = writeConfig;
exports.zero = zero;
exports.zoomLinear = zoomLinear;