From 0d1f2ffe2d235232ac8d6a17032171af5ebfb95a Mon Sep 17 00:00:00 2001 From: Kanit Wongsuphasawat Date: Sun, 26 May 2019 23:08:19 -0700 Subject: [PATCH] release 0.21.1 b3b2482d66edfcbea65e75bd811123b13301445a --- build/compassql.js | 9681 ++++++++++++++++++++++++++++++ build/compassql.js.map | 1 + build/compassql.min.js | 1 + build/compassql.min.js.map | 1 + build/src/constraint/base.js | 55 + build/src/constraint/encoding.js | 44 + build/src/constraint/field.js | 403 ++ build/src/constraint/index.js | 4 + build/src/constraint/spec.js | 797 +++ build/src/constraint/value.js | 28 + build/src/query/encoding.js | 196 + build/src/query/expandedtype.js | 13 + build/src/query/groupby.js | 69 + build/src/query/index.js | 8 + build/src/query/normalize.js | 29 + build/src/query/query.js | 1 + build/src/query/shorthand.js | 451 ++ build/src/query/spec.js | 148 + build/src/query/transform.js | 1 + build/src/ranking/aggregation.js | 85 + build/src/ranking/fieldorder.js | 51 + build/src/ranking/ranking.js | 87 + 22 files changed, 12154 insertions(+) create mode 100644 build/compassql.js create mode 100644 build/compassql.js.map create mode 100644 build/compassql.min.js create mode 100644 build/compassql.min.js.map create mode 100644 build/src/constraint/base.js create mode 100644 build/src/constraint/encoding.js create mode 100644 build/src/constraint/field.js create mode 100644 build/src/constraint/index.js create mode 100644 build/src/constraint/spec.js create mode 100644 build/src/constraint/value.js create mode 100644 build/src/query/encoding.js create mode 100644 build/src/query/expandedtype.js create mode 100644 build/src/query/groupby.js create mode 100644 build/src/query/index.js create mode 100644 build/src/query/normalize.js create mode 100644 build/src/query/query.js create mode 100644 build/src/query/shorthand.js create mode 100644 build/src/query/spec.js create mode 100644 build/src/query/transform.js create mode 100644 build/src/ranking/aggregation.js create mode 100644 build/src/ranking/fieldorder.js create mode 100644 build/src/ranking/ranking.js diff --git a/build/compassql.js b/build/compassql.js new file mode 100644 index 00000000..077bd679 --- /dev/null +++ b/build/compassql.js @@ -0,0 +1,9681 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.cql = {})); +}(this, function (exports) { 'use strict'; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var clone_1 = createCommonjsModule(function (module) { + var clone = (function() { + + function _instanceof(obj, type) { + return type != null && obj instanceof type; + } + + var nativeMap; + try { + nativeMap = Map; + } catch(_) { + // maybe a reference error because no `Map`. Give it a dummy value that no + // value will ever be an instanceof. + nativeMap = function() {}; + } + + var nativeSet; + try { + nativeSet = Set; + } catch(_) { + nativeSet = function() {}; + } + + var nativePromise; + try { + nativePromise = Promise; + } catch(_) { + nativePromise = function() {}; + } + + /** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). + * @param `includeNonEnumerable` - set to true if the non-enumerable properties + * should be cloned as well. Non-enumerable properties on the prototype + * chain will be ignored. (optional - false by default) + */ + function clone(parent, circular, depth, prototype, includeNonEnumerable) { + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + includeNonEnumerable = circular.includeNonEnumerable; + circular = circular.circular; + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth === 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (_instanceof(parent, nativeMap)) { + child = new nativeMap(); + } else if (_instanceof(parent, nativeSet)) { + child = new nativeSet(); + } else if (_instanceof(parent, nativePromise)) { + child = new nativePromise(function (resolve, reject) { + parent.then(function(value) { + resolve(_clone(value, depth - 1)); + }, function(err) { + reject(_clone(err, depth - 1)); + }); + }); + } else if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.allocUnsafe) { + // Node.js >= 4.5.0 + child = Buffer.allocUnsafe(parent.length); + } else { + // Older Node.js versions + child = new Buffer(parent.length); + } + parent.copy(child); + return child; + } else if (_instanceof(parent, Error)) { + child = Object.create(parent); + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + if (_instanceof(parent, nativeMap)) { + parent.forEach(function(value, key) { + var keyChild = _clone(key, depth - 1); + var valueChild = _clone(value, depth - 1); + child.set(keyChild, valueChild); + }); + } + if (_instanceof(parent, nativeSet)) { + parent.forEach(function(value) { + var entryChild = _clone(value, depth - 1); + child.add(entryChild); + }); + } + + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } + + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(parent); + for (var i = 0; i < symbols.length; i++) { + // Don't need to worry about cloning a symbol because it is a primitive, + // like a number or string. + var symbol = symbols[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); + if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { + continue; + } + child[symbol] = _clone(parent[symbol], depth - 1); + if (!descriptor.enumerable) { + Object.defineProperty(child, symbol, { + enumerable: false + }); + } + } + } + + if (includeNonEnumerable) { + var allPropertyNames = Object.getOwnPropertyNames(parent); + for (var i = 0; i < allPropertyNames.length; i++) { + var propertyName = allPropertyNames[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); + if (descriptor && descriptor.enumerable) { + continue; + } + child[propertyName] = _clone(parent[propertyName], depth - 1); + Object.defineProperty(child, propertyName, { + enumerable: false + }); + } + } + + return child; + } + + return _clone(parent, depth); + } + + /** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ + clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); + }; + + // private utility functions + + function __objToStr(o) { + return Object.prototype.toString.call(o); + } + clone.__objToStr = __objToStr; + + function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; + } + clone.__isDate = __isDate; + + function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; + } + clone.__isArray = __isArray; + + function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; + } + clone.__isRegExp = __isRegExp; + + function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; + } + clone.__getRegExpFlags = __getRegExpFlags; + + return clone; + })(); + + if (module.exports) { + module.exports = clone; + } + }); + + var fastJsonStableStringify = function (data, opts) { + if (!opts) opts = {}; + if (typeof opts === 'function') opts = { cmp: opts }; + var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; + + var cmp = opts.cmp && (function (f) { + return function (node) { + return function (a, b) { + var aobj = { key: a, value: node[a] }; + var bobj = { key: b, value: node[b] }; + return f(aobj, bobj); + }; + }; + })(opts.cmp); + + var seen = []; + return (function stringify (node) { + if (node && node.toJSON && typeof node.toJSON === 'function') { + node = node.toJSON(); + } + + if (node === undefined) return; + if (typeof node == 'number') return isFinite(node) ? '' + node : 'null'; + if (typeof node !== 'object') return JSON.stringify(node); + + var i, out; + if (Array.isArray(node)) { + out = '['; + for (i = 0; i < node.length; i++) { + if (i) out += ','; + out += stringify(node[i]) || 'null'; + } + return out + ']'; + } + + if (node === null) return 'null'; + + if (seen.indexOf(node) !== -1) { + if (cycles) return JSON.stringify('__cycle__'); + throw new TypeError('Converting circular structure to JSON'); + } + + var seenIndex = seen.push(node) - 1; + var keys = Object.keys(node).sort(cmp && cmp(node)); + out = ''; + for (i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = stringify(node[key]); + + if (!value) continue; + if (out) out += ','; + out += JSON.stringify(key) + ':' + value; + } + seen.splice(seenIndex, 1); + return '{' + out + '}'; + })(data); + }; + + function accessor(fn, fields, name) { + fn.fields = fields || []; + fn.fname = name; + return fn; + } + + function error(message) { + throw Error(message); + } + + function splitAccessPath(p) { + var path = [], + q = null, + b = 0, + n = p.length, + s = '', + i, j, c; + + p = p + ''; + + function push() { + path.push(s + p.substring(i, j)); + s = ''; + i = j + 1; + } + + for (i=j=0; j i) { + push(); + } else { + i = j + 1; + } + } else if (c === '[') { + if (j > i) push(); + b = i = j + 1; + } else if (c === ']') { + if (!b) error('Access path missing open bracket: ' + p); + if (b > 0) push(); + b = 0; + i = j + 1; + } + } + + if (b) error('Access path missing closing bracket: ' + p); + if (q) error('Access path missing closing quote: ' + p); + + if (j > i) { + j++; + push(); + } + + return path; + } + + var isArray = Array.isArray; + + function isObject(_) { + return _ === Object(_); + } + + function isString(_) { + return typeof _ === 'string'; + } + + function $(x) { + return isArray(x) ? '[' + x.map($) + ']' + : isObject(x) || isString(x) ? + // Output valid JSON and JS source strings. + // See http://timelessrepo.com/json-isnt-a-javascript-subset + JSON.stringify(x).replace('\u2028','\\u2028').replace('\u2029', '\\u2029') + : x; + } + + function field(field, name) { + var path = splitAccessPath(field), + code = 'return _[' + path.map($).join('][') + '];'; + + return accessor( + Function('_', code), + [(field = path.length===1 ? path[0] : field)], + name || field + ); + } + + var empty = []; + + var id = field('id'); + + var identity = accessor(function(_) { return _; }, empty, 'identity'); + + var zero = accessor(function() { return 0; }, empty, 'zero'); + + var one = accessor(function() { return 1; }, empty, 'one'); + + var truthy = accessor(function() { return true; }, empty, 'true'); + + var falsy = accessor(function() { return false; }, empty, 'false'); + + function log(method, level, input) { + var msg = [level].concat([].slice.call(input)); + console[method](...msg); // eslint-disable-line no-console + } + + var None = 0; + var Error$1 = 1; + var Warn = 2; + var Info = 3; + var Debug = 4; + + function logger(_, method) { + var level = _ || None; + return { + level: function(_) { + if (arguments.length) { + level = +_; + return this; + } else { + return level; + } + }, + error: function() { + if (level >= Error$1) log(method || 'error', 'ERROR', arguments); + return this; + }, + warn: function() { + if (level >= Warn) log(method || 'warn', 'WARN', arguments); + return this; + }, + info: function() { + if (level >= Info) log(method || 'log', 'INFO', arguments); + return this; + }, + debug: function() { + if (level >= Debug) log(method || 'log', 'DEBUG', arguments); + return this; + } + } + } + + /** + * 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), the range [min, max] is returned. + */ + + /** + * Return an array with minimum and maximum values, in the + * form [min, max]. Ignores null, undefined, and NaN values. + */ + + /** + * Predicate that returns true if the value lies within the span + * of the given range. The left and right flags control the use + * of inclusive (true) or exclusive (false) comparisons. + */ + + function isBoolean(_) { + return typeof _ === 'boolean'; + } + + function isNumber(_) { + return typeof _ === 'number'; + } + + function toSet(_) { + for (var s={}, i=0, n=_.length; i fastJsonStableStringify(x)).join(',')})`; + }; + /** + * Converts any object to a string representation that can be consumed by humans. + */ + const stringify = fastJsonStableStringify; + function contains(array, item) { + return array.indexOf(item) > -1; + } + /** + * Returns true if any item returns true. + */ + function some(arr, f) { + let i = 0; + for (const [k, a] of arr.entries()) { + if (f(a, k, i++)) { + return true; + } + } + return false; + } + // This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208 + const keys = Object.keys; + function flagKeys(f) { + return keys(f); + } + /** + * Convert a string into a valid variable name + */ + function varName(s) { + // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _ + const alphanumericS = s.replace(/\W/g, '_'); + // Add _ if the string has leading numbers. + return (s.match(/^\d+/) ? '_' : '') + alphanumericS; + } + function titlecase(s) { + return s.charAt(0).toUpperCase() + s.substr(1); + } + /** + * Return access with datum to the flattened field. + * + * @param path The field name. + * @param datum The string to use for `datum`. + */ + function flatAccessWithDatum(path, datum = 'datum') { + return `${datum}[${$(splitAccessPath(path).join('.'))}]`; + } + /** + * Replaces path accesses with access to non-nested field. + * For example, `foo["bar"].baz` becomes `foo\\.bar\\.baz`. + */ + function replacePathInField(path) { + return `${splitAccessPath(path) + .map(p => p.replace('.', '\\.')) + .join('\\.')}`; + } + /** + * This is a replacement for chained || for numeric properties or properties that respect null so that 0 will be included. + */ + function getFirstDefined(...args) { + for (const arg of args) { + if (arg !== undefined) { + return arg; + } + } + return undefined; + } + function internalField(name) { + return isInternalField(name) ? name : `__${name}`; + } + function isInternalField(name) { + return name.indexOf('__') === 0; + } + + /* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ + // Facet + const ROW = 'row'; + const COLUMN = 'column'; + const FACET = 'facet'; + // Position + const X = 'x'; + const Y = 'y'; + const X2 = 'x2'; + const Y2 = 'y2'; + // Geo Position + const LATITUDE = 'latitude'; + const LONGITUDE = 'longitude'; + const LATITUDE2 = 'latitude2'; + const LONGITUDE2 = 'longitude2'; + // Mark property with scale + const COLOR = 'color'; + const FILL = 'fill'; + const STROKE = 'stroke'; + const SHAPE = 'shape'; + const SIZE = 'size'; + const OPACITY = 'opacity'; + const FILLOPACITY = 'fillOpacity'; + const STROKEOPACITY = 'strokeOpacity'; + const STROKEWIDTH = 'strokeWidth'; + // Non-scale channel + const TEXT = 'text'; + const ORDER = 'order'; + const DETAIL = 'detail'; + const KEY = 'key'; + const TOOLTIP = 'tooltip'; + const HREF = 'href'; + const GEOPOSITION_CHANNEL_INDEX = { + longitude: 1, + longitude2: 1, + latitude: 1, + latitude2: 1 + }; + const UNIT_CHANNEL_INDEX = Object.assign({ + // position + x: 1, y: 1, x2: 1, y2: 1 }, GEOPOSITION_CHANNEL_INDEX, { + // color + color: 1, fill: 1, stroke: 1, + // other non-position with scale + opacity: 1, fillOpacity: 1, strokeOpacity: 1, strokeWidth: 1, size: 1, shape: 1, + // channels without scales + order: 1, text: 1, detail: 1, key: 1, tooltip: 1, href: 1 }); + function isColorChannel(channel) { + return channel === 'color' || channel === 'fill' || channel === 'stroke'; + } + const FACET_CHANNEL_INDEX = { + row: 1, + column: 1, + facet: 1 + }; + const CHANNEL_INDEX = Object.assign({}, UNIT_CHANNEL_INDEX, FACET_CHANNEL_INDEX); + const CHANNELS = flagKeys(CHANNEL_INDEX); + const SINGLE_DEF_CHANNEL_INDEX = __rest(CHANNEL_INDEX, ["order", "detail"]); + const SINGLE_DEF_UNIT_CHANNEL_INDEX = __rest(CHANNEL_INDEX, ["order", "detail", "row", "column", "facet"]); + function isChannel(str) { + return !!CHANNEL_INDEX[str]; + } + function isSecondaryRangeChannel(c) { + const main = getMainRangeChannel(c); + return main !== c; + } + function getMainRangeChannel(channel) { + switch (channel) { + case 'x2': + return 'x'; + case 'y2': + return 'y'; + case 'latitude2': + return 'latitude'; + case 'longitude2': + return 'longitude'; + } + return channel; + } + // NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2; + const // The rest of unit channels then have scale + NONPOSITION_CHANNEL_INDEX = __rest(UNIT_CHANNEL_INDEX, ["x", "y", "x2", "y2", "latitude", "longitude", "latitude2", "longitude2"]); + const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX); + // POSITION_SCALE_CHANNELS = X and Y; + const POSITION_SCALE_CHANNEL_INDEX = { x: 1, y: 1 }; + const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX); + // NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y + const NONPOSITION_SCALE_CHANNEL_INDEX = __rest(NONPOSITION_CHANNEL_INDEX, ["text", "tooltip", "href", "detail", "key", "order"]); + // Declare SCALE_CHANNEL_INDEX + const SCALE_CHANNEL_INDEX = Object.assign({}, POSITION_SCALE_CHANNEL_INDEX, NONPOSITION_SCALE_CHANNEL_INDEX); + function isScaleChannel(channel) { + return !!SCALE_CHANNEL_INDEX[channel]; + } + /** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ + function supportMark(channel, mark) { + return getSupportedMark(channel)[mark]; + } + /** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to 'always', 'binned', or undefined + */ + function getSupportedMark(channel) { + switch (channel) { + case COLOR: + case FILL: + case STROKE: + // falls through + case DETAIL: + case KEY: + case TOOLTIP: + case HREF: + case ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case OPACITY: + case FILLOPACITY: + case STROKEOPACITY: + case STROKEWIDTH: + // falls through + case FACET: + case ROW: // falls through + case COLUMN: + return { + // all marks + point: 'always', + tick: 'always', + rule: 'always', + circle: 'always', + square: 'always', + bar: 'always', + rect: 'always', + line: 'always', + trail: 'always', + area: 'always', + text: 'always', + geoshape: 'always' + }; + case X: + case Y: + case LATITUDE: + case LONGITUDE: + return { + // all marks except geoshape. geoshape does not use X, Y -- it uses a projection + point: 'always', + tick: 'always', + rule: 'always', + circle: 'always', + square: 'always', + bar: 'always', + rect: 'always', + line: 'always', + trail: 'always', + area: 'always', + text: 'always' + }; + case X2: + case Y2: + case LATITUDE2: + case LONGITUDE2: + return { + rule: 'always', + bar: 'always', + rect: 'always', + area: 'always', + circle: 'binned', + point: 'binned', + square: 'binned', + tick: 'binned' + }; + case SIZE: + return { + point: 'always', + tick: 'always', + rule: 'always', + circle: 'always', + square: 'always', + bar: 'always', + text: 'always', + line: 'always', + trail: 'always' + }; + case SHAPE: + return { point: 'always', geoshape: 'always' }; + case TEXT: + return { text: 'always' }; + } + } + function rangeType(channel) { + switch (channel) { + case X: + case Y: + case SIZE: + case STROKEWIDTH: + case OPACITY: + case FILLOPACITY: + case STROKEOPACITY: + // X2 and Y2 use X and Y scales, so they similarly have continuous range. [falls through] + case X2: + case Y2: + return undefined; + case FACET: + case ROW: + case COLUMN: + case SHAPE: + // TEXT, TOOLTIP, and HREF have no scale but have discrete output [falls through] + case TEXT: + case TOOLTIP: + case HREF: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case COLOR: + case FILL: + case STROKE: + return 'flexible'; + // No scale, no range type. + case LATITUDE: + case LONGITUDE: + case LATITUDE2: + case LONGITUDE2: + case DETAIL: + case KEY: + case ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('rangeType not implemented for ' + channel); + } + + const COMMON_AXIS_PROPERTIES_INDEX = { + orient: 1, + bandPosition: 1, + domain: 1, + domainColor: 1, + domainDash: 1, + domainDashOffset: 1, + domainOpacity: 1, + domainWidth: 1, + format: 1, + formatType: 1, + grid: 1, + gridColor: 1, + gridDash: 1, + gridDashOffset: 1, + gridOpacity: 1, + gridWidth: 1, + labelAlign: 1, + labelAngle: 1, + labelBaseline: 1, + labelBound: 1, + labelColor: 1, + labelFlush: 1, + labelFlushOffset: 1, + labelFont: 1, + labelFontSize: 1, + labelFontStyle: 1, + labelFontWeight: 1, + labelLimit: 1, + labelOpacity: 1, + labelOverlap: 1, + labelPadding: 1, + labels: 1, + labelSeparation: 1, + maxExtent: 1, + minExtent: 1, + offset: 1, + position: 1, + tickColor: 1, + tickCount: 1, + tickDash: 1, + tickDashOffset: 1, + tickExtra: 1, + tickMinStep: 1, + tickOffset: 1, + tickOpacity: 1, + tickRound: 1, + ticks: 1, + tickSize: 1, + tickWidth: 1, + title: 1, + titleAlign: 1, + titleAnchor: 1, + titleAngle: 1, + titleBaseline: 1, + titleColor: 1, + titleFont: 1, + titleFontSize: 1, + titleFontStyle: 1, + titleFontWeight: 1, + titleLimit: 1, + titleOpacity: 1, + titlePadding: 1, + titleX: 1, + titleY: 1, + values: 1, + zindex: 1 + }; + const AXIS_PROPERTIES_INDEX = Object.assign({}, COMMON_AXIS_PROPERTIES_INDEX, { encoding: 1 }); + const VG_AXIS_PROPERTIES_INDEX = Object.assign({ gridScale: 1, scale: 1 }, COMMON_AXIS_PROPERTIES_INDEX, { encode: 1 }); + // Export for dependent projects + const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX); + + const COMMON_LEGEND_PROPERTY_INDEX = { + clipHeight: 1, + columnPadding: 1, + columns: 1, + cornerRadius: 1, + direction: 1, + fillColor: 1, + format: 1, + formatType: 1, + gradientLength: 1, + gradientOpacity: 1, + gradientStrokeColor: 1, + gradientStrokeWidth: 1, + gradientThickness: 1, + gridAlign: 1, + labelAlign: 1, + labelBaseline: 1, + labelColor: 1, + labelFont: 1, + labelFontSize: 1, + labelFontStyle: 1, + labelFontWeight: 1, + labelLimit: 1, + labelOffset: 1, + labelOpacity: 1, + labelOverlap: 1, + labelPadding: 1, + labelSeparation: 1, + legendX: 1, + legendY: 1, + offset: 1, + orient: 1, + padding: 1, + rowPadding: 1, + strokeColor: 1, + symbolDash: 1, + symbolDashOffset: 1, + symbolFillColor: 1, + symbolOffset: 1, + symbolOpacity: 1, + symbolSize: 1, + symbolStrokeColor: 1, + symbolStrokeWidth: 1, + symbolType: 1, + tickCount: 1, + tickMinStep: 1, + title: 1, + titleAlign: 1, + titleAnchor: 1, + titleBaseline: 1, + titleColor: 1, + titleFont: 1, + titleFontSize: 1, + titleFontStyle: 1, + titleFontWeight: 1, + titleLimit: 1, + titleOpacity: 1, + titleOrient: 1, + titlePadding: 1, + type: 1, + values: 1, + zindex: 1 + }; + const VG_LEGEND_PROPERTY_INDEX = Object.assign({}, COMMON_LEGEND_PROPERTY_INDEX, { + // channel scales + opacity: 1, shape: 1, stroke: 1, fill: 1, size: 1, strokeWidth: 1, + // encode + encode: 1 }); + const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX); + + /** + * Collection of all Vega-Lite Error Messages + */ + const INVALID_SPEC = 'Invalid spec'; + // FIT + const FIT_NON_SINGLE = 'Autosize "fit" only works for single views and layered views.'; + const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of "rangeStep" when "autosize" is "fit".'; + // SELECTION + function cannotProjectOnChannelWithoutField(channel) { + return `Cannot project a selection on encoding channel "${channel}", which has no field.`; + } + function nearestNotSupportForContinuous(mark) { + return `The "nearest" transform is not supported for ${mark} marks.`; + } + function selectionNotSupported(mark) { + return `Selection not supported for ${mark} yet`; + } + function selectionNotFound(name) { + return `Cannot find a selection named "${name}"`; + } + const SCALE_BINDINGS_CONTINUOUS = 'Scale bindings are currently only supported for scales with unbinned, continuous domains.'; + const NO_INIT_SCALE_BINDINGS = 'Selections bound to scales cannot be separately initialized.'; + // REPEAT + function noSuchRepeatedValue(field) { + return `Unknown repeated value "${field}".`; + } + function columnsNotSupportByRowCol(type) { + return `The "columns" property cannot be used when "${type}" has nested row/column.`; + } + // CONCAT + const CONCAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in concatenated views yet (https://github.com/vega/vega-lite/issues/2415).'; + // REPEAT + const REPEAT_CANNOT_SHARE_AXIS = 'Axes cannot be shared in repeated views yet (https://github.com/vega/vega-lite/issues/2415).'; + // DATA + function unrecognizedParse(p) { + return `Unrecognized parse "${p}".`; + } + function differentParse(field, local, ancestor) { + return `An ancestor parsed field "${field}" as ${ancestor} but a child wants to parse the field as ${local}.`; + } + // TRANSFORMS + function invalidTransformIgnored(transform) { + return `Ignoring an invalid transform: ${stringify(transform)}.`; + } + const NO_FIELDS_NEEDS_AS = 'If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.'; + // ENCODING & FACET + function encodingOverridden(channels) { + return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`; + } + function projectionOverridden(opt) { + const { parentProjection, projection } = opt; + return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(projection)}.`; + } + function primitiveChannelDef(channel, type, value) { + return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`; + } + function invalidFieldType(type) { + return `Invalid field type "${type}"`; + } + function nonZeroScaleUsedWithLengthMark(mark, channel, opt) { + const scaleText = opt.scaleType + ? `${opt.scaleType} scale` + : opt.zeroFalse + ? 'scale with zero=false' + : 'scale with custom domain that excludes zero'; + return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${channel === 'x' ? 'width' : 'height'} of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`; + } + function invalidFieldTypeForCountAggregate(type, aggregate) { + return `Invalid field type "${type}" for aggregate: "${aggregate}", using "quantitative" instead.`; + } + function invalidAggregate(aggregate) { + return `Invalid aggregation operator "${aggregate}"`; + } + function missingFieldType(channel, newType) { + return `Missing type for channel "${channel}", using "${newType}" instead.`; + } + function droppingColor(type, opt) { + const { fill, stroke } = opt; + return (`Dropping color ${type} as the plot also has ` + (fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke')); + } + function emptyFieldDef(fieldDef, channel) { + return `Dropping ${stringify(fieldDef)} from channel "${channel}" since it does not contain data field or value.`; + } + function latLongDeprecated(channel, type, newChannel) { + return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`; + } + const LINE_WITH_VARYING_SIZE = 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.'; + function incompatibleChannel(channel, markOrFacet, when) { + return `${channel} dropped as it is incompatible with "${markOrFacet}"${when ? ` when ${when}` : ''}.`; + } + function invalidEncodingChannel(channel) { + return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`; + } + function facetChannelShouldBeDiscrete(channel) { + return `${channel} encoding should be discrete (ordinal / nominal / binned).`; + } + function facetChannelDropped(channels) { + return `Facet encoding dropped as ${channels.join(' and ')} ${channels.length > 1 ? 'are' : 'is'} also specified.`; + } + function discreteChannelCannotEncode(channel, type) { + return `Using discrete channel "${channel}" to encode "${type}" field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`; + } + // Mark + const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.'; + function lineWithRange(hasX2, hasY2) { + const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2'; + return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`; + } + function orientOverridden(original, actual) { + return `Specified orient "${original}" overridden with "${actual}"`; + } + // SCALE + const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain'; + function cannotUseScalePropertyWithNonColor(prop) { + return `Cannot use the scale property "${prop}" with non-color channel.`; + } + function unaggregateDomainHasNoEffectForRawField(fieldDef) { + return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`; + } + function unaggregateDomainWithNonSharedDomainOp(aggregate) { + return `Unaggregated domain not applicable for "${aggregate}" since it produces values outside the origin domain of the source data.`; + } + function unaggregatedDomainWithLogScale(fieldDef) { + return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`; + } + function cannotApplySizeToNonOrientedMark(mark) { + return `Cannot apply size to non-oriented mark "${mark}".`; + } + function rangeStepDropped(channel) { + return `rangeStep for "${channel}" is dropped as top-level ${channel === 'x' ? 'width' : 'height'} is provided.`; + } + function scaleTypeNotWorkWithChannel(channel, scaleType, defaultScaleType) { + return `Channel "${channel}" does not work with "${scaleType}" scale. We are using "${defaultScaleType}" scale instead.`; + } + function scaleTypeNotWorkWithFieldDef(scaleType, defaultScaleType) { + return `FieldDef does not work with "${scaleType}" scale. We are using "${defaultScaleType}" scale instead.`; + } + function scalePropertyNotWorkWithScaleType(scaleType, propName, channel) { + return `${channel}-scale's "${propName}" is dropped as it does not work with ${scaleType} scale.`; + } + function scaleTypeNotWorkWithMark(mark, scaleType) { + return `Scale type "${scaleType}" does not work with mark "${mark}".`; + } + function mergeConflictingProperty(property, propertyOf, v1, v2) { + return `Conflicting ${propertyOf.toString()} property "${property.toString()}" (${stringify(v1)} and ${stringify(v2)}). Using ${stringify(v1)}.`; + } + function independentScaleMeansIndependentGuide(channel) { + return `Setting the scale to be independent for "${channel}" means we also have to set the guide (axis or legend) to be independent.`; + } + function domainSortDropped(sort) { + return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`; + } + const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains'; + const MORE_THAN_ONE_SORT = 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.'; + // AXIS + const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.'; + // STACK + function cannotStackRangedMark(channel) { + return `Cannot stack "${channel}" if there is already "${channel}2"`; + } + function cannotStackNonLinearScale(scaleType) { + return `Cannot stack non-linear scale (${scaleType})`; + } + function stackNonSummativeAggregate(aggregate) { + return `Stacking is applied even though the aggregate function is non-summative ("${aggregate}")`; + } + // TIMEUNIT + function invalidTimeUnit(unitName, value) { + return `Invalid ${unitName}: ${stringify(value)}`; + } + function dayReplacedWithDate(fullTimeUnit) { + return `Time unit "${fullTimeUnit}" is not supported. We are replacing it with ${fullTimeUnit.replace('day', 'date')}.`; + } + function droppedDay(d) { + return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`; + } + function errorBarCenterAndExtentAreNotNeeded(center, extent) { + return `${extent ? 'extent ' : ''}${extent && center ? 'and ' : ''}${center ? 'center ' : ''}${extent && center ? 'are ' : 'is '}not needed when data are aggregated.`; + } + function errorBarCenterIsUsedWithWrongExtent(center, extent, mark) { + return `${center} is not usually used with ${extent} for ${mark}.`; + } + function errorBarContinuousAxisHasCustomizedAggregate(aggregate, compositeMark) { + return `Continuous axis should not have customized aggregation function ${aggregate}; ${compositeMark} already agregates the axis.`; + } + function errorBarCenterIsNotNeeded(extent, mark) { + return `Center is not needed to be specified in ${mark} when extent is ${extent}.`; + } + function errorBand1DNotSupport(property) { + return `1D error band does not support ${property}`; + } + // CHANNEL + function channelRequiredForBinned(channel) { + return `Channel ${channel} is required for "binned" bin`; + } + function domainRequiredForThresholdScale(channel) { + return `Domain for ${channel} is required for threshold scale`; + } + + var message_ = /*#__PURE__*/Object.freeze({ + INVALID_SPEC: INVALID_SPEC, + FIT_NON_SINGLE: FIT_NON_SINGLE, + CANNOT_FIX_RANGE_STEP_WITH_FIT: CANNOT_FIX_RANGE_STEP_WITH_FIT, + cannotProjectOnChannelWithoutField: cannotProjectOnChannelWithoutField, + nearestNotSupportForContinuous: nearestNotSupportForContinuous, + selectionNotSupported: selectionNotSupported, + selectionNotFound: selectionNotFound, + SCALE_BINDINGS_CONTINUOUS: SCALE_BINDINGS_CONTINUOUS, + NO_INIT_SCALE_BINDINGS: NO_INIT_SCALE_BINDINGS, + noSuchRepeatedValue: noSuchRepeatedValue, + columnsNotSupportByRowCol: columnsNotSupportByRowCol, + CONCAT_CANNOT_SHARE_AXIS: CONCAT_CANNOT_SHARE_AXIS, + REPEAT_CANNOT_SHARE_AXIS: REPEAT_CANNOT_SHARE_AXIS, + unrecognizedParse: unrecognizedParse, + differentParse: differentParse, + invalidTransformIgnored: invalidTransformIgnored, + NO_FIELDS_NEEDS_AS: NO_FIELDS_NEEDS_AS, + encodingOverridden: encodingOverridden, + projectionOverridden: projectionOverridden, + primitiveChannelDef: primitiveChannelDef, + invalidFieldType: invalidFieldType, + nonZeroScaleUsedWithLengthMark: nonZeroScaleUsedWithLengthMark, + invalidFieldTypeForCountAggregate: invalidFieldTypeForCountAggregate, + invalidAggregate: invalidAggregate, + missingFieldType: missingFieldType, + droppingColor: droppingColor, + emptyFieldDef: emptyFieldDef, + latLongDeprecated: latLongDeprecated, + LINE_WITH_VARYING_SIZE: LINE_WITH_VARYING_SIZE, + incompatibleChannel: incompatibleChannel, + invalidEncodingChannel: invalidEncodingChannel, + facetChannelShouldBeDiscrete: facetChannelShouldBeDiscrete, + facetChannelDropped: facetChannelDropped, + discreteChannelCannotEncode: discreteChannelCannotEncode, + BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL: BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL, + lineWithRange: lineWithRange, + orientOverridden: orientOverridden, + CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN: CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN, + cannotUseScalePropertyWithNonColor: cannotUseScalePropertyWithNonColor, + unaggregateDomainHasNoEffectForRawField: unaggregateDomainHasNoEffectForRawField, + unaggregateDomainWithNonSharedDomainOp: unaggregateDomainWithNonSharedDomainOp, + unaggregatedDomainWithLogScale: unaggregatedDomainWithLogScale, + cannotApplySizeToNonOrientedMark: cannotApplySizeToNonOrientedMark, + rangeStepDropped: rangeStepDropped, + scaleTypeNotWorkWithChannel: scaleTypeNotWorkWithChannel, + scaleTypeNotWorkWithFieldDef: scaleTypeNotWorkWithFieldDef, + scalePropertyNotWorkWithScaleType: scalePropertyNotWorkWithScaleType, + scaleTypeNotWorkWithMark: scaleTypeNotWorkWithMark, + mergeConflictingProperty: mergeConflictingProperty, + independentScaleMeansIndependentGuide: independentScaleMeansIndependentGuide, + domainSortDropped: domainSortDropped, + UNABLE_TO_MERGE_DOMAINS: UNABLE_TO_MERGE_DOMAINS, + MORE_THAN_ONE_SORT: MORE_THAN_ONE_SORT, + INVALID_CHANNEL_FOR_AXIS: INVALID_CHANNEL_FOR_AXIS, + cannotStackRangedMark: cannotStackRangedMark, + cannotStackNonLinearScale: cannotStackNonLinearScale, + stackNonSummativeAggregate: stackNonSummativeAggregate, + invalidTimeUnit: invalidTimeUnit, + dayReplacedWithDate: dayReplacedWithDate, + droppedDay: droppedDay, + errorBarCenterAndExtentAreNotNeeded: errorBarCenterAndExtentAreNotNeeded, + errorBarCenterIsUsedWithWrongExtent: errorBarCenterIsUsedWithWrongExtent, + errorBarContinuousAxisHasCustomizedAggregate: errorBarContinuousAxisHasCustomizedAggregate, + errorBarCenterIsNotNeeded: errorBarCenterIsNotNeeded, + errorBand1DNotSupport: errorBand1DNotSupport, + channelRequiredForBinned: channelRequiredForBinned, + domainRequiredForThresholdScale: domainRequiredForThresholdScale + }); + + /** + * Vega-Lite's singleton logger utility. + */ + const message = message_; + /** + * Main (default) Vega Logger instance for Vega-Lite + */ + const main = logger(Warn); + let current = main; + /** + * Logger tool for checking if the code throws correct warning + */ + class LocalLogger { + constructor() { + this.warns = []; + this.infos = []; + this.debugs = []; + } + level() { + return this; + } + warn(...args) { + this.warns.push(...args); + return this; + } + info(...args) { + this.infos.push(...args); + return this; + } + debug(...args) { + this.debugs.push(...args); + return this; + } + error(...args) { + throw Error(...args); + return this; // @ts-ignore + } + } + function wrap(f) { + return () => { + current = new LocalLogger(); + f(current); + reset(); + }; + } + /** + * Set the singleton logger to be a custom logger + */ + function set(newLogger) { + current = newLogger; + return current; + } + /** + * Reset the main logger to use the default Vega Logger + */ + function reset() { + current = main; + return current; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function warn(..._) { + current.warn.apply(current, arguments); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function info(..._) { + current.info.apply(current, arguments); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function debug(..._) { + current.debug.apply(current, arguments); + } + + var log$1 = /*#__PURE__*/Object.freeze({ + message: message, + LocalLogger: LocalLogger, + wrap: wrap, + set: set, + reset: reset, + warn: warn, + info: info, + debug: debug + }); + + /** Constants and utilities for data type */ + /** Data type based on level of measurement */ + const TYPE_INDEX = { + quantitative: 1, + ordinal: 1, + temporal: 1, + nominal: 1, + geojson: 1 + }; + const QUANTITATIVE = 'quantitative'; + const ORDINAL = 'ordinal'; + const TEMPORAL = 'temporal'; + const NOMINAL = 'nominal'; + const GEOJSON = 'geojson'; + /** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ + function getFullName(type) { + if (type) { + type = type.toLowerCase(); + switch (type) { + case 'q': + case QUANTITATIVE: + return 'quantitative'; + case 't': + case TEMPORAL: + return 'temporal'; + case 'o': + case ORDINAL: + return 'ordinal'; + case 'n': + case NOMINAL: + return 'nominal'; + case GEOJSON: + return 'geojson'; + } + } + // If we get invalid input, return undefined type. + return undefined; + } + + var ScaleType; + (function (ScaleType) { + // Continuous - Quantitative + ScaleType.LINEAR = 'linear'; + ScaleType.LOG = 'log'; + ScaleType.POW = 'pow'; + ScaleType.SQRT = 'sqrt'; + ScaleType.SYMLOG = 'symlog'; + // Continuous - Time + ScaleType.TIME = 'time'; + ScaleType.UTC = 'utc'; + // Discretizing scales + ScaleType.QUANTILE = 'quantile'; + ScaleType.QUANTIZE = 'quantize'; + ScaleType.THRESHOLD = 'threshold'; + ScaleType.BIN_ORDINAL = 'bin-ordinal'; + // Discrete scales + ScaleType.ORDINAL = 'ordinal'; + ScaleType.POINT = 'point'; + ScaleType.BAND = 'band'; + })(ScaleType || (ScaleType = {})); + /** + * Index for scale categories -- only scale of the same categories can be merged together. + * Current implementation is trying to be conservative and avoid merging scale type that might not work together + */ + const SCALE_CATEGORY_INDEX = { + linear: 'numeric', + log: 'numeric', + pow: 'numeric', + sqrt: 'numeric', + symlog: 'numeric', + time: 'time', + utc: 'time', + ordinal: 'ordinal', + 'bin-ordinal': 'bin-ordinal', + point: 'ordinal-position', + band: 'ordinal-position', + quantile: 'discretizing', + quantize: 'discretizing', + threshold: 'discretizing' + }; + const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX); + const CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'log', 'pow', 'sqrt', 'symlog', 'time', 'utc']; + const CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES); + const CONTINUOUS_TO_DISCRETE_SCALES = ['quantile', 'quantize', 'threshold']; + const CONTINUOUS_TO_DISCRETE_INDEX = toSet(CONTINUOUS_TO_DISCRETE_SCALES); + const CONTINUOUS_DOMAIN_SCALES = CONTINUOUS_TO_CONTINUOUS_SCALES.concat([ + 'quantile', + 'quantize', + 'threshold' + ]); + const CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES); + const DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; + const DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES); + function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; + } + function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; + } + function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; + } + function isContinuousToDiscrete(type) { + return type in CONTINUOUS_TO_DISCRETE_INDEX; + } + const SCALE_PROPERTY_INDEX = { + type: 1, + domain: 1, + range: 1, + rangeStep: 1, + scheme: 1, + bins: 1, + // Other properties + reverse: 1, + round: 1, + // quantitative / time + clamp: 1, + nice: 1, + // quantitative + base: 1, + exponent: 1, + constant: 1, + interpolate: 1, + zero: 1, + // band/point + padding: 1, + paddingInner: 1, + paddingOuter: 1 + }; + const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX); + const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX = __rest(SCALE_PROPERTY_INDEX, ["type", "domain", "range", "rangeStep", "scheme"]); + const SCALE_TYPE_INDEX = generateScaleTypeIndex(); + function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'reverse': + case 'range': + return true; + case 'scheme': + case 'interpolate': + return !contains(['point', 'band', 'identity'], scaleType); + case 'bins': + return !contains(['point', 'band', 'identity', 'ordinal'], scaleType); + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'padding': + return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType); + case 'paddingOuter': + case 'rangeStep': + return contains(['point', 'band'], scaleType); + case 'paddingInner': + return scaleType === 'band'; + case 'clamp': + return isContinuousToContinuous(scaleType); + case 'nice': + return isContinuousToContinuous(scaleType) || scaleType === 'quantize' || scaleType === 'threshold'; + case 'exponent': + return scaleType === 'pow'; + case 'base': + return scaleType === 'log'; + case 'constant': + return scaleType === 'symlog'; + case 'zero': + return (hasContinuousDomain(scaleType) && + !contains([ + 'log', + 'time', + 'utc', + 'threshold', + 'quantile' // quantile depends on distribution so zero does not matter + ], scaleType)); + } + /* istanbul ignore next: should never reach here*/ + throw new Error(`Invalid scale property ${propName}.`); + } + /** + * Returns undefined if the input channel supports the input scale property name + */ + function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'interpolate': + case 'scheme': + if (!isColorChannel(channel)) { + return message.cannotUseScalePropertyWithNonColor(channel); + } + return undefined; + case 'type': + case 'bins': + case 'domain': + case 'range': + case 'base': + case 'exponent': + case 'constant': + case 'nice': + case 'padding': + case 'paddingInner': + case 'paddingOuter': + case 'rangeStep': + case 'reverse': + case 'round': + case 'clamp': + case 'zero': + return undefined; // GOOD! + } + /* istanbul ignore next: it should never reach here */ + throw new Error(`Invalid scale property "${propName}".`); + } + function scaleTypeSupportDataType(specifiedType, fieldDefType) { + if (contains([ORDINAL, NOMINAL], fieldDefType)) { + return specifiedType === undefined || hasDiscreteDomain(specifiedType); + } + else if (fieldDefType === TEMPORAL) { + return contains([ScaleType.TIME, ScaleType.UTC, undefined], specifiedType); + } + else if (fieldDefType === QUANTITATIVE) { + return contains([ + ScaleType.LOG, + ScaleType.POW, + ScaleType.SQRT, + ScaleType.SYMLOG, + ScaleType.QUANTILE, + ScaleType.QUANTIZE, + ScaleType.THRESHOLD, + ScaleType.LINEAR, + undefined + ], specifiedType); + } + return true; + } + function channelSupportScaleType(channel, scaleType) { + switch (channel) { + case X: + case Y: + return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType); + case SIZE: // TODO: size and opacity can support ordinal with more modification + case STROKEWIDTH: + case OPACITY: + case FILLOPACITY: + case STROKEOPACITY: + // Although it generally doesn't make sense to use band with size and opacity, + // it can also work since we use band: 0.5 to get midpoint. + return (isContinuousToContinuous(scaleType) || + isContinuousToDiscrete(scaleType) || + contains(['band', 'point'], scaleType)); + case COLOR: + case FILL: + case STROKE: + return scaleType !== 'band'; // band does not make sense with color + case SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; + } + // generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes + function generateScaleTypeIndex() { + const index = {}; + for (const channel of CHANNELS) { + for (const fieldDefType of keys(TYPE_INDEX)) { + for (const scaleType of SCALE_TYPES) { + const key = generateScaleTypeIndexKey(channel, fieldDefType); + if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType)) { + index[key] = index[key] || []; + index[key].push(scaleType); + } + } + } + } + return index; + } + function generateScaleTypeIndexKey(channel, fieldDefType) { + return channel + '_' + fieldDefType; + } + + function isEncodingNestedProp(p) { + return !!p['parent']; + } + const ENCODING_TOPLEVEL_PROP_INDEX = { + channel: 1, + aggregate: 1, + autoCount: 1, + bin: 1, + timeUnit: 1, + hasFn: 1, + sort: 1, + stack: 1, + field: 1, + type: 1, + format: 1, + scale: 1, + axis: 1, + legend: 1, + value: 1 + }; + const ENCODING_TOPLEVEL_PROPS = flagKeys(ENCODING_TOPLEVEL_PROP_INDEX); + function isEncodingTopLevelProperty(p) { + return p in ENCODING_TOPLEVEL_PROP_INDEX; + } + const ENCODING_NESTED_PROP_PARENT_INDEX = { + bin: 1, + scale: 1, + sort: 1, + axis: 1, + legend: 1 + }; + function isEncodingNestedParent(prop) { + return ENCODING_NESTED_PROP_PARENT_INDEX[prop]; + } + // FIXME -- we should not have to manually specify these + const BIN_CHILD_PROPS = ['maxbins', 'divide', 'extent', 'base', 'step', 'steps', 'minstep']; + const SORT_CHILD_PROPS = ['field', 'op', 'order']; + const BIN_PROPS = BIN_CHILD_PROPS.map((c) => { + return { parent: 'bin', child: c }; + }); + const SORT_PROPS = SORT_CHILD_PROPS.map((c) => { + return { parent: 'sort', child: c }; + }); + const SCALE_PROPS = SCALE_PROPERTIES.map((c) => { + return { parent: 'scale', child: c }; + }); + const AXIS_PROPS = AXIS_PROPERTIES.map((c) => { + return { parent: 'axis', child: c }; + }); + const LEGEND_PROPS = LEGEND_PROPERTIES.map((c) => { + return { parent: 'legend', child: c }; + }); + const ENCODING_NESTED_PROPS = [].concat(BIN_PROPS, SORT_PROPS, SCALE_PROPS, AXIS_PROPS, LEGEND_PROPS); + const VIEW_PROPS = ['width', 'height', 'background', 'padding', 'title']; + const PROP_KEY_DELIMITER = '.'; + function toKey(p) { + if (isEncodingNestedProp(p)) { + return p.parent + PROP_KEY_DELIMITER + p.child; + } + return p; + } + function fromKey(k) { + const split = k.split(PROP_KEY_DELIMITER); + /* istanbul ignore else */ + if (split.length === 1) { + return k; + } + else if (split.length === 2) { + return { + parent: split[0], + child: split[1] + }; + } + else { + throw 'Invalid property key with ' + split.length + ' dots: ' + k; + } + } + const ENCODING_NESTED_PROP_INDEX = ENCODING_NESTED_PROPS.reduce((i, prop) => { + i[prop.parent] = i[prop.parent] || []; + i[prop.parent][prop.child] = prop; + return i; + }, {}); + // FIXME consider using a more general method + function getEncodingNestedProp(parent, child) { + return (ENCODING_NESTED_PROP_INDEX[parent] || {})[child]; + } + function isEncodingProperty(p) { + return isEncodingTopLevelProperty(p) || isEncodingNestedProp(p); + } + const ALL_ENCODING_PROPS = [].concat(ENCODING_TOPLEVEL_PROPS, ENCODING_NESTED_PROPS); + const DEFAULT_PROP_PRECEDENCE = [ + 'type', + 'field', + // Field Transform + 'bin', + 'timeUnit', + 'aggregate', + 'autoCount', + // Encoding + 'channel', + // Mark + 'mark', + 'stack', + 'scale', + 'sort', + 'axis', + 'legend' + ].concat(BIN_PROPS, SCALE_PROPS, AXIS_PROPS, LEGEND_PROPS, SORT_PROPS); + var Property; + (function (Property) { + Property.MARK = 'mark'; + Property.TRANSFORM = 'transform'; + // Layout + Property.STACK = 'stack'; + Property.FORMAT = 'format'; + // TODO: sub parts of stack + // Encoding Properties + Property.CHANNEL = 'channel'; + Property.AGGREGATE = 'aggregate'; + Property.AUTOCOUNT = 'autoCount'; + Property.BIN = 'bin'; + Property.HAS_FN = 'hasFn'; + Property.TIMEUNIT = 'timeUnit'; + Property.FIELD = 'field'; + Property.TYPE = 'type'; + Property.SORT = 'sort'; + Property.SCALE = 'scale'; + Property.AXIS = 'axis'; + Property.LEGEND = 'legend'; + Property.WIDTH = 'width'; + Property.HEIGHT = 'height'; + Property.BACKGROUND = 'background'; + Property.PADDING = 'padding'; + Property.TITLE = 'title'; + })(Property || (Property = {})); + + var property = /*#__PURE__*/Object.freeze({ + isEncodingNestedProp: isEncodingNestedProp, + ENCODING_TOPLEVEL_PROPS: ENCODING_TOPLEVEL_PROPS, + isEncodingTopLevelProperty: isEncodingTopLevelProperty, + isEncodingNestedParent: isEncodingNestedParent, + BIN_CHILD_PROPS: BIN_CHILD_PROPS, + SORT_CHILD_PROPS: SORT_CHILD_PROPS, + SORT_PROPS: SORT_PROPS, + SCALE_PROPS: SCALE_PROPS, + ENCODING_NESTED_PROPS: ENCODING_NESTED_PROPS, + VIEW_PROPS: VIEW_PROPS, + toKey: toKey, + fromKey: fromKey, + getEncodingNestedProp: getEncodingNestedProp, + isEncodingProperty: isEncodingProperty, + ALL_ENCODING_PROPS: ALL_ENCODING_PROPS, + DEFAULT_PROP_PRECEDENCE: DEFAULT_PROP_PRECEDENCE, + get Property () { return Property; } + }); + + const AREA = 'area'; + const BAR = 'bar'; + const LINE = 'line'; + const POINT = 'point'; + const RECT = 'rect'; + const RULE = 'rule'; + const TEXT$1 = 'text'; + const TICK = 'tick'; + const CIRCLE = 'circle'; + const SQUARE = 'square'; + // Using mapped type to declare index, ensuring we always have all marks when we add more. + const MARK_INDEX = { + area: 1, + bar: 1, + line: 1, + point: 1, + text: 1, + tick: 1, + trail: 1, + rect: 1, + geoshape: 1, + rule: 1, + circle: 1, + square: 1 + }; + function isPathMark(m) { + return contains(['line', 'area', 'trail'], m); + } + const PRIMITIVE_MARKS = flagKeys(MARK_INDEX); + function isMarkDef(mark) { + return mark['type']; + } + const PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS); + + // DateTime definition object + /* + * A designated year that starts on Sunday. + */ + const SUNDAY_YEAR = 2006; + function isDateTime(o) { + return (!!o && + (!!o.year || + !!o.quarter || + !!o.month || + !!o.date || + !!o.day || + !!o.hours || + !!o.minutes || + !!o.seconds || + !!o.milliseconds)); + } + const MONTHS = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december' + ]; + const SHORT_MONTHS = MONTHS.map(m => m.substr(0, 3)); + const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; + const SHORT_DAYS = DAYS.map(d => d.substr(0, 3)); + function normalizeQuarter(q) { + if (isNumber(q)) { + if (q > 4) { + warn(message.invalidTimeUnit('quarter', q)); + } + // We accept 1-based quarter, so need to readjust to 0-based quarter + return (q - 1).toString(); + } + else { + // Invalid quarter + throw new Error(message.invalidTimeUnit('quarter', q)); + } + } + function normalizeMonth(m) { + if (isNumber(m)) { + // We accept 1-based month, so need to readjust to 0-based month + return (m - 1).toString(); + } + else { + const lowerM = m.toLowerCase(); + const monthIndex = MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + const shortM = lowerM.substr(0, 3); + const shortMonthIndex = SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(message.invalidTimeUnit('month', m)); + } + } + function normalizeDay(d) { + if (isNumber(d)) { + // mod so that this can be both 0-based where 0 = sunday + // and 1-based where 7=sunday + return (d % 7) + ''; + } + else { + const lowerD = d.toLowerCase(); + const dayIndex = DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + const shortD = lowerD.substr(0, 3); + const shortDayIndex = SHORT_DAYS.indexOf(shortD); + if (shortDayIndex !== -1) { + return shortDayIndex + ''; + } + // Invalid day + throw new Error(message.invalidTimeUnit('day', d)); + } + } + /** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ + function dateTimeExpr(d, normalize = false) { + const units = []; + if (normalize && d.day !== undefined) { + if (keys(d).length > 1) { + warn(message.droppedDay(d)); + d = duplicate(d); + delete d.day; + } + } + if (d.year !== undefined) { + units.push(d.year); + } + else if (d.day !== undefined) { + // Set year to 2006 for working with day since January 1 2006 is a Sunday + units.push(SUNDAY_YEAR); + } + else { + units.push(0); + } + if (d.month !== undefined) { + const month = normalize ? normalizeMonth(d.month) : d.month; + units.push(month); + } + else if (d.quarter !== undefined) { + const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + units.push(quarter + '*3'); + } + else { + units.push(0); // months start at zero in JS + } + if (d.date !== undefined) { + units.push(d.date); + } + else if (d.day !== undefined) { + // HACK: Day only works as a standalone unit + // This is only correct because we always set year to 2006 for day + const day = normalize ? normalizeDay(d.day) : d.day; + units.push(day + '+1'); + } + else { + units.push(1); // Date starts at 1 in JS + } + // Note: can't use TimeUnit enum here as importing it will create + // circular dependency problem! + for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) { + if (d[timeUnit] !== undefined) { + units.push(d[timeUnit]); + } + else { + units.push(0); + } + } + if (d.utc) { + return `utc(${units.join(', ')})`; + } + else { + return `datetime(${units.join(', ')})`; + } + } + + var TimeUnit; + (function (TimeUnit) { + TimeUnit.YEAR = 'year'; + TimeUnit.MONTH = 'month'; + TimeUnit.DAY = 'day'; + TimeUnit.DATE = 'date'; + TimeUnit.HOURS = 'hours'; + TimeUnit.MINUTES = 'minutes'; + TimeUnit.SECONDS = 'seconds'; + TimeUnit.MILLISECONDS = 'milliseconds'; + TimeUnit.YEARMONTH = 'yearmonth'; + TimeUnit.YEARMONTHDATE = 'yearmonthdate'; + TimeUnit.YEARMONTHDATEHOURS = 'yearmonthdatehours'; + TimeUnit.YEARMONTHDATEHOURSMINUTES = 'yearmonthdatehoursminutes'; + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS = 'yearmonthdatehoursminutesseconds'; + // MONTHDATE and MONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year); + TimeUnit.MONTHDATE = 'monthdate'; + TimeUnit.MONTHDATEHOURS = 'monthdatehours'; + TimeUnit.HOURSMINUTES = 'hoursminutes'; + TimeUnit.HOURSMINUTESSECONDS = 'hoursminutesseconds'; + TimeUnit.MINUTESSECONDS = 'minutesseconds'; + TimeUnit.SECONDSMILLISECONDS = 'secondsmilliseconds'; + TimeUnit.QUARTER = 'quarter'; + TimeUnit.YEARQUARTER = 'yearquarter'; + TimeUnit.QUARTERMONTH = 'quartermonth'; + TimeUnit.YEARQUARTERMONTH = 'yearquartermonth'; + TimeUnit.UTCYEAR = 'utcyear'; + TimeUnit.UTCMONTH = 'utcmonth'; + TimeUnit.UTCDAY = 'utcday'; + TimeUnit.UTCDATE = 'utcdate'; + TimeUnit.UTCHOURS = 'utchours'; + TimeUnit.UTCMINUTES = 'utcminutes'; + TimeUnit.UTCSECONDS = 'utcseconds'; + TimeUnit.UTCMILLISECONDS = 'utcmilliseconds'; + TimeUnit.UTCYEARMONTH = 'utcyearmonth'; + TimeUnit.UTCYEARMONTHDATE = 'utcyearmonthdate'; + TimeUnit.UTCYEARMONTHDATEHOURS = 'utcyearmonthdatehours'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTES = 'utcyearmonthdatehoursminutes'; + TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS = 'utcyearmonthdatehoursminutesseconds'; + // UTCMONTHDATE and UTCMONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year); + TimeUnit.UTCMONTHDATE = 'utcmonthdate'; + TimeUnit.UTCMONTHDATEHOURS = 'utcmonthdatehours'; + TimeUnit.UTCHOURSMINUTES = 'utchoursminutes'; + TimeUnit.UTCHOURSMINUTESSECONDS = 'utchoursminutesseconds'; + TimeUnit.UTCMINUTESSECONDS = 'utcminutesseconds'; + TimeUnit.UTCSECONDSMILLISECONDS = 'utcsecondsmilliseconds'; + TimeUnit.UTCQUARTER = 'utcquarter'; + TimeUnit.UTCYEARQUARTER = 'utcyearquarter'; + TimeUnit.UTCQUARTERMONTH = 'utcquartermonth'; + TimeUnit.UTCYEARQUARTERMONTH = 'utcyearquartermonth'; + })(TimeUnit || (TimeUnit = {})); + /** Time Unit that only corresponds to only one part of Date objects. */ + const LOCAL_SINGLE_TIMEUNIT_INDEX = { + year: 1, + quarter: 1, + month: 1, + day: 1, + date: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1 + }; + const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX); + function isLocalSingleTimeUnit(timeUnit) { + return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit]; + } + const UTC_SINGLE_TIMEUNIT_INDEX = { + utcyear: 1, + utcquarter: 1, + utcmonth: 1, + utcday: 1, + utcdate: 1, + utchours: 1, + utcminutes: 1, + utcseconds: 1, + utcmilliseconds: 1 + }; + function isUtcSingleTimeUnit(timeUnit) { + return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit]; + } + const LOCAL_MULTI_TIMEUNIT_INDEX = { + yearquarter: 1, + yearquartermonth: 1, + yearmonth: 1, + yearmonthdate: 1, + yearmonthdatehours: 1, + yearmonthdatehoursminutes: 1, + yearmonthdatehoursminutesseconds: 1, + quartermonth: 1, + monthdate: 1, + monthdatehours: 1, + hoursminutes: 1, + hoursminutesseconds: 1, + minutesseconds: 1, + secondsmilliseconds: 1 + }; + const UTC_MULTI_TIMEUNIT_INDEX = { + utcyearquarter: 1, + utcyearquartermonth: 1, + utcyearmonth: 1, + utcyearmonthdate: 1, + utcyearmonthdatehours: 1, + utcyearmonthdatehoursminutes: 1, + utcyearmonthdatehoursminutesseconds: 1, + utcquartermonth: 1, + utcmonthdate: 1, + utcmonthdatehours: 1, + utchoursminutes: 1, + utchoursminutesseconds: 1, + utcminutesseconds: 1, + utcsecondsmilliseconds: 1 + }; + const UTC_TIMEUNIT_INDEX = Object.assign({}, UTC_SINGLE_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); + function isUTCTimeUnit(t) { + return !!UTC_TIMEUNIT_INDEX[t]; + } + function getLocalTimeUnit(t) { + return t.substr(3); + } + const TIMEUNIT_INDEX = Object.assign({}, LOCAL_SINGLE_TIMEUNIT_INDEX, UTC_SINGLE_TIMEUNIT_INDEX, LOCAL_MULTI_TIMEUNIT_INDEX, UTC_MULTI_TIMEUNIT_INDEX); + function isTimeUnit(t) { + return !!TIMEUNIT_INDEX[t]; + } + const SET_DATE_METHOD = { + year: 'setFullYear', + month: 'setMonth', + date: 'setDate', + hours: 'setHours', + minutes: 'setMinutes', + seconds: 'setSeconds', + milliseconds: 'setMilliseconds', + // Day and quarter have their own special cases + quarter: null, + day: null + }; + /** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ + function convert(unit, date) { + const isUTC = isUTCTimeUnit(unit); + const result = isUTC + ? // start with uniform date + new Date(Date.UTC(1972, 0, 1, 0, 0, 0, 0)) // 1972 is the first leap year after 1970, the start of unix time + : new Date(1972, 0, 1, 0, 0, 0, 0); + for (const timeUnitPart of TIMEUNIT_PARTS) { + if (containsTimeUnit(unit, timeUnitPart)) { + switch (timeUnitPart) { + case TimeUnit.DAY: + throw new Error("Cannot convert to TimeUnits containing 'day'"); + case TimeUnit.QUARTER: { + const { getDateMethod, setDateMethod } = dateMethods('month', isUTC); + // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3) + result[setDateMethod](Math.floor(date[getDateMethod]() / 3) * 3); + break; + } + default: { + const { getDateMethod, setDateMethod } = dateMethods(timeUnitPart, isUTC); + result[setDateMethod](date[getDateMethod]()); + } + } + } + } + return result; + } + function dateMethods(singleUnit, isUtc) { + const rawSetDateMethod = SET_DATE_METHOD[singleUnit]; + const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod; + const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3); + return { setDateMethod, getDateMethod }; + } + function getTimeUnitParts(timeUnit) { + return TIMEUNIT_PARTS.reduce((parts, part) => { + if (containsTimeUnit(timeUnit, part)) { + return [...parts, part]; + } + return parts; + }, []); + } + /** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ + function containsTimeUnit(fullTimeUnit, timeUnit) { + const index = fullTimeUnit.indexOf(timeUnit); + return (index > -1 && (timeUnit !== TimeUnit.SECONDS || index === 0 || fullTimeUnit.charAt(index - 1) !== 'i') // exclude milliseconds + ); + } + function normalizeTimeUnit(timeUnit) { + if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) { + warn(message.dayReplacedWithDate(timeUnit)); + return timeUnit.replace('day', 'date'); + } + return timeUnit; + } + + var util = createCommonjsModule(function (module) { + var u = module.exports; + + // utility functions + + var FNAME = '__name__'; + + u.namedfunc = function(name, f) { return (f[FNAME] = name, f); }; + + u.name = function(f) { return f==null ? null : f[FNAME]; }; + + u.identity = function(x) { return x; }; + + u.true = u.namedfunc('true', function() { return true; }); + + u.false = u.namedfunc('false', function() { return false; }); + + u.duplicate = function(obj) { + return JSON.parse(JSON.stringify(obj)); + }; + + u.equal = function(a, b) { + return JSON.stringify(a) === JSON.stringify(b); + }; + + u.extend = function(obj) { + for (var x, name, i=1, len=arguments.length; i 1 ? + function(x, v) { + for (var i=0; i b || b == null) && a != null ? 1 : + ((b = b instanceof Date ? +b : b), + (a = a instanceof Date ? +a : a)) !== a && b === b ? -1 : + b !== b && a === a ? 1 : 0; + }; + + u.numcmp = function(a, b) { return a - b; }; + + u.stablesort = function(array, sortBy, keyFn) { + var indices = array.reduce(function(idx, v, i) { + return (idx[keyFn(v)] = i, idx); + }, {}); + + array.sort(function(a, b) { + var sa = sortBy(a), + sb = sortBy(b); + return sa < sb ? -1 : sa > sb ? 1 + : (indices[keyFn(a)] - indices[keyFn(b)]); + }); + + return array; + }; + + // permutes an array using a Knuth shuffle + u.permute = function(a) { + var m = a.length, + swap, + i; + + while (m) { + i = Math.floor(Math.random() * m--); + swap = a[m]; + a[m] = a[i]; + a[i] = swap; + } + }; + + // string functions + + u.pad = function(s, length, pos, padchar) { + padchar = padchar || " "; + var d = length - s.length; + if (d <= 0) return s; + switch (pos) { + case 'left': + return strrep(d, padchar) + s; + case 'middle': + case 'center': + return strrep(Math.floor(d/2), padchar) + + s + strrep(Math.ceil(d/2), padchar); + default: + return s + strrep(d, padchar); + } + }; + + function strrep(n, str) { + var s = "", i; + for (i=0; i { + if (util_1(a)) { + return nestedMap(a, f); + } + return f(a); + }); + } + /** Returns the array without the elements in item */ + function without(array, excludedItems) { + return array.filter(function (item) { + return !contains$1(excludedItems, item); + }); + } + + var util$1 = /*#__PURE__*/Object.freeze({ + isArray: util_1, + contains: contains$1, + every: every, + forEach: forEach, + some: some$1, + nestedMap: nestedMap, + without: without, + cmp: util_2, + keys: util_3, + duplicate: util_4, + extend: util_5, + isObject: util_6, + isBoolean: util_7, + toMap: util_8 + }); + + const SHORT_WILDCARD = '?'; + function isWildcard(prop) { + return isShortWildcard(prop) || isWildcardDef(prop); + } + function isShortWildcard(prop) { + return prop === SHORT_WILDCARD; + } + function isWildcardDef(prop) { + return prop !== undefined && prop != null && (!!prop.enum || !!prop.name) && !util_1(prop); + } + function initWildcard(prop, defaultName, defaultEnumValues) { + return util_5({}, { + name: defaultName, + enum: defaultEnumValues + }, prop === SHORT_WILDCARD ? {} : prop); + } + /** + * Initial short names from list of full camelCaseNames. + * For each camelCaseNames, return unique short names based on initial (e.g., `ccn`) + */ + function initNestedPropName(fullNames) { + let index = {}; + let has = {}; + for (const fullName of fullNames) { + const initialIndices = [0]; + for (let i = 0; i < fullName.length; i++) { + if (fullName.charAt(i).toUpperCase() === fullName.charAt(i)) { + initialIndices.push(i); + } + } + let shortName = initialIndices + .map(i => fullName.charAt(i)) + .join('') + .toLowerCase(); + if (!has[shortName]) { + index[fullName] = shortName; + has[shortName] = true; + continue; + } + // If duplicate, add last character and try again! + if (initialIndices[initialIndices.length - 1] !== fullName.length - 1) { + shortName = initialIndices + .concat([fullName.length - 1]) + .map(i => fullName.charAt(i)) + .join('') + .toLowerCase(); + if (!has[shortName]) { + index[fullName] = shortName; + has[shortName] = true; + continue; + } + } + for (let i = 1; !index[fullName]; i++) { + let shortNameWithNo = shortName + '_' + i; + if (!has[shortNameWithNo]) { + index[fullName] = shortNameWithNo; + has[shortNameWithNo] = true; + break; + } + } + } + return index; + } + const DEFAULT_NAME = { + mark: 'm', + channel: 'c', + aggregate: 'a', + autoCount: '#', + hasFn: 'h', + bin: 'b', + sort: 'so', + stack: 'st', + scale: 's', + format: 'f', + axis: 'ax', + legend: 'l', + value: 'v', + timeUnit: 'tu', + field: 'f', + type: 't', + binProps: { + maxbins: 'mb', + min: 'mi', + max: 'ma', + base: 'b', + step: 's', + steps: 'ss', + minstep: 'ms', + divide: 'd' + }, + sortProps: { + field: 'f', + op: 'o', + order: 'or' + }, + scaleProps: initNestedPropName(SCALE_PROPERTIES), + axisProps: initNestedPropName(AXIS_PROPERTIES), + legendProps: initNestedPropName(LEGEND_PROPERTIES) + }; + function getDefaultName(prop) { + if (isEncodingNestedProp(prop)) { + return DEFAULT_NAME[prop.parent] + '-' + DEFAULT_NAME[prop.parent + 'Props'][prop.child]; + } + if (DEFAULT_NAME[prop]) { + return DEFAULT_NAME[prop]; + } + /* istanbul ignore next */ + throw new Error('Default name undefined for ' + prop); + } + const DEFAULT_BOOLEAN_ENUM = [false, true]; + const DEFAULT_BIN_PROPS_ENUM = { + maxbins: [5, 10, 20], + extent: [undefined], + base: [10], + step: [undefined], + steps: [undefined], + minstep: [undefined], + divide: [[5, 2]], + binned: [false], + anchor: [undefined], + nice: [true] + }; + const DEFAULT_SORT_PROPS = { + field: [undefined], + op: ['min', 'mean'], + order: ['ascending', 'descending'] + }; + const DEFAULT_SCALE_PROPS_ENUM = { + type: [undefined, ScaleType.LOG], + domain: [undefined], + base: [undefined], + exponent: [1, 2], + constant: [undefined], + bins: [undefined], + clamp: DEFAULT_BOOLEAN_ENUM, + nice: DEFAULT_BOOLEAN_ENUM, + reverse: DEFAULT_BOOLEAN_ENUM, + round: DEFAULT_BOOLEAN_ENUM, + zero: DEFAULT_BOOLEAN_ENUM, + padding: [undefined], + paddingInner: [undefined], + paddingOuter: [undefined], + interpolate: [undefined], + range: [undefined], + rangeStep: [17, 21], + scheme: [undefined] + }; + const DEFAULT_AXIS_PROPS_ENUM = { + zindex: [1, 0], + offset: [undefined], + orient: [undefined], + values: [undefined], + bandPosition: [undefined], + encoding: [undefined], + domain: DEFAULT_BOOLEAN_ENUM, + domainColor: [undefined], + domainDash: [undefined], + domainDashOffset: [undefined], + domainOpacity: [undefined], + domainWidth: [undefined], + formatType: [undefined], + grid: DEFAULT_BOOLEAN_ENUM, + gridColor: [undefined], + gridDash: [undefined], + gridDashOffset: [undefined], + gridOpacity: [undefined], + gridWidth: [undefined], + format: [undefined], + labels: DEFAULT_BOOLEAN_ENUM, + labelAlign: [undefined], + labelAngle: [undefined], + labelBaseline: [undefined], + labelColor: [undefined], + labelFlushOffset: [undefined], + labelFont: [undefined], + labelFontSize: [undefined], + labelFontStyle: [undefined], + labelFontWeight: [undefined], + labelLimit: [undefined], + labelOpacity: [undefined], + labelSeparation: [undefined], + labelOverlap: [undefined], + labelPadding: [undefined], + labelBound: [undefined], + labelFlush: [undefined], + maxExtent: [undefined], + minExtent: [undefined], + position: [undefined], + ticks: DEFAULT_BOOLEAN_ENUM, + tickColor: [undefined], + tickCount: [undefined], + tickDash: [undefined], + tickExtra: [undefined], + tickDashOffset: [undefined], + tickMinStep: [undefined], + tickOffset: [undefined], + tickOpacity: [undefined], + tickRound: [undefined], + tickSize: [undefined], + tickWidth: [undefined], + title: [undefined], + titleAlign: [undefined], + titleAnchor: [undefined], + titleAngle: [undefined], + titleBaseline: [undefined], + titleColor: [undefined], + titleFont: [undefined], + titleFontSize: [undefined], + titleFontStyle: [undefined], + titleFontWeight: [undefined], + titleLimit: [undefined], + titleOpacity: [undefined], + titlePadding: [undefined], + titleX: [undefined], + titleY: [undefined] + }; + const DEFAULT_LEGEND_PROPS_ENUM = { + orient: ['left', 'right'], + format: [undefined], + type: [undefined], + values: [undefined], + zindex: [undefined], + clipHeight: [undefined], + columnPadding: [undefined], + columns: [undefined], + cornerRadius: [undefined], + direction: [undefined], + encoding: [undefined], + fillColor: [undefined], + formatType: [undefined], + gridAlign: [undefined], + offset: [undefined], + padding: [undefined], + rowPadding: [undefined], + strokeColor: [undefined], + labelAlign: [undefined], + labelBaseline: [undefined], + labelColor: [undefined], + labelFont: [undefined], + labelFontSize: [undefined], + labelFontStyle: [undefined], + labelFontWeight: [undefined], + labelLimit: [undefined], + labelOffset: [undefined], + labelOpacity: [undefined], + labelOverlap: [undefined], + labelPadding: [undefined], + labelSeparation: [undefined], + legendX: [undefined], + legendY: [undefined], + gradientLength: [undefined], + gradientOpacity: [undefined], + gradientStrokeColor: [undefined], + gradientStrokeWidth: [undefined], + gradientThickness: [undefined], + symbolDash: [undefined], + symbolDashOffset: [undefined], + symbolFillColor: [undefined], + symbolOffset: [undefined], + symbolOpacity: [undefined], + symbolSize: [undefined], + symbolStrokeColor: [undefined], + symbolStrokeWidth: [undefined], + symbolType: [undefined], + tickCount: [undefined], + tickMinStep: [undefined], + title: [undefined], + titleAnchor: [undefined], + titleAlign: [undefined], + titleBaseline: [undefined], + titleColor: [undefined], + titleFont: [undefined], + titleFontSize: [undefined], + titleFontStyle: [undefined], + titleFontWeight: [undefined], + titleLimit: [undefined], + titleOpacity: [undefined], + titleOrient: [undefined], + titlePadding: [undefined] + }; + // Use FullEnumIndex to make sure we have all properties specified here! + const DEFAULT_ENUM_INDEX = { + mark: [POINT, BAR, LINE, AREA, RECT, TICK, TEXT$1], + channel: [X, Y, ROW, COLUMN, SIZE, COLOR], + aggregate: [undefined, 'mean'], + autoCount: DEFAULT_BOOLEAN_ENUM, + bin: DEFAULT_BOOLEAN_ENUM, + hasFn: DEFAULT_BOOLEAN_ENUM, + timeUnit: [undefined, TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.MINUTES, TimeUnit.SECONDS], + field: [undefined], + type: [NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL], + sort: ['ascending', 'descending'], + stack: ['zero', 'normalize', 'center', null], + value: [undefined], + format: [undefined], + title: [undefined], + scale: [true], + axis: DEFAULT_BOOLEAN_ENUM, + legend: DEFAULT_BOOLEAN_ENUM, + binProps: DEFAULT_BIN_PROPS_ENUM, + sortProps: DEFAULT_SORT_PROPS, + scaleProps: DEFAULT_SCALE_PROPS_ENUM, + axisProps: DEFAULT_AXIS_PROPS_ENUM, + legendProps: DEFAULT_LEGEND_PROPS_ENUM + }; + // TODO: rename this to getDefaultEnum + function getDefaultEnumValues(prop, schema, opt) { + if (prop === 'field' || (isEncodingNestedProp(prop) && prop.parent === 'sort' && prop.child === 'field')) { + // For field, by default enumerate all fields + return schema.fieldNames(); + } + let val; + if (isEncodingNestedProp(prop)) { + val = opt.enum[prop.parent + 'Props'][prop.child]; + } + else { + val = opt.enum[prop]; + } + if (val !== undefined) { + return val; + } + /* istanbul ignore next */ + throw new Error('No default enumValues for ' + JSON.stringify(prop)); + } + + var wildcard = /*#__PURE__*/Object.freeze({ + SHORT_WILDCARD: SHORT_WILDCARD, + isWildcard: isWildcard, + isShortWildcard: isShortWildcard, + isWildcardDef: isWildcardDef, + initWildcard: initWildcard, + DEFAULT_NAME: DEFAULT_NAME, + getDefaultName: getDefaultName, + DEFAULT_ENUM_INDEX: DEFAULT_ENUM_INDEX, + getDefaultEnumValues: getDefaultEnumValues + }); + + const DEFAULT_QUERY_CONFIG = { + verbose: false, + defaultSpecConfig: { + line: { point: true }, + scale: { useUnaggregatedDomain: true } + }, + propertyPrecedence: DEFAULT_PROP_PRECEDENCE.map(toKey), + enum: DEFAULT_ENUM_INDEX, + numberNominalProportion: 0.05, + numberNominalLimit: 40, + // CONSTRAINTS + constraintManuallySpecifiedValue: false, + // Spec Constraints -- See description inside src/constraints/spec.ts + autoAddCount: false, + hasAppropriateGraphicTypeForMark: true, + omitAggregate: false, + omitAggregatePlotWithDimensionOnlyOnFacet: true, + omitAggregatePlotWithoutDimension: false, + omitBarLineAreaWithOcclusion: true, + omitBarTickWithSize: true, + omitMultipleNonPositionalChannels: true, + omitRaw: false, + omitRawContinuousFieldForAggregatePlot: true, + omitRepeatedField: true, + omitNonPositionalOrFacetOverPositionalChannels: true, + omitTableWithOcclusionIfAutoAddCount: true, + omitVerticalDotPlot: false, + omitInvalidStackSpec: true, + omitNonSumStack: true, + preferredBinAxis: X, + preferredTemporalAxis: X, + preferredOrdinalAxis: Y, + preferredNominalAxis: Y, + preferredFacet: ROW, + // Field Encoding Constraints -- See description inside src/constraint/field.ts + minCardinalityForBin: 15, + maxCardinalityForCategoricalColor: 20, + maxCardinalityForFacet: 20, + maxCardinalityForShape: 6, + timeUnitShouldHaveVariation: true, + typeMatchesSchemaType: true, + // STYLIZE + stylize: true, + smallRangeStepForHighCardinalityOrFacet: { maxCardinality: 10, rangeStep: 12 }, + nominalColorScaleForHighCardinality: { maxCardinality: 10, palette: 'category20' }, + xAxisOnTopForHighYCardinalityWithoutColumn: { maxCardinality: 30 }, + // RANKING PREFERENCE + maxGoodCardinalityForFacet: 5, + maxGoodCardinalityForColor: 7, + // HIGH CARDINALITY STRINGS + minPercentUniqueForKey: 0.8, + minCardinalityForKey: 50 + }; + function extendConfig(opt) { + return Object.assign({}, DEFAULT_QUERY_CONFIG, opt, { enum: extendEnumIndex(opt.enum) }); + } + function extendEnumIndex(enumIndex) { + const enumOpt = Object.assign({}, DEFAULT_ENUM_INDEX, enumIndex, { binProps: extendNestedEnumIndex(enumIndex, 'bin'), scaleProps: extendNestedEnumIndex(enumIndex, 'scale'), axisProps: extendNestedEnumIndex(enumIndex, 'axis'), legendProps: extendNestedEnumIndex(enumIndex, 'legend') }); + return enumOpt; + } + function extendNestedEnumIndex(enumIndex, prop) { + return Object.assign({}, DEFAULT_ENUM_INDEX[prop + 'Props'], enumIndex[prop + 'Props']); + } + + var config = /*#__PURE__*/Object.freeze({ + DEFAULT_QUERY_CONFIG: DEFAULT_QUERY_CONFIG, + extendConfig: extendConfig + }); + + const AGGREGATE_OP_INDEX = { + argmax: 1, + argmin: 1, + average: 1, + count: 1, + distinct: 1, + max: 1, + mean: 1, + median: 1, + min: 1, + missing: 1, + q1: 1, + q3: 1, + ci0: 1, + ci1: 1, + stderr: 1, + stdev: 1, + stdevp: 1, + sum: 1, + valid: 1, + values: 1, + variance: 1, + variancep: 1 + }; + function isArgminDef(a) { + return !!a && !!a['argmin']; + } + function isArgmaxDef(a) { + return !!a && !!a['argmax']; + } + function isAggregateOp(a) { + return isString(a) && !!AGGREGATE_OP_INDEX[a]; + } + const COUNTING_OPS = ['count', 'valid', 'missing', 'distinct']; + function isCountingAggregateOp(aggregate) { + return aggregate && isString(aggregate) && contains(COUNTING_OPS, aggregate); + } + /** Additive-based aggregation operations. These can be applied to stack. */ + const SUM_OPS = ['count', 'sum', 'distinct', 'valid', 'missing']; + /** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ + const SHARED_DOMAIN_OPS = ['mean', 'average', 'median', 'q1', 'q3', 'min', 'max']; + const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS); + + /** + * Create a key for the bin configuration. Not for prebinned bin. + */ + function binToString(bin) { + if (isBoolean(bin)) { + bin = normalizeBin(bin, undefined); + } + return ('bin' + + keys(bin) + .map(p => varName(`_${p}_${bin[p]}`)) + .join('')); + } + /** + * Vega-Lite should bin the data. + */ + function isBinning(bin) { + return bin === true || (isBinParams(bin) && !bin.binned); + } + /** + * The data is already binned and so Vega-Lite should not bin it again. + */ + function isBinned(bin) { + return bin === 'binned' || (isBinParams(bin) && bin.binned); + } + function isBinParams(bin) { + return isObject(bin); + } + function autoMaxBins(channel) { + switch (channel) { + case ROW: + case COLUMN: + case SIZE: + case COLOR: + case FILL: + case STROKE: + case STROKEWIDTH: + case OPACITY: + case FILLOPACITY: + case STROKEOPACITY: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule [falls through] + case SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } + } + + function isFacetFieldDef(channelDef) { + return !!channelDef && !!channelDef['header']; + } + + function isConditionalSelection(c) { + return c['selection']; + } + function isRepeatRef(field) { + return field && !isString(field) && 'repeat' in field; + } + function toFieldDefBase(fieldDef) { + const { field, timeUnit, bin, aggregate } = fieldDef; + return Object.assign({}, (timeUnit ? { timeUnit } : {}), (bin ? { bin } : {}), (aggregate ? { aggregate } : {}), { field }); + } + function isSortableFieldDef(fieldDef) { + return isTypedFieldDef(fieldDef) && !!fieldDef['sort']; + } + function isConditionalDef(channelDef) { + return !!channelDef && !!channelDef.condition; + } + /** + * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef + */ + function hasConditionalFieldDef(channelDef) { + return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition); + } + function hasConditionalValueDef(channelDef) { + return !!channelDef && !!channelDef.condition && (isArray(channelDef.condition) || isValueDef(channelDef.condition)); + } + function isFieldDef(channelDef) { + return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); + } + function isTypedFieldDef(channelDef) { + return !!channelDef && ((!!channelDef['field'] && !!channelDef['type']) || channelDef['aggregate'] === 'count'); + } + function isStringFieldDef(channelDef) { + return isFieldDef(channelDef) && isString(channelDef.field); + } + function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; + } + function isScaleFieldDef(channelDef) { + return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']); + } + function isPositionFieldDef(channelDef) { + return !!channelDef && (!!channelDef['axis'] || !!channelDef['stack'] || !!channelDef['impute']); + } + function isMarkPropFieldDef(channelDef) { + return !!channelDef && !!channelDef['legend']; + } + function isTextFieldDef(channelDef) { + return !!channelDef && !!channelDef['format']; + } + function isOpFieldDef(fieldDef) { + return !!fieldDef['op']; + } + /** + * Get a Vega field reference from a Vega-Lite field def. + */ + function vgField(fieldDef, opt = {}) { + let field = fieldDef.field; + const prefix = opt.prefix; + let suffix = opt.suffix; + let argAccessor = ''; // for accessing argmin/argmax field at the end without getting escaped + if (isCount(fieldDef)) { + field = internalField('count'); + } + else { + let fn; + if (!opt.nofn) { + if (isOpFieldDef(fieldDef)) { + fn = fieldDef.op; + } + else { + const { bin, aggregate, timeUnit } = fieldDef; + if (isBinning(bin)) { + fn = binToString(bin); + suffix = (opt.binSuffix || '') + (opt.suffix || ''); + } + else if (aggregate) { + if (isArgmaxDef(aggregate)) { + argAccessor = `.${field}`; + field = `argmax_${aggregate.argmax}`; + } + else if (isArgminDef(aggregate)) { + argAccessor = `.${field}`; + field = `argmin_${aggregate.argmin}`; + } + else { + fn = String(aggregate); + } + } + else if (timeUnit) { + fn = String(timeUnit); + } + } + } + if (fn) { + field = field ? `${fn}_${field}` : fn; + } + } + if (suffix) { + field = `${field}_${suffix}`; + } + if (prefix) { + field = `${prefix}_${field}`; + } + if (opt.forAs) { + return field; + } + else if (opt.expr) { + // Expression to access flattened field. No need to escape dots. + return flatAccessWithDatum(field, opt.expr) + argAccessor; + } + else { + // We flattened all fields so paths should have become dot. + return replacePathInField(field) + argAccessor; + } + } + function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + case 'geojson': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'temporal': + return false; + } + throw new Error(message.invalidFieldType(fieldDef.type)); + } + function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); + } + function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; + } + function verbalTitleFormatter(fieldDef, config) { + const { field, bin, timeUnit, aggregate } = fieldDef; + if (aggregate === 'count') { + return config.countTitle; + } + else if (isBinning(bin)) { + return `${field} (binned)`; + } + else if (timeUnit) { + const units = getTimeUnitParts(timeUnit).join('-'); + return `${field} (${units})`; + } + else if (aggregate) { + if (isArgmaxDef(aggregate)) { + return `${field} for max ${aggregate.argmax}`; + } + else if (isArgminDef(aggregate)) { + return `${field} for min ${aggregate.argmin}`; + } + else { + return `${titlecase(aggregate)} of ${field}`; + } + } + return field; + } + function functionalTitleFormatter(fieldDef) { + const { aggregate, bin, timeUnit, field } = fieldDef; + if (isArgmaxDef(aggregate)) { + return `${field} for argmax(${aggregate.argmax})`; + } + else if (isArgminDef(aggregate)) { + return `${field} for argmin(${aggregate.argmin})`; + } + const fn = aggregate || timeUnit || (isBinning(bin) && 'bin'); + if (fn) { + return fn.toUpperCase() + '(' + field + ')'; + } + else { + return field; + } + } + const defaultTitleFormatter = (fieldDef, config) => { + switch (config.fieldTitle) { + case 'plain': + return fieldDef.field; + case 'functional': + return functionalTitleFormatter(fieldDef); + default: + return verbalTitleFormatter(fieldDef, config); + } + }; + let titleFormatter = defaultTitleFormatter; + function setTitleFormatter(formatter) { + titleFormatter = formatter; + } + function resetTitleFormatter() { + setTitleFormatter(defaultTitleFormatter); + } + function title(fieldDef, config, { allowDisabling, includeDefault = true }) { + const guide = getGuide(fieldDef) || {}; + const guideTitle = guide.title; + const def = includeDefault ? defaultTitle(fieldDef, config) : undefined; + if (allowDisabling) { + return getFirstDefined(guideTitle, fieldDef.title, def); + } + else { + return guideTitle || fieldDef.title || def; + } + } + function getGuide(fieldDef) { + if (isPositionFieldDef(fieldDef) && fieldDef.axis) { + return fieldDef.axis; + } + else if (isMarkPropFieldDef(fieldDef) && fieldDef.legend) { + return fieldDef.legend; + } + else if (isFacetFieldDef(fieldDef) && fieldDef.header) { + return fieldDef.header; + } + return undefined; + } + function defaultTitle(fieldDef, config) { + return titleFormatter(fieldDef, config); + } + function format(fieldDef) { + if (isTextFieldDef(fieldDef) && fieldDef.format) { + return fieldDef.format; + } + else { + const guide = getGuide(fieldDef) || {}; + return guide.format; + } + } + function defaultType(fieldDef, channel) { + if (fieldDef.timeUnit) { + return 'temporal'; + } + if (isBinning(fieldDef.bin)) { + return 'quantitative'; + } + switch (rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible': // color + return 'nominal'; + default: + return 'quantitative'; + } + } + /** + * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef. + * @param channelDef + */ + function getFieldDef(channelDef) { + if (isFieldDef(channelDef)) { + return channelDef; + } + else if (hasConditionalFieldDef(channelDef)) { + return channelDef.condition; + } + return undefined; + } + function getTypedFieldDef(channelDef) { + if (isFieldDef(channelDef)) { + return channelDef; + } + else if (hasConditionalFieldDef(channelDef)) { + return channelDef.condition; + } + return undefined; + } + /** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ + function normalize(channelDef, channel) { + if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) { + const primitiveType = isString(channelDef) ? 'string' : isNumber(channelDef) ? 'number' : 'boolean'; + warn(message.primitiveChannelDef(channel, primitiveType, channelDef)); + return { value: channelDef }; + } + // If a fieldDef contains a field, we need type. + if (isFieldDef(channelDef)) { + return normalizeFieldDef(channelDef, channel); + } + else if (hasConditionalFieldDef(channelDef)) { + return Object.assign({}, channelDef, { + // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition + condition: normalizeFieldDef(channelDef.condition, channel) }); + } + return channelDef; + } + function normalizeFieldDef(fieldDef, channel) { + const { aggregate, timeUnit, bin } = fieldDef; + // Drop invalid aggregate + if (aggregate && !isAggregateOp(aggregate) && !isArgmaxDef(aggregate) && !isArgminDef(aggregate)) { + const fieldDefWithoutAggregate = __rest(fieldDef, ["aggregate"]); + warn(message.invalidAggregate(aggregate)); + fieldDef = fieldDefWithoutAggregate; + } + // Normalize Time Unit + if (timeUnit) { + fieldDef = Object.assign({}, fieldDef, { timeUnit: normalizeTimeUnit(timeUnit) }); + } + // Normalize bin + if (isBinning(bin)) { + fieldDef = Object.assign({}, fieldDef, { bin: normalizeBin(bin, channel) }); + } + if (isBinned(bin) && !contains(POSITION_SCALE_CHANNELS, channel)) { + warn(`Channel ${channel} should not be used with "binned" bin`); + } + // Normalize Type + if (isTypedFieldDef(fieldDef)) { + const { type } = fieldDef; + const fullType = getFullName(type); + if (type !== fullType) { + // convert short type to full type + fieldDef = Object.assign({}, fieldDef, { type: fullType }); + } + if (type !== 'quantitative') { + if (isCountingAggregateOp(aggregate)) { + warn(message.invalidFieldTypeForCountAggregate(type, aggregate)); + fieldDef = Object.assign({}, fieldDef, { type: 'quantitative' }); + } + } + } + else if (!isSecondaryRangeChannel(channel)) { + // If type is empty / invalid, then augment with default type + const newType = defaultType(fieldDef, channel); + warn(message.missingFieldType(channel, newType)); + fieldDef = Object.assign({}, fieldDef, { type: newType }); + } + if (isTypedFieldDef(fieldDef)) { + const { compatible, warning } = channelCompatibility(fieldDef, channel); + if (!compatible) { + warn(warning); + } + } + return fieldDef; + } + function normalizeBin(bin, channel) { + if (isBoolean(bin)) { + return { maxbins: autoMaxBins(channel) }; + } + else if (bin === 'binned') { + return { + binned: true + }; + } + else if (!bin.maxbins && !bin.step) { + return Object.assign({}, bin, { maxbins: autoMaxBins(channel) }); + } + else { + return bin; + } + } + const COMPATIBLE = { compatible: true }; + function channelCompatibility(fieldDef, channel) { + const type = fieldDef.type; + if (type === 'geojson' && channel !== 'shape') { + return { + compatible: false, + warning: `Channel ${channel} should not be used with a geojson data.` + }; + } + switch (channel) { + case 'row': + case 'column': + case 'facet': + if (isContinuous(fieldDef)) { + return { + compatible: false, + warning: message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'fill': + case 'stroke': + case 'text': + case 'detail': + case 'key': + case 'tooltip': + case 'href': + return COMPATIBLE; + case 'longitude': + case 'longitude2': + case 'latitude': + case 'latitude2': + if (type !== QUANTITATIVE) { + return { + compatible: false, + warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.` + }; + } + return COMPATIBLE; + case 'opacity': + case 'fillOpacity': + case 'strokeOpacity': + case 'strokeWidth': + case 'size': + case 'x2': + case 'y2': + if (type === 'nominal' && !fieldDef['sort']) { + return { + compatible: false, + warning: `Channel ${channel} should not be used with an unsorted discrete field.` + }; + } + return COMPATIBLE; + case 'shape': + if (!contains(['ordinal', 'nominal', 'geojson'], fieldDef.type)) { + return { + compatible: false, + warning: 'Shape channel should be used with only either discrete or geojson data.' + }; + } + return COMPATIBLE; + case 'order': + if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) { + return { + compatible: false, + warning: `Channel order is inappropriate for nominal field, which has no inherent order.` + }; + } + return COMPATIBLE; + } + throw new Error('channelCompatability not implemented for channel ' + channel); + } + function isNumberFieldDef(fieldDef) { + return fieldDef.type === 'quantitative' || isBinning(fieldDef.bin); + } + /** + * Check if the field def uses a time format or does not use any format but is temporal (this does not cover field defs that are temporal but use a number format). + */ + function isTimeFormatFieldDef(fieldDef) { + const formatType = (isPositionFieldDef(fieldDef) && fieldDef.axis && fieldDef.axis.formatType) || + (isMarkPropFieldDef(fieldDef) && fieldDef.legend && fieldDef.legend.formatType) || + (isTextFieldDef(fieldDef) && fieldDef.formatType); + return formatType === 'time' || (!formatType && isTimeFieldDef(fieldDef)); + } + /** + * Check if field def has tye `temporal`. If you want to also cover field defs that use a time format, use `isTimeFormatFieldDef`. + */ + function isTimeFieldDef(fieldDef) { + return fieldDef.type === 'temporal' || !!fieldDef.timeUnit; + } + /** + * Getting a value associated with a fielddef. + * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit) + */ + function valueExpr(v, { timeUnit, type, time, undefinedIfExprNotRequired }) { + let expr; + if (isDateTime(v)) { + expr = dateTimeExpr(v, true); + } + else if (isString(v) || isNumber(v)) { + if (timeUnit || type === 'temporal') { + if (isLocalSingleTimeUnit(timeUnit)) { + expr = dateTimeExpr({ [timeUnit]: v }, true); + } + else if (isUtcSingleTimeUnit(timeUnit)) { + // FIXME is this really correct? + expr = valueExpr(v, { timeUnit: getLocalTimeUnit(timeUnit) }); + } + else { + // just pass the string to date function (which will call JS Date.parse()) + expr = `datetime(${JSON.stringify(v)})`; + } + } + } + if (expr) { + return time ? `time(${expr})` : expr; + } + // number or boolean or normal string + return undefinedIfExprNotRequired ? undefined : JSON.stringify(v); + } + /** + * Standardize value array -- convert each value to Vega expression if applicable + */ + function valueArray(fieldDef, values) { + const { timeUnit, type } = fieldDef; + return values.map(v => { + const expr = valueExpr(v, { timeUnit, type, undefinedIfExprNotRequired: true }); + // return signal for the expression if we need an expression + if (expr !== undefined) { + return { signal: expr }; + } + // otherwise just return the original value + return v; + }); + } + /** + * Checks whether a fieldDef for a particular channel requires a computed bin range. + */ + function binRequiresRange(fieldDef, channel) { + if (!isBinning(fieldDef.bin)) { + console.warn('Only use this method with binned field defs'); + return false; + } + // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels. + // We could check whether the axis or legend exists (not disabled) but that seems overkill. + return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type); + } + + var vlChannelDef = /*#__PURE__*/Object.freeze({ + isConditionalSelection: isConditionalSelection, + isRepeatRef: isRepeatRef, + toFieldDefBase: toFieldDefBase, + isSortableFieldDef: isSortableFieldDef, + isConditionalDef: isConditionalDef, + hasConditionalFieldDef: hasConditionalFieldDef, + hasConditionalValueDef: hasConditionalValueDef, + isFieldDef: isFieldDef, + isTypedFieldDef: isTypedFieldDef, + isStringFieldDef: isStringFieldDef, + isValueDef: isValueDef, + isScaleFieldDef: isScaleFieldDef, + isPositionFieldDef: isPositionFieldDef, + isMarkPropFieldDef: isMarkPropFieldDef, + isTextFieldDef: isTextFieldDef, + vgField: vgField, + isDiscrete: isDiscrete, + isContinuous: isContinuous, + isCount: isCount, + verbalTitleFormatter: verbalTitleFormatter, + functionalTitleFormatter: functionalTitleFormatter, + defaultTitleFormatter: defaultTitleFormatter, + setTitleFormatter: setTitleFormatter, + resetTitleFormatter: resetTitleFormatter, + title: title, + getGuide: getGuide, + defaultTitle: defaultTitle, + format: format, + defaultType: defaultType, + getFieldDef: getFieldDef, + getTypedFieldDef: getTypedFieldDef, + normalize: normalize, + normalizeFieldDef: normalizeFieldDef, + normalizeBin: normalizeBin, + channelCompatibility: channelCompatibility, + isNumberFieldDef: isNumberFieldDef, + isTimeFormatFieldDef: isTimeFormatFieldDef, + isTimeFieldDef: isTimeFieldDef, + valueExpr: valueExpr, + valueArray: valueArray, + binRequiresRange: binRequiresRange + }); + + /** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ + // NOTE: CompassQL uses this method. + function scaleType(specifiedScale, channel, fieldDef, mark) { + const defaultScaleType = defaultType$1(channel, fieldDef, mark); + const { type } = specifiedScale; + if (!isScaleChannel(channel)) { + // There is no scale for these channels + return null; + } + if (type !== undefined) { + // Check if explicitly specified scale type is supported by the channel + if (!channelSupportScaleType(channel, type)) { + warn(message.scaleTypeNotWorkWithChannel(channel, type, defaultScaleType)); + return defaultScaleType; + } + // Check if explicitly specified scale type is supported by the data type + if (!scaleTypeSupportDataType(type, fieldDef.type)) { + warn(message.scaleTypeNotWorkWithFieldDef(type, defaultScaleType)); + return defaultScaleType; + } + return type; + } + return defaultScaleType; + } + /** + * Determine appropriate default scale type. + */ + // NOTE: Voyager uses this method. + function defaultType$1(channel, fieldDef, mark) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + if (isColorChannel(channel) || rangeType(channel) === 'discrete') { + if (channel === 'shape' && fieldDef.type === 'ordinal') { + warn(message.discreteChannelCannotEncode(channel, 'ordinal')); + } + return 'ordinal'; + } + if (contains(['x', 'y'], channel)) { + if (contains(['rect', 'bar', 'rule'], mark)) { + // The rect/bar mark should fit into a band. + // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429 + return 'band'; + } + if (mark === 'bar') { + return 'band'; + } + } + // Otherwise, use ordinal point scale so we can easily get center positions of the marks. + return 'point'; + case 'temporal': + if (isColorChannel(channel)) { + return 'time'; + } + else if (rangeType(channel) === 'discrete') { + warn(message.discreteChannelCannotEncode(channel, 'temporal')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + return 'time'; + case 'quantitative': + if (isColorChannel(channel)) { + if (isBinning(fieldDef.bin)) { + return 'bin-ordinal'; + } + return 'linear'; + } + else if (rangeType(channel) === 'discrete') { + warn(message.discreteChannelCannotEncode(channel, 'quantitative')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + return 'linear'; + case 'geojson': + return undefined; + } + /* istanbul ignore next: should never reach this */ + throw new Error(message.invalidFieldType(fieldDef.type)); + } + + var ExpandedType; + (function (ExpandedType) { + ExpandedType.QUANTITATIVE = QUANTITATIVE; + ExpandedType.ORDINAL = ORDINAL; + ExpandedType.TEMPORAL = TEMPORAL; + ExpandedType.NOMINAL = NOMINAL; + ExpandedType.KEY = 'key'; + })(ExpandedType || (ExpandedType = {})); + function isDiscrete$1(fieldType) { + return fieldType === ORDINAL || fieldType === NOMINAL || fieldType === ExpandedType.KEY; + } + + /** + * Dictionary that takes property as a key. + */ + class PropIndex { + constructor(i = null) { + this.index = i ? Object.assign({}, i) : {}; + } + has(p) { + return toKey(p) in this.index; + } + get(p) { + return this.index[toKey(p)]; + } + set(p, value) { + this.index[toKey(p)] = value; + return this; + } + setByKey(key, value) { + this.index[key] = value; + } + map(f) { + const i = new PropIndex(); + for (const k in this.index) { + i.index[k] = f(this.index[k]); + } + return i; + } + size() { + return util_3(this.index).length; + } + duplicate() { + return new PropIndex(this.index); + } + } + + function channelHasField(encoding, channel) { + const channelDef = encoding && encoding[channel]; + if (channelDef) { + if (isArray(channelDef)) { + return some(channelDef, fieldDef => !!fieldDef.field); + } + else { + return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef); + } + } + return false; + } + + const STACK_OFFSET_INDEX = { + zero: 1, + center: 1, + normalize: 1 + }; + function isStackOffset(s) { + return !!STACK_OFFSET_INDEX[s]; + } + const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT$1, TICK]; + const STACK_BY_DEFAULT_MARKS = [BAR, AREA]; + function potentialStackedChannel(encoding) { + const xDef = encoding.x; + const yDef = encoding.y; + if (isFieldDef(xDef) && isFieldDef(yDef)) { + if (xDef.type === 'quantitative' && yDef.type === 'quantitative') { + if (xDef.stack) { + return 'x'; + } + else if (yDef.stack) { + return 'y'; + } + // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y + if (!!xDef.aggregate !== !!yDef.aggregate) { + return xDef.aggregate ? 'x' : 'y'; + } + } + else if (xDef.type === 'quantitative') { + return 'x'; + } + else if (yDef.type === 'quantitative') { + return 'y'; + } + } + else if (isFieldDef(xDef) && xDef.type === 'quantitative') { + return 'x'; + } + else if (isFieldDef(yDef) && yDef.type === 'quantitative') { + return 'y'; + } + return undefined; + } + // Note: CompassQL uses this method and only pass in required properties of each argument object. + // If required properties change, make sure to update CompassQL. + function stack(m, encoding, stackConfig, opt = {}) { + const mark = isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!contains(STACKABLE_MARKS, mark)) { + return null; + } + const fieldChannel = potentialStackedChannel(encoding); + if (!fieldChannel) { + return null; + } + const stackedFieldDef = encoding[fieldChannel]; + const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined; + const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x'; + const dimensionDef = encoding[dimensionChannel]; + const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined; + // Should have grouping level of detail that is different from the dimension field + const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => { + // Ignore tooltip in stackBy (https://github.com/vega/vega-lite/issues/4001) + if (channel !== 'tooltip' && channelHasField(encoding, channel)) { + const channelDef = encoding[channel]; + (isArray(channelDef) ? channelDef : [channelDef]).forEach(cDef => { + const fieldDef = getTypedFieldDef(cDef); + if (fieldDef.aggregate) { + return; + } + // Check whether the channel's field is identical to x/y's field or if the channel is a repeat + const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined; + if ( + // if fielddef is a repeat, just include it in the stack by + !f || + // otherwise, the field must be different from x and y fields. + (f !== dimensionField && f !== stackedField)) { + sc.push({ channel, fieldDef }); + } + }); + } + return sc; + }, []); + if (stackBy.length === 0) { + return null; + } + // Automatically determine offset + let offset; + if (stackedFieldDef.stack !== undefined) { + if (isBoolean(stackedFieldDef.stack)) { + offset = stackedFieldDef.stack ? 'zero' : null; + } + else { + offset = stackedFieldDef.stack; + } + } + else if (contains(STACK_BY_DEFAULT_MARKS, mark)) { + // Bar and Area with sum ops are automatically stacked by default + offset = getFirstDefined(stackConfig, 'zero'); + } + else { + offset = stackConfig; + } + if (!offset || !isStackOffset(offset)) { + return null; + } + // warn when stacking non-linear + if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) { + if (opt.disallowNonLinearStack) { + return null; + } + else { + warn(message.cannotStackNonLinearScale(stackedFieldDef.scale.type)); + } + } + // Check if it is a ranged mark + if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) { + if (stackedFieldDef.stack !== undefined) { + warn(message.cannotStackRangedMark(fieldChannel)); + } + return null; + } + // Warn if stacking summative aggregate + if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) { + warn(message.stackNonSummativeAggregate(stackedFieldDef.aggregate)); + } + return { + groupbyChannel: dimensionDef ? dimensionChannel : undefined, + fieldChannel, + impute: isPathMark(mark), + stackBy, + offset + }; + } + + /** + * Convert a Vega-Lite's ExtendedUnitSpec into a CompassQL's SpecQuery + * @param {ExtendedUnitSpec} spec + * @returns + */ + function fromSpec(spec) { + return util_5(spec.data ? { data: spec.data } : {}, spec.transform ? { transform: spec.transform } : {}, spec.width ? { width: spec.width } : {}, spec.height ? { height: spec.height } : {}, spec.background ? { background: spec.background } : {}, spec.padding ? { padding: spec.padding } : {}, spec.title ? { title: spec.title } : {}, { + mark: spec.mark, + encodings: util_3(spec.encoding).map((channel) => { + let encQ = { channel: channel }; + let channelDef = spec.encoding[channel]; + for (const prop in channelDef) { + if (isEncodingTopLevelProperty(prop) && channelDef[prop] !== undefined) { + // Currently bin, scale, axis, legend only support boolean, but not null. + // Therefore convert null to false. + if (contains$1(['bin', 'scale', 'axis', 'legend'], prop) && channelDef[prop] === null) { + encQ[prop] = false; + } + else { + encQ[prop] = channelDef[prop]; + } + } + } + if (isFieldQuery(encQ) && encQ.aggregate === 'count' && !encQ.field) { + encQ.field = '*'; + } + return encQ; + }) + }, spec.config ? { config: spec.config } : {}); + } + function isAggregate(specQ) { + return some$1(specQ.encodings, (encQ) => { + return (isFieldQuery(encQ) && !isWildcard(encQ.aggregate) && !!encQ.aggregate) || isEnabledAutoCountQuery(encQ); + }); + } + /** + * @return The Vega-Lite `StackProperties` object that describes the stack + * configuration of `specQ`. Returns `null` if this is not stackable. + */ + function getVlStack(specQ) { + if (!hasRequiredStackProperties(specQ)) { + return null; + } + const encoding = toEncoding(specQ.encodings, { schema: null, wildcardMode: 'null' }); + const mark = specQ.mark; + return stack(mark, encoding, undefined, { disallowNonLinearStack: true }); + } + /** + * @return The `StackOffset` specified in `specQ`, `undefined` if none + * is specified. + */ + function getStackOffset(specQ) { + for (const encQ of specQ.encodings) { + if (encQ[Property.STACK] !== undefined && !isWildcard(encQ[Property.STACK])) { + return encQ[Property.STACK]; + } + } + return undefined; + } + /** + * @return The `Channel` in which `stack` is specified in `specQ`, or + * `null` if none is specified. + */ + function getStackChannel(specQ) { + for (const encQ of specQ.encodings) { + if (encQ[Property.STACK] !== undefined && !isWildcard(encQ.channel)) { + return encQ.channel; + } + } + return null; + } + /** + * Returns true iff the given SpecQuery has the properties defined + * to be a potential Stack spec. + * @param specQ The SpecQuery in question. + */ + function hasRequiredStackProperties(specQ) { + // TODO(haldenl): make this leaner, a lot of encQ properties aren't required for stack. + // TODO(haldenl): check mark, then encodings + if (isWildcard(specQ.mark)) { + return false; + } + const requiredEncodingProps = [ + Property.STACK, + Property.CHANNEL, + Property.MARK, + Property.FIELD, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ]; + const exclude = util_8(without(ALL_ENCODING_PROPS, requiredEncodingProps)); + const encodings = specQ.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ)); + for (const encQ of encodings) { + if (objectContainsWildcard(encQ, { exclude: exclude })) { + return false; + } + } + return true; + } + /** + * Returns true iff the given object does not contain a nested wildcard. + * @param obj The object in question. + * @param opt With optional `exclude` property, which defines properties to + * ignore when testing for wildcards. + */ + // TODO(haldenl): rename to objectHasWildcard, rename prop to obj + function objectContainsWildcard(obj, opt = {}) { + if (!util_6(obj)) { + return false; + } + for (const childProp in obj) { + if (obj.hasOwnProperty(childProp)) { + const wildcard = isWildcard(obj[childProp]); + if ((wildcard && (!opt.exclude || !opt.exclude[childProp])) || objectContainsWildcard(obj[childProp], opt)) { + return true; + } + } + } + return false; + } + /** + * Returns true iff the given `specQ` contains a wildcard. + * @param specQ The `SpecQuery` in question. + * @param opt With optional `exclude` property, which defines properties to + * ignore when testing for wildcards. + */ + function hasWildcard(specQ, opt = {}) { + const exclude = opt.exclude ? util_8(opt.exclude.map(toKey)) : {}; + if (isWildcard(specQ.mark) && !exclude['mark']) { + return true; + } + for (const encQ of specQ.encodings) { + if (objectContainsWildcard(encQ, exclude)) { + return true; + } + } + return false; + } + + var spec = /*#__PURE__*/Object.freeze({ + fromSpec: fromSpec, + isAggregate: isAggregate, + getVlStack: getVlStack, + getStackOffset: getStackOffset, + getStackChannel: getStackChannel, + hasRequiredStackProperties: hasRequiredStackProperties, + hasWildcard: hasWildcard + }); + + function getReplacerIndex(replaceIndex) { + return replaceIndex.map(r => getReplacer(r)); + } + function getReplacer(replace) { + return (s) => { + if (replace[s] !== undefined) { + return replace[s]; + } + return s; + }; + } + function value$1(v, replacer) { + if (isWildcard(v)) { + // Return the enum array if it's a full wildcard, or just return SHORT_WILDCARD for short ones. + if (!isShortWildcard(v) && v.enum) { + return SHORT_WILDCARD + JSON.stringify(v.enum); + } + else { + return SHORT_WILDCARD; + } + } + if (replacer) { + return replacer(v); + } + return v; + } + function replace(v, replacer) { + if (replacer) { + return replacer(v); + } + return v; + } + const REPLACE_NONE = new PropIndex(); + const INCLUDE_ALL = + // FIXME: remove manual TRANSFORM concat once we really support enumerating transform. + [] + .concat(DEFAULT_PROP_PRECEDENCE, SORT_PROPS, [Property.TRANSFORM, Property.STACK], VIEW_PROPS) + .reduce((pi, prop) => pi.set(prop, true), new PropIndex()); + function vlSpec(vlspec, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const specQ = fromSpec(vlspec); + return spec$1(specQ, include, replace); + } + const PROPERTY_SUPPORTED_CHANNELS = { + axis: { x: true, y: true, row: true, column: true }, + legend: { color: true, opacity: true, size: true, shape: true }, + scale: { x: true, y: true, color: true, opacity: true, row: true, column: true, size: true, shape: true }, + sort: { x: true, y: true, path: true, order: true }, + stack: { x: true, y: true } + }; + /** + * Returns a shorthand for a spec query + * @param specQ a spec query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ + function spec$1(specQ, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const parts = []; + if (include.get(Property.MARK)) { + parts.push(value$1(specQ.mark, replace.get(Property.MARK))); + } + if (specQ.transform && specQ.transform.length > 0) { + parts.push('transform:' + JSON.stringify(specQ.transform)); + } + let stack; + if (include.get(Property.STACK)) { + stack = getVlStack(specQ); + } + if (specQ.encodings) { + const encodings = specQ.encodings + .reduce((encQs, encQ) => { + // Exclude encoding mapping with autoCount=false as they are basically disabled. + if (!isDisabledAutoCountQuery(encQ)) { + let str; + if (!!stack && encQ.channel === stack.fieldChannel) { + str = encoding(Object.assign({}, encQ, { stack: stack.offset }), include, replace); + } + else { + str = encoding(encQ, include, replace); + } + if (str) { + // only add if the shorthand isn't an empty string. + encQs.push(str); + } + } + return encQs; + }, []) + .sort() // sort at the end to ignore order + .join('|'); + if (encodings) { + parts.push(encodings); + } + } + for (let viewProp of VIEW_PROPS) { + const propString = viewProp.toString(); + if (include.get(viewProp) && !!specQ[propString]) { + const value = specQ[propString]; + parts.push(`${propString}=${JSON.stringify(value)}`); + } + } + return parts.join('|'); + } + /** + * Returns a shorthand for an encoding query + * @param encQ an encoding query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ + function encoding(encQ, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const parts = []; + if (include.get(Property.CHANNEL)) { + parts.push(value$1(encQ.channel, replace.get(Property.CHANNEL))); + } + if (isFieldQuery(encQ)) { + const fieldDefStr = fieldDef(encQ, include, replace); + if (fieldDefStr) { + parts.push(fieldDefStr); + } + } + else if (isValueQuery(encQ)) { + parts.push(encQ.value); + } + else if (isAutoCountQuery(encQ)) { + parts.push('autocount()'); + } + return parts.join(':'); + } + /** + * Returns a field definition shorthand for an encoding query + * @param encQ an encoding query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ + function fieldDef(encQ, include = INCLUDE_ALL, replacer = REPLACE_NONE) { + if (include.get(Property.AGGREGATE) && isDisabledAutoCountQuery(encQ)) { + return '-'; + } + const fn = func(encQ, include, replacer); + const props = fieldDefProps(encQ, include, replacer); + let fieldAndParams; + if (isFieldQuery(encQ)) { + // field + fieldAndParams = include.get('field') ? value$1(encQ.field, replacer.get('field')) : '...'; + // type + if (include.get(Property.TYPE)) { + if (isWildcard(encQ.type)) { + fieldAndParams += ',' + value$1(encQ.type, replacer.get(Property.TYPE)); + } + else { + const typeShort = ((encQ.type || QUANTITATIVE) + '').substr(0, 1); + fieldAndParams += ',' + value$1(typeShort, replacer.get(Property.TYPE)); + } + } + // encoding properties + fieldAndParams += props + .map(p => { + let val = p.value instanceof Array ? '[' + p.value + ']' : p.value; + return ',' + p.key + '=' + val; + }) + .join(''); + } + else if (isAutoCountQuery(encQ)) { + fieldAndParams = '*,q'; + } + if (!fieldAndParams) { + return null; + } + if (fn) { + let fnPrefix = util_9(fn) ? fn : SHORT_WILDCARD + (util_3(fn).length > 0 ? JSON.stringify(fn) : ''); + return fnPrefix + '(' + fieldAndParams + ')'; + } + return fieldAndParams; + } + /** + * Return function part of + */ + function func(fieldQ, include, replacer) { + if (include.get(Property.AGGREGATE) && fieldQ.aggregate && !isWildcard(fieldQ.aggregate)) { + return replace(fieldQ.aggregate, replacer.get(Property.AGGREGATE)); + } + else if (include.get(Property.AGGREGATE) && isEnabledAutoCountQuery(fieldQ)) { + // autoCount is considered a part of aggregate + return replace('count', replacer.get(Property.AGGREGATE)); + } + else if (include.get(Property.TIMEUNIT) && fieldQ.timeUnit && !isWildcard(fieldQ.timeUnit)) { + return replace(fieldQ.timeUnit, replacer.get(Property.TIMEUNIT)); + } + else if (include.get(Property.BIN) && fieldQ.bin && !isWildcard(fieldQ.bin)) { + return 'bin'; + } + else { + let fn = null; + for (const prop of [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN]) { + const val = fieldQ[prop]; + if (include.get(prop) && fieldQ[prop] && isWildcard(val)) { + // assign fnEnumIndex[prop] = array of enum values or just "?" if it is SHORT_WILDCARD + fn = fn || {}; + fn[prop] = isShortWildcard(val) ? val : val.enum; + } + } + if (fn && fieldQ.hasFn) { + fn.hasFn = true; + } + return fn; + } + } + /** + * Return key-value of parameters of field defs + */ + function fieldDefProps(fieldQ, include, replacer) { + /** Encoding properties e.g., Scale, Axis, Legend */ + const props = []; + // Parameters of function such as bin will be just top-level properties + if (!util_7(fieldQ.bin) && !isShortWildcard(fieldQ.bin)) { + const bin = fieldQ.bin; + for (const child in bin) { + const prop = getEncodingNestedProp('bin', child); + if (prop && include.get(prop) && bin[child] !== undefined) { + props.push({ + key: child, + value: value$1(bin[child], replacer.get(prop)) + }); + } + } + // Sort to make sure that parameter are ordered consistently + props.sort((a, b) => a.key.localeCompare(b.key)); + } + for (const parent of [Property.SCALE, Property.SORT, Property.STACK, Property.AXIS, Property.LEGEND]) { + if (!isWildcard(fieldQ.channel) && !PROPERTY_SUPPORTED_CHANNELS[parent][fieldQ.channel]) { + continue; + } + if (include.get(parent) && fieldQ[parent] !== undefined) { + const parentValue = fieldQ[parent]; + if (util_7(parentValue) || parentValue === null) { + // `scale`, `axis`, `legend` can be false/null. + props.push({ + key: parent + '', + value: parentValue || false // return true or false (false if null) + }); + } + else if (util_9(parentValue)) { + // `sort` can be a string (ascending/descending). + props.push({ + key: parent + '', + value: replace(JSON.stringify(parentValue), replacer.get(parent)) + }); + } + else { + let nestedPropChildren = []; + for (const child in parentValue) { + const nestedProp = getEncodingNestedProp(parent, child); + if (nestedProp && include.get(nestedProp) && parentValue[child] !== undefined) { + nestedPropChildren.push({ + key: child, + value: value$1(parentValue[child], replacer.get(nestedProp)) + }); + } + } + if (nestedPropChildren.length > 0) { + const nestedPropObject = nestedPropChildren + .sort((a, b) => a.key.localeCompare(b.key)) + .reduce((o, item) => { + o[item.key] = item.value; + return o; + }, {}); + // Sort to make sure that parameter are ordered consistently + props.push({ + key: parent + '', + value: JSON.stringify(nestedPropObject) + }); + } + } + } + } + return props; + } + function parse(shorthand) { + // TODO(https://github.com/uwdata/compassql/issues/259): + // Do not split directly, but use an upgraded version of `getClosingBraceIndex()` + let splitShorthand = shorthand.split('|'); + let specQ = { + mark: splitShorthand[0], + encodings: [] + }; + for (let i = 1; i < splitShorthand.length; i++) { + let part = splitShorthand[i]; + const splitPart = splitWithTail(part, ':', 1); + const splitPartKey = splitPart[0]; + const splitPartValue = splitPart[1]; + if (isChannel(splitPartKey) || splitPartKey === '?') { + const encQ = shorthandParser.encoding(splitPartKey, splitPartValue); + specQ.encodings.push(encQ); + continue; + } + if (splitPartKey === 'transform') { + specQ.transform = JSON.parse(splitPartValue); + continue; + } + } + return specQ; + } + /** + * Split a string n times into substrings with the specified delimiter and return them as an array. + * @param str The string to be split + * @param delim The delimiter string used to separate the string + * @param number The value used to determine how many times the string is split + */ + function splitWithTail(str, delim, count) { + let result = []; + let lastIndex = 0; + for (let i = 0; i < count; i++) { + let indexOfDelim = str.indexOf(delim, lastIndex); + if (indexOfDelim !== -1) { + result.push(str.substring(lastIndex, indexOfDelim)); + lastIndex = indexOfDelim + 1; + } + else { + break; + } + } + result.push(str.substr(lastIndex)); + // If the specified count is greater than the number of delimiters that exist in the string, + // an empty string will be pushed count minus number of delimiter occurence times. + if (result.length !== count + 1) { + while (result.length !== count + 1) { + result.push(''); + } + } + return result; + } + var shorthandParser; + (function (shorthandParser) { + function encoding(channel, fieldDefShorthand) { + let encQMixins = fieldDefShorthand.indexOf('(') !== -1 + ? fn(fieldDefShorthand) + : rawFieldDef(splitWithTail(fieldDefShorthand, ',', 2)); + return Object.assign({ channel }, encQMixins); + } + shorthandParser.encoding = encoding; + function rawFieldDef(fieldDefPart) { + const fieldQ = {}; + fieldQ.field = fieldDefPart[0]; + fieldQ.type = getFullName(fieldDefPart[1].toUpperCase()) || '?'; + let partParams = fieldDefPart[2]; + let closingBraceIndex = 0; + let i = 0; + while (i < partParams.length) { + let propEqualSignIndex = partParams.indexOf('=', i); + let parsedValue; + if (propEqualSignIndex !== -1) { + let prop = partParams.substring(i, propEqualSignIndex); + if (partParams[i + prop.length + 1] === '{') { + let openingBraceIndex = i + prop.length + 1; + closingBraceIndex = getClosingIndex(openingBraceIndex, partParams, '}'); + const value = partParams.substring(openingBraceIndex, closingBraceIndex + 1); + parsedValue = JSON.parse(value); + // index after next comma + i = closingBraceIndex + 2; + } + else if (partParams[i + prop.length + 1] === '[') { + // find closing square bracket + let openingBracketIndex = i + prop.length + 1; + let closingBracketIndex = getClosingIndex(openingBracketIndex, partParams, ']'); + const value = partParams.substring(openingBracketIndex, closingBracketIndex + 1); + parsedValue = JSON.parse(value); + // index after next comma + i = closingBracketIndex + 2; + } + else { + let propIndex = i; + // Substring until the next comma (or end of the string) + let nextCommaIndex = partParams.indexOf(',', i + prop.length); + if (nextCommaIndex === -1) { + nextCommaIndex = partParams.length; + } + // index after next comma + i = nextCommaIndex + 1; + parsedValue = JSON.parse(partParams.substring(propIndex + prop.length + 1, nextCommaIndex)); + } + if (isEncodingNestedParent(prop)) { + fieldQ[prop] = parsedValue; + } + else { + // prop is a property of the aggregation function such as bin + fieldQ.bin = fieldQ.bin || {}; + fieldQ.bin[prop] = parsedValue; + } + } + else { + // something is wrong with the format of the partParams + // exits loop if don't have then infintie loop + break; + } + } + return fieldQ; + } + shorthandParser.rawFieldDef = rawFieldDef; + function getClosingIndex(openingBraceIndex, str, closingChar) { + for (let i = openingBraceIndex; i < str.length; i++) { + if (str[i] === closingChar) { + return i; + } + } + } + shorthandParser.getClosingIndex = getClosingIndex; + function fn(fieldDefShorthand) { + const fieldQ = {}; + // Aggregate, Bin, TimeUnit as wildcard case + if (fieldDefShorthand[0] === '?') { + let closingBraceIndex = getClosingIndex(1, fieldDefShorthand, '}'); + let fnEnumIndex = JSON.parse(fieldDefShorthand.substring(1, closingBraceIndex + 1)); + for (let encodingProperty in fnEnumIndex) { + if (util_1(fnEnumIndex[encodingProperty])) { + fieldQ[encodingProperty] = { enum: fnEnumIndex[encodingProperty] }; + } + else { + // Definitely a `SHORT_WILDCARD` + fieldQ[encodingProperty] = fnEnumIndex[encodingProperty]; + } + } + return Object.assign({}, fieldQ, rawFieldDef(splitWithTail(fieldDefShorthand.substring(closingBraceIndex + 2, fieldDefShorthand.length - 1), ',', 2))); + } + else { + let func = fieldDefShorthand.substring(0, fieldDefShorthand.indexOf('(')); + let insideFn = fieldDefShorthand.substring(func.length + 1, fieldDefShorthand.length - 1); + let insideFnParts = splitWithTail(insideFn, ',', 2); + if (isAggregateOp(func)) { + return Object.assign({ aggregate: func }, rawFieldDef(insideFnParts)); + } + else if (isTimeUnit(func)) { + return Object.assign({ timeUnit: func }, rawFieldDef(insideFnParts)); + } + else if (func === 'bin') { + return Object.assign({ bin: {} }, rawFieldDef(insideFnParts)); + } + } + } + shorthandParser.fn = fn; + })(shorthandParser || (shorthandParser = {})); + + var shorthand = /*#__PURE__*/Object.freeze({ + getReplacerIndex: getReplacerIndex, + getReplacer: getReplacer, + value: value$1, + replace: replace, + REPLACE_NONE: REPLACE_NONE, + INCLUDE_ALL: INCLUDE_ALL, + vlSpec: vlSpec, + PROPERTY_SUPPORTED_CHANNELS: PROPERTY_SUPPORTED_CHANNELS, + spec: spec$1, + encoding: encoding, + fieldDef: fieldDef, + parse: parse, + splitWithTail: splitWithTail, + get shorthandParser () { return shorthandParser; } + }); + + function isValueQuery(encQ) { + return encQ !== null && encQ !== undefined && encQ['value'] !== undefined; + } + function isFieldQuery(encQ) { + return encQ !== null && encQ !== undefined && (encQ['field'] || encQ['aggregate'] === 'count'); + } + function isAutoCountQuery(encQ) { + return encQ !== null && encQ !== undefined && 'autoCount' in encQ; + } + function isDisabledAutoCountQuery(encQ) { + return isAutoCountQuery(encQ) && encQ.autoCount === false; + } + function isEnabledAutoCountQuery(encQ) { + return isAutoCountQuery(encQ) && encQ.autoCount === true; + } + const DEFAULT_PROPS = [ + Property.AGGREGATE, + Property.BIN, + Property.TIMEUNIT, + Property.FIELD, + Property.TYPE, + Property.SCALE, + Property.SORT, + Property.AXIS, + Property.LEGEND, + Property.STACK, + Property.FORMAT + ]; + function toEncoding(encQs, params) { + let encoding = {}; + for (const encQ of encQs) { + if (isDisabledAutoCountQuery(encQ)) { + continue; // Do not include this in the output. + } + const { channel } = encQ; + // if channel is a wildcard, return null + if (isWildcard(channel)) { + throw new Error('Cannot convert wildcard channel to a fixed channel'); + } + const channelDef = isValueQuery(encQ) ? toValueDef(encQ) : toFieldDef(encQ, params); + if (channelDef === null) { + if (params.wildcardMode === 'null') { + // contains invalid property (e.g., wildcard, thus cannot return a proper spec.) + return null; + } + continue; + } + // Otherwise, we can set the channelDef + encoding[channel] = channelDef; + } + return encoding; + } + function toValueDef(valueQ) { + const { value } = valueQ; + if (isWildcard(value)) { + return null; + } + return { value }; + } + function toFieldDef(encQ, params = {}) { + const { props = DEFAULT_PROPS, schema, wildcardMode = 'skip' } = params; + if (isFieldQuery(encQ)) { + const fieldDef = {}; + for (const prop of props) { + let encodingProperty = encQ[prop]; + if (isWildcard(encodingProperty)) { + if (wildcardMode === 'skip') + continue; + return null; + } + if (encodingProperty !== undefined) { + // if the channel supports this prop + const isSupportedByChannel = !PROPERTY_SUPPORTED_CHANNELS[prop] || PROPERTY_SUPPORTED_CHANNELS[prop][encQ.channel]; + if (!isSupportedByChannel) { + continue; + } + if (isEncodingNestedParent(prop) && util_6(encodingProperty)) { + encodingProperty = Object.assign({}, encodingProperty); // Make a shallow copy first + for (const childProp in encodingProperty) { + // ensure nested properties are not wildcard before assigning to field def + if (isWildcard(encodingProperty[childProp])) { + if (wildcardMode === 'null') { + return null; + } + delete encodingProperty[childProp]; // skip + } + } + } + if (prop === 'bin' && encodingProperty === false) { + continue; + } + else if (prop === 'type' && encodingProperty === 'key') { + fieldDef.type = 'nominal'; + } + else { + fieldDef[prop] = encodingProperty; + } + } + if (prop === Property.SCALE && schema && encQ.type === ORDINAL) { + const scale = encQ.scale; + const { ordinalDomain } = schema.fieldSchema(encQ.field); + if (scale !== null && ordinalDomain) { + fieldDef[Property.SCALE] = Object.assign({ domain: ordinalDomain }, (util_6(scale) ? scale : {})); + } + } + } + return fieldDef; + } + else { + if (encQ.autoCount === false) { + throw new Error(`Cannot convert {autoCount: false} into a field def`); + } + else { + return { + aggregate: 'count', + field: '*', + type: 'quantitative' + }; + } + } + } + /** + * Is a field query continuous field? + * This method is applicable only for fieldQuery without wildcard + */ + function isContinuous$1(encQ) { + if (isFieldQuery(encQ)) { + return isContinuous(toFieldDef(encQ, { props: ['bin', 'timeUnit', 'field', 'type'] })); + } + return isAutoCountQuery(encQ); + } + function isMeasure(encQ) { + if (isFieldQuery(encQ)) { + return !isDimension(encQ) && encQ.type !== 'temporal'; + } + return isAutoCountQuery(encQ); + } + /** + * Is a field query discrete field? + * This method is applicable only for fieldQuery without wildcard + */ + function isDimension(encQ) { + if (isFieldQuery(encQ)) { + const fieldDef = toFieldDef(encQ, { props: ['bin', 'timeUnit', 'type'] }); + return isDiscrete(fieldDef) || !!fieldDef.timeUnit; + } + return false; + } + /** + * Returns the true scale type of an encoding. + * @returns {ScaleType} If the scale type was not specified, it is inferred from the encoding's TYPE. + * @returns {undefined} If the scale type was not specified and Type (or TimeUnit if applicable) is a Wildcard, there is no clear scale type + */ + function scaleType$1(fieldQ) { + const scale = fieldQ.scale === true || fieldQ.scale === SHORT_WILDCARD ? {} : fieldQ.scale || {}; + const { type, channel, timeUnit, bin } = fieldQ; + // HACK: All of markType, and scaleConfig only affect + // sub-type of ordinal to quantitative scales (point or band) + // Currently, most of scaleType usage in CompassQL doesn't care about this subtle difference. + // Thus, instead of making this method requiring the global mark, + // we will just call it with mark = undefined . + // Thus, currently, we will always get a point scale unless a CompassQuery specifies band. + const markType = undefined; + if (isWildcard(scale.type) || isWildcard(type) || isWildcard(channel) || isWildcard(bin)) { + return undefined; + } + // If scale type is specified, then use scale.type + if (scale.type) { + return scale.type; + } + // if type is fixed and it's not temporal, we can ignore time unit. + if (type === 'temporal' && isWildcard(timeUnit)) { + return undefined; + } + // if type is fixed and it's not quantitative, we can ignore bin + if (type === 'quantitative' && isWildcard(bin)) { + return undefined; + } + let vegaLiteType = type === ExpandedType.KEY ? 'nominal' : type; + const fieldDef = { + type: vegaLiteType, + timeUnit: timeUnit, + bin: bin + }; + return scaleType({ type: scale.type }, channel, fieldDef, markType); + } + + var encoding$1 = /*#__PURE__*/Object.freeze({ + isValueQuery: isValueQuery, + isFieldQuery: isFieldQuery, + isAutoCountQuery: isAutoCountQuery, + isDisabledAutoCountQuery: isDisabledAutoCountQuery, + isEnabledAutoCountQuery: isEnabledAutoCountQuery, + toEncoding: toEncoding, + toValueDef: toValueDef, + toFieldDef: toFieldDef, + isContinuous: isContinuous$1, + isMeasure: isMeasure, + isDimension: isDimension, + scaleType: scaleType$1 + }); + + var d3Time = createCommonjsModule(function (module, exports) { + (function (global, factory) { + factory(exports); + }(commonjsGlobal, function (exports) { + var t0 = new Date; + var t1 = new Date; + function newInterval(floori, offseti, count, field) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.round = function(date) { + var d0 = new Date(+date), + d1 = new Date(date - 1); + floori(d0), floori(d1), offseti(d1, 1); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), date; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = []; + start = new Date(start - 1); + stop = new Date(+stop); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + offseti(start, 1), floori(start); + if (start < stop) range.push(new Date(+start)); + while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start)); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + while (--step >= 0) while (offseti(date, 1), !test(date)); + }); + }; + + if (count) { + interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + interval.every = function(step) { + step = Math.floor(step); + return !isFinite(step) || !(step > 0) ? null + : !(step > 1) ? interval + : interval.filter(field + ? function(d) { return field(d) % step === 0; } + : function(d) { return interval.count(0, d) % step === 0; }); + }; + } + + return interval; + } + var millisecond = newInterval(function() { + // noop + }, function(date, step) { + date.setTime(+date + step); + }, function(start, end) { + return end - start; + }); + + // An optimized implementation for this simple case. + millisecond.every = function(k) { + k = Math.floor(k); + if (!isFinite(k) || !(k > 0)) return null; + if (!(k > 1)) return millisecond; + return newInterval(function(date) { + date.setTime(Math.floor(date / k) * k); + }, function(date, step) { + date.setTime(+date + step * k); + }, function(start, end) { + return (end - start) / k; + }); + }; + + var second = newInterval(function(date) { + date.setMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }, function(date) { + return date.getSeconds(); + }); + + var minute = newInterval(function(date) { + date.setSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }, function(date) { + return date.getMinutes(); + }); + + var hour = newInterval(function(date) { + date.setMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }, function(date) { + return date.getHours(); + }); + + var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5; + }, function(date) { + return date.getDate() - 1; + }); + + function weekday(i) { + return newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5; + }); + } + + var sunday = weekday(0); + var monday = weekday(1); + var tuesday = weekday(2); + var wednesday = weekday(3); + var thursday = weekday(4); + var friday = weekday(5); + var saturday = weekday(6); + + var month = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(1); + }, function(date, step) { + date.setMonth(date.getMonth() + step); + }, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; + }, function(date) { + return date.getMonth(); + }); + + var year = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setMonth(0, 1); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step); + }, function(start, end) { + return end.getFullYear() - start.getFullYear(); + }, function(date) { + return date.getFullYear(); + }); + + var utcSecond = newInterval(function(date) { + date.setUTCMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }, function(date) { + return date.getUTCSeconds(); + }); + + var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }, function(date) { + return date.getUTCMinutes(); + }); + + var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }, function(date) { + return date.getUTCHours(); + }); + + var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); + }, function(start, end) { + return (end - start) / 864e5; + }, function(date) { + return date.getUTCDate() - 1; + }); + + function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / 6048e5; + }); + } + + var utcSunday = utcWeekday(0); + var utcMonday = utcWeekday(1); + var utcTuesday = utcWeekday(2); + var utcWednesday = utcWeekday(3); + var utcThursday = utcWeekday(4); + var utcFriday = utcWeekday(5); + var utcSaturday = utcWeekday(6); + + var utcMonth = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(1); + }, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); + }, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; + }, function(date) { + return date.getUTCMonth(); + }); + + var utcYear = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCMonth(0, 1); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); + }, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); + }, function(date) { + return date.getUTCFullYear(); + }); + + var milliseconds = millisecond.range; + var seconds = second.range; + var minutes = minute.range; + var hours = hour.range; + var days = day.range; + var sundays = sunday.range; + var mondays = monday.range; + var tuesdays = tuesday.range; + var wednesdays = wednesday.range; + var thursdays = thursday.range; + var fridays = friday.range; + var saturdays = saturday.range; + var weeks = sunday.range; + var months = month.range; + var years = year.range; + + var utcMillisecond = millisecond; + var utcMilliseconds = milliseconds; + var utcSeconds = utcSecond.range; + var utcMinutes = utcMinute.range; + var utcHours = utcHour.range; + var utcDays = utcDay.range; + var utcSundays = utcSunday.range; + var utcMondays = utcMonday.range; + var utcTuesdays = utcTuesday.range; + var utcWednesdays = utcWednesday.range; + var utcThursdays = utcThursday.range; + var utcFridays = utcFriday.range; + var utcSaturdays = utcSaturday.range; + var utcWeeks = utcSunday.range; + var utcMonths = utcMonth.range; + var utcYears = utcYear.range; + + var version = "0.1.1"; + + exports.version = version; + exports.milliseconds = milliseconds; + exports.seconds = seconds; + exports.minutes = minutes; + exports.hours = hours; + exports.days = days; + exports.sundays = sundays; + exports.mondays = mondays; + exports.tuesdays = tuesdays; + exports.wednesdays = wednesdays; + exports.thursdays = thursdays; + exports.fridays = fridays; + exports.saturdays = saturdays; + exports.weeks = weeks; + exports.months = months; + exports.years = years; + exports.utcMillisecond = utcMillisecond; + exports.utcMilliseconds = utcMilliseconds; + exports.utcSeconds = utcSeconds; + exports.utcMinutes = utcMinutes; + exports.utcHours = utcHours; + exports.utcDays = utcDays; + exports.utcSundays = utcSundays; + exports.utcMondays = utcMondays; + exports.utcTuesdays = utcTuesdays; + exports.utcWednesdays = utcWednesdays; + exports.utcThursdays = utcThursdays; + exports.utcFridays = utcFridays; + exports.utcSaturdays = utcSaturdays; + exports.utcWeeks = utcWeeks; + exports.utcMonths = utcMonths; + exports.utcYears = utcYears; + exports.millisecond = millisecond; + exports.second = second; + exports.minute = minute; + exports.hour = hour; + exports.day = day; + exports.sunday = sunday; + exports.monday = monday; + exports.tuesday = tuesday; + exports.wednesday = wednesday; + exports.thursday = thursday; + exports.friday = friday; + exports.saturday = saturday; + exports.week = sunday; + exports.month = month; + exports.year = year; + exports.utcSecond = utcSecond; + exports.utcMinute = utcMinute; + exports.utcHour = utcHour; + exports.utcDay = utcDay; + exports.utcSunday = utcSunday; + exports.utcMonday = utcMonday; + exports.utcTuesday = utcTuesday; + exports.utcWednesday = utcWednesday; + exports.utcThursday = utcThursday; + exports.utcFriday = utcFriday; + exports.utcSaturday = utcSaturday; + exports.utcWeek = utcSunday; + exports.utcMonth = utcMonth; + exports.utcYear = utcYear; + exports.interval = newInterval; + + })); + }); + + var tempDate = new Date(), + baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD + utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0); + + function date(d) { + return (tempDate.setTime(+d), tempDate); + } + + // create a time unit entry + function entry(type, date, unit, step, min, max) { + var e = { + type: type, + date: date, + unit: unit + }; + if (step) { + e.step = step; + } else { + e.minstep = 1; + } + if (min != null) e.min = min; + if (max != null) e.max = max; + return e; + } + + function create(type, unit, base, step, min, max) { + return entry(type, + function(d) { return unit.offset(base, d); }, + function(d) { return unit.count(base, d); }, + step, min, max); + } + + var locale = [ + create('second', d3Time.second, baseDate), + create('minute', d3Time.minute, baseDate), + create('hour', d3Time.hour, baseDate), + create('day', d3Time.day, baseDate, [1, 7]), + create('month', d3Time.month, baseDate, [1, 3, 6]), + create('year', d3Time.year, baseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(1970, 0, 1, 0, 0, d); }, + function(d) { return date(d).getSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(1970, 0, 1, 0, d); }, + function(d) { return date(d).getMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(1970, 0, 1, d); }, + function(d) { return date(d).getHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(1970, 0, 4+d); }, + function(d) { return date(d).getDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(1970, 0, d); }, + function(d) { return date(d).getDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(1970, d % 12, 1); }, + function(d) { return date(d).getMonth(); }, + [1], 0, 11 + ) + ]; + + var utc = [ + create('second', d3Time.utcSecond, utcBaseDate), + create('minute', d3Time.utcMinute, utcBaseDate), + create('hour', d3Time.utcHour, utcBaseDate), + create('day', d3Time.utcDay, utcBaseDate, [1, 7]), + create('month', d3Time.utcMonth, utcBaseDate, [1, 3, 6]), + create('year', d3Time.utcYear, utcBaseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); }, + function(d) { return date(d).getUTCSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); }, + function(d) { return date(d).getUTCMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(Date.UTC(1970, 0, 1, d)); }, + function(d) { return date(d).getUTCHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(Date.UTC(1970, 0, 4+d)); }, + function(d) { return date(d).getUTCDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(Date.UTC(1970, 0, d)); }, + function(d) { return date(d).getUTCDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(Date.UTC(1970, d % 12, 1)); }, + function(d) { return date(d).getUTCMonth(); }, + [1], 0, 11 + ) + ]; + + var STEPS = [ + [31536e6, 5], // 1-year + [7776e6, 4], // 3-month + [2592e6, 4], // 1-month + [12096e5, 3], // 2-week + [6048e5, 3], // 1-week + [1728e5, 3], // 2-day + [864e5, 3], // 1-day + [432e5, 2], // 12-hour + [216e5, 2], // 6-hour + [108e5, 2], // 3-hour + [36e5, 2], // 1-hour + [18e5, 1], // 30-minute + [9e5, 1], // 15-minute + [3e5, 1], // 5-minute + [6e4, 1], // 1-minute + [3e4, 0], // 30-second + [15e3, 0], // 15-second + [5e3, 0], // 5-second + [1e3, 0] // 1-second + ]; + + function find(units, span, minb, maxb) { + var step = STEPS[0], i, n, bins; + + for (i=1, n=STEPS.length; i step[0]) { + bins = span / step[0]; + if (bins > maxb) { + return units[STEPS[i-1][1]]; + } + if (bins >= minb) { + return units[step[1]]; + } + } + } + return units[STEPS[n-1][1]]; + } + + function toUnitMap(units) { + var map = {}, i, n; + for (i=0, n=units.length; i maxb) { step *= base; } + + // decrease step size if allowed + for (i=0; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + min = Math.min(min, Math.floor(min / step + eps) * step); + max = Math.ceil(max / step) * step; + + return { + start: min, + stop: max, + step: step, + unit: {precision: precision}, + value: value$2, + index: index + }; + } + + function bisect(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (util.cmp(a[mid], x) < 0) { lo = mid + 1; } + else { hi = mid; } + } + return lo; + } + + function value$2(v) { + return this.step * Math.floor(v / this.step + EPSILON); + } + + function index(v) { + return Math.floor((v - this.start) / this.step + EPSILON); + } + + function date_value(v) { + return this.unit.date(value$2.call(this, v)); + } + + function date_index(v) { + return index.call(this, this.unit.unit(v)); + } + + bins.date = function(opt) { + if (!opt) { throw Error("Missing date binning options."); } + + // find time step, then bin + var units = opt.utc ? time.utc : time, + dmin = opt.min, + dmax = opt.max, + maxb = opt.maxbins || 20, + minb = opt.minbins || 4, + span = (+dmax) - (+dmin), + unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb), + spec = bins({ + min: unit.min != null ? unit.min : unit.unit(dmin), + max: unit.max != null ? unit.max : unit.unit(dmax), + maxbins: maxb, + minstep: unit.minstep, + steps: unit.step + }); + + spec.unit = unit; + spec.index = date_index; + if (!opt.raw) spec.value = date_value; + return spec; + }; + + var bins_1 = bins; + + var TYPES = '__types__'; + + var PARSERS = { + boolean: util.boolean, + integer: util.number, + number: util.number, + date: util.date, + string: function(x) { return x == null || x === '' ? null : x + ''; } + }; + + var TESTS = { + boolean: function(x) { return x==='true' || x==='false' || util.isBoolean(x); }, + integer: function(x) { return TESTS.number(x) && (x=+x) === ~~x; }, + number: function(x) { return !isNaN(+x) && !util.isDate(x); }, + date: function(x) { return !isNaN(Date.parse(x)); } + }; + + function annotation(data, types) { + if (!types) return data && data[TYPES] || null; + data[TYPES] = types; + } + + function fieldNames(datum) { + return util.keys(datum); + } + + function bracket(fieldName) { + return '[' + fieldName + ']'; + } + + function type(values, f) { + values = util.array(values); + f = util.$(f); + var v, i, n; + + // if data array has type annotations, use them + if (values[TYPES]) { + v = f(values[TYPES]); + if (util.isString(v)) return v; + } + + for (i=0, n=values.length; !util.isValid(v) && i stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; + }; + + gen.random = {}; + + gen.random.uniform = function(min, max) { + if (max === undefined) { + max = min === undefined ? 1 : min; + min = 0; + } + var d = max - min; + var f = function() { + return min + d * Math.random(); + }; + f.samples = function(n) { + return gen.zeros(n).map(f); + }; + f.pdf = function(x) { + return (x >= min && x <= max) ? 1/d : 0; + }; + f.cdf = function(x) { + return x < min ? 0 : x > max ? 1 : (x - min) / d; + }; + f.icdf = function(p) { + return (p >= 0 && p <= 1) ? min + p*d : NaN; + }; + return f; + }; + + gen.random.integer = function(a, b) { + if (b === undefined) { + b = a; + a = 0; + } + var d = b - a; + var f = function() { + return a + Math.floor(d * Math.random()); + }; + f.samples = function(n) { + return gen.zeros(n).map(f); + }; + f.pdf = function(x) { + return (x === Math.floor(x) && x >= a && x < b) ? 1/d : 0; + }; + f.cdf = function(x) { + var v = Math.floor(x); + return v < a ? 0 : v >= b ? 1 : (v - a + 1) / d; + }; + f.icdf = function(p) { + return (p >= 0 && p <= 1) ? a - 1 + Math.floor(p*d) : NaN; + }; + return f; + }; + + gen.random.normal = function(mean, stdev) { + mean = mean || 0; + stdev = stdev || 1; + var next; + var f = function() { + var x = 0, y = 0, rds, c; + if (next !== undefined) { + x = next; + next = undefined; + return x; + } + do { + x = Math.random()*2-1; + y = Math.random()*2-1; + rds = x*x + y*y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform + next = mean + y*c*stdev; + return mean + x*c*stdev; + }; + f.samples = function(n) { + return gen.zeros(n).map(f); + }; + f.pdf = function(x) { + var exp = Math.exp(Math.pow(x-mean, 2) / (-2 * Math.pow(stdev, 2))); + return (1 / (stdev * Math.sqrt(2*Math.PI))) * exp; + }; + f.cdf = function(x) { + // Approximation from West (2009) + // Better Approximations to Cumulative Normal Functions + var cd, + z = (x - mean) / stdev, + Z = Math.abs(z); + if (Z > 37) { + cd = 0; + } else { + var sum, exp = Math.exp(-Z*Z/2); + if (Z < 7.07106781186547) { + sum = 3.52624965998911e-02 * Z + 0.700383064443688; + sum = sum * Z + 6.37396220353165; + sum = sum * Z + 33.912866078383; + sum = sum * Z + 112.079291497871; + sum = sum * Z + 221.213596169931; + sum = sum * Z + 220.206867912376; + cd = exp * sum; + sum = 8.83883476483184e-02 * Z + 1.75566716318264; + sum = sum * Z + 16.064177579207; + sum = sum * Z + 86.7807322029461; + sum = sum * Z + 296.564248779674; + sum = sum * Z + 637.333633378831; + sum = sum * Z + 793.826512519948; + sum = sum * Z + 440.413735824752; + cd = cd / sum; + } else { + sum = Z + 0.65; + sum = Z + 4 / sum; + sum = Z + 3 / sum; + sum = Z + 2 / sum; + sum = Z + 1 / sum; + cd = exp / sum / 2.506628274631; + } + } + return z > 0 ? 1 - cd : cd; + }; + f.icdf = function(p) { + // Approximation of Probit function using inverse error function. + if (p <= 0 || p >= 1) return NaN; + var x = 2*p - 1, + v = (8 * (Math.PI - 3)) / (3 * Math.PI * (4-Math.PI)), + a = (2 / (Math.PI*v)) + (Math.log(1 - Math.pow(x,2)) / 2), + b = Math.log(1 - (x*x)) / v, + s = (x > 0 ? 1 : -1) * Math.sqrt(Math.sqrt((a*a) - b) - a); + return mean + stdev * Math.SQRT2 * s; + }; + return f; + }; + + gen.random.bootstrap = function(domain, smooth) { + // Generates a bootstrap sample from a set of observations. + // Smooth bootstrapping adds random zero-centered noise to the samples. + var val = domain.filter(util.isValid), + len = val.length, + err = smooth ? gen.random.normal(0, smooth) : null; + var f = function() { + return val[~~(Math.random()*len)] + (err ? err() : 0); + }; + f.samples = function(n) { + return gen.zeros(n).map(f); + }; + return f; + }; + }); + + var stats_1 = createCommonjsModule(function (module) { + var stats = module.exports; + + // Collect unique values. + // Output: an array of unique values, in first-observed order + stats.unique = function(values, f, results) { + f = util.$(f); + results = results || []; + var u = {}, v, i, n; + for (i=0, n=values.length; i 0 ? Math.pow(mean, 1/c) : 0; + return mean; + }; + + // Compute the harmonic mean of an array of numbers. + stats.mean.harmonic = function(values, f) { + f = util.$(f); + var mean = 0, c, n, v, i; + for (i=0, c=0, n=values.length; i b) b = v; + } + } + return [a, b]; + }; + + // Find the integer indices of the minimum and maximum values. + stats.extent.index = function(values, f) { + f = util.$(f); + var x = -1, y = -1, a, b, v, i, n = values.length; + for (i=0; i b) { b = v; y = i; } + } + } + return [x, y]; + }; + + // Compute the dot product of two arrays of numbers. + stats.dot = function(values, a, b) { + var sum = 0, i, v; + if (!b) { + if (values.length !== a.length) { + throw Error('Array lengths must match.'); + } + for (i=0; i -1 && p !== v) { + mu = 1 + (i-1 + tie) / 2; + for (; tie -1) { + mu = 1 + (n-1 + tie) / 2; + for (; tie max) max = x; + delta = x - mean; + mean = mean + delta / (++valid); + M2 = M2 + delta * (x - mean); + vals.push(x); + } + } + M2 = M2 / (valid - 1); + sd = Math.sqrt(M2); + + // sort values for median and iqr + vals.sort(util.cmp); + + return { + type: type_1(values, f), + unique: u, + count: values.length, + valid: valid, + missing: missing, + distinct: distinct, + min: min, + max: max, + mean: mean, + stdev: sd, + median: (v = stats.quantile(vals, 0.5)), + q1: stats.quantile(vals, 0.25), + q3: stats.quantile(vals, 0.75), + modeskew: sd === 0 ? 0 : (mean - v) / sd + }; + }; + + // Compute profiles for all variables in a data set. + stats.summary = function(data, fields) { + fields = fields || util.keys(data[0]); + var s = fields.map(function(f) { + var p = stats.profile(data, util.$(f)); + return (p.field = f, p); + }); + return (s.__summary__ = true, s); + }; + }); + var stats_2 = stats_1.summary; + + const dlBin = bins_1; + /** + * Build a Schema object. + * + * @param data - a set of raw data in the same format that Vega-Lite / Vega takes + * Basically, it's an array in the form of: + * + * [ + * {a: 1, b:2}, + * {a: 2, b:3}, + * ... + * ] + * + * @return a Schema object + */ + function build(data, opt = {}, tableSchema = { fields: [] }) { + opt = util_5({}, DEFAULT_QUERY_CONFIG, opt); + // create profiles for each variable + let summaries = stats_2(data); + let types = type_2(data); // inferAll does stronger type inference than summary + let tableSchemaFieldIndex = tableSchema.fields.reduce((m, field) => { + m[field.name] = field; + return m; + }, {}); + let fieldSchemas = summaries.map(function (fieldProfile, index) { + const name = fieldProfile.field; + // In Table schema, 'date' doesn't include time so use 'datetime' + const type = types[name] === 'date' ? PrimitiveType.DATETIME : types[name]; + let distinct = fieldProfile.distinct; + let vlType; + if (type === PrimitiveType.NUMBER) { + vlType = QUANTITATIVE; + } + else if (type === PrimitiveType.INTEGER) { + // use ordinal or nominal when cardinality of integer type is relatively low and the distinct values are less than an amount specified in options + if (distinct < opt.numberNominalLimit && distinct / fieldProfile.count < opt.numberNominalProportion) { + vlType = NOMINAL; + } + else { + vlType = QUANTITATIVE; + } + } + else if (type === PrimitiveType.DATETIME) { + vlType = TEMPORAL; + // need to get correct min/max of date data because datalib's summary method does not + // calculate this correctly for date types. + fieldProfile.min = new Date(data[0][name]); + fieldProfile.max = new Date(data[0][name]); + for (const dataEntry of data) { + const time = new Date(dataEntry[name]).getTime(); + if (time < fieldProfile.min.getTime()) { + fieldProfile.min = new Date(time); + } + if (time > fieldProfile.max.getTime()) { + fieldProfile.max = new Date(time); + } + } + } + else { + vlType = NOMINAL; + } + if (vlType === NOMINAL && + distinct / fieldProfile.count > opt.minPercentUniqueForKey && + fieldProfile.count > opt.minCardinalityForKey) { + vlType = ExpandedType.KEY; + } + let fieldSchema = { + name: name, + // Need to keep original index for re-exporting TableSchema + originalIndex: index, + vlType: vlType, + type: type, + stats: fieldProfile, + timeStats: {}, + binStats: {} + }; + // extend field schema with table schema field - if present + const orgFieldSchema = tableSchemaFieldIndex[fieldSchema.name]; + fieldSchema = util_5(fieldSchema, orgFieldSchema); + return fieldSchema; + }); + // calculate preset bins for quantitative and temporal data + for (let fieldSchema of fieldSchemas) { + if (fieldSchema.vlType === QUANTITATIVE) { + for (let maxbins of opt.enum.binProps.maxbins) { + fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats); + } + } + else if (fieldSchema.vlType === TEMPORAL) { + for (let unit of opt.enum.timeUnit) { + if (unit !== undefined) { + fieldSchema.timeStats[unit] = timeSummary(unit, fieldSchema.stats); + } + } + } + } + const derivedTableSchema = Object.assign({}, tableSchema, { fields: fieldSchemas }); + return new Schema(derivedTableSchema); + } + // order the field schema when we construct a new Schema + // this orders the fields in the UI + const order = { + nominal: 0, + key: 1, + ordinal: 2, + temporal: 3, + quantitative: 4 + }; + class Schema { + constructor(tableSchema) { + this._tableSchema = tableSchema; + tableSchema.fields.sort(function (a, b) { + // first order by vlType: nominal < temporal < quantitative < ordinal + if (order[a.vlType] < order[b.vlType]) { + return -1; + } + else if (order[a.vlType] > order[b.vlType]) { + return 1; + } + else { + // then order by field (alphabetically) + return a.name.localeCompare(b.name); + } + }); + // Add index for sorting + tableSchema.fields.forEach((fieldSchema, index) => (fieldSchema.index = index)); + this._fieldSchemaIndex = tableSchema.fields.reduce((m, fieldSchema) => { + m[fieldSchema.name] = fieldSchema; + return m; + }, {}); + } + /** @return a list of the field names (for enumerating). */ + fieldNames() { + return this._tableSchema.fields.map(fieldSchema => fieldSchema.name); + } + /** @return a list of FieldSchemas */ + get fieldSchemas() { + return this._tableSchema.fields; + } + fieldSchema(fieldName) { + return this._fieldSchemaIndex[fieldName]; + } + tableSchema() { + // the fieldschemas are re-arranged + // but this is not allowed in table schema. + // so we will re-order based on original index. + const tableSchema = util_4(this._tableSchema); + tableSchema.fields.sort((a, b) => a.originalIndex - b.originalIndex); + return tableSchema; + } + /** + * @return primitive type of the field if exist, otherwise return null + */ + primitiveType(fieldName) { + return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].type : null; + } + /** + * @return vlType of measturement of the field if exist, otherwise return null + */ + vlType(fieldName) { + return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].vlType : null; + } + /** @return cardinality of the field associated with encQ, null if it doesn't exist. + * @param augmentTimeUnitDomain - TimeUnit field domains will not be augmented if explicitly set to false. + */ + cardinality(fieldQ, augmentTimeUnitDomain = true, excludeInvalid = false) { + const fieldSchema = this._fieldSchemaIndex[fieldQ.field]; + if (fieldQ.aggregate || (isAutoCountQuery(fieldQ) && fieldQ.autoCount)) { + return 1; + } + else if (fieldQ.bin) { + // encQ.bin will either be a boolean or a BinQuery + let bin; + if (typeof fieldQ.bin === 'boolean') { + // autoMaxBins defaults to 10 if channel is Wildcard + bin = { + maxbins: autoMaxBins(fieldQ.channel) + }; + } + else if (fieldQ.bin === '?') { + bin = { + enum: [true, false] + }; + } + else { + bin = fieldQ.bin; + } + const maxbins = bin.maxbins; + if (!fieldSchema.binStats[maxbins]) { + // need to calculate + fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats); + } + // don't need to worry about excludeInvalid here because invalid values don't affect linearly binned field's cardinality + return fieldSchema.binStats[maxbins].distinct; + } + else if (fieldQ.timeUnit) { + if (augmentTimeUnitDomain) { + switch (fieldQ.timeUnit) { + // TODO: this should not always be the case once Vega-Lite supports turning off domain augmenting (VL issue #1385) + case TimeUnit.SECONDS: + return 60; + case TimeUnit.MINUTES: + return 60; + case TimeUnit.HOURS: + return 24; + case TimeUnit.DAY: + return 7; + case TimeUnit.DATE: + return 31; + case TimeUnit.MONTH: + return 12; + case TimeUnit.QUARTER: + return 4; + case TimeUnit.MILLISECONDS: + return 1000; + } + } + let unit = fieldQ.timeUnit; + let timeStats = fieldSchema.timeStats; + // if the cardinality for the timeUnit is not cached, calculate it + if (!timeStats || !timeStats[unit]) { + timeStats = Object.assign({}, timeStats, { [unit]: timeSummary(fieldQ.timeUnit, fieldSchema.stats) }); + } + if (excludeInvalid) { + return timeStats[unit].distinct - invalidCount(timeStats[unit].unique, ['Invalid Date', null]); + } + else { + return timeStats[unit].distinct; + } + } + else { + if (fieldSchema) { + if (excludeInvalid) { + return fieldSchema.stats.distinct - invalidCount(fieldSchema.stats.unique, [NaN, null]); + } + else { + return fieldSchema.stats.distinct; + } + } + else { + return null; + } + } + } + /** + * Given an EncodingQuery with a timeUnit, returns true if the date field + * has multiple distinct values for all parts of the timeUnit. Returns undefined + * if the timeUnit is undefined. + * i.e. + * ('yearmonth', [Jan 1 2000, Feb 2 2000] returns false) + * ('yearmonth', [Jan 1 2000, Feb 2 2001] returns true) + */ + timeUnitHasVariation(fieldQ) { + if (!fieldQ.timeUnit) { + return; + } + // if there is no variation in `date`, there should not be variation in `day` + if (fieldQ.timeUnit === TimeUnit.DAY) { + const dateEncQ = util_5({}, fieldQ, { timeUnit: TimeUnit.DATE }); + if (this.cardinality(dateEncQ, false, true) <= 1) { + return false; + } + } + let fullTimeUnit = fieldQ.timeUnit; + for (let timeUnitPart of TIMEUNIT_PARTS) { + if (containsTimeUnit(fullTimeUnit, timeUnitPart)) { + // Create a clone of encQ, but with singleTimeUnit + const singleUnitEncQ = util_5({}, fieldQ, { timeUnit: timeUnitPart }); + if (this.cardinality(singleUnitEncQ, false, true) <= 1) { + return false; + } + } + } + return true; + } + domain(fieldQueryParts) { + // TODO: differentiate for field with bin / timeUnit + const fieldSchema = this._fieldSchemaIndex[fieldQueryParts.field]; + let domain = util_3(fieldSchema.stats.unique); + if (fieldSchema.vlType === QUANTITATIVE) { + // return [min, max], coerced into number types + return [+fieldSchema.stats.min, +fieldSchema.stats.max]; + } + else if (fieldSchema.type === PrimitiveType.DATETIME) { + // return [min, max] dates + return [fieldSchema.stats.min, fieldSchema.stats.max]; + } + else if (fieldSchema.type === PrimitiveType.INTEGER || fieldSchema.type === PrimitiveType.NUMBER) { + // coerce non-quantitative numerical data into number type + domain = domain.map(x => +x); + return domain.sort(util_2); + } + else if (fieldSchema.vlType === ORDINAL && fieldSchema.ordinalDomain) { + return fieldSchema.ordinalDomain; + } + return domain + .map(x => { + // Convert 'null' to null as it is encoded similarly in datalib. + // This is wrong when it is a string 'null' but that rarely happens. + return x === 'null' ? null : x; + }) + .sort(util_2); + } + /** + * @return a Summary corresponding to the field of the given EncodingQuery + */ + stats(fieldQ) { + // TODO: differentiate for field with bin / timeUnit vs without + const fieldSchema = this._fieldSchemaIndex[fieldQ.field]; + return fieldSchema ? fieldSchema.stats : null; + } + } + /** + * @return a summary of the binning scheme determined from the given max number of bins + */ + function binSummary(maxbins, summary) { + const bin = dlBin({ + min: summary.min, + max: summary.max, + maxbins: maxbins + }); + // start with summary, pre-binning + const result = util_5({}, summary); + result.unique = binUnique(bin, summary.unique); + result.distinct = (bin.stop - bin.start) / bin.step; + result.min = bin.start; + result.max = bin.stop; + return result; + } + /** @return a modified version of the passed summary with unique and distinct set according to the timeunit. + * Maps 'null' (string) keys to the null value and invalid dates to 'Invalid Date' in the unique dictionary. + */ + function timeSummary(timeunit, summary) { + const result = util_5({}, summary); + let unique = {}; + util_3(summary.unique).forEach(function (dateString) { + // don't convert null value because the Date constructor will actually convert it to a date + let date = dateString === 'null' ? null : new Date(dateString); + // at this point, `date` is either the null value, a valid Date object, or "Invalid Date" which is a Date + let key; + if (date === null) { + key = null; + } + else if (isNaN(date.getTime())) { + key = 'Invalid Date'; + } + else { + key = (timeunit === TimeUnit.DAY ? date.getDay() : convert(timeunit, date)).toString(); + } + unique[key] = (unique[key] || 0) + summary.unique[dateString]; + }); + result.unique = unique; + result.distinct = util_3(unique).length; + return result; + } + /** + * @return a new unique object based off of the old unique count and a binning scheme + */ + function binUnique(bin, oldUnique) { + const newUnique = {}; + for (let value in oldUnique) { + let bucket; + if (value === null) { + bucket = null; + } + else if (isNaN(Number(value))) { + bucket = NaN; + } + else { + bucket = bin.value(Number(value)); + } + newUnique[bucket] = (newUnique[bucket] || 0) + oldUnique[value]; + } + return newUnique; + } + /** @return the number of items in list that occur as keys of unique */ + function invalidCount(unique, list) { + return list.reduce(function (prev, cur) { + return unique[cur] ? prev + 1 : prev; + }, 0); + } + var PrimitiveType; + (function (PrimitiveType) { + PrimitiveType[PrimitiveType["STRING"] = 'string'] = "STRING"; + PrimitiveType[PrimitiveType["NUMBER"] = 'number'] = "NUMBER"; + PrimitiveType[PrimitiveType["INTEGER"] = 'integer'] = "INTEGER"; + PrimitiveType[PrimitiveType["BOOLEAN"] = 'boolean'] = "BOOLEAN"; + PrimitiveType[PrimitiveType["DATETIME"] = 'datetime'] = "DATETIME"; + })(PrimitiveType || (PrimitiveType = {})); + + var schema = /*#__PURE__*/Object.freeze({ + build: build, + Schema: Schema, + get PrimitiveType () { return PrimitiveType; } + }); + + /** + * Abstract model for a constraint. + */ + class AbstractConstraintModel { + constructor(constraint) { + this.constraint = constraint; + } + name() { + return this.constraint.name; + } + description() { + return this.constraint.description; + } + properties() { + return this.constraint.properties; + } + strict() { + return this.constraint.strict; + } + } + class EncodingConstraintModel extends AbstractConstraintModel { + constructor(constraint) { + super(constraint); + } + hasAllRequiredPropertiesSpecific(encQ) { + return every(this.constraint.properties, (prop) => { + if (isEncodingNestedProp(prop)) { + let parent = prop.parent; + let child = prop.child; + if (!encQ[parent]) { + return true; + } + return !isWildcard(encQ[parent][child]); + } + if (!encQ[prop]) { + return true; + } + return !isWildcard(encQ[prop]); + }); + } + satisfy(encQ, schema, encWildcardIndex, opt) { + // TODO: Re-order logic to optimize the "allowWildcardForProperties" check + if (!this.constraint.allowWildcardForProperties) { + // TODO: extract as a method and do unit test + if (!this.hasAllRequiredPropertiesSpecific(encQ)) { + return true; + } + } + return this.constraint.satisfy(encQ, schema, encWildcardIndex, opt); + } + } + + const FIELD_CONSTRAINTS = [ + { + name: 'aggregateOpSupportedByType', + description: 'Aggregate function should be supported by data type.', + properties: [Property.TYPE, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.aggregate) { + return !isDiscrete$1(fieldQ.type); + } + // TODO: some aggregate function are actually supported by ordinal + return true; // no aggregate is okay with any type. + } + }, + { + name: 'asteriskFieldWithCountOnly', + description: 'Field="*" should be disallowed except aggregate="count"', + properties: [Property.FIELD, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + return (fieldQ.field === '*') === (fieldQ.aggregate === 'count'); + } + }, + { + name: 'minCardinalityForBin', + description: 'binned quantitative field should not have too low cardinality', + properties: [Property.BIN, Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.bin && fieldQ.type === QUANTITATIVE) { + // We remove bin so schema can infer the raw unbinned cardinality. + let fieldQwithoutBin = { + channel: fieldQ.channel, + field: fieldQ.field, + type: fieldQ.type + }; + return schema.cardinality(fieldQwithoutBin) >= opt.minCardinalityForBin; + } + return true; + } + }, + { + name: 'binAppliedForQuantitative', + description: 'bin should be applied to quantitative field only.', + properties: [Property.TYPE, Property.BIN], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.bin) { + // If binned, the type must be quantitative + return fieldQ.type === QUANTITATIVE; + } + return true; + } + }, + { + name: 'channelFieldCompatible', + description: `encoding channel's range type be compatible with channel type.`, + properties: [Property.CHANNEL, Property.TYPE, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + const fieldDef = Object.assign({ field: 'f' }, toFieldDef(fieldQ, { schema, props: ['bin', 'timeUnit', 'type'] })); + const { compatible } = channelCompatibility(fieldDef, fieldQ.channel); + if (compatible) { + return true; + } + else { + // In VL, facet's field def must be discrete (O/N), but in CompassQL we can relax this a bit. + const isFacet = fieldQ.channel === 'row' || fieldQ.channel === 'column'; + if (isFacet && (isLocalSingleTimeUnit(fieldDef.timeUnit) || isUtcSingleTimeUnit(fieldDef.timeUnit))) { + return true; + } + return false; + } + } + }, + { + name: 'hasFn', + description: 'A field with as hasFn flag should have one of aggregate, timeUnit, or bin.', + properties: [Property.AGGREGATE, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.hasFn) { + return !!fieldQ.aggregate || !!fieldQ.bin || !!fieldQ.timeUnit; + } + return true; + } + }, + { + name: 'omitScaleZeroWithBinnedField', + description: 'Do not use scale zero with binned field', + properties: [Property.SCALE, getEncodingNestedProp('scale', 'zero'), Property.BIN], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.bin && fieldQ.scale) { + if (fieldQ.scale.zero === true) { + return false; + } + } + return true; + } + }, + { + name: 'onlyOneTypeOfFunction', + description: 'Only of of aggregate, autoCount, timeUnit, or bin should be applied at the same time.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN], + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (isFieldQuery(fieldQ)) { + const numFn = (!isWildcard(fieldQ.aggregate) && !!fieldQ.aggregate ? 1 : 0) + + (!isWildcard(fieldQ.bin) && !!fieldQ.bin ? 1 : 0) + + (!isWildcard(fieldQ.timeUnit) && !!fieldQ.timeUnit ? 1 : 0); + return numFn <= 1; + } + // For autoCount there is always only one type of function + return true; + } + }, + { + name: 'timeUnitAppliedForTemporal', + description: 'Time unit should be applied to temporal field only.', + properties: [Property.TYPE, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.timeUnit && fieldQ.type !== TEMPORAL) { + return false; + } + return true; + } + }, + { + name: 'timeUnitShouldHaveVariation', + description: 'A particular time unit should be applied only if they produce unique values.', + properties: [Property.TIMEUNIT, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (fieldQ.timeUnit && fieldQ.type === TEMPORAL) { + if (!encWildcardIndex.has('timeUnit') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + return schema.timeUnitHasVariation(fieldQ); + } + return true; + } + }, + { + name: 'scalePropertiesSupportedByScaleType', + description: 'Scale properties must be supported by correct scale type', + properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.TYPE]), + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.scale) { + const scale = fieldQ.scale; + // If fieldQ.type is an Wildcard and scale.type is undefined, it is equivalent + // to scale type is Wildcard. If scale type is an Wildcard, we do not yet know + // what the scale type is, and thus can ignore the constraint. + const sType = scaleType$1(fieldQ); + if (sType === undefined || sType === null) { + // If still ambiguous, doesn't check the constraint + return true; + } + for (let scaleProp in scale) { + if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') { + // ignore type and properties of wildcards + continue; + } + const sProp = scaleProp; + if (sType === 'point') { + // HACK: our current implementation of scaleType() can return point + // when the scaleType is a band since we didn't pass all parameter to Vega-Lite's scale type method. + if (!scaleTypeSupportProperty('point', sProp) && !scaleTypeSupportProperty('band', sProp)) { + return false; + } + } + else if (!scaleTypeSupportProperty(sType, sProp)) { + return false; + } + } + } + return true; + } + }, + { + name: 'scalePropertiesSupportedByChannel', + description: 'Not all scale properties are supported by all encoding channels', + properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.CHANNEL]), + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ) { + let channel = fieldQ.channel; + let scale = fieldQ.scale; + if (channel && !isWildcard(channel) && scale) { + if (channel === 'row' || channel === 'column') { + // row / column do not have scale + return false; + } + for (let scaleProp in scale) { + if (!scale.hasOwnProperty(scaleProp)) + continue; + if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') { + // ignore type and properties of wildcards + continue; + } + let isSupported = channelScalePropertyIncompatability(channel, scaleProp) === undefined; + if (!isSupported) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'typeMatchesPrimitiveType', + description: "Data type should be supported by field's primitive type.", + properties: [Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (fieldQ.field === '*') { + return true; + } + const primitiveType = schema.primitiveType(fieldQ.field); + const type = fieldQ.type; + if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + switch (primitiveType) { + case PrimitiveType.BOOLEAN: + case PrimitiveType.STRING: + return type !== QUANTITATIVE && type !== TEMPORAL; + case PrimitiveType.NUMBER: + case PrimitiveType.INTEGER: + return type !== TEMPORAL; + case PrimitiveType.DATETIME: + // TODO: add NOMINAL, ORDINAL support after we support this in Vega-Lite + return type === TEMPORAL; + case null: + // field does not exist in the schema + return false; + } + throw new Error('Not implemented'); + } + }, + { + name: 'typeMatchesSchemaType', + description: "Enumerated data type of a field should match the field's type in the schema.", + properties: [Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + if (fieldQ.field === '*') { + return fieldQ.type === QUANTITATIVE; + } + return schema.vlType(fieldQ.field) === fieldQ.type; + } + }, + { + name: 'maxCardinalityForCategoricalColor', + description: 'Categorical channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + // TODO: missing case where ordinal / temporal use categorical color + // (once we do so, need to add Property.BIN, Property.TIMEUNIT) + if (fieldQ.channel === COLOR && (fieldQ.type === NOMINAL || fieldQ.type === ExpandedType.KEY)) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForCategoricalColor; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'maxCardinalityForFacet', + description: 'Row/column channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.channel === ROW || fieldQ.channel === COLUMN) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForFacet; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'maxCardinalityForShape', + description: 'Shape channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.channel === SHAPE) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForShape; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'dataTypeAndFunctionMatchScaleType', + description: 'Scale type must match data type', + properties: [ + Property.TYPE, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TIMEUNIT, + Property.BIN + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.scale) { + const type = fieldQ.type; + const sType = scaleType$1(fieldQ); + if (isDiscrete$1(type)) { + return sType === undefined || hasDiscreteDomain(sType); + } + else if (type === TEMPORAL) { + if (!fieldQ.timeUnit) { + return contains$1([ScaleType.TIME, ScaleType.UTC, undefined], sType); + } + else { + return contains$1([ScaleType.TIME, ScaleType.UTC, undefined], sType) || hasDiscreteDomain(sType); + } + } + else if (type === QUANTITATIVE) { + if (fieldQ.bin) { + return contains$1([ScaleType.LINEAR, undefined], sType); + } + else { + return contains$1([ + ScaleType.LOG, + ScaleType.POW, + ScaleType.SQRT, + ScaleType.QUANTILE, + ScaleType.QUANTIZE, + ScaleType.LINEAR, + undefined + ], sType); + } + } + } + return true; + } + }, + { + name: 'stackIsOnlyUsedWithXY', + description: 'stack should only be allowed for x and y channels', + properties: [Property.STACK, Property.CHANNEL], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (!!fieldQ.stack) { + return fieldQ.channel === X || fieldQ.channel === Y; + } + return true; + } + } + ].map((ec) => new EncodingConstraintModel(ec)); + const FIELD_CONSTRAINT_INDEX = FIELD_CONSTRAINTS.reduce((m, ec) => { + m[ec.name()] = ec; + return m; + }, {}); + const FIELD_CONSTRAINTS_BY_PROPERTY = FIELD_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + // Initialize array and use it + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; + }, new PropIndex()); + + const VALUE_CONSTRAINTS = [ + { + name: 'doesNotSupportConstantValue', + description: 'row, column, x, y, order, and detail should not work with constant values.', + properties: [Property.TYPE, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (valueQ, _, __, ___) => { + return !(contains$1(['row', 'column', 'x', 'y', 'detail', 'order'], valueQ.channel)); + } + } + ].map((ec) => new EncodingConstraintModel(ec)); + const VALUE_CONSTRAINT_INDEX = VALUE_CONSTRAINTS.reduce((m, ec) => { + m[ec.name()] = ec; + return m; + }, {}); + const VALUE_CONSTRAINTS_BY_PROPERTY = VALUE_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; + }, new PropIndex()); + + /** + * Check all encoding constraints for a particular property and index tuple + */ + function checkEncoding(prop, wildcard, index, specM, schema, opt) { + // Check encoding constraint + const encodingConstraints = FIELD_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + const encQ = specM.getEncodingQueryByIndex(index); + for (const c of encodingConstraints) { + // Check if the constraint is enabled + if (c.strict() || !!opt[c.name()]) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt); + if (!satisfy) { + let violatedConstraint = '(enc) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + const valueContraints = VALUE_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + for (const c of valueContraints) { + // Check if the constraint is enabled + if ((c.strict() || !!opt[c.name()]) && isValueQuery(encQ)) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt); + if (!satisfy) { + let violatedConstraint = '(enc) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + return null; + } + + var encoding$2 = /*#__PURE__*/Object.freeze({ + checkEncoding: checkEncoding + }); + + const NONPOSITION_CHANNELS_INDEX = NONPOSITION_CHANNELS.reduce((m, channel) => { + m[channel] = true; + return m; + }, {}); + class SpecConstraintModel extends AbstractConstraintModel { + constructor(specConstraint) { + super(specConstraint); + } + hasAllRequiredPropertiesSpecific(specM) { + return every(this.constraint.properties, prop => { + if (prop === Property.MARK) { + return !isWildcard(specM.getMark()); + } + // TODO: transform + if (isEncodingNestedProp(prop)) { + let parent = prop.parent; + let child = prop.child; + return every(specM.getEncodings(), encQ => { + if (!encQ[parent]) { + return true; + } + return !isWildcard(encQ[parent][child]); + }); + } + if (!isEncodingProperty(prop)) { + throw new Error('UNIMPLEMENTED'); + } + return every(specM.getEncodings(), encQ => { + if (!encQ[prop]) { + return true; + } + return !isWildcard(encQ[prop]); + }); + }); + } + satisfy(specM, schema, opt) { + // TODO: Re-order logic to optimize the "allowWildcardForProperties" check + if (!this.constraint.allowWildcardForProperties) { + if (!this.hasAllRequiredPropertiesSpecific(specM)) { + return true; + } + } + return this.constraint.satisfy(specM, schema, opt); + } + } + const SPEC_CONSTRAINTS = [ + { + name: 'noRepeatedChannel', + description: 'Each encoding channel should only be used once.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: true, + satisfy: (specM, _, __) => { + let usedChannel = {}; + // channel for all encodings should be valid + return every(specM.getEncodings(), encQ => { + if (!isWildcard(encQ.channel)) { + // If channel is specified, it should no be used already + if (usedChannel[encQ.channel]) { + return false; + } + usedChannel[encQ.channel] = true; + return true; + } + return true; // unspecified channel is valid + }); + } + }, + { + name: 'alwaysIncludeZeroInScaleWithBarMark', + description: 'Do not recommend bar mark if scale does not start at zero', + properties: [ + Property.MARK, + Property.SCALE, + getEncodingNestedProp('scale', 'zero'), + Property.CHANNEL, + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + const encodings = specM.getEncodings(); + if (mark === BAR) { + for (let encQ of encodings) { + if (isFieldQuery(encQ) && + (encQ.channel === X || encQ.channel === Y) && + encQ.type === QUANTITATIVE && + (encQ.scale && encQ.scale.zero === false)) { + // TODO: zero shouldn't be manually specified + return false; + } + } + } + return true; + } + }, + { + name: 'autoAddCount', + description: 'Automatically adding count only for plots with only ordinal, binned quantitative, or temporal with timeunit fields.', + properties: [Property.BIN, Property.TIMEUNIT, Property.TYPE, Property.AUTOCOUNT], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + const hasAutoCount = some$1(specM.getEncodings(), (encQ) => isEnabledAutoCountQuery(encQ)); + if (hasAutoCount) { + // Auto count should only be applied if all fields are nominal, ordinal, temporal with timeUnit, binned quantitative, or autoCount + return every(specM.getEncodings(), (encQ) => { + if (isValueQuery(encQ)) { + return true; + } + if (isAutoCountQuery(encQ)) { + return true; + } + switch (encQ.type) { + case QUANTITATIVE: + return !!encQ.bin; + case TEMPORAL: + return !!encQ.timeUnit; + case ORDINAL: + case ExpandedType.KEY: + case NOMINAL: + return true; + } + /* istanbul ignore next */ + throw new Error('Unsupported Type'); + }); + } + else { + const autoCountEncIndex = specM.wildcardIndex.encodingIndicesByProperty.get('autoCount') || []; + const neverHaveAutoCount = every(autoCountEncIndex, (index) => { + let encQ = specM.getEncodingQueryByIndex(index); + return isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount); + }); + if (neverHaveAutoCount) { + // If the query surely does not have autoCount + // then one of the field should be + // (1) unbinned quantitative + // (2) temporal without time unit + // (3) nominal or ordinal field + // or at least have potential to be (still ambiguous). + return some$1(specM.getEncodings(), (encQ) => { + if ((isFieldQuery(encQ) || isAutoCountQuery(encQ)) && encQ.type === QUANTITATIVE) { + if (isDisabledAutoCountQuery(encQ)) { + return false; + } + else { + return isFieldQuery(encQ) && (!encQ.bin || isWildcard(encQ.bin)); + } + } + else if (isFieldQuery(encQ) && encQ.type === TEMPORAL) { + return !encQ.timeUnit || isWildcard(encQ.timeUnit); + } + return false; // nominal or ordinal + }); + } + } + return true; // no auto count, no constraint + } + }, + { + name: 'channelPermittedByMarkType', + description: 'Each encoding channel should be supported by the mark type', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: true, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + // if mark is unspecified, no need to check + if (isWildcard(mark)) + return true; + // TODO: can optimize this to detect only what's the changed property if needed. + return every(specM.getEncodings(), encQ => { + // channel unspecified, no need to check + if (isWildcard(encQ.channel)) + return true; + return !!supportMark(encQ.channel, mark); + }); + } + }, + { + name: 'hasAllRequiredChannelsForMark', + description: 'All required channels for the specified mark should be specified', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + switch (mark) { + case AREA: + case LINE: + return specM.channelUsed(X) && specM.channelUsed(Y); + case TEXT$1: + return specM.channelUsed(TEXT); + case BAR: + case CIRCLE: + case SQUARE: + case TICK: + case RULE: + case RECT: + return specM.channelUsed(X) || specM.channelUsed(Y); + case POINT: + // This allows generating a point plot if channel was not a wildcard. + return (!specM.wildcardIndex.hasProperty(Property.CHANNEL) || + specM.channelUsed(X) || + specM.channelUsed(Y)); + } + /* istanbul ignore next */ + throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + JSON.stringify(mark)); + } + }, + { + name: 'omitAggregate', + description: 'Omit aggregate plots.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + if (specM.isAggregate()) { + return false; + } + return true; + } + }, + { + name: 'omitAggregatePlotWithDimensionOnlyOnFacet', + description: 'Omit aggregate plots with dimensions only on facets as that leads to inefficient use of space.', + properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + let hasNonFacetDim = false, hasDim = false, hasEnumeratedFacetDim = false; + specM.specQuery.encodings.forEach((encQ, index) => { + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + return; // skip unused field + // FieldQuery & !encQ.aggregate + if (isFieldQuery(encQ) && !encQ.aggregate) { + // isDimension + hasDim = true; + if (contains$1([ROW, COLUMN], encQ.channel)) { + if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL)) { + hasEnumeratedFacetDim = true; + } + } + else { + hasNonFacetDim = true; + } + } + }); + if (hasDim && !hasNonFacetDim) { + if (hasEnumeratedFacetDim || opt.constraintManuallySpecifiedValue) { + return false; + } + } + } + return true; + } + }, + { + name: 'omitAggregatePlotWithoutDimension', + description: 'Aggregate plots without dimension should be omitted', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.BIN, Property.TIMEUNIT, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (specM.isAggregate()) { + // TODO relax + return some$1(specM.getEncodings(), (encQ) => { + if (isDimension(encQ) || (isFieldQuery(encQ) && encQ.type === 'temporal')) { + return true; + } + return false; + }); + } + return true; + } + }, + { + // TODO: we can be smarter and check if bar has occlusion based on profiling statistics + name: 'omitBarLineAreaWithOcclusion', + description: "Don't use bar, line or area to visualize raw plot as they often lead to occlusion.", + properties: [Property.MARK, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (contains$1([BAR, LINE, AREA], specM.getMark())) { + return specM.isAggregate(); + } + return true; + } + }, + { + name: 'omitBarTickWithSize', + description: 'Do not map field to size channel with bar and tick mark', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + const mark = specM.getMark(); + if (contains$1([TICK, BAR], mark)) { + if (specM.channelEncodingField(SIZE)) { + if (opt.constraintManuallySpecifiedValue) { + // If size is used and we constraintManuallySpecifiedValue, + // then the spec violates this constraint. + return false; + } + else { + // Otherwise have to search for the size channel and check if it is enumerated + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (encQ.channel === SIZE) { + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + // If enumerated, then this is bad + return false; + } + else { + // If it's manually specified, no need to continue searching, just return. + return true; + } + } + } + } + } + } + return true; // skip + } + }, + { + name: 'omitBarAreaForLogScale', + description: "Do not use bar and area mark for x and y's log scale", + properties: [ + Property.MARK, + Property.CHANNEL, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + const encodings = specM.getEncodings(); + // TODO: mark or scale type should be enumerated + if (mark === AREA || mark === BAR) { + for (let encQ of encodings) { + if (isFieldQuery(encQ) && ((encQ.channel === X || encQ.channel === Y) && encQ.scale)) { + let sType = scaleType$1(encQ); + if (sType === ScaleType.LOG) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'omitMultipleNonPositionalChannels', + description: 'Unless manually specified, do not use multiple non-positional encoding channel to avoid over-encoding.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + // have to use specM.specQuery.encodings insetad of specM.getEncodings() + // since specM.getEncodings() remove encQ with autoCount===false from the array + // and thus might shift the index + const encodings = specM.specQuery.encodings; + let nonPositionChannelCount = 0; + let hasEnumeratedNonPositionChannel = false; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) { + continue; // ignore skipped encoding + } + const channel = encQ.channel; + if (!isWildcard(channel)) { + if (NONPOSITION_CHANNELS_INDEX[channel + '']) { + nonPositionChannelCount += 1; + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + hasEnumeratedNonPositionChannel = true; + } + if (nonPositionChannelCount > 1 && + (hasEnumeratedNonPositionChannel || opt.constraintManuallySpecifiedValue)) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'omitNonPositionalOrFacetOverPositionalChannels', + description: 'Do not use non-positional channels unless all positional channels are used', + properties: [Property.CHANNEL], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + const encodings = specM.specQuery.encodings; + let hasNonPositionalChannelOrFacet = false; + let hasEnumeratedNonPositionOrFacetChannel = false; + let hasX = false, hasY = false; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) { + continue; // ignore skipped encoding + } + const channel = encQ.channel; + if (channel === X) { + hasX = true; + } + else if (channel === Y) { + hasY = true; + } + else if (!isWildcard(channel)) { + // All non positional channel / Facet + hasNonPositionalChannelOrFacet = true; + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + hasEnumeratedNonPositionOrFacetChannel = true; + } + } + } + if (hasEnumeratedNonPositionOrFacetChannel || + (opt.constraintManuallySpecifiedValue && hasNonPositionalChannelOrFacet)) { + return hasX && hasY; + } + return true; + } + }, + { + name: 'omitRaw', + description: 'Omit raw plots.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (!specM.isAggregate()) { + return false; + } + return true; + } + }, + { + name: 'omitRawContinuousFieldForAggregatePlot', + description: 'Aggregate plot should not use raw continuous field as group by values. ' + + '(Quantitative should be binned. Temporal should have time unit.)', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN, Property.TYPE], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + continue; // skip unused encoding + // TODO: aggregate for ordinal and temporal + if (isFieldQuery(encQ) && encQ.type === TEMPORAL) { + // Temporal fields should have timeUnit or is still a wildcard + if (!encQ.timeUnit && + (specM.wildcardIndex.hasEncodingProperty(i, Property.TIMEUNIT) || opt.constraintManuallySpecifiedValue)) { + return false; + } + } + if (encQ.type === QUANTITATIVE) { + if (isFieldQuery(encQ) && !encQ.bin && !encQ.aggregate) { + // If Raw Q + if (specM.wildcardIndex.hasEncodingProperty(i, Property.BIN) || + specM.wildcardIndex.hasEncodingProperty(i, Property.AGGREGATE) || + specM.wildcardIndex.hasEncodingProperty(i, Property.AUTOCOUNT)) { + // and it's raw from enumeration + return false; + } + if (opt.constraintManuallySpecifiedValue) { + // or if we constraintManuallySpecifiedValue + return false; + } + } + } + } + } + return true; + } + }, + { + name: 'omitRawDetail', + description: 'Do not use detail channel with raw plot.', + properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + return true; + } + return every(specM.specQuery.encodings, (encQ, index) => { + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + return true; // ignore autoCount field + if (encQ.channel === DETAIL) { + // Detail channel for raw plot is not good, except when its enumerated + // or when it's manually specified but we constraintManuallySpecifiedValue. + if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL) || + opt.constraintManuallySpecifiedValue) { + return false; + } + } + return true; + }); + } + }, + { + name: 'omitRepeatedField', + description: 'Each field should be mapped to only one channel', + properties: [Property.FIELD], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + let fieldUsed = {}; + let fieldEnumerated = {}; + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isAutoCountQuery(encQ)) + continue; + let field; + if (encQ.field && !isWildcard(encQ.field)) { + field = encQ.field; + } + if (isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount)) { + field = 'count_*'; + } + if (field) { + if (specM.wildcardIndex.hasEncodingProperty(i, Property.FIELD)) { + fieldEnumerated[field] = true; + } + // When the field is specified previously, + // if it is enumerated (either previously or in this encQ) + // or if the opt.constraintManuallySpecifiedValue is true, + // then it violates the constraint. + if (fieldUsed[field]) { + if (fieldEnumerated[field] || opt.constraintManuallySpecifiedValue) { + return false; + } + } + fieldUsed[field] = true; + } + } + return true; + } + }, + // TODO: omitShapeWithBin + { + name: 'omitVerticalDotPlot', + description: 'Do not output vertical dot plot.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + const encodings = specM.getEncodings(); + if (encodings.length === 1 && encodings[0].channel === Y) { + return false; + } + return true; + } + }, + // EXPENSIVE CONSTRAINTS -- check them later! + { + name: 'hasAppropriateGraphicTypeForMark', + description: 'Has appropriate graphic type for mark', + properties: [ + Property.CHANNEL, + Property.MARK, + Property.TYPE, + Property.TIMEUNIT, + Property.BIN, + Property.AGGREGATE, + Property.AUTOCOUNT + ], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + switch (mark) { + case AREA: + case LINE: + if (specM.isAggregate()) { + // TODO: refactor based on profiling statistics + const xEncQ = specM.getEncodingQueryByChannel(X); + const yEncQ = specM.getEncodingQueryByChannel(Y); + const xIsMeasure = isMeasure(xEncQ); + const yIsMeasure = isMeasure(yEncQ); + // for aggregate line / area, we need at least one group-by axis and one measure axis. + return (xEncQ && + yEncQ && + xIsMeasure !== yIsMeasure && + // and the dimension axis should not be nominal + // TODO: make this clause optional + !(isFieldQuery(xEncQ) && !xIsMeasure && contains$1(['nominal', 'key'], xEncQ.type)) && + !(isFieldQuery(yEncQ) && !yIsMeasure && contains$1(['nominal', 'key'], yEncQ.type))); + // TODO: allow connected scatterplot + } + return true; + case TEXT$1: + // FIXME correctly when we add text + return true; + case BAR: + case TICK: + // Bar and tick should not use size. + if (specM.channelEncodingField(SIZE)) { + return false; + } + else { + // Tick and Bar should have one and only one measure + const xEncQ = specM.getEncodingQueryByChannel(X); + const yEncQ = specM.getEncodingQueryByChannel(Y); + const xIsMeasure = isMeasure(xEncQ); + const yIsMeasure = isMeasure(yEncQ); + if (xIsMeasure !== yIsMeasure) { + return true; + } + return false; + } + case RECT: + // Until CompassQL supports layering, it only makes sense for + // rect to encode DxD or 1xD (otherwise just use bar). + // Furthermore, color should only be used in a 'heatmap' fashion + // (with a measure field). + const xEncQ = specM.getEncodingQueryByChannel(X); + const yEncQ = specM.getEncodingQueryByChannel(Y); + const xIsDimension = isDimension(xEncQ); + const yIsDimension = isDimension(yEncQ); + const colorEncQ = specM.getEncodingQueryByChannel(COLOR); + const colorIsQuantitative = isMeasure(colorEncQ); + const colorIsOrdinal = isFieldQuery(colorEncQ) ? colorEncQ.type === ORDINAL : false; + const correctChannels = (xIsDimension && yIsDimension) || + (xIsDimension && !specM.channelUsed(Y)) || + (yIsDimension && !specM.channelUsed(X)); + const correctColor = !colorEncQ || (colorEncQ && (colorIsQuantitative || colorIsOrdinal)); + return correctChannels && correctColor; + case CIRCLE: + case POINT: + case SQUARE: + case RULE: + return true; + } + /* istanbul ignore next */ + throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + mark); + } + }, + { + name: 'omitInvalidStackSpec', + description: 'If stack is specified, must follow Vega-Lite stack rules', + properties: [ + Property.STACK, + Property.FIELD, + Property.CHANNEL, + Property.MARK, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + if (!specM.wildcardIndex.hasProperty(Property.STACK)) { + return true; + } + const stackProps = specM.getVlStack(); + if (stackProps === null && specM.getStackOffset() !== null) { + return false; + } + if (stackProps.fieldChannel !== specM.getStackChannel()) { + return false; + } + return true; + } + }, + { + name: 'omitNonSumStack', + description: 'Stack specifications that use non-summative aggregates should be omitted (even implicit ones)', + properties: [ + Property.CHANNEL, + Property.MARK, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const specStack = specM.getVlStack(); + if (specStack != null) { + const stackParentEncQ = specM.getEncodingQueryByChannel(specStack.fieldChannel); + if (!contains$1(SUM_OPS, stackParentEncQ.aggregate)) { + return false; + } + } + return true; + } + }, + { + name: 'omitTableWithOcclusionIfAutoAddCount', + description: 'Plots without aggregation or autocount where x and y are both discrete should be omitted if autoAddCount is enabled as they often lead to occlusion', + properties: [ + Property.CHANNEL, + Property.TYPE, + Property.TIMEUNIT, + Property.BIN, + Property.AGGREGATE, + Property.AUTOCOUNT + ], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + if (opt.autoAddCount) { + const xEncQ = specM.getEncodingQueryByChannel('x'); + const yEncQ = specM.getEncodingQueryByChannel('y'); + if ((!isFieldQuery(xEncQ) || isDimension(xEncQ)) && (!isFieldQuery(yEncQ) || isDimension(yEncQ))) { + if (!specM.isAggregate()) { + return false; + } + else { + return every(specM.getEncodings(), encQ => { + let channel = encQ.channel; + if (channel !== X && + channel !== Y && + channel !== ROW && + channel !== COLUMN) { + // Non-position fields should not be unaggreated fields + if (isFieldQuery(encQ) && !encQ.aggregate) { + return false; + } + } + return true; + }); + } + } + } + return true; + } + } + ].map(sc => new SpecConstraintModel(sc)); + // For testing + const SPEC_CONSTRAINT_INDEX = SPEC_CONSTRAINTS.reduce((m, c) => { + m[c.name()] = c; + return m; + }, {}); + const SPEC_CONSTRAINTS_BY_PROPERTY = SPEC_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + // Initialize array and use it + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; + }, new PropIndex()); + /** + * Check all encoding constraints for a particular property and index tuple + */ + function checkSpec(prop, wildcard, specM, schema, opt) { + // Check encoding constraint + const specConstraints = SPEC_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + for (const c of specConstraints) { + // Check if the constraint is enabled + if (c.strict() || !!opt[c.name()]) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(specM, schema, opt); + if (!satisfy) { + let violatedConstraint = '(spec) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + return null; + } + + var spec$2 = /*#__PURE__*/Object.freeze({ + SpecConstraintModel: SpecConstraintModel, + SPEC_CONSTRAINTS: SPEC_CONSTRAINTS, + SPEC_CONSTRAINT_INDEX: SPEC_CONSTRAINT_INDEX, + checkSpec: checkSpec + }); + + + + var index$1 = /*#__PURE__*/Object.freeze({ + encoding: encoding$2, + spec: spec$2 + }); + + const ENUMERATOR_INDEX = new PropIndex(); + function getEnumerator(prop) { + return ENUMERATOR_INDEX.get(prop); + } + ENUMERATOR_INDEX.set('mark', (wildcardIndex, schema, opt) => { + return (answerSet, specM) => { + const markWildcard = specM.getMark(); + // enumerate the value + markWildcard.enum.forEach((mark) => { + specM.setMark(mark); + // Check spec constraint + const violatedSpecConstraint = checkSpec('mark', wildcardIndex.mark, specM, schema, opt); + if (!violatedSpecConstraint) { + // emit + answerSet.push(specM.duplicate()); + } + }); + // Reset to avoid side effect + specM.resetMark(); + return answerSet; + }; + }); + ENCODING_TOPLEVEL_PROPS.forEach((prop) => { + ENUMERATOR_INDEX.set(prop, EncodingPropertyGeneratorFactory(prop)); + }); + ENCODING_NESTED_PROPS.forEach((nestedProp) => { + ENUMERATOR_INDEX.set(nestedProp, EncodingPropertyGeneratorFactory(nestedProp)); + }); + /** + * @param prop property type. + * @return an answer set reducer factory for the given prop. + */ + function EncodingPropertyGeneratorFactory(prop) { + /** + * @return as reducer that takes a specQueryModel as input and output an answer set array. + */ + return (wildcardIndex, schema, opt) => { + return (answerSet, specM) => { + // index of encoding mappings that require enumeration + const indices = wildcardIndex.encodingIndicesByProperty.get(prop); + function enumerate(jobIndex) { + if (jobIndex === indices.length) { + // emit and terminate + answerSet.push(specM.duplicate()); + return; + } + const index = indices[jobIndex]; + const wildcard = wildcardIndex.encodings[index].get(prop); + const encQ = specM.getEncodingQueryByIndex(index); + const propWildcard = specM.getEncodingProperty(index, prop); + if (isValueQuery(encQ) || ( + // TODO: encQ.exclude + // If this encoding query is an excluded autoCount, there is no point enumerating other properties + // for this encoding query because they will be excluded anyway. + // Thus, we can just move on to the next encoding to enumerate. + (isDisabledAutoCountQuery(encQ)) || + // nested encoding property might have its parent set to false + // therefore, we no longer have to enumerate them + !propWildcard)) { // TODO: encQ.excluded + enumerate(jobIndex + 1); + } + else { + wildcard.enum.forEach((propVal) => { + if (propVal === null) { + // our duplicate() method use JSON.stringify, parse and thus can accidentally + // convert undefined in an array into null + propVal = undefined; + } + specM.setEncodingProperty(index, prop, propVal, wildcard); + // Check encoding constraint + const violatedEncodingConstraint = checkEncoding(prop, wildcard, index, specM, schema, opt); + if (violatedEncodingConstraint) { + return; // do not keep searching + } + // Check spec constraint + const violatedSpecConstraint = checkSpec(prop, wildcard, specM, schema, opt); + if (violatedSpecConstraint) { + return; // do not keep searching + } + // If qualify all of the constraints, keep enumerating + enumerate(jobIndex + 1); + }); + // Reset to avoid side effect + specM.resetEncodingProperty(index, prop, wildcard); + } + } + // start enumerating from 0 + enumerate(0); + return answerSet; + }; + }; + } + + var enumerator = /*#__PURE__*/Object.freeze({ + getEnumerator: getEnumerator, + EncodingPropertyGeneratorFactory: EncodingPropertyGeneratorFactory + }); + + const REPLACE_BLANK_FIELDS = { '*': '' }; + const REPLACE_XY_CHANNELS = { x: 'xy', y: 'xy' }; + const REPLACE_FACET_CHANNELS = { row: 'facet', column: 'facet' }; + const REPLACE_MARK_STYLE_CHANNELS = { color: 'style', opacity: 'style', shape: 'style', size: 'style' }; + function isExtendedGroupBy(g) { + return util_6(g) && !!g['property']; + } + function parseGroupBy(groupBy, include, replaceIndex) { + include = include || new PropIndex(); + replaceIndex = replaceIndex || new PropIndex(); + groupBy.forEach((grpBy) => { + if (isExtendedGroupBy(grpBy)) { + include.setByKey(grpBy.property, true); + replaceIndex.setByKey(grpBy.property, grpBy.replace); + } + else { + include.setByKey(grpBy, true); + } + }); + return { + include: include, + replaceIndex: replaceIndex, + replacer: getReplacerIndex(replaceIndex) + }; + } + function toString(groupBy) { + if (util_1(groupBy)) { + return groupBy.map((g) => { + if (isExtendedGroupBy(g)) { + if (g.replace) { + let replaceIndex = util_3(g.replace).reduce((index, valFrom) => { + const valTo = g.replace[valFrom]; + (index[valTo] = index[valTo] || []).push(valFrom); + return index; + }, {}); + return g.property + '[' + util_3(replaceIndex).map((valTo) => { + const valsFrom = replaceIndex[valTo].sort(); + return valsFrom.join(',') + '=>' + valTo; + }).join(';') + ']'; + } + return g.property; + } + return g; + }).join(','); + } + else { + return groupBy; + } + } + const GROUP_BY_FIELD_TRANSFORM = [ + Property.FIELD, Property.TYPE, + Property.AGGREGATE, Property.BIN, Property.TIMEUNIT, Property.STACK + ]; + const GROUP_BY_ENCODING = GROUP_BY_FIELD_TRANSFORM.concat([ + { + property: Property.CHANNEL, + replace: { + 'x': 'xy', 'y': 'xy', + 'color': 'style', 'size': 'style', 'shape': 'style', 'opacity': 'style', + 'row': 'facet', 'column': 'facet' + } + } + ]); + + var groupby = /*#__PURE__*/Object.freeze({ + REPLACE_BLANK_FIELDS: REPLACE_BLANK_FIELDS, + REPLACE_XY_CHANNELS: REPLACE_XY_CHANNELS, + REPLACE_FACET_CHANNELS: REPLACE_FACET_CHANNELS, + REPLACE_MARK_STYLE_CHANNELS: REPLACE_MARK_STYLE_CHANNELS, + isExtendedGroupBy: isExtendedGroupBy, + parseGroupBy: parseGroupBy, + toString: toString, + GROUP_BY_FIELD_TRANSFORM: GROUP_BY_FIELD_TRANSFORM, + GROUP_BY_ENCODING: GROUP_BY_ENCODING + }); + + /** + * Registry for all possible grouping key functions. + */ + let groupRegistry = {}; + /** + * Add a grouping function to the registry. + */ + function registerKeyFn(name, keyFn) { + groupRegistry[name] = keyFn; + } + const FIELD = 'field'; + const FIELD_TRANSFORM = 'fieldTransform'; + const ENCODING = 'encoding'; + const SPEC = 'spec'; + /** + * Group the input spec query model by a key function registered in the group registry + * @return + */ + function nest(specModels, queryNest) { + if (queryNest) { + const rootGroup = { + name: '', + path: '', + items: [] + }; + let groupIndex = {}; + // global `includes` and `replaces` will get augmented by each level's groupBy. + // Upper level's `groupBy` will get cascaded to lower-level groupBy. + // `replace` can be overriden in a lower-level to support different grouping. + let includes = []; + let replaces = []; + let replacers = []; + for (let l = 0; l < queryNest.length; l++) { + includes.push(l > 0 ? includes[l - 1].duplicate() : new PropIndex()); + replaces.push(l > 0 ? replaces[l - 1].duplicate() : new PropIndex()); + const groupBy = queryNest[l].groupBy; + if (util_1(groupBy)) { + // If group is array, it's an array of extended group by that need to be parsed + let parsedGroupBy = parseGroupBy(groupBy, includes[l], replaces[l]); + replacers.push(parsedGroupBy.replacer); + } + } + // With includes and replacers, now we can construct the nesting tree + specModels.forEach(specM => { + let path = ''; + let group = rootGroup; + for (let l = 0; l < queryNest.length; l++) { + const groupBy = (group.groupBy = queryNest[l].groupBy); + group.orderGroupBy = queryNest[l].orderGroupBy; + const key = util_1(groupBy) + ? spec$1(specM.specQuery, includes[l], replacers[l]) + : groupRegistry[groupBy](specM.specQuery); + path += '/' + key; + if (!groupIndex[path]) { + // this item already exists on the path + groupIndex[path] = { + name: key, + path: path, + items: [] + }; + group.items.push(groupIndex[path]); + } + group = groupIndex[path]; + } + group.items.push(specM); + }); + return rootGroup; + } + else { + // no nesting, just return a flat group + return { + name: '', + path: '', + items: specModels + }; + } + } + // TODO: move this to groupBy, rename properly, and export + const GROUP_BY_FIELD = [Property.FIELD]; + const PARSED_GROUP_BY_FIELD = parseGroupBy(GROUP_BY_FIELD); + function getGroupByKey(specM, groupBy) { + return groupRegistry[groupBy](specM); + } + registerKeyFn(FIELD, (specQ) => { + return spec$1(specQ, PARSED_GROUP_BY_FIELD.include, PARSED_GROUP_BY_FIELD.replacer); + }); + const PARSED_GROUP_BY_FIELD_TRANSFORM = parseGroupBy(GROUP_BY_FIELD_TRANSFORM); + registerKeyFn(FIELD_TRANSFORM, (specQ) => { + return spec$1(specQ, PARSED_GROUP_BY_FIELD_TRANSFORM.include, PARSED_GROUP_BY_FIELD_TRANSFORM.replacer); + }); + const PARSED_GROUP_BY_ENCODING = parseGroupBy(GROUP_BY_ENCODING); + registerKeyFn(ENCODING, (specQ) => { + return spec$1(specQ, PARSED_GROUP_BY_ENCODING.include, PARSED_GROUP_BY_ENCODING.replacer); + }); + registerKeyFn(SPEC, (specQ) => JSON.stringify(specQ)); + + var nest$1 = /*#__PURE__*/Object.freeze({ + registerKeyFn: registerKeyFn, + FIELD: FIELD, + FIELD_TRANSFORM: FIELD_TRANSFORM, + ENCODING: ENCODING, + SPEC: SPEC, + nest: nest, + getGroupByKey: getGroupByKey, + PARSED_GROUP_BY_FIELD_TRANSFORM: PARSED_GROUP_BY_FIELD_TRANSFORM, + PARSED_GROUP_BY_ENCODING: PARSED_GROUP_BY_ENCODING + }); + + class WildcardIndex { + constructor() { + this._mark = undefined; + this._encodings = {}; + this._encodingIndicesByProperty = new PropIndex(); + } + setEncodingProperty(index, prop, wildcard) { + const encodingsIndex = this._encodings; + // Init encoding index and set prop + const encIndex = encodingsIndex[index] = encodingsIndex[index] || new PropIndex(); + encIndex.set(prop, wildcard); + // Initialize indicesByProperty[prop] and add index + const indicesByProp = this._encodingIndicesByProperty; + indicesByProp.set(prop, (indicesByProp.get(prop) || [])); + indicesByProp.get(prop).push(index); + return this; + } + hasEncodingProperty(index, prop) { + return !!this._encodings[index] && this._encodings[index].has(prop); + } + hasProperty(prop) { + if (isEncodingProperty(prop)) { + return this.encodingIndicesByProperty.has(prop); + } + else if (prop === 'mark') { + return !!this.mark; + } + /* istanbul ignore next */ + throw new Error('Unimplemented for property ' + prop); + } + isEmpty() { + return !this.mark && this.encodingIndicesByProperty.size() === 0; + } + setMark(mark) { + this._mark = mark; + return this; + } + get mark() { + return this._mark; + } + get encodings() { + return this._encodings; + } + get encodingIndicesByProperty() { + return this._encodingIndicesByProperty; + } + } + + /** + * Internal class for specQuery that provides helper for the enumeration process. + */ + class SpecQueryModel { + constructor(spec, wildcardIndex, schema, opt, wildcardAssignment) { + this._rankingScore = {}; + this._spec = spec; + this._channelFieldCount = spec.encodings.reduce((m, encQ) => { + if (!isWildcard(encQ.channel) && (!isAutoCountQuery(encQ) || encQ.autoCount !== false)) { + m[encQ.channel + ''] = 1; + } + return m; + }, {}); + this._wildcardIndex = wildcardIndex; + this._assignedWildcardIndex = wildcardAssignment; + this._opt = opt; + this._schema = schema; + } + /** + * Build a WildcardIndex by detecting wildcards + * in the input specQuery and replacing short wildcards ("?") + * with full ones (objects with `name` and `enum` values). + * + * @return a SpecQueryModel that wraps the specQuery and the WildcardIndex. + */ + static build(specQ, schema, opt) { + let wildcardIndex = new WildcardIndex(); + // mark + if (isWildcard(specQ.mark)) { + const name = getDefaultName(Property.MARK); + specQ.mark = initWildcard(specQ.mark, name, opt.enum.mark); + wildcardIndex.setMark(specQ.mark); + } + // TODO: transform + // encodings + specQ.encodings.forEach((encQ, index) => { + if (isAutoCountQuery(encQ)) { + // This is only for testing purpose + console.warn('A field with autoCount should not be included as autoCount meant to be an internal object.'); + encQ.type = QUANTITATIVE; // autoCount is always quantitative + } + if (isFieldQuery(encQ) && encQ.type === undefined) { + // type is optional -- we automatically augment wildcard if not specified + encQ.type = SHORT_WILDCARD; + } + // For each property of the encodingQuery, enumerate + ENCODING_TOPLEVEL_PROPS.forEach(prop => { + if (isWildcard(encQ[prop])) { + // Assign default wildcard name and enum values. + const defaultWildcardName = getDefaultName(prop) + index; + const defaultEnumValues = getDefaultEnumValues(prop, schema, opt); + const wildcard = (encQ[prop] = initWildcard(encQ[prop], defaultWildcardName, defaultEnumValues)); + // Add index of the encoding mapping to the property's wildcard index. + wildcardIndex.setEncodingProperty(index, prop, wildcard); + } + }); + // For each nested property of the encoding query (e.g., encQ.bin.maxbins) + ENCODING_NESTED_PROPS.forEach(prop => { + const propObj = encQ[prop.parent]; // the property object e.g., encQ.bin + if (propObj) { + const child = prop.child; + if (isWildcard(propObj[child])) { + // Assign default wildcard name and enum values. + const defaultWildcardName = getDefaultName(prop) + index; + const defaultEnumValues = getDefaultEnumValues(prop, schema, opt); + const wildcard = (propObj[child] = initWildcard(propObj[child], defaultWildcardName, defaultEnumValues)); + // Add index of the encoding mapping to the property's wildcard index. + wildcardIndex.setEncodingProperty(index, prop, wildcard); + } + } + }); + }); + // AUTO COUNT + // Add Auto Count Field + if (opt.autoAddCount) { + const channel = { + name: getDefaultName(Property.CHANNEL) + specQ.encodings.length, + enum: getDefaultEnumValues(Property.CHANNEL, schema, opt) + }; + const autoCount = { + name: getDefaultName(Property.AUTOCOUNT) + specQ.encodings.length, + enum: [false, true] + }; + const countEncQ = { + channel, + autoCount, + type: QUANTITATIVE + }; + specQ.encodings.push(countEncQ); + const index = specQ.encodings.length - 1; + // Add index of the encoding mapping to the property's wildcard index. + wildcardIndex.setEncodingProperty(index, Property.CHANNEL, channel); + wildcardIndex.setEncodingProperty(index, Property.AUTOCOUNT, autoCount); + } + return new SpecQueryModel(specQ, wildcardIndex, schema, opt, {}); + } + get wildcardIndex() { + return this._wildcardIndex; + } + get schema() { + return this._schema; + } + get specQuery() { + return this._spec; + } + duplicate() { + return new SpecQueryModel(util_4(this._spec), this._wildcardIndex, this._schema, this._opt, util_4(this._assignedWildcardIndex)); + } + setMark(mark) { + const name = this._wildcardIndex.mark.name; + this._assignedWildcardIndex[name] = this._spec.mark = mark; + } + resetMark() { + const wildcard = (this._spec.mark = this._wildcardIndex.mark); + delete this._assignedWildcardIndex[wildcard.name]; + } + getMark() { + return this._spec.mark; + } + getEncodingProperty(index, prop) { + const encQ = this._spec.encodings[index]; + if (isEncodingNestedProp(prop)) { + // nested encoding property + return encQ[prop.parent][prop.child]; + } + return encQ[prop]; // encoding property (non-nested) + } + setEncodingProperty(index, prop, value, wildcard) { + const encQ = this._spec.encodings[index]; + if (prop === Property.CHANNEL && encQ.channel && !isWildcard(encQ.channel)) { + // If there is an old channel + this._channelFieldCount[encQ.channel]--; + } + if (isEncodingNestedProp(prop)) { + // nested encoding property + encQ[prop.parent][prop.child] = value; + } + else if (isEncodingNestedParent(prop) && value === true) { + encQ[prop] = util_5({}, encQ[prop], // copy all existing properties + { enum: undefined, name: undefined } // except name and values to it no longer an wildcard + ); + } + else { + // encoding property (non-nested) + encQ[prop] = value; + } + this._assignedWildcardIndex[wildcard.name] = value; + if (prop === Property.CHANNEL) { + // If there is a new channel, make sure it exists and add it to the count. + this._channelFieldCount[value] = (this._channelFieldCount[value] || 0) + 1; + } + } + resetEncodingProperty(index, prop, wildcard) { + const encQ = this._spec.encodings[index]; + if (prop === Property.CHANNEL) { + this._channelFieldCount[encQ.channel]--; + } + // reset it to wildcard + if (isEncodingNestedProp(prop)) { + // nested encoding property + encQ[prop.parent][prop.child] = wildcard; + } + else { + // encoding property (non-nested) + encQ[prop] = wildcard; + } + // add remove value that is reset from the assignment map + delete this._assignedWildcardIndex[wildcard.name]; + } + channelUsed(channel) { + // do not include encoding that has autoCount = false because it is not a part of the output spec. + return this._channelFieldCount[channel] > 0; + } + channelEncodingField(channel) { + const encodingQuery = this.getEncodingQueryByChannel(channel); + return isFieldQuery(encodingQuery); + } + getEncodings() { + // do not include encoding that has autoCount = false because it is not a part of the output spec. + return this._spec.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ)); + } + getEncodingQueryByChannel(channel) { + for (let specEncoding of this._spec.encodings) { + if (specEncoding.channel === channel) { + return specEncoding; + } + } + return undefined; + } + getEncodingQueryByIndex(i) { + return this._spec.encodings[i]; + } + isAggregate() { + return isAggregate(this._spec); + } + /** + * @return The Vega-Lite `StackProperties` object that describes the stack + * configuration of `this`. Returns `null` if this is not stackable. + */ + getVlStack() { + return getVlStack(this._spec); + } + /** + * @return The `StackOffset` specified in `this`, `undefined` if none + * is specified. + */ + getStackOffset() { + return getStackOffset(this._spec); + } + /** + * @return The `Channel` in which `stack` is specified in `this`, or + * `null` if none is specified. + */ + getStackChannel() { + return getStackChannel(this._spec); + } + toShorthand(groupBy) { + if (groupBy) { + if (util_9(groupBy)) { + return getGroupByKey(this.specQuery, groupBy); + } + const parsedGroupBy = parseGroupBy(groupBy); + return spec$1(this._spec, parsedGroupBy.include, parsedGroupBy.replacer); + } + return spec$1(this._spec); + } + /** + * Convert a query to a Vega-Lite spec if it is completed. + * @return a Vega-Lite spec if completed, null otherwise. + */ + toSpec(data) { + if (isWildcard(this._spec.mark)) + return null; + let spec = {}; + data = data || this._spec.data; + if (data) { + spec.data = data; + } + if (this._spec.transform) { + spec.transform = this._spec.transform; + } + spec.mark = this._spec.mark; + spec.encoding = toEncoding(this.specQuery.encodings, { schema: this._schema, wildcardMode: 'null' }); + if (this._spec.width) { + spec.width = this._spec.width; + } + if (this._spec.height) { + spec.height = this._spec.height; + } + if (this._spec.background) { + spec.background = this._spec.background; + } + if (this._spec.padding) { + spec.padding = this._spec.padding; + } + if (this._spec.title) { + spec.title = this._spec.title; + } + if (spec.encoding === null) { + return null; + } + if (this._spec.config || this._opt.defaultSpecConfig) + spec.config = util_5({}, this._opt.defaultSpecConfig, this._spec.config); + return spec; + } + getRankingScore(rankingName) { + return this._rankingScore[rankingName]; + } + setRankingScore(rankingName, score) { + this._rankingScore[rankingName] = score; + } + } + + var model = /*#__PURE__*/Object.freeze({ + SpecQueryModel: SpecQueryModel + }); + + + + var transform = /*#__PURE__*/Object.freeze({ + + }); + + /** + * Normalize the non-nested version of the query + * (basically when you have a `groupBy`) + * to a standardize nested. + */ + function normalize$1(q) { + if (q.groupBy) { + let nest = { + groupBy: q.groupBy + }; + if (q.orderBy) { + nest.orderGroupBy = q.orderBy; + } + let normalizedQ = { + spec: util_4(q.spec), + nest: [nest], + }; + if (q.chooseBy) { + normalizedQ.chooseBy = q.chooseBy; + } + if (q.config) { + normalizedQ.config = q.config; + } + return normalizedQ; + } + return util_4(q); // We will cause side effect to q.spec in SpecQueryModel.build + } + + + + var index$2 = /*#__PURE__*/Object.freeze({ + encoding: encoding$1, + groupBy: groupby, + shorthand: shorthand, + spec: spec, + transform: transform, + normalize: normalize$1 + }); + + function isResultTree(item) { + return item.items !== undefined; + } + function getTopResultTreeItem(specQuery) { + let topItem = specQuery.items[0]; + while (topItem && isResultTree(topItem)) { + topItem = topItem.items[0]; + } + return topItem; + } + function mapLeaves(group, f) { + return Object.assign({}, group, { items: group.items.map(item => (isResultTree(item) ? mapLeaves(item, f) : f(item))) }); + } + + var result = /*#__PURE__*/Object.freeze({ + isResultTree: isResultTree, + getTopResultTreeItem: getTopResultTreeItem, + mapLeaves: mapLeaves + }); + + class Scorer { + constructor(type) { + this.type = type; + this.scoreIndex = this.initScore(); + } + getFeatureScore(feature) { + const type = this.type; + const score = this.scoreIndex[feature]; + if (score !== undefined) { + return { type, feature, score }; + } + return undefined; + } + } + + /** + * Finer grained data types that takes binning and timeUnit into account. + */ + var ExtendedType; + (function (ExtendedType) { + ExtendedType[ExtendedType["Q"] = QUANTITATIVE] = "Q"; + ExtendedType[ExtendedType["BIN_Q"] = ('bin_' + QUANTITATIVE)] = "BIN_Q"; + ExtendedType[ExtendedType["T"] = TEMPORAL] = "T"; + /** + * Time Unit Temporal Field with time scale. + */ + ExtendedType[ExtendedType["TIMEUNIT_T"] = 'timeUnit_time'] = "TIMEUNIT_T"; + /** + * Time Unit Temporal Field with ordinal scale. + */ + ExtendedType[ExtendedType["TIMEUNIT_O"] = ('timeUnit_' + ORDINAL)] = "TIMEUNIT_O"; + ExtendedType[ExtendedType["O"] = ORDINAL] = "O"; + ExtendedType[ExtendedType["N"] = NOMINAL] = "N"; + ExtendedType[ExtendedType["K"] = ExpandedType.KEY] = "K"; + ExtendedType[ExtendedType["NONE"] = '-'] = "NONE"; + })(ExtendedType || (ExtendedType = {})); + const Q = ExtendedType.Q; + const BIN_Q = ExtendedType.BIN_Q; + const T = ExtendedType.T; + const TIMEUNIT_T = ExtendedType.TIMEUNIT_T; + const TIMEUNIT_O = ExtendedType.TIMEUNIT_O; + const O = ExtendedType.O; + const N = ExtendedType.N; + const K = ExtendedType.K; + const NONE = ExtendedType.NONE; + function getExtendedType(fieldQ) { + if (fieldQ.bin) { + return ExtendedType.BIN_Q; + } + else if (fieldQ.timeUnit) { + const sType = scaleType$1(fieldQ); + return hasDiscreteDomain(sType) ? ExtendedType.TIMEUNIT_O : ExtendedType.TIMEUNIT_T; + } + return fieldQ.type; + } + + /** + * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based) + */ + /** + * Effectiveness Score for preferred axis. + */ + class AxisScorer extends Scorer { + constructor() { + super('Axis'); + } + initScore(opt = {}) { + opt = Object.assign({}, DEFAULT_QUERY_CONFIG, opt); + let score = {}; + const preferredAxes = [ + { + feature: BIN_Q, + opt: 'preferredBinAxis' + }, + { + feature: T, + opt: 'preferredTemporalAxis' + }, + { + feature: TIMEUNIT_T, + opt: 'preferredTemporalAxis' + }, + { + feature: TIMEUNIT_O, + opt: 'preferredTemporalAxis' + }, + { + feature: O, + opt: 'preferredOrdinalAxis' + }, + { + feature: N, + opt: 'preferredNominalAxis' + } + ]; + preferredAxes.forEach(pAxis => { + if (opt[pAxis.opt] === X) { + // penalize the other axis + score[pAxis.feature + '_' + Y] = -0.01; + } + else if (opt[pAxis.opt] === Y) { + // penalize the other axis + score[pAxis.feature + '_' + X] = -0.01; + } + }); + return score; + } + featurize(type, channel) { + return type + '_' + channel; + } + getScore(specM, _, __) { + return specM.getEncodings().reduce((features, encQ) => { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { + const type = getExtendedType(encQ); + const feature = this.featurize(type, encQ.channel); + const featureScore = this.getFeatureScore(feature); + if (featureScore) { + features.push(featureScore); + } + } + return features; + }, []); + } + } + + /** + * Penalize if facet channels are the only dimensions + */ + class DimensionScorer extends Scorer { + constructor() { + super('Dimension'); + } + initScore() { + return { + row: -2, + column: -2, + color: 0, + opacity: 0, + size: 0, + shape: 0 + }; + } + getScore(specM, _, __) { + if (specM.isAggregate()) { + specM.getEncodings().reduce((maxFScore, encQ) => { + if (isAutoCountQuery(encQ) || (isFieldQuery(encQ) && !encQ.aggregate)) { // isDimension + const featureScore = this.getFeatureScore(encQ.channel + ''); + if (featureScore && featureScore.score > maxFScore.score) { + return featureScore; + } + } + return maxFScore; + }, { type: 'Dimension', feature: 'No Dimension', score: -5 }); + } + return []; + } + } + + /** + * Effective Score for preferred facet + */ + class FacetScorer extends Scorer { + constructor() { + super('Facet'); + } + initScore(opt) { + opt = Object.assign({}, DEFAULT_QUERY_CONFIG, opt); + let score = {}; + if (opt.preferredFacet === ROW) { + // penalize the other axis + score[COLUMN] = -0.01; + } + else if (opt.preferredFacet === COLUMN) { + // penalize the other axis + score[ROW] = -0.01; + } + return score; + } + getScore(specM, _, __) { + return specM.getEncodings().reduce((features, encQ) => { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { + const featureScore = this.getFeatureScore(encQ.channel); + if (featureScore) { + features.push(featureScore); + } + } + return features; + }, []); + } + } + + /** + * Effectivenss score that penalize size for bar and tick + */ + class SizeChannelScorer extends Scorer { + constructor() { + super('SizeChannel'); + } + initScore() { + return { + bar_size: -2, + tick_size: -2 + }; + } + getScore(specM, _, __) { + const mark = specM.getMark(); + return specM.getEncodings().reduce((featureScores, encQ) => { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { + const feature = mark + '_' + encQ.channel; + const featureScore = this.getFeatureScore(feature); + if (featureScore) { + featureScores.push(featureScore); + } + } + return featureScores; + }, []); + } + } + + const TERRIBLE = -10; + /** + * Effectiveness score for relationship between + * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based) + */ + class TypeChannelScorer extends Scorer { + constructor() { + super('TypeChannel'); + } + initScore() { + let SCORE = {}; + // Continuous Quantitative / Temporal Fields + const CONTINUOUS_TYPE_CHANNEL_SCORE = { + x: 0, + y: 0, + size: -0.575, + color: -0.725, + text: -2, + opacity: -3, + shape: TERRIBLE, + row: TERRIBLE, + column: TERRIBLE, + detail: 2 * TERRIBLE + }; + [Q, T, TIMEUNIT_T].forEach((type) => { + util_3(CONTINUOUS_TYPE_CHANNEL_SCORE).forEach((channel) => { + SCORE[this.featurize(type, channel)] = CONTINUOUS_TYPE_CHANNEL_SCORE[channel]; + }); + }); + // Discretized Quantitative / Temporal Fields / Ordinal + const ORDERED_TYPE_CHANNEL_SCORE = util_5({}, CONTINUOUS_TYPE_CHANNEL_SCORE, { + row: -0.75, + column: -0.75, + shape: -3.1, + text: -3.2, + detail: -4 + }); + [BIN_Q, TIMEUNIT_O, O].forEach((type) => { + util_3(ORDERED_TYPE_CHANNEL_SCORE).forEach((channel) => { + SCORE[this.featurize(type, channel)] = ORDERED_TYPE_CHANNEL_SCORE[channel]; + }); + }); + const NOMINAL_TYPE_CHANNEL_SCORE = { + x: 0, + y: 0, + color: -0.6, + shape: -0.65, + row: -0.7, + column: -0.7, + text: -0.8, + detail: -2, + size: -3, + opacity: -3.1, + }; + util_3(NOMINAL_TYPE_CHANNEL_SCORE).forEach((channel) => { + SCORE[this.featurize(N, channel)] = NOMINAL_TYPE_CHANNEL_SCORE[channel]; + SCORE[this.featurize(K, channel)] = + // Putting key on position or detail isn't terrible + contains$1(['x', 'y', 'detail'], channel) ? -1 : + NOMINAL_TYPE_CHANNEL_SCORE[channel] - 2; + }); + return SCORE; + } + featurize(type, channel) { + return type + '_' + channel; + } + getScore(specM, schema, opt) { + const encodingQueryByField = specM.getEncodings().reduce((m, encQ) => { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { + const fieldKey = fieldDef(encQ); + (m[fieldKey] = m[fieldKey] || []).push(encQ); + } + return m; + }, {}); + const features = []; + forEach(encodingQueryByField, (encQs) => { + const bestFieldFeature = encQs.reduce((best, encQ) => { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { + const type = getExtendedType(encQ); + const feature = this.featurize(type, encQ.channel); + const featureScore = this.getFeatureScore(feature); + if (best === null || featureScore.score > best.score) { + return featureScore; + } + } + return best; + }, null); + features.push(bestFieldFeature); + // TODO: add plus for over-encoding of one field + }); + return features; + } + } + + class MarkScorer extends Scorer { + constructor() { + super('Mark'); + } + initScore() { + return init(); + } + getScore(specM, _, __) { + let mark = specM.getMark(); + if (mark === CIRCLE || mark === SQUARE) { + mark = POINT; + } + const xEncQ = specM.getEncodingQueryByChannel(X); + const xType = xEncQ ? getExtendedType(xEncQ) : NONE; + const yEncQ = specM.getEncodingQueryByChannel(Y); + const yType = yEncQ ? getExtendedType(yEncQ) : NONE; + const isOccluded = !specM.isAggregate(); // FIXME + const feature = xType + '_' + yType + '_' + isOccluded + '_' + mark; + const featureScore = this.getFeatureScore(feature); + if (featureScore) { + return [featureScore]; + } + console.error('feature score missing for', feature); + return []; + } + } + function featurize(xType, yType, hasOcclusion, mark) { + return xType + '_' + yType + '_' + hasOcclusion + '_' + mark; + } + function init() { + const MEASURES = [Q, T]; + const DISCRETE = [BIN_Q, TIMEUNIT_O, O, N, K]; + const DISCRETE_OR_NONE = DISCRETE.concat([NONE]); + let SCORE = {}; + // QxQ + MEASURES.forEach(xType => { + MEASURES.forEach(yType => { + // has occlusion + const occludedQQMark = { + point: 0, + text: -0.2, + tick: -0.5, + rect: -1, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + forEach(occludedQQMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + }); + // no occlusion + // TODO: possible to use connected scatter plot + const noOccludedQQMark = { + point: 0, + text: -0.2, + tick: -0.5, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + forEach(noOccludedQQMark, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + }); + }); + }); + // DxQ, QxD + MEASURES.forEach(xType => { + // HAS OCCLUSION + DISCRETE_OR_NONE.forEach(yType => { + const occludedDimensionMeasureMark = { + tick: 0, + point: -0.2, + text: -0.5, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + forEach(occludedDimensionMeasureMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + // also do the inverse + const feature2 = featurize(yType, xType, true, mark); + SCORE[feature2] = score; + }); + }); + [TIMEUNIT_T].forEach(yType => { + const occludedDimensionMeasureMark = { + // For Time Dimension with time scale, tick is not good + point: 0, + text: -0.5, + tick: -1, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + forEach(occludedDimensionMeasureMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + // also do the inverse + const feature2 = featurize(yType, xType, true, mark); + SCORE[feature2] = score; + }); + }); + // NO OCCLUSION + [NONE, N, O, K].forEach(yType => { + const noOccludedQxN = { + bar: 0, + point: -0.2, + tick: -0.25, + text: -0.3, + // Line / Area can mislead trend for N + line: -2, + area: -2, + // Non-sense to use rule here + rule: -2.5 + }; + forEach(noOccludedQxN, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + // also do the inverse + const feature2 = featurize(yType, xType, false, mark); + SCORE[feature2] = score; + }); + }); + [BIN_Q].forEach(yType => { + const noOccludedQxBinQ = { + bar: 0, + point: -0.2, + tick: -0.25, + text: -0.3, + // Line / Area isn't the best fit for bin + line: -0.5, + area: -0.5, + // Non-sense to use rule here + rule: -2.5 + }; + forEach(noOccludedQxBinQ, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + // also do the inverse + const feature2 = featurize(yType, xType, false, mark); + SCORE[feature2] = score; + }); + }); + [TIMEUNIT_T, TIMEUNIT_O].forEach(yType => { + // For aggregate / surely no occlusion plot, Temporal with time or ordinal + // are not that different. + const noOccludedQxBinQ = { + line: 0, + area: -0.1, + bar: -0.2, + point: -0.3, + tick: -0.35, + text: -0.4, + // Non-sense to use rule here + rule: -2.5 + }; + forEach(noOccludedQxBinQ, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + // also do the inverse + const feature2 = featurize(yType, xType, false, mark); + SCORE[feature2] = score; + }); + }); + }); + [TIMEUNIT_T].forEach(xType => { + [TIMEUNIT_T].forEach(yType => { + // has occlusion + const ttMark = { + point: 0, + rect: -0.1, + text: -0.5, + tick: -1, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + // No difference between has occlusion and no occlusion + // as most of the time, it will be the occluded case. + forEach(ttMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + }); + forEach(ttMark, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + }); + }); + DISCRETE_OR_NONE.forEach(yType => { + // has occlusion + const tdMark = { + tick: 0, + point: -0.2, + text: -0.5, + rect: -1, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + // No difference between has occlusion and no occlusion + // as most of the time, it will be the occluded case. + forEach(tdMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + }); + forEach(tdMark, (score, mark) => { + const feature = featurize(yType, xType, true, mark); + SCORE[feature] = score; + }); + forEach(tdMark, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + }); + forEach(tdMark, (score, mark) => { + const feature = featurize(yType, xType, false, mark); + SCORE[feature] = score; + }); + }); + }); + // DxD + // Note: We use for loop here because using forEach sometimes leads to a mysterious bug + for (const xType of DISCRETE_OR_NONE) { + for (const yType of DISCRETE_OR_NONE) { + // has occlusion + const ddMark = { + point: 0, + rect: 0, + text: -0.1, + tick: -1, + bar: -2, + line: -2, + area: -2, + rule: -2.5 + }; + forEach(ddMark, (score, mark) => { + const feature = featurize(xType, yType, true, mark); + SCORE[feature] = score; + }); + // same for no occlusion. + forEach(ddMark, (score, mark) => { + const feature = featurize(xType, yType, false, mark); + SCORE[feature] = score; + }); + } + } + return SCORE; + } + + const SCORERS = [ + new AxisScorer(), + new DimensionScorer(), + new FacetScorer(), + new MarkScorer(), + new SizeChannelScorer(), + new TypeChannelScorer() + ]; + // TODO: x/y, row/column preference + // TODO: stacking + // TODO: Channel, Cardinality + // TODO: Penalize over encoding + function effectiveness(specM, schema, opt) { + const features = SCORERS.reduce((f, scorer) => { + const scores = scorer.getScore(specM, schema, opt); + return f.concat(scores); + }, []); + return { + score: features.reduce((s, f) => { + return s + f.score; + }, 0), + features: features + }; + } + + const name = 'aggregationQuality'; + function score(specM, schema, opt) { + const feature = aggregationQualityFeature(specM, schema, opt); + return { + score: feature.score, + features: [feature] + }; + } + function aggregationQualityFeature(specM, _, __) { + const encodings = specM.getEncodings(); + if (specM.isAggregate()) { + const isRawContinuous = (encQ) => { + return (isFieldQuery(encQ) && + ((encQ.type === QUANTITATIVE && !encQ.bin && !encQ.aggregate) || + (encQ.type === TEMPORAL && !encQ.timeUnit))); + }; + if (some$1(encodings, isRawContinuous)) { + // These are plots that pollute continuous fields as dimension. + // They are often intermediate visualizations rather than what users actually want. + return { + type: name, + score: 0.1, + feature: 'Aggregate with raw continuous' + }; + } + if (some$1(encodings, encQ => isFieldQuery(encQ) && isDimension(encQ))) { + let hasCount = some$1(encodings, (encQ) => { + return (isFieldQuery(encQ) && encQ.aggregate === 'count') || isEnabledAutoCountQuery(encQ); + }); + let hasBin = some$1(encodings, (encQ) => { + return isFieldQuery(encQ) && !!encQ.bin; + }); + if (hasCount) { + // If there is count, we might add additional count field, making it a little less simple + // then when we just apply aggregate to Q field + return { + type: name, + score: 0.8, + feature: 'Aggregate with count' + }; + } + else if (hasBin) { + // This is not as good as binning all the Q and show heatmap + return { + type: name, + score: 0.7, + feature: 'Aggregate with bin but without count' + }; + } + else { + return { + type: name, + score: 0.9, + feature: 'Aggregate without count and without bin' + }; + } + } + // no dimension -- often not very useful + return { + type: name, + score: 0.3, + feature: 'Aggregate without dimension' + }; + } + else { + if (some$1(encodings, encQ => isFieldQuery(encQ) && !isDimension(encQ))) { + // raw plots with measure -- simplest of all! + return { + type: name, + score: 1, + feature: 'Raw with measure' + }; + } + // raw plots with no measure -- often a lot of occlusion + return { + type: name, + score: 0.2, + feature: 'Raw without measure' + }; + } + } + + var aggregation = /*#__PURE__*/Object.freeze({ + name: name, + score: score + }); + + const name$1 = 'fieldOrder'; + /** + * Return ranking score based on indices of encoded fields in the schema. + * If there are multiple fields, prioritize field on the lower indices of encodings. + * + * For example, to compare two specs with two encodings each, + * first we compare the field on the 0-th index + * and only compare the field on the 1-th index only if the fields on the 0-th index are the same. + */ + function score$1(specM, schema, _) { + const fieldWildcardIndices = specM.wildcardIndex.encodingIndicesByProperty.get('field'); + if (!fieldWildcardIndices) { + return { + score: 0, + features: [] + }; + } + const encodings = specM.specQuery.encodings; + const numFields = schema.fieldSchemas.length; + const features = []; + let totalScore = 0, base = 1; + for (let i = fieldWildcardIndices.length - 1; i >= 0; i--) { + const index = fieldWildcardIndices[i]; + const encoding = encodings[index]; + // Skip ValueQuery as we only care about order of fields. + let field; + if (isFieldQuery(encoding)) { + field = encoding.field; + } + else { // ignore ValueQuery / AutoCountQuery + continue; + } + const fieldWildcard = specM.wildcardIndex.encodings[index].get('field'); + const fieldIndex = schema.fieldSchema(field).index; + // reverse order field with lower index should get higher score and come first + const score = -fieldIndex * base; + totalScore += score; + features.push({ + score: score, + type: 'fieldOrder', + feature: `field ${fieldWildcard.name} is ${field} (#${fieldIndex} in the schema)` + }); + base *= numFields; + } + return { + score: totalScore, + features: features + }; + } + + var fieldorder = /*#__PURE__*/Object.freeze({ + name: name$1, + score: score$1 + }); + + /** + * Registry for all encoding ranking functions + */ + let rankingRegistry = {}; + /** + * Add an ordering function to the registry. + */ + function register(name, keyFn) { + rankingRegistry[name] = keyFn; + } + function get(name) { + return rankingRegistry[name]; + } + function rank(group, query, schema, level) { + if (!query.nest || level === query.nest.length) { + if (query.orderBy || query.chooseBy) { + group.items.sort(comparatorFactory(query.orderBy || query.chooseBy, schema, query.config)); + if (query.chooseBy) { + if (group.items.length > 0) { + // for chooseBy -- only keep the top-item + group.items.splice(1); + } + } + } + } + else { + // sort lower-level nodes first because our ranking takes top-item in the subgroup + group.items.forEach((subgroup) => { + rank(subgroup, query, schema, level + 1); + }); + if (query.nest[level].orderGroupBy) { + group.items.sort(groupComparatorFactory(query.nest[level].orderGroupBy, schema, query.config)); + } + } + return group; + } + function comparatorFactory(name, schema, opt) { + return (m1, m2) => { + if (name instanceof Array) { + return getScoreDifference(name, m1, m2, schema, opt); + } + else { + return getScoreDifference([name], m1, m2, schema, opt); + } + }; + } + function groupComparatorFactory(name, schema, opt) { + return (g1, g2) => { + const m1 = getTopResultTreeItem(g1); + const m2 = getTopResultTreeItem(g2); + if (name instanceof Array) { + return getScoreDifference(name, m1, m2, schema, opt); + } + else { + return getScoreDifference([name], m1, m2, schema, opt); + } + }; + } + function getScoreDifference(name, m1, m2, schema, opt) { + for (let rankingName of name) { + let scoreDifference = getScore(m2, rankingName, schema, opt).score - getScore(m1, rankingName, schema, opt).score; + if (scoreDifference !== 0) { + return scoreDifference; + } + } + return 0; + } + function getScore(model, rankingName, schema, opt) { + if (model.getRankingScore(rankingName) !== undefined) { + return model.getRankingScore(rankingName); + } + const fn = get(rankingName); + const score = fn(model, schema, opt); + model.setRankingScore(rankingName, score); + return score; + } + const EFFECTIVENESS = 'effectiveness'; + register(EFFECTIVENESS, effectiveness); + register(name, score); + register(name$1, score$1); + + var ranking = /*#__PURE__*/Object.freeze({ + aggregation: aggregation, + fieldOrder: fieldorder, + register: register, + get: get, + rank: rank, + comparatorFactory: comparatorFactory, + groupComparatorFactory: groupComparatorFactory, + getScore: getScore, + EFFECTIVENESS: EFFECTIVENESS, + effectiveness: effectiveness + }); + + function stylize(answerSet, schema, opt) { + let encQIndex = {}; + answerSet = answerSet.map(function (specM) { + if (opt.smallRangeStepForHighCardinalityOrFacet) { + specM = smallRangeStepForHighCardinalityOrFacet(specM, schema, encQIndex, opt); + } + if (opt.nominalColorScaleForHighCardinality) { + specM = nominalColorScaleForHighCardinality(specM, schema, encQIndex, opt); + } + if (opt.xAxisOnTopForHighYCardinalityWithoutColumn) { + specM = xAxisOnTopForHighYCardinalityWithoutColumn(specM, schema, encQIndex, opt); + } + return specM; + }); + return answerSet; + } + function smallRangeStepForHighCardinalityOrFacet(specM, schema, encQIndex, opt) { + [ROW, Y, COLUMN, X].forEach(channel => { + encQIndex[channel] = specM.getEncodingQueryByChannel(channel); + }); + const yEncQ = encQIndex[Y]; + if (yEncQ !== undefined && isFieldQuery(yEncQ)) { + if (encQIndex[ROW] || + schema.cardinality(yEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality) { + // We check for undefined rather than + // yEncQ.scale = yEncQ.scale || {} to cover the case where + // yEncQ.scale has been set to false/null. + // This prevents us from incorrectly overriding scale and + // assigning a rangeStep when scale is set to false. + if (yEncQ.scale === undefined) { + yEncQ.scale = {}; + } + // We do not want to assign a rangeStep if scale is set to false + // and we only apply this if the scale is (or can be) an ordinal scale. + const yScaleType = scaleType$1(yEncQ); + if (yEncQ.scale && (yScaleType === undefined || hasDiscreteDomain(yScaleType))) { + if (!yEncQ.scale.rangeStep) { + yEncQ.scale.rangeStep = 12; + } + } + } + } + const xEncQ = encQIndex[X]; + if (isFieldQuery(xEncQ)) { + if (encQIndex[COLUMN] || + schema.cardinality(xEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality) { + // Just like y, we don't want to do this if scale is null/false + if (xEncQ.scale === undefined) { + xEncQ.scale = {}; + } + // We do not want to assign a rangeStep if scale is set to false + // and we only apply this if the scale is (or can be) an ordinal scale. + const xScaleType = scaleType$1(xEncQ); + if (xEncQ.scale && (xScaleType === undefined || hasDiscreteDomain(xScaleType))) { + if (!xEncQ.scale.rangeStep) { + xEncQ.scale.rangeStep = 12; + } + } + } + } + return specM; + } + function nominalColorScaleForHighCardinality(specM, schema, encQIndex, opt) { + encQIndex[COLOR] = specM.getEncodingQueryByChannel(COLOR); + const colorEncQ = encQIndex[COLOR]; + if (isFieldQuery(colorEncQ) && + colorEncQ !== undefined && + (colorEncQ.type === NOMINAL || colorEncQ.type === ExpandedType.KEY) && + schema.cardinality(colorEncQ) > opt.nominalColorScaleForHighCardinality.maxCardinality) { + if (colorEncQ.scale === undefined) { + colorEncQ.scale = {}; + } + if (colorEncQ.scale) { + if (!colorEncQ.scale.range) { + colorEncQ.scale.scheme = opt.nominalColorScaleForHighCardinality.palette; + } + } + } + return specM; + } + function xAxisOnTopForHighYCardinalityWithoutColumn(specM, schema, encQIndex, opt) { + [COLUMN, X, Y].forEach(channel => { + encQIndex[channel] = specM.getEncodingQueryByChannel(channel); + }); + if (encQIndex[COLUMN] === undefined) { + const xEncQ = encQIndex[X]; + const yEncQ = encQIndex[Y]; + if (isFieldQuery(xEncQ) && + isFieldQuery(yEncQ) && + yEncQ !== undefined && + yEncQ.field && + hasDiscreteDomain(scaleType$1(yEncQ))) { + if (xEncQ !== undefined) { + if (schema.cardinality(yEncQ) > opt.xAxisOnTopForHighYCardinalityWithoutColumn.maxCardinality) { + if (xEncQ.axis === undefined) { + xEncQ.axis = {}; + } + if (xEncQ.axis && !xEncQ.axis.orient) { + xEncQ.axis.orient = 'top'; + } + } + } + } + } + return specM; + } + + function generate$1(specQ, schema, opt = DEFAULT_QUERY_CONFIG) { + // 1. Build a SpecQueryModel, which also contains wildcardIndex + const specM = SpecQueryModel.build(specQ, schema, opt); + const wildcardIndex = specM.wildcardIndex; + // 2. Enumerate each of the properties based on propPrecedence. + let answerSet = [specM]; // Initialize Answer Set with only the input spec query. + opt.propertyPrecedence.forEach((propKey) => { + const prop = fromKey(propKey); + // If the original specQuery contains wildcard for this prop + if (wildcardIndex.hasProperty(prop)) { + // update answerset + const enumerator = getEnumerator(prop); + const reducer = enumerator(wildcardIndex, schema, opt); + answerSet = answerSet.reduce(reducer, []); + } + }); + if (opt.stylize) { + if ((opt.nominalColorScaleForHighCardinality !== null) || + (opt.smallRangeStepForHighCardinalityOrFacet !== null) || + (opt.xAxisOnTopForHighYCardinalityWithoutColumn !== null)) { + return stylize(answerSet, schema, opt); + } + } + return answerSet; + } + + function recommend(q, schema, config) { + // 1. Normalize non-nested `groupBy` to always have `groupBy` inside `nest` + // and merge config with the following precedence + // query.config > config > DEFAULT_QUERY_CONFIG + q = Object.assign({}, normalize$1(q), { config: Object.assign({}, DEFAULT_QUERY_CONFIG, config, q.config) }); + // 2. Generate + const answerSet = generate$1(q.spec, schema, q.config); + const nestedAnswerSet = nest(answerSet, q.nest); + const result = rank(nestedAnswerSet, q, schema, 0); + return { + query: q, + result: result + }; + } + + var version = "0.21.1"; + + /// + + exports.config = config; + exports.constraint = index$1; + exports.enumerate = enumerator; + exports.generate = generate$1; + exports.model = model; + exports.nest = nest$1; + exports.property = property; + exports.query = index$2; + exports.ranking = ranking; + exports.recommend = recommend; + exports.result = result; + exports.schema = schema; + exports.util = util$1; + exports.version = version; + exports.wildcard = wildcard; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); +//# sourceMappingURL=compassql.js.map diff --git a/build/compassql.js.map b/build/compassql.js.map new file mode 100644 index 00000000..4829b6b0 --- /dev/null +++ b/build/compassql.js.map @@ -0,0 +1 @@ +{"version":3,"file":"compassql.js","sources":["../node_modules/tslib/tslib.es6.js","../node_modules/clone/clone.js","../node_modules/fast-json-stable-stringify/index.js","../node_modules/vega-util/src/accessor.js","../node_modules/vega-util/src/error.js","../node_modules/vega-util/src/splitAccessPath.js","../node_modules/vega-util/src/isArray.js","../node_modules/vega-util/src/isObject.js","../node_modules/vega-util/src/isString.js","../node_modules/vega-util/src/stringValue.js","../node_modules/vega-util/src/field.js","../node_modules/vega-util/src/accessors.js","../node_modules/vega-util/src/logger.js","../node_modules/vega-util/src/clampRange.js","../node_modules/vega-util/src/extent.js","../node_modules/vega-util/src/inrange.js","../node_modules/vega-util/src/isBoolean.js","../node_modules/vega-util/src/isNumber.js","../node_modules/vega-util/src/toSet.js","../node_modules/vega-lite/src/util.ts","../node_modules/vega-lite/src/channel.ts","../node_modules/vega-lite/src/axis.ts","../node_modules/vega-lite/src/legend.ts","../node_modules/vega-lite/src/log/message.ts","../node_modules/vega-lite/src/log/index.ts","../node_modules/vega-lite/src/type.ts","../node_modules/vega-lite/src/scale.ts","../src/property.ts","../node_modules/vega-lite/src/mark.ts","../node_modules/vega-lite/src/datetime.ts","../node_modules/vega-lite/src/timeunit.ts","../node_modules/datalib/src/util.js","../src/util.ts","../src/wildcard.ts","../src/config.ts","../node_modules/vega-lite/src/aggregate.ts","../node_modules/vega-lite/src/bin.ts","../node_modules/vega-lite/src/spec/facet.ts","../node_modules/vega-lite/src/channeldef.ts","../node_modules/vega-lite/src/compile/scale/type.ts","../src/query/expandedtype.ts","../src/propindex.ts","../node_modules/vega-lite/src/encoding.ts","../node_modules/vega-lite/src/stack.ts","../src/query/spec.ts","../src/query/shorthand.ts","../src/query/encoding.ts","../node_modules/d3-time/build/d3-time.js","../node_modules/datalib/src/time.js","../node_modules/datalib/src/bins/bins.js","../node_modules/datalib/src/import/type.js","../node_modules/datalib/src/generate.js","../node_modules/datalib/src/stats.js","../src/schema.ts","../src/constraint/base.ts","../src/constraint/field.ts","../src/constraint/value.ts","../src/constraint/encoding.ts","../src/constraint/spec.ts","../src/enumerator.ts","../src/query/groupby.ts","../src/nest.ts","../src/wildcardindex.ts","../src/model.ts","../src/query/normalize.ts","../src/result.ts","../src/ranking/effectiveness/base.ts","../src/ranking/effectiveness/type.ts","../src/ranking/effectiveness/axis.ts","../src/ranking/effectiveness/dimension.ts","../src/ranking/effectiveness/facet.ts","../src/ranking/effectiveness/sizechannel.ts","../src/ranking/effectiveness/typechannel.ts","../src/ranking/effectiveness/mark.ts","../src/ranking/effectiveness/index.ts","../src/ranking/aggregation.ts","../src/ranking/fieldorder.ts","../src/ranking/ranking.ts","../src/stylize.ts","../src/generate.ts","../src/recommend.ts","../src/index.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","var clone = (function() {\n'use strict';\n\nfunction _instanceof(obj, type) {\n return type != null && obj instanceof type;\n}\n\nvar nativeMap;\ntry {\n nativeMap = Map;\n} catch(_) {\n // maybe a reference error because no `Map`. Give it a dummy value that no\n // value will ever be an instanceof.\n nativeMap = function() {};\n}\n\nvar nativeSet;\ntry {\n nativeSet = Set;\n} catch(_) {\n nativeSet = function() {};\n}\n\nvar nativePromise;\ntry {\n nativePromise = Promise;\n} catch(_) {\n nativePromise = function() {};\n}\n\n/**\n * Clones (copies) an Object using deep copying.\n *\n * This function supports circular references by default, but if you are certain\n * there are no circular references in your object, you can save some CPU time\n * by calling clone(obj, false).\n *\n * Caution: if `circular` is false and `parent` contains circular references,\n * your program may enter an infinite loop and crash.\n *\n * @param `parent` - the object to be cloned\n * @param `circular` - set to true if the object to be cloned may contain\n * circular references. (optional - true by default)\n * @param `depth` - set to a number if the object is only to be cloned to\n * a particular depth. (optional - defaults to Infinity)\n * @param `prototype` - sets the prototype to be used when cloning an object.\n * (optional - defaults to parent prototype).\n * @param `includeNonEnumerable` - set to true if the non-enumerable properties\n * should be cloned as well. Non-enumerable properties on the prototype\n * chain will be ignored. (optional - false by default)\n*/\nfunction clone(parent, circular, depth, prototype, includeNonEnumerable) {\n if (typeof circular === 'object') {\n depth = circular.depth;\n prototype = circular.prototype;\n includeNonEnumerable = circular.includeNonEnumerable;\n circular = circular.circular;\n }\n // maintain two arrays for circular references, where corresponding parents\n // and children have the same index\n var allParents = [];\n var allChildren = [];\n\n var useBuffer = typeof Buffer != 'undefined';\n\n if (typeof circular == 'undefined')\n circular = true;\n\n if (typeof depth == 'undefined')\n depth = Infinity;\n\n // recurse this function so we don't reset allParents and allChildren\n function _clone(parent, depth) {\n // cloning null always returns null\n if (parent === null)\n return null;\n\n if (depth === 0)\n return parent;\n\n var child;\n var proto;\n if (typeof parent != 'object') {\n return parent;\n }\n\n if (_instanceof(parent, nativeMap)) {\n child = new nativeMap();\n } else if (_instanceof(parent, nativeSet)) {\n child = new nativeSet();\n } else if (_instanceof(parent, nativePromise)) {\n child = new nativePromise(function (resolve, reject) {\n parent.then(function(value) {\n resolve(_clone(value, depth - 1));\n }, function(err) {\n reject(_clone(err, depth - 1));\n });\n });\n } else if (clone.__isArray(parent)) {\n child = [];\n } else if (clone.__isRegExp(parent)) {\n child = new RegExp(parent.source, __getRegExpFlags(parent));\n if (parent.lastIndex) child.lastIndex = parent.lastIndex;\n } else if (clone.__isDate(parent)) {\n child = new Date(parent.getTime());\n } else if (useBuffer && Buffer.isBuffer(parent)) {\n if (Buffer.allocUnsafe) {\n // Node.js >= 4.5.0\n child = Buffer.allocUnsafe(parent.length);\n } else {\n // Older Node.js versions\n child = new Buffer(parent.length);\n }\n parent.copy(child);\n return child;\n } else if (_instanceof(parent, Error)) {\n child = Object.create(parent);\n } else {\n if (typeof prototype == 'undefined') {\n proto = Object.getPrototypeOf(parent);\n child = Object.create(proto);\n }\n else {\n child = Object.create(prototype);\n proto = prototype;\n }\n }\n\n if (circular) {\n var index = allParents.indexOf(parent);\n\n if (index != -1) {\n return allChildren[index];\n }\n allParents.push(parent);\n allChildren.push(child);\n }\n\n if (_instanceof(parent, nativeMap)) {\n parent.forEach(function(value, key) {\n var keyChild = _clone(key, depth - 1);\n var valueChild = _clone(value, depth - 1);\n child.set(keyChild, valueChild);\n });\n }\n if (_instanceof(parent, nativeSet)) {\n parent.forEach(function(value) {\n var entryChild = _clone(value, depth - 1);\n child.add(entryChild);\n });\n }\n\n for (var i in parent) {\n var attrs;\n if (proto) {\n attrs = Object.getOwnPropertyDescriptor(proto, i);\n }\n\n if (attrs && attrs.set == null) {\n continue;\n }\n child[i] = _clone(parent[i], depth - 1);\n }\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(parent);\n for (var i = 0; i < symbols.length; i++) {\n // Don't need to worry about cloning a symbol because it is a primitive,\n // like a number or string.\n var symbol = symbols[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);\n if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {\n continue;\n }\n child[symbol] = _clone(parent[symbol], depth - 1);\n if (!descriptor.enumerable) {\n Object.defineProperty(child, symbol, {\n enumerable: false\n });\n }\n }\n }\n\n if (includeNonEnumerable) {\n var allPropertyNames = Object.getOwnPropertyNames(parent);\n for (var i = 0; i < allPropertyNames.length; i++) {\n var propertyName = allPropertyNames[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);\n if (descriptor && descriptor.enumerable) {\n continue;\n }\n child[propertyName] = _clone(parent[propertyName], depth - 1);\n Object.defineProperty(child, propertyName, {\n enumerable: false\n });\n }\n }\n\n return child;\n }\n\n return _clone(parent, depth);\n}\n\n/**\n * Simple flat clone using prototype, accepts only objects, usefull for property\n * override on FLAT configuration object (no nested props).\n *\n * USE WITH CAUTION! This may not behave as you wish if you do not know how this\n * works.\n */\nclone.clonePrototype = function clonePrototype(parent) {\n if (parent === null)\n return null;\n\n var c = function () {};\n c.prototype = parent;\n return new c();\n};\n\n// private utility functions\n\nfunction __objToStr(o) {\n return Object.prototype.toString.call(o);\n}\nclone.__objToStr = __objToStr;\n\nfunction __isDate(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Date]';\n}\nclone.__isDate = __isDate;\n\nfunction __isArray(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Array]';\n}\nclone.__isArray = __isArray;\n\nfunction __isRegExp(o) {\n return typeof o === 'object' && __objToStr(o) === '[object RegExp]';\n}\nclone.__isRegExp = __isRegExp;\n\nfunction __getRegExpFlags(re) {\n var flags = '';\n if (re.global) flags += 'g';\n if (re.ignoreCase) flags += 'i';\n if (re.multiline) flags += 'm';\n return flags;\n}\nclone.__getRegExpFlags = __getRegExpFlags;\n\nreturn clone;\n})();\n\nif (typeof module === 'object' && module.exports) {\n module.exports = clone;\n}\n","'use strict';\n\nmodule.exports = function (data, opts) {\n if (!opts) opts = {};\n if (typeof opts === 'function') opts = { cmp: opts };\n var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;\n\n var cmp = opts.cmp && (function (f) {\n return function (node) {\n return function (a, b) {\n var aobj = { key: a, value: node[a] };\n var bobj = { key: b, value: node[b] };\n return f(aobj, bobj);\n };\n };\n })(opts.cmp);\n\n var seen = [];\n return (function stringify (node) {\n if (node && node.toJSON && typeof node.toJSON === 'function') {\n node = node.toJSON();\n }\n\n if (node === undefined) return;\n if (typeof node == 'number') return isFinite(node) ? '' + node : 'null';\n if (typeof node !== 'object') return JSON.stringify(node);\n\n var i, out;\n if (Array.isArray(node)) {\n out = '[';\n for (i = 0; i < node.length; i++) {\n if (i) out += ',';\n out += stringify(node[i]) || 'null';\n }\n return out + ']';\n }\n\n if (node === null) return 'null';\n\n if (seen.indexOf(node) !== -1) {\n if (cycles) return JSON.stringify('__cycle__');\n throw new TypeError('Converting circular structure to JSON');\n }\n\n var seenIndex = seen.push(node) - 1;\n var keys = Object.keys(node).sort(cmp && cmp(node));\n out = '';\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = stringify(node[key]);\n\n if (!value) continue;\n if (out) out += ',';\n out += JSON.stringify(key) + ':' + value;\n }\n seen.splice(seenIndex, 1);\n return '{' + out + '}';\n })(data);\n};\n","export default function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n}\n\nexport function accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nexport function accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n","export default function(message) {\n throw Error(message);\n}\n","import error from './error';\n\nexport default function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) {\n push();\n } else {\n i = j + 1;\n }\n } else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n } else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n\n if (j > i) {\n j++;\n push();\n }\n\n return path;\n}\n","export default Array.isArray;\n","export default function(_) {\n return _ === Object(_);\n}\n","export default function(_) {\n return typeof _ === 'string';\n}\n","import isArray from './isArray';\nimport isObject from './isObject';\nimport isString from './isString';\n\nexport default function $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n","import accessor from './accessor';\nimport splitAccessPath from './splitAccessPath';\nimport stringValue from './stringValue';\n\nexport default function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map(stringValue).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n","import accessor from './accessor';\nimport field from './field';\n\nvar empty = [];\n\nexport var id = field('id');\n\nexport var identity = accessor(function(_) { return _; }, empty, 'identity');\n\nexport var zero = accessor(function() { return 0; }, empty, 'zero');\n\nexport var one = accessor(function() { return 1; }, empty, 'one');\n\nexport var truthy = accessor(function() { return true; }, empty, 'true');\n\nexport var falsy = accessor(function() { return false; }, empty, 'false');\n","function log(method, level, input) {\n var msg = [level].concat([].slice.call(input));\n console[method](...msg); // eslint-disable-line no-console\n}\n\nexport var None = 0;\nexport var Error = 1;\nexport var Warn = 2;\nexport var Info = 3;\nexport var Debug = 4;\n\nexport default function(_, method) {\n var level = _ || None;\n return {\n level: function(_) {\n if (arguments.length) {\n level = +_;\n return this;\n } else {\n return level;\n }\n },\n error: function() {\n if (level >= Error) log(method || 'error', 'ERROR', arguments);\n return this;\n },\n warn: function() {\n if (level >= Warn) log(method || 'warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log(method || 'log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log(method || 'log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n","/**\n * Span-preserving range clamp. If the span of the input range is less\n * than (max - min) and an endpoint exceeds either the min or max value,\n * the range is translated such that the span is preserved and one\n * endpoint touches the boundary of the min/max range.\n * If the span exceeds (max - min), the range [min, max] is returned.\n */\nexport default function(range, min, max) {\n var lo = range[0],\n hi = range[1],\n span;\n\n if (hi < lo) {\n span = hi;\n hi = lo;\n lo = span;\n }\n span = hi - lo;\n\n return span >= (max - min)\n ? [min, max]\n : [\n (lo = Math.min(Math.max(lo, min), max - span)),\n lo + span\n ];\n}\n","/**\n * Return an array with minimum and maximum values, in the\n * form [min, max]. Ignores null, undefined, and NaN values.\n */\nexport default function(array, f) {\n var i = 0, n, v, min, max;\n\n if (array && (n = array.length)) {\n if (f == null) {\n // find first valid value\n for (v = array[i]; v == null || v !== v; v = array[++i]);\n min = max = v;\n\n // visit all other values\n for (; i max) max = v;\n }\n }\n } else {\n // find first valid value\n for (v = f(array[i]); v == null || v !== v; v = f(array[++i]));\n min = max = v;\n\n // visit all other values\n for (; i max) max = v;\n }\n }\n }\n }\n\n return [min, max];\n}\n","/**\n * Predicate that returns true if the value lies within the span\n * of the given range. The left and right flags control the use\n * of inclusive (true) or exclusive (false) comparisons.\n */\nexport default function(value, range, left, right) {\n var r0 = range[0], r1 = range[range.length-1], t;\n if (r0 > r1) {\n t = r0;\n r0 = r1;\n r1 = t;\n }\n left = left === undefined || left;\n right = right === undefined || right;\n\n return (left ? r0 <= value : r0 < value) &&\n (right ? value <= r1 : value < r1);\n}\n","export default function(_) {\n return typeof _ === 'boolean';\n}\n","export default function(_) {\n return typeof _ === 'number';\n}\n","export default function(_) {\n for (var s={}, i=0, n=_.length; i(obj: T, props: K[]): Pick {\n const copy: any = {};\n for (const prop of props) {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n }\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: T, props: K[]): Omit {\n const copy = {...(obj as any)};\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\n/**\n * Monkey patch Set so that `stringify` produces a string representation of sets.\n */\nSet.prototype['toJSON'] = function() {\n return `Set(${[...this].map(x => stableStringify(x)).join(',')})`;\n};\n\n/**\n * Converts any object to a string representation that can be consumed by humans.\n */\nexport const stringify = stableStringify;\n\n/**\n * Converts any object to a string of limited size, or a number.\n */\nexport function hash(a: any): string | number {\n if (isNumber(a)) {\n return a;\n }\n\n const str = isString(a) ? a : stableStringify(a);\n\n // short strings can be used as hash directly, longer strings are hashed to reduce memory usage\n if (str.length < 250) {\n return str;\n }\n\n // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n h = (h << 5) - h + char;\n h = h & h; // Convert to 32bit integer\n }\n return h;\n}\n\nexport function isNullOrFalse(x: any): x is false | null {\n return x === false || x === null;\n}\n\nexport function contains(array: T[], item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: T[], excludedItems: T[]) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: T[], other: T[]) {\n return array.concat(without(other, array));\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (const [k, a] of arr.entries()) {\n if (f(a, k, i++)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Returns true if all items return true.\n */\nexport function every(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (const [k, a] of arr.entries()) {\n if (!f(a, k, i++)) {\n return false;\n }\n }\n return true;\n}\n\nexport function flatten(arrays: T[][]): T[] {\n return ([] as T[]).concat(...arrays);\n}\n\nexport function fill(val: T, len: number) {\n const arr = new Array(len);\n for (let i = 0; i < len; ++i) {\n arr[i] = val;\n }\n return arr;\n}\n\n/**\n * Like TS Partial but applies recursively to all properties.\n */\nexport type DeepPartial = {[P in keyof T]?: DeepPartial};\n\n/**\n * recursively merges src into dest\n */\nexport function mergeDeep(dest: T, ...src: DeepPartial[]): T {\n for (const s of src) {\n dest = deepMerge_(dest, s);\n }\n return dest;\n}\n\n// recursively merges src into dest\nfunction deepMerge_(dest: any, src: any) {\n if (typeof src !== 'object' || src === null) {\n return dest;\n }\n\n for (const p in src) {\n if (!src.hasOwnProperty(p)) {\n continue;\n }\n if (src[p] === undefined) {\n continue;\n }\n if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) {\n dest[p] = src[p];\n } else if (typeof dest[p] !== 'object' || dest[p] === null) {\n dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]);\n } else {\n mergeDeep(dest[p], src[p]);\n }\n }\n return dest;\n}\n\nexport function unique(values: T[], f: (item: T) => string | number): T[] {\n const results: T[] = [];\n const u = {};\n let v: string | number;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n}\n\nexport interface Dict {\n [key: string]: T;\n}\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function isEqual(dict: Dict, other: Dict) {\n const dictKeys = keys(dict);\n const otherKeys = keys(other);\n if (dictKeys.length !== otherKeys.length) {\n return false;\n }\n for (const key of dictKeys) {\n if (dict[key] !== other[key]) {\n return false;\n }\n }\n return true;\n}\n\nexport function setEqual(a: Set, b: Set) {\n if (a.size !== b.size) {\n return false;\n }\n for (const e of a) {\n if (!b.has(e)) {\n return false;\n }\n }\n return true;\n}\n\nexport function hasIntersection(a: Set, b: Set) {\n for (const key of a) {\n if (b.has(key)) {\n return true;\n }\n }\n return false;\n}\n\nexport function prefixGenerator(a: Set): Set {\n const prefixes = new Set();\n for (const x of a) {\n const splitField = splitAccessPath(x);\n // Wrap every element other than the first in `[]`\n const wrappedWithAccessors = splitField.map((y, i) => (i === 0 ? y : `[${y}]`));\n const computedPrefixes = wrappedWithAccessors.map((_, i) => wrappedWithAccessors.slice(0, i + 1).join(''));\n computedPrefixes.forEach(y => prefixes.add(y));\n }\n return prefixes;\n}\n\nexport function fieldIntersection(a: Set, b: Set): boolean {\n return hasIntersection(prefixGenerator(a), prefixGenerator(b));\n}\n\nexport function isNumeric(num: string | number) {\n return !isNaN(num as any);\n}\n\nexport function differArray(array: T[], other: T[]) {\n if (array.length !== other.length) {\n return true;\n }\n\n array.sort();\n other.sort();\n\n for (let i = 0; i < array.length; i++) {\n if (other[i] !== array[i]) {\n return true;\n }\n }\n\n return false;\n}\n\n// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\nexport const keys = Object.keys as (o: T) => (Extract)[];\n\nexport function vals(x: {[key: string]: T}): T[] {\n const _vals: T[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n}\n\nexport function entries(x: {[key: string]: T}): {key: string; value: T}[] {\n const _entries: {key: string; value: T}[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _entries.push({\n key: k,\n value: x[k]\n });\n }\n }\n return _entries;\n}\n\n// Using mapped type to declare a collect of flags for a string literal type S\n// https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types\nexport type Flag = {[K in S]: 1};\n\nexport function flagKeys(f: Flag): S[] {\n return keys(f) as S[];\n}\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n\n/**\n * Convert a string into a valid variable name\n */\nexport function varName(s: string): string {\n // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _\n const alphanumericS = s.replace(/\\W/g, '_');\n\n // Add _ if the string has leading numbers.\n return (s.match(/^\\d+/) ? '_' : '') + alphanumericS;\n}\n\nexport function logicalExpr(op: LogicalOperand, cb: (...args: any[]) => string): string {\n if (isLogicalNot(op)) {\n return '!(' + logicalExpr(op.not, cb) + ')';\n } else if (isLogicalAnd(op)) {\n return '(' + op.and.map((and: LogicalOperand) => logicalExpr(and, cb)).join(') && (') + ')';\n } else if (isLogicalOr(op)) {\n return '(' + op.or.map((or: LogicalOperand) => logicalExpr(or, cb)).join(') || (') + ')';\n } else {\n return cb(op);\n }\n}\n\nexport type Omit = Pick>;\n\n/**\n * Delete nested property of an object, and delete the ancestors of the property if they become empty.\n */\nexport function deleteNestedProperty(obj: any, orderedProps: string[]) {\n if (orderedProps.length === 0) {\n return true;\n }\n const prop = orderedProps.shift();\n if (deleteNestedProperty(obj[prop], orderedProps)) {\n delete obj[prop];\n }\n return keys(obj).length === 0;\n}\n\nexport function titlecase(s: string) {\n return s.charAt(0).toUpperCase() + s.substr(1);\n}\n\n/**\n * Converts a path to an access path with datum.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function accessPathWithDatum(path: string, datum = 'datum') {\n const pieces = splitAccessPath(path);\n const prefixes = [];\n for (let i = 1; i <= pieces.length; i++) {\n const prefix = `[${pieces\n .slice(0, i)\n .map(stringValue)\n .join('][')}]`;\n prefixes.push(`${datum}${prefix}`);\n }\n return prefixes.join(' && ');\n}\n\n/**\n * Return access with datum to the flattened field.\n *\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function flatAccessWithDatum(path: string, datum: 'datum' | 'parent' | 'datum.datum' = 'datum') {\n return `${datum}[${stringValue(splitAccessPath(path).join('.'))}]`;\n}\n\n/**\n * Replaces path accesses with access to non-nested field.\n * For example, `foo[\"bar\"].baz` becomes `foo\\\\.bar\\\\.baz`.\n */\nexport function replacePathInField(path: string) {\n return `${splitAccessPath(path)\n .map(p => p.replace('.', '\\\\.'))\n .join('\\\\.')}`;\n}\n\n/**\n * Remove path accesses with access from field.\n * For example, `foo[\"bar\"].baz` becomes `foo.bar.baz`.\n */\nexport function removePathFromField(path: string) {\n return `${splitAccessPath(path).join('.')}`;\n}\n\n/**\n * Count the depth of the path. Returns 1 for fields that are not nested.\n */\nexport function accessPathDepth(path: string) {\n if (!path) {\n return 0;\n }\n return splitAccessPath(path).length;\n}\n\n/**\n * This is a replacement for chained || for numeric properties or properties that respect null so that 0 will be included.\n */\nexport function getFirstDefined(...args: T[]): T {\n for (const arg of args) {\n if (arg !== undefined) {\n return arg;\n }\n }\n return undefined;\n}\n\n// variable used to generate id\nlet idCounter = 42;\n\n/**\n * Returns a new random id every time it gets called.\n *\n * Has side effect!\n */\nexport function uniqueId(prefix?: string) {\n const id = ++idCounter;\n return prefix ? String(prefix) + id : id;\n}\n\n/**\n * Resets the id counter used in uniqueId. This can be useful for testing.\n */\nexport function resetIdCounter() {\n idCounter = 42;\n}\n\nexport function internalField(name: string) {\n return isInternalField(name) ? name : `__${name}`;\n}\n\nexport function isInternalField(name: string) {\n return name.indexOf('__') === 0;\n}\n\n/**\n * Normalize angle to be within [0,360).\n */\nexport function normalizeAngle(angle: number) {\n return ((angle % 360) + 360) % 360;\n}\n","/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {RangeType} from './compile/scale/type';\nimport {Encoding} from './encoding';\nimport {Mark} from './mark';\nimport {EncodingFacetMapping, EncodingFacetMapping as ExtendedFacetMapping} from './spec/facet';\nimport {Flag, flagKeys} from './util';\n\nexport type Channel = keyof Encoding | keyof ExtendedFacetMapping;\n\n// Facet\nexport const ROW: 'row' = 'row';\nexport const COLUMN: 'column' = 'column';\n\nexport const FACET: 'facet' = 'facet';\n\n// Position\nexport const X: 'x' = 'x';\nexport const Y: 'y' = 'y';\nexport const X2: 'x2' = 'x2';\nexport const Y2: 'y2' = 'y2';\n// Geo Position\nexport const LATITUDE: 'latitude' = 'latitude';\nexport const LONGITUDE: 'longitude' = 'longitude';\nexport const LATITUDE2: 'latitude2' = 'latitude2';\nexport const LONGITUDE2: 'longitude2' = 'longitude2';\n\n// Mark property with scale\nexport const COLOR: 'color' = 'color';\n\nexport const FILL: 'fill' = 'fill';\n\nexport const STROKE: 'stroke' = 'stroke';\n\nexport const SHAPE: 'shape' = 'shape';\nexport const SIZE: 'size' = 'size';\nexport const OPACITY: 'opacity' = 'opacity';\nexport const FILLOPACITY: 'fillOpacity' = 'fillOpacity';\n\nexport const STROKEOPACITY: 'strokeOpacity' = 'strokeOpacity';\n\nexport const STROKEWIDTH: 'strokeWidth' = 'strokeWidth';\n\n// Non-scale channel\nexport const TEXT: 'text' = 'text';\nexport const ORDER: 'order' = 'order';\nexport const DETAIL: 'detail' = 'detail';\nexport const KEY: 'key' = 'key';\n\nexport const TOOLTIP: 'tooltip' = 'tooltip';\nexport const HREF: 'href' = 'href';\n\nexport type PositionChannel = 'x' | 'y' | 'x2' | 'y2';\n\nexport type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2';\n\nexport function isGeoPositionChannel(c: Channel): c is GeoPositionChannel {\n switch (c) {\n case LATITUDE:\n case LATITUDE2:\n case LONGITUDE:\n case LONGITUDE2:\n return true;\n }\n return false;\n}\n\nexport function getPositionChannelFromLatLong(channel: GeoPositionChannel): PositionChannel {\n switch (channel) {\n case LATITUDE:\n return 'y';\n case LATITUDE2:\n return 'y2';\n case LONGITUDE:\n return 'x';\n case LONGITUDE2:\n return 'x2';\n }\n}\n\nexport const GEOPOSITION_CHANNEL_INDEX: Flag = {\n longitude: 1,\n longitude2: 1,\n latitude: 1,\n latitude2: 1\n};\n\nexport const GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX);\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n // position\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n\n ...GEOPOSITION_CHANNEL_INDEX,\n\n // color\n color: 1,\n fill: 1,\n stroke: 1,\n\n // other non-position with scale\n opacity: 1,\n fillOpacity: 1,\n strokeOpacity: 1,\n\n strokeWidth: 1,\n size: 1,\n shape: 1,\n\n // channels without scales\n order: 1,\n text: 1,\n detail: 1,\n key: 1,\n tooltip: 1,\n href: 1\n};\n\nexport type ColorChannel = 'color' | 'fill' | 'stroke';\n\nexport function isColorChannel(channel: Channel): channel is ColorChannel {\n return channel === 'color' || channel === 'fill' || channel === 'stroke';\n}\n\nexport type FacetChannel = keyof EncodingFacetMapping;\n\nconst FACET_CHANNEL_INDEX: Flag> = {\n row: 1,\n column: 1,\n facet: 1\n};\n\nexport const FACET_CHANNELS = flagKeys(FACET_CHANNEL_INDEX);\n\nconst CHANNEL_INDEX = {\n ...UNIT_CHANNEL_INDEX,\n ...FACET_CHANNEL_INDEX\n};\n\nexport const CHANNELS = flagKeys(CHANNEL_INDEX);\n\nconst {order: _o, detail: _d, ...SINGLE_DEF_CHANNEL_INDEX} = CHANNEL_INDEX;\nconst {order: _o1, detail: _d1, row: _r, column: _c, facet: _f, ...SINGLE_DEF_UNIT_CHANNEL_INDEX} = CHANNEL_INDEX;\n/**\n * Channels that cannot have an array of channelDef.\n * model.fieldDef, getFieldDef only work for these channels.\n *\n * (The only two channels that can have an array of channelDefs are \"detail\" and \"order\".\n * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef\n * are not applicable for them. Similarly, selection projection won't work with \"detail\" and \"order\".)\n */\n\nexport const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANNEL_INDEX);\n\nexport const SINGLE_DEF_UNIT_CHANNELS: SingleDefUnitChannel[] = flagKeys(SINGLE_DEF_UNIT_CHANNEL_INDEX);\n\n// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined\n// when running the schema generator\n// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0];\n\nexport type SingleDefUnitChannel =\n | 'x'\n | 'y'\n | 'x2'\n | 'y2'\n | 'longitude'\n | 'latitude'\n | 'longitude2'\n | 'latitude2'\n | 'color'\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'size'\n | 'shape'\n | 'fillOpacity'\n | 'strokeOpacity'\n | 'opacity'\n | 'text'\n | 'tooltip'\n | 'href'\n | 'key';\n\nexport type SingleDefChannel = SingleDefUnitChannel | 'row' | 'column' | 'facet';\n\nexport function isSingleDefUnitChannel(str: string): str is SingleDefUnitChannel {\n return !!SINGLE_DEF_UNIT_CHANNEL_INDEX[str];\n}\n\nexport function isChannel(str: string): str is Channel {\n return !!CHANNEL_INDEX[str];\n}\n\nexport type SecondaryRangeChannel = 'x2' | 'y2' | 'latitude2' | 'longitude2';\n\nexport const SECONDARY_RANGE_CHANNEL: SecondaryRangeChannel[] = ['x2', 'y2', 'latitude2', 'longitude2'];\n\nexport function isSecondaryRangeChannel(c: Channel): c is SecondaryRangeChannel {\n const main = getMainRangeChannel(c);\n return main !== c;\n}\n\nexport function getMainRangeChannel(channel: Channel): Channel {\n switch (channel) {\n case 'x2':\n return 'x';\n case 'y2':\n return 'y';\n case 'latitude2':\n return 'latitude';\n case 'longitude2':\n return 'longitude';\n }\n return channel;\n}\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX);\n\n// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2;\nconst {\n x: _x,\n y: _y,\n // x2 and y2 share the same scale as x and y\n x2: _x2,\n y2: _y2,\n latitude: _latitude,\n longitude: _longitude,\n latitude2: _latitude2,\n longitude2: _longitude2,\n // The rest of unit channels then have scale\n ...NONPOSITION_CHANNEL_INDEX\n} = UNIT_CHANNEL_INDEX;\n\nexport const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX);\nexport type NonPositionChannel = typeof NONPOSITION_CHANNELS[0];\n\n// POSITION_SCALE_CHANNELS = X and Y;\nconst POSITION_SCALE_CHANNEL_INDEX: {x: 1; y: 1} = {x: 1, y: 1};\nexport const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX);\nexport type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0];\n\n// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y\nconst {\n // x2 and y2 share the same scale as x and y\n // text and tooltip have format instead of scale,\n // href has neither format, nor scale\n text: _t,\n tooltip: _tt,\n href: _hr,\n // detail and order have no scale\n detail: _dd,\n key: _k,\n order: _oo,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n} = NONPOSITION_CHANNEL_INDEX;\nexport const NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX);\nexport type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0];\n\nexport function isNonPositionScaleChannel(channel: Channel): channel is NonPositionScaleChannel {\n return !!NONPOSITION_CHANNEL_INDEX[channel];\n}\n\n/**\n * @returns whether Vega supports legends for a particular channel\n */\nexport function supportLegend(channel: NonPositionScaleChannel) {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n case SIZE:\n case SHAPE:\n case OPACITY:\n return true;\n\n case FILLOPACITY:\n case STROKEOPACITY:\n case STROKEWIDTH:\n return false;\n }\n}\n\n// Declare SCALE_CHANNEL_INDEX\nconst SCALE_CHANNEL_INDEX = {\n ...POSITION_SCALE_CHANNEL_INDEX,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n};\n\n/** List of channels with scales */\nexport const SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX);\nexport type ScaleChannel = typeof SCALE_CHANNELS[0];\n\nexport function isScaleChannel(channel: Channel): channel is ScaleChannel {\n return !!SCALE_CHANNEL_INDEX[channel];\n}\n\nexport type SupportedMark = {[mark in Mark]?: 'always' | 'binned'};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return getSupportedMark(channel)[mark];\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to 'always', 'binned', or undefined\n */\nfunction getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n // falls through\n\n case DETAIL:\n case KEY:\n case TOOLTIP:\n case HREF:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n case STROKEWIDTH:\n // falls through\n\n case FACET:\n case ROW: // falls through\n case COLUMN:\n return {\n // all marks\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n rect: 'always',\n line: 'always',\n trail: 'always',\n area: 'always',\n text: 'always',\n geoshape: 'always'\n };\n case X:\n case Y:\n case LATITUDE:\n case LONGITUDE:\n return {\n // all marks except geoshape. geoshape does not use X, Y -- it uses a projection\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n rect: 'always',\n line: 'always',\n trail: 'always',\n area: 'always',\n text: 'always'\n };\n case X2:\n case Y2:\n case LATITUDE2:\n case LONGITUDE2:\n return {\n rule: 'always',\n bar: 'always',\n rect: 'always',\n area: 'always',\n circle: 'binned',\n point: 'binned',\n square: 'binned',\n tick: 'binned'\n };\n case SIZE:\n return {\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n text: 'always',\n line: 'always',\n trail: 'always'\n };\n case SHAPE:\n return {point: 'always', geoshape: 'always'};\n case TEXT:\n return {text: 'always'};\n }\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case STROKEWIDTH:\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n\n // X2 and Y2 use X and Y scales, so they similarly have continuous range. [falls through]\n case X2:\n case Y2:\n return undefined;\n\n case FACET:\n case ROW:\n case COLUMN:\n case SHAPE:\n // TEXT, TOOLTIP, and HREF have no scale but have discrete output [falls through]\n case TEXT:\n case TOOLTIP:\n case HREF:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n case FILL:\n case STROKE:\n return 'flexible';\n\n // No scale, no range type.\n\n case LATITUDE:\n case LONGITUDE:\n case LATITUDE2:\n case LONGITUDE2:\n case DETAIL:\n case KEY:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('rangeType not implemented for ' + channel);\n}\n","import {\n Align,\n Axis as VgAxis,\n AxisOrient,\n BaseAxis,\n FontStyle,\n FontWeight,\n LabelOverlap,\n TextBaseline,\n TitleAnchor\n} from 'vega';\nimport {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {Color, LayoutAlign} from './vega.schema';\n\ntype BaseAxisNoSignals = AxisMixins &\n BaseAxis<\n number,\n number,\n boolean,\n number | boolean,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n number[],\n TitleAnchor\n >;\n\n// Vega axis config is the same as vega axis base. If this is not the case, add specific type.\ntype VgAxisConfigNoSignals = BaseAxisNoSignals;\n\n// Change comments to be Vega-Lite specific\ninterface AxisMixins {\n /**\n * A boolean flag indicating if grid lines should be included as part of the axis\n *\n * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.\n */\n grid?: boolean;\n\n /**\n * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n *\n * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.\n */\n labelFlush?: boolean | number;\n\n /**\n * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`.\n */\n labelOverlap?: LabelOverlap;\n}\n\nexport interface AxisOrientMixins {\n /**\n * The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y-axis oriented towards the right edge of the chart).\n *\n * __Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes.\n */\n orient?: AxisOrient;\n}\n\nexport type AxisConfig = VgAxisConfigNoSignals & VlOnlyGuideConfig & AxisOrientMixins;\n\nexport interface Axis extends AxisOrientMixins, BaseAxisNoSignals, Guide {\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axes with top or bottom orientation, this sets the axis group x coordinate. For y-axes with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n *\n * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.\n */\n tickCount?: number;\n\n /**\n * The minimum desired step between axis ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value.\n *\n * __Default value__: `undefined`\n */\n tickMinStep?: number;\n\n /**\n * Explicitly set the visible axis tick values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use `\"zindex = 1\"`.\n *\n * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Mark definitions for custom axis encoding.\n *\n * @hide\n */\n encoding?: AxisEncoding;\n}\n\nexport type AxisPart = keyof AxisEncoding;\nexport const AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\n/**\n * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes.\n * (Properties not listed are applicable for both)\n */\nexport const AXIS_PROPERTY_TYPE: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in keyof VgAxis]: 'main' | 'grid' | 'both'\n} = {\n grid: 'grid',\n gridColor: 'grid',\n gridDash: 'grid',\n gridOpacity: 'grid',\n gridScale: 'grid',\n gridWidth: 'grid',\n\n orient: 'main',\n\n bandPosition: 'both', // Need to be applied to grid axis too, so the grid will align with ticks.\n domain: 'main',\n domainColor: 'main',\n domainOpacity: 'main',\n domainWidth: 'main',\n format: 'main',\n formatType: 'main',\n labelAlign: 'main',\n labelAngle: 'main',\n labelBaseline: 'main',\n labelBound: 'main',\n labelColor: 'main',\n labelFlush: 'main',\n labelFlushOffset: 'main',\n labelFont: 'main',\n labelFontSize: 'main',\n labelFontWeight: 'main',\n labelLimit: 'main',\n labelOpacity: 'main',\n labelOverlap: 'main',\n labelPadding: 'main',\n labels: 'main',\n maxExtent: 'main',\n minExtent: 'main',\n offset: 'main',\n position: 'main',\n tickColor: 'main',\n tickExtra: 'main',\n tickOffset: 'both', // Need to be applied to grid axis too, so the grid will align with ticks.\n tickOpacity: 'main',\n tickRound: 'main',\n ticks: 'main',\n tickSize: 'main',\n title: 'main',\n titleAlign: 'main',\n titleAngle: 'main',\n titleBaseline: 'main',\n titleColor: 'main',\n titleFont: 'main',\n titleFontSize: 'main',\n titleFontWeight: 'main',\n titleLimit: 'main',\n titleOpacity: 'main',\n titlePadding: 'main',\n titleX: 'main',\n titleY: 'main',\n\n tickWidth: 'both',\n tickCount: 'both',\n values: 'both',\n scale: 'both',\n zindex: 'both' // this is actually set afterward, so it doesn't matter\n};\n\nexport interface AxisEncoding {\n /**\n * Custom encoding for the axis container.\n */\n axis?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis domain rule mark.\n */\n domain?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis gridline rule marks.\n */\n grid?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis tick rule marks.\n */\n ticks?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis title text mark.\n */\n title?: GuideEncodingEntry;\n}\n\nconst COMMON_AXIS_PROPERTIES_INDEX: Flag = {\n orient: 1, // other things can depend on orient\n\n bandPosition: 1,\n domain: 1,\n domainColor: 1,\n domainDash: 1,\n domainDashOffset: 1,\n domainOpacity: 1,\n domainWidth: 1,\n format: 1,\n formatType: 1,\n grid: 1,\n gridColor: 1,\n gridDash: 1,\n gridDashOffset: 1,\n gridOpacity: 1,\n gridWidth: 1,\n labelAlign: 1,\n labelAngle: 1,\n labelBaseline: 1,\n labelBound: 1,\n labelColor: 1,\n labelFlush: 1,\n labelFlushOffset: 1,\n labelFont: 1,\n labelFontSize: 1,\n labelFontStyle: 1,\n labelFontWeight: 1,\n labelLimit: 1,\n labelOpacity: 1,\n labelOverlap: 1,\n labelPadding: 1,\n labels: 1,\n labelSeparation: 1,\n maxExtent: 1,\n minExtent: 1,\n offset: 1,\n position: 1,\n tickColor: 1,\n tickCount: 1,\n tickDash: 1,\n tickDashOffset: 1,\n tickExtra: 1,\n tickMinStep: 1,\n tickOffset: 1,\n tickOpacity: 1,\n tickRound: 1,\n ticks: 1,\n tickSize: 1,\n tickWidth: 1,\n title: 1,\n titleAlign: 1,\n titleAnchor: 1,\n titleAngle: 1,\n titleBaseline: 1,\n titleColor: 1,\n titleFont: 1,\n titleFontSize: 1,\n titleFontStyle: 1,\n titleFontWeight: 1,\n titleLimit: 1,\n titleOpacity: 1,\n titlePadding: 1,\n titleX: 1,\n titleY: 1,\n values: 1,\n zindex: 1\n};\n\nconst AXIS_PROPERTIES_INDEX: Flag = {\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encoding: 1\n};\n\nconst VG_AXIS_PROPERTIES_INDEX: Flag = {\n gridScale: 1,\n scale: 1,\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encode: 1\n};\n\nexport function isAxisProperty(prop: string): prop is keyof Axis {\n return !!AXIS_PROPERTIES_INDEX[prop];\n}\n\nexport const VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX);\n\n// Export for dependent projects\nexport const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX);\n\nexport interface AxisConfigMixins {\n /**\n * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config).\n */\n axis?: AxisConfig;\n\n /**\n * X-axis specific config.\n */\n axisX?: AxisConfig;\n\n /**\n * Y-axis specific config.\n */\n axisY?: AxisConfig;\n\n /**\n * Specific axis config for y-axis along the left edge of the chart.\n */\n axisLeft?: AxisConfig;\n\n /**\n * Specific axis config for y-axis along the right edge of the chart.\n */\n axisRight?: AxisConfig;\n\n /**\n * Specific axis config for x-axis along the top edge of the chart.\n */\n axisTop?: AxisConfig;\n\n /**\n * Specific axis config for x-axis along the bottom edge of the chart.\n */\n axisBottom?: AxisConfig;\n\n /**\n * Specific axis config for axes with \"band\" scales.\n */\n axisBand?: AxisConfig;\n}\n","import {\n Align,\n BaseLegend,\n FontStyle,\n FontWeight,\n LabelOverlap,\n Legend as VgLegend,\n LegendConfig as VgLegendConfig,\n LegendOrient,\n Orient,\n Orientation,\n SymbolShape,\n TextBaseline,\n TitleAnchor\n} from 'vega';\nimport {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {Color, LayoutAlign} from './vega.schema';\n\nexport type LegendConfig = LegendMixins &\n VlOnlyGuideConfig &\n VgLegendConfig<\n number,\n number,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n SymbolShape,\n number[],\n Orient,\n TitleAnchor,\n LegendOrient\n > & {\n /**\n * Max legend length for a vertical gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `200`\n */\n gradientVerticalMaxLength?: number;\n\n /**\n * Min legend length for a vertical gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `100`\n */\n gradientVerticalMinLength?: number;\n\n /**\n * Max legend length for a horizontal gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `200`\n */\n gradientHorizontalMaxLength?: number;\n\n /**\n * Min legend length for a horizontal gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `100`\n */\n gradientHorizontalMinLength?: number;\n\n /**\n * The length in pixels of the primary axis of a color gradient. This value corresponds to the height of a vertical gradient or the width of a horizontal gradient.\n *\n * __Default value:__ `undefined`. If `undefined`, the default gradient will be determined based on the following rules:\n * - For vertical gradients, `clamp(plot_height, gradientVerticalMinLength, gradientVerticalMaxLength)`\n * - For top-`orient`ed or bottom-`orient`ed horizontal gradients, `clamp(plot_width, gradientHorizontalMinLength, gradientHorizontalMaxLength)`\n * - For other horizontal gradients, `gradientHorizontalMinLength`\n *\n * where `clamp(value, min, max)` restricts _value_ to be between the specified _min_ and _max_.\n * @minimum 0\n */\n gradientLength?: number;\n };\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend\n extends BaseLegend<\n number,\n number,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n SymbolShape,\n number[],\n Orient,\n TitleAnchor,\n LegendOrient\n >,\n LegendMixins,\n Guide {\n /**\n * Mark definitions for custom legend encoding.\n *\n * @hide\n */\n encoding?: LegendEncoding;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * The minimum desired step between legend ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value.\n *\n * __Default value__: `undefined`\n */\n tickMinStep?: number;\n\n /**\n * Explicitly set the visible legend values.\n */\n values?: (number | string | boolean | DateTime)[];\n\n /**\n * The type of the legend. Use `\"symbol\"` to create a discrete legend and `\"gradient\"` for a continuous color gradient.\n *\n * __Default value:__ `\"gradient\"` for non-binned quantitative fields and temporal fields; `\"symbol\"` otherwise.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * The direction of the legend, one of `\"vertical\"` or `\"horizontal\"`.\n *\n * __Default value:__\n * - For top-/bottom-`orient`ed legends, `\"horizontal\"`\n * - For left-/right-`orient`ed legends, `\"vertical\"`\n * - For top/bottom-left/right-`orient`ed legends, `\"horizontal\"` for gradient legends and `\"vertical\"` for symbol legends.\n */\n direction?: Orientation;\n\n /**\n * The orientation of the legend, which determines how the legend is positioned within the scene. One of `\"left\"`, `\"right\"`, `\"top-left\"`, `\"top-right\"`, `\"bottom-left\"`, `\"bottom-right\"`, `\"none\"`.\n *\n * __Default value:__ `\"right\"`\n */\n orient?: LegendOrient;\n}\n\n// Change comments to be Vega-Lite specific\ninterface LegendMixins {\n /**\n * The strategy to use for resolving overlap of labels in gradient legends. If `false`, no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used. If set to `\"greedy\"`, a linear scan of the labels is performed, removing any label that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `\"greedy\"` for `log scales otherwise `true`.\n */\n labelOverlap?: LabelOverlap;\n}\n\nexport interface LegendEncoding {\n /**\n * Custom encoding for the legend container.\n * This can be useful for creating legend with custom x, y position.\n */\n legend?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the legend title text mark.\n */\n title?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend symbol marks.\n */\n symbols?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend gradient filled rect marks.\n */\n gradient?: GuideEncodingEntry;\n}\n\nexport const defaultLegendConfig: LegendConfig = {\n gradientHorizontalMaxLength: 200,\n gradientHorizontalMinLength: 100,\n gradientVerticalMaxLength: 200,\n gradientVerticalMinLength: 64 // This is the Vega's minimum.\n};\n\nconst COMMON_LEGEND_PROPERTY_INDEX: Flag = {\n clipHeight: 1,\n columnPadding: 1,\n columns: 1,\n cornerRadius: 1,\n direction: 1,\n fillColor: 1,\n format: 1,\n formatType: 1,\n gradientLength: 1,\n gradientOpacity: 1,\n gradientStrokeColor: 1,\n gradientStrokeWidth: 1,\n gradientThickness: 1,\n gridAlign: 1,\n labelAlign: 1,\n labelBaseline: 1,\n labelColor: 1,\n labelFont: 1,\n labelFontSize: 1,\n labelFontStyle: 1,\n labelFontWeight: 1,\n labelLimit: 1,\n labelOffset: 1,\n labelOpacity: 1,\n labelOverlap: 1,\n labelPadding: 1,\n labelSeparation: 1,\n legendX: 1,\n legendY: 1,\n offset: 1,\n orient: 1,\n padding: 1,\n rowPadding: 1,\n strokeColor: 1,\n symbolDash: 1,\n symbolDashOffset: 1,\n symbolFillColor: 1,\n symbolOffset: 1,\n symbolOpacity: 1,\n symbolSize: 1,\n symbolStrokeColor: 1,\n symbolStrokeWidth: 1,\n symbolType: 1,\n tickCount: 1,\n tickMinStep: 1,\n title: 1,\n titleAlign: 1,\n titleAnchor: 1,\n titleBaseline: 1,\n titleColor: 1,\n titleFont: 1,\n titleFontSize: 1,\n titleFontStyle: 1,\n titleFontWeight: 1,\n titleLimit: 1,\n titleOpacity: 1,\n titleOrient: 1,\n titlePadding: 1,\n type: 1,\n values: 1,\n zindex: 1\n};\n\nconst VG_LEGEND_PROPERTY_INDEX: Flag> = {\n ...COMMON_LEGEND_PROPERTY_INDEX,\n // channel scales\n opacity: 1,\n shape: 1,\n stroke: 1,\n fill: 1,\n size: 1,\n strokeWidth: 1,\n // encode\n encode: 1\n};\n\nexport const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX);\n\nexport const VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX);\n","import {AggregateOp} from 'vega';\nimport {CompositeMark} from '../compositemark';\nimport {Aggregate} from '../aggregate';\nimport {Channel, FacetChannel, GeoPositionChannel} from '../channel';\nimport {TypedFieldDef} from '../channeldef';\nimport {ErrorBarCenter, ErrorBarExtent} from '../compositemark/errorbar';\nimport {DateTime, DateTimeExpr} from '../datetime';\nimport {Mark} from '../mark';\nimport {Projection} from '../projection';\nimport {ScaleType} from '../scale';\nimport {Type} from '../type';\nimport {stringify} from '../util';\nimport {VgSortField} from '../vega.schema';\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\n\nexport const INVALID_SPEC = 'Invalid spec';\n\n// FIT\nexport const FIT_NON_SINGLE = 'Autosize \"fit\" only works for single views and layered views.';\n\nexport const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\".';\n\n// SELECTION\nexport function cannotProjectOnChannelWithoutField(channel: Channel) {\n return `Cannot project a selection on encoding channel \"${channel}\", which has no field.`;\n}\n\nexport function nearestNotSupportForContinuous(mark: string) {\n return `The \"nearest\" transform is not supported for ${mark} marks.`;\n}\n\nexport function selectionNotSupported(mark: CompositeMark) {\n return `Selection not supported for ${mark} yet`;\n}\n\nexport function selectionNotFound(name: string) {\n return `Cannot find a selection named \"${name}\"`;\n}\n\nexport const SCALE_BINDINGS_CONTINUOUS =\n 'Scale bindings are currently only supported for scales with unbinned, continuous domains.';\n\nexport const NO_INIT_SCALE_BINDINGS = 'Selections bound to scales cannot be separately initialized.';\n\n// REPEAT\nexport function noSuchRepeatedValue(field: string) {\n return `Unknown repeated value \"${field}\".`;\n}\n\nexport function columnsNotSupportByRowCol(type: 'facet' | 'repeat') {\n return `The \"columns\" property cannot be used when \"${type}\" has nested row/column.`;\n}\n\n// CONCAT\nexport const CONCAT_CANNOT_SHARE_AXIS =\n 'Axes cannot be shared in concatenated views yet (https://github.com/vega/vega-lite/issues/2415).';\n\n// REPEAT\nexport const REPEAT_CANNOT_SHARE_AXIS =\n 'Axes cannot be shared in repeated views yet (https://github.com/vega/vega-lite/issues/2415).';\n\n// DATA\nexport function unrecognizedParse(p: string) {\n return `Unrecognized parse \"${p}\".`;\n}\n\nexport function differentParse(field: string, local: string, ancestor: string) {\n return `An ancestor parsed field \"${field}\" as ${ancestor} but a child wants to parse the field as ${local}.`;\n}\n\n// TRANSFORMS\nexport function invalidTransformIgnored(transform: any) {\n return `Ignoring an invalid transform: ${stringify(transform)}.`;\n}\n\nexport const NO_FIELDS_NEEDS_AS =\n 'If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';\n\n// ENCODING & FACET\n\nexport function encodingOverridden(channels: Channel[]) {\n return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`;\n}\nexport function projectionOverridden(opt: {parentProjection: Projection; projection: Projection}) {\n const {parentProjection, projection} = opt;\n return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(\n projection\n )}.`;\n}\n\nexport function primitiveChannelDef(\n channel: Channel,\n type: 'string' | 'number' | 'boolean',\n value: string | number | boolean\n) {\n return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`;\n}\n\nexport function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n}\n\nexport function nonZeroScaleUsedWithLengthMark(\n mark: 'bar' | 'area',\n channel: Channel,\n opt: {scaleType?: ScaleType; zeroFalse?: boolean}\n) {\n const scaleText = opt.scaleType\n ? `${opt.scaleType} scale`\n : opt.zeroFalse\n ? 'scale with zero=false'\n : 'scale with custom domain that excludes zero';\n\n return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${\n channel === 'x' ? 'width' : 'height'\n } of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`;\n}\n\nexport function invalidFieldTypeForCountAggregate(type: Type, aggregate: Aggregate | string) {\n return `Invalid field type \"${type}\" for aggregate: \"${aggregate}\", using \"quantitative\" instead.`;\n}\n\nexport function invalidAggregate(aggregate: AggregateOp | string) {\n return `Invalid aggregation operator \"${aggregate}\"`;\n}\n\nexport function missingFieldType(channel: Channel, newType: Type) {\n return `Missing type for channel \"${channel}\", using \"${newType}\" instead.`;\n}\nexport function droppingColor(type: 'encoding' | 'property', opt: {fill?: boolean; stroke?: boolean}) {\n const {fill, stroke} = opt;\n return (\n `Dropping color ${type} as the plot also has ` + (fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke')\n );\n}\n\nexport function emptyFieldDef(fieldDef: TypedFieldDef, channel: Channel) {\n return `Dropping ${stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n}\nexport function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel) {\n return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`;\n}\n\nexport const LINE_WITH_VARYING_SIZE =\n 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.';\n\nexport function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string) {\n return `${channel} dropped as it is incompatible with \"${markOrFacet}\"${when ? ` when ${when}` : ''}.`;\n}\n\nexport function invalidEncodingChannel(channel: string) {\n return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`;\n}\n\nexport function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n}\n\nexport function facetChannelDropped(channels: FacetChannel[]) {\n return `Facet encoding dropped as ${channels.join(' and ')} ${channels.length > 1 ? 'are' : 'is'} also specified.`;\n}\n\nexport function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel \"${channel}\" to encode \"${type}\" field can be misleading as it does not encode ${\n type === 'ordinal' ? 'order' : 'magnitude'\n }.`;\n}\n\n// Mark\nexport const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL =\n 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\nexport function lineWithRange(hasX2: boolean, hasY2: boolean) {\n const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2';\n return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`;\n}\n\nexport function orientOverridden(original: string, actual: string) {\n return `Specified orient \"${original}\" overridden with \"${actual}\"`;\n}\n\n// SCALE\nexport const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN =\n 'custom domain scale cannot be unioned with default field-based domain';\n\nexport function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use the scale property \"${prop}\" with non-color channel.`;\n}\n\nexport function unaggregateDomainHasNoEffectForRawField(fieldDef: TypedFieldDef) {\n return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`;\n}\n\nexport function unaggregateDomainWithNonSharedDomainOp(aggregate: Aggregate | string) {\n return `Unaggregated domain not applicable for \"${aggregate}\" since it produces values outside the origin domain of the source data.`;\n}\n\nexport function unaggregatedDomainWithLogScale(fieldDef: TypedFieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`;\n}\n\nexport function cannotApplySizeToNonOrientedMark(mark: Mark) {\n return `Cannot apply size to non-oriented mark \"${mark}\".`;\n}\n\nexport function rangeStepDropped(channel: Channel) {\n return `rangeStep for \"${channel}\" is dropped as top-level ${channel === 'x' ? 'width' : 'height'} is provided.`;\n}\n\nexport function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel \"${channel}\" does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n}\n\nexport function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `FieldDef does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n}\n\nexport function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n}\n\nexport function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark \"${mark}\".`;\n}\n\nexport function mergeConflictingProperty(\n property: string | number | symbol,\n propertyOf: string | number | symbol,\n v1: T,\n v2: T\n) {\n return `Conflicting ${propertyOf.toString()} property \"${property.toString()}\" (${stringify(v1)} and ${stringify(\n v2\n )}). Using ${stringify(v1)}.`;\n}\n\nexport function independentScaleMeansIndependentGuide(channel: Channel) {\n return `Setting the scale to be independent for \"${channel}\" means we also have to set the guide (axis or legend) to be independent.`;\n}\n\nexport function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`;\n}\n\nexport const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\nexport const MORE_THAN_ONE_SORT =\n 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.';\n\n// AXIS\nexport const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n// STACK\nexport function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack \"${channel}\" if there is already \"${channel}2\"`;\n}\n\nexport function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n}\n\nexport function stackNonSummativeAggregate(aggregate: Aggregate | string) {\n return `Stacking is applied even though the aggregate function is non-summative (\"${aggregate}\")`;\n}\n\n// TIMEUNIT\nexport function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${stringify(value)}`;\n}\n\nexport function dayReplacedWithDate(fullTimeUnit: string) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ${fullTimeUnit.replace(\n 'day',\n 'date'\n )}.`;\n}\n\nexport function droppedDay(d: DateTime | DateTimeExpr) {\n return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`;\n}\n\nexport function errorBarCenterAndExtentAreNotNeeded(center: ErrorBarCenter, extent: ErrorBarExtent) {\n return `${extent ? 'extent ' : ''}${extent && center ? 'and ' : ''}${center ? 'center ' : ''}${\n extent && center ? 'are ' : 'is '\n }not needed when data are aggregated.`;\n}\n\nexport function errorBarCenterIsUsedWithWrongExtent(\n center: ErrorBarCenter,\n extent: ErrorBarExtent,\n mark: 'errorbar' | 'errorband'\n) {\n return `${center} is not usually used with ${extent} for ${mark}.`;\n}\n\nexport function errorBarContinuousAxisHasCustomizedAggregate(\n aggregate: Aggregate | string,\n compositeMark: CompositeMark\n) {\n return `Continuous axis should not have customized aggregation function ${aggregate}; ${compositeMark} already agregates the axis.`;\n}\n\nexport function errorBarCenterIsNotNeeded(extent: ErrorBarExtent, mark: 'errorbar' | 'errorband') {\n return `Center is not needed to be specified in ${mark} when extent is ${extent}.`;\n}\n\nexport function errorBand1DNotSupport(property: 'interpolate' | 'tension') {\n return `1D error band does not support ${property}`;\n}\n\n// CHANNEL\nexport function channelRequiredForBinned(channel: Channel) {\n return `Channel ${channel} is required for \"binned\" bin`;\n}\n\nexport function domainRequiredForThresholdScale(channel: Channel) {\n return `Domain for ${channel} is required for threshold scale`;\n}\n","/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport * as message_ from './message';\n\nexport const message = message_;\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n\n public error(...args: any[]) {\n throw Error(...args);\n return this; // @ts-ignore\n }\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n current = new LocalLogger();\n f(current as LocalLogger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(newLogger: LoggerInterface) {\n current = newLogger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n","import {Flag} from './util';\n/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport const TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 1,\n geojson: 1\n};\n\nexport function isType(t: any): t is Type {\n return !!TYPE_INDEX[t];\n}\n\nexport const QUANTITATIVE: 'quantitative' = 'quantitative';\nexport const ORDINAL: 'ordinal' = 'ordinal';\nexport const TEMPORAL: 'temporal' = 'temporal';\nexport const NOMINAL: 'nominal' = 'nominal';\n\nexport const GEOJSON: 'geojson' = 'geojson';\n\nexport type StandardType = typeof QUANTITATIVE | typeof ORDINAL | typeof TEMPORAL | typeof NOMINAL;\n\nexport type Type = StandardType | typeof GEOJSON;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type | string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n case GEOJSON:\n return 'geojson';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","import {toSet} from 'vega-util';\nimport * as CHANNEL from './channel';\nimport {Channel, CHANNELS, isColorChannel} from './channel';\nimport {FieldName} from './channeldef';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport * as TYPE from './type';\nimport {Type, TYPE_INDEX} from './type';\nimport {contains, Flag, flagKeys, keys} from './util';\nimport {ScaleInterpolate, ScaleInterpolateParams} from './vega.schema';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n export const SYMLOG: 'symlog' = 'symlog';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n\n // Discretizing scales\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n\n // Discrete scales\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType =\n | typeof ScaleType.LINEAR\n | typeof ScaleType.LOG\n | typeof ScaleType.POW\n | typeof ScaleType.SQRT\n | typeof ScaleType.SYMLOG\n | typeof ScaleType.TIME\n | typeof ScaleType.UTC\n | typeof ScaleType.QUANTILE\n | typeof ScaleType.QUANTIZE\n | typeof ScaleType.THRESHOLD\n | typeof ScaleType.BIN_ORDINAL\n | typeof ScaleType.ORDINAL\n | typeof ScaleType.POINT\n | typeof ScaleType.BAND;\n\n/**\n * Index for scale categories -- only scale of the same categories can be merged together.\n * Current implementation is trying to be conservative and avoid merging scale type that might not work together\n */\nconst SCALE_CATEGORY_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: ScaleType | 'numeric' | 'ordinal-position' | 'discretizing'\n} = {\n linear: 'numeric',\n log: 'numeric',\n pow: 'numeric',\n sqrt: 'numeric',\n symlog: 'numeric',\n time: 'time',\n utc: 'time',\n ordinal: 'ordinal',\n 'bin-ordinal': 'bin-ordinal', // TODO: should bin-ordinal support merging with other\n point: 'ordinal-position',\n band: 'ordinal-position',\n quantile: 'discretizing',\n quantize: 'discretizing',\n threshold: 'discretizing'\n};\n\nexport const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX) as ScaleType[];\n\n/**\n * Whether the two given scale types can be merged together.\n */\nexport function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType) {\n const scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1];\n const scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2];\n return (\n scaleCategory1 === scaleCategory2 ||\n (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') ||\n (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time')\n );\n}\n\n/**\n * Index for scale precedence -- high score = higher priority for merging.\n */\nconst SCALE_PRECEDENCE_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: number\n} = {\n // numeric\n linear: 0,\n log: 1,\n pow: 1,\n sqrt: 1,\n symlog: 1,\n // time\n time: 0,\n utc: 0,\n // ordinal-position -- these have higher precedence than continuous scales as they support more types of data\n point: 10,\n band: 11, // band has higher precedence as it is better for interaction\n // non grouped types\n ordinal: 0,\n 'bin-ordinal': 0,\n quantile: 0,\n quantize: 0,\n threshold: 0\n};\n\n/**\n * Return scale categories -- only scale of the same categories can be merged together.\n */\nexport function scaleTypePrecedence(scaleType: ScaleType): number {\n return SCALE_PRECEDENCE_INDEX[scaleType];\n}\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'log', 'pow', 'sqrt', 'symlog', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_TO_DISCRETE_SCALES: ScaleType[] = ['quantile', 'quantize', 'threshold'];\nconst CONTINUOUS_TO_DISCRETE_INDEX = toSet(CONTINUOUS_TO_DISCRETE_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat([\n 'quantile',\n 'quantize',\n 'threshold'\n]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function hasContinuousDomain(\n type: ScaleType\n): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'time' | 'utc' | 'quantile' | 'quantize' | 'threshold' {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(\n type: ScaleType\n): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport function isContinuousToDiscrete(type: ScaleType): type is 'quantile' | 'quantize' | 'threshold' {\n return type in CONTINUOUS_TO_DISCRETE_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, and `size` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` band and point scales of text marks.\n *\n * __Default value:__ `90`\n *\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n\n /**\n * Default range step for band and point scales of (1) the `y` channel\n * and (2) the `x` channel when the mark is not `text`.\n *\n * __Default value:__ `20`\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n *\n * __Default value:__\n * - `barBandPaddingInner` for bar marks (`0.1` by default)\n * - `rectBandPaddingInner` for rect and other marks (`0` by default)\n *\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n *\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales of `\"bar\"` marks.\n *\n * __Default value:__ `0.1`\n *\n * @minimum 0\n * @maximum 1\n */\n barBandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales of `\"bar\"` marks.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n barBandPaddingOuter?: number;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales of `\"rect\"` marks.\n *\n * __Default value:__ `0`\n *\n * @minimum 0\n * @maximum 1\n */\n rectBandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales of `\"rect\"` marks.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n rectBandPaddingOuter?: number;\n\n /**\n * Default padding for continuous scales.\n *\n * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise.\n *\n * @minimum 0\n */\n continuousPadding?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n *\n * __Default value:__ `0.5`\n *\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n *\n * This is equivalent to setting `domain` to `\"unaggregate\"` for aggregated _quantitative_ fields by default.\n *\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n *\n * __Default value:__ `false`\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n *\n * If undefined (default), we will use the scale's `rangeStep` - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false.\n *\n * __Default value:__ `2`\n *\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n *\n * __Default value:__ `40`\n *\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n *\n * __Default value:__ `8`\n *\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.3`\n *\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.8`\n *\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n /**\n * Default minimum value for point size scale with zero=false.\n *\n * __Default value:__ `9`\n *\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n maxStrokeWidth?: number;\n\n /**\n * Default range cardinality for [`quantile`](https://vega.github.io/vega-lite/docs/scale.html#quantile) scale.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n quantileCount?: number;\n\n /**\n * Default range cardinality for [`quantize`](https://vega.github.io/vega-lite/docs/scale.html#quantize) scale.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n quantizeCount?: number;\n}\n\nexport const defaultScaleConfig: ScaleConfig = {\n textXRangeStep: 90,\n rangeStep: 20,\n pointPadding: 0.5,\n\n barBandPaddingInner: 0.1,\n rectBandPaddingInner: 0,\n\n minBandSize: 2,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4,\n quantileCount: 4,\n quantizeCount: 4\n};\n\nexport interface SchemeParams {\n /**\n * A color scheme name for ordinal scales (e.g., `\"category10\"` or `\"blues\"`).\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n name: string;\n\n /**\n * The extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme.\n */\n extent?: number[];\n\n /**\n * The number of colors to use in the scheme. This can be useful for scale types such as `\"quantize\"`, which use the length of the scale range to determine the number of discrete bins for the scale domain.\n */\n count?: number;\n}\n\nexport type SelectionDomain =\n | {\n /**\n * The name of a selection.\n */\n selection: string;\n /**\n * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n field?: FieldName;\n }\n | {\n /**\n * The name of a selection.\n */\n selection: string;\n /**\n * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n encoding?: string;\n };\n\nexport type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\nexport type Scheme = string | SchemeParams;\n\nexport function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams {\n return scheme && !!scheme['name'];\n}\n\nexport function isSelectionDomain(domain: Domain): domain is SelectionDomain {\n return domain && domain['selection'];\n}\n\nexport interface Scale {\n /**\n * The type of scale. Vega-Lite supports the following categories of scale types:\n *\n * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`\"pow\"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`\"sqrt\"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`\"symlog\"`](https://vega.github.io/vega-lite/docs/scale.html#symlog), [`\"log\"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`\"time\"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`\"utc\"`](https://vega.github.io/vega-lite/docs/scale.html#utc).\n *\n * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`\"band\"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`\"point\"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges [`\"bin-ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal), [`\"quantile\"`](https://vega.github.io/vega-lite/docs/scale.html#quantile), [`\"quantize\"`](https://vega.github.io/vega-lite/docs/scale.html#quantize) and [`\"threshold\"`](https://vega.github.io/vega-lite/docs/scale.html#threshold).\n *\n * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type).\n */\n type?: ScaleType;\n\n /**\n * Customized domain values.\n *\n * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries.\n * If the input field is aggregated, `domain` can also be a string value `\"unaggregated\"`, indicating that the domain should include the raw data values prior to the aggregation.\n *\n * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime).\n *\n * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values.\n *\n * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain.\n */\n domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\n\n // Hide because we might not really need this.\n /**\n * If true, reverses the order of the scale range.\n * __Default value:__ `false`.\n *\n * @hide\n */\n reverse?: boolean;\n\n /**\n * The range of the scale. One of:\n *\n * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).\n *\n * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For color scales you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`.\n *\n * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales.\n */\n range?: number[] | string[] | string;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view.\n *\n * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales.\n *\n * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly.\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `\"category10\"` or `\"blues\"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with color scales.\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n scheme?: string | SchemeParams;\n\n /**\n * An array of bin boundaries over the scale domain. If provided, axes and legends will use the bin boundaries to inform the choice of tick marks and text labels.\n */\n bins?: number[];\n\n /**\n * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default value:__ `false`.\n */\n round?: boolean;\n\n /**\n * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the `zero`, `nice`, `domainMin`, and `domainMax` properties.\n *\n * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`.\n * For _band and point_ scales, see `paddingInner` and `paddingOuter`.\n *\n * @minimum 0\n */\n padding?: number;\n\n /**\n * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1].\n *\n * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands).\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding (spacing) at the ends of the range of band and point scales,\n * as a fraction of the step size. This value must lie in the range [0,1].\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default).\n */\n clamp?: boolean;\n\n /**\n * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_.\n *\n * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain.\n *\n * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries.\n *\n * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise.\n *\n */\n nice?: boolean | number | NiceTime | {interval: string; step: number};\n\n /**\n * The logarithm base of the `log` scale (default `10`).\n */\n base?: number;\n\n /**\n * The exponent of the `pow` scale.\n */\n exponent?: number;\n\n /**\n * A constant determining the slope of the symlog function around zero. Only used for `symlog` scales.\n *\n * __Default value:__ `1`\n */\n constant?: number;\n\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n *\n * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise.\n *\n * __Note:__ Log, time, and utc scales do not support `zero`.\n */\n zero?: boolean;\n\n /**\n * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in HCL space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate).\n *\n * * __Default value:__ `hcl`\n */\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n}\n\nconst SCALE_PROPERTY_INDEX: Flag = {\n type: 1,\n domain: 1,\n range: 1,\n rangeStep: 1,\n scheme: 1,\n bins: 1,\n // Other properties\n reverse: 1,\n round: 1,\n // quantitative / time\n clamp: 1,\n nice: 1,\n // quantitative\n base: 1,\n exponent: 1,\n constant: 1,\n interpolate: 1,\n zero: 1, // zero depends on domain\n // band/point\n padding: 1,\n paddingInner: 1,\n paddingOuter: 1\n};\n\nexport const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX);\n\nconst {\n type,\n domain,\n range,\n rangeStep,\n scheme,\n ...NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX\n} = SCALE_PROPERTY_INDEX;\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX);\n\nexport const SCALE_TYPE_INDEX = generateScaleTypeIndex();\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'reverse':\n case 'range':\n return true;\n case 'scheme':\n case 'interpolate':\n return !contains(['point', 'band', 'identity'], scaleType);\n case 'bins':\n return !contains(['point', 'band', 'identity', 'ordinal'], scaleType);\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'padding':\n return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType);\n case 'paddingOuter':\n case 'rangeStep':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType);\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'quantize' || scaleType === 'threshold';\n case 'exponent':\n return scaleType === 'pow';\n case 'base':\n return scaleType === 'log';\n case 'constant':\n return scaleType === 'symlog';\n case 'zero':\n return (\n hasContinuousDomain(scaleType) &&\n !contains(\n [\n 'log', // log scale cannot have zero value\n 'time',\n 'utc', // zero is not meaningful for time\n 'threshold', // threshold requires custom domain so zero does not matter\n 'quantile' // quantile depends on distribution so zero does not matter\n ],\n scaleType\n )\n );\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'interpolate':\n case 'scheme':\n if (!isColorChannel(channel)) {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'bins':\n case 'domain':\n case 'range':\n case 'base':\n case 'exponent':\n case 'constant':\n case 'nice':\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n case 'rangeStep':\n case 'reverse':\n case 'round':\n case 'clamp':\n case 'zero':\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid scale property \"${propName}\".`);\n}\n\nexport function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type): boolean {\n if (contains([TYPE.ORDINAL, TYPE.NOMINAL], fieldDefType)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (fieldDefType === TYPE.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], specifiedType);\n } else if (fieldDefType === TYPE.QUANTITATIVE) {\n return contains(\n [\n ScaleType.LOG,\n ScaleType.POW,\n ScaleType.SQRT,\n ScaleType.SYMLOG,\n ScaleType.QUANTILE,\n ScaleType.QUANTIZE,\n ScaleType.THRESHOLD,\n ScaleType.LINEAR,\n undefined\n ],\n specifiedType\n );\n }\n\n return true;\n}\n\nexport function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case CHANNEL.X:\n case CHANNEL.Y:\n return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType);\n case CHANNEL.SIZE: // TODO: size and opacity can support ordinal with more modification\n case CHANNEL.STROKEWIDTH:\n case CHANNEL.OPACITY:\n case CHANNEL.FILLOPACITY:\n case CHANNEL.STROKEOPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return (\n isContinuousToContinuous(scaleType) ||\n isContinuousToDiscrete(scaleType) ||\n contains(['band', 'point'], scaleType)\n );\n case CHANNEL.COLOR:\n case CHANNEL.FILL:\n case CHANNEL.STROKE:\n return scaleType !== 'band'; // band does not make sense with color\n case CHANNEL.SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function getSupportedScaleType(channel: Channel, fieldDefType: Type) {\n return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType)];\n}\n\nexport interface ScaleTypeIndex {\n [channel: string]: ScaleType[];\n}\n\n// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes\nfunction generateScaleTypeIndex() {\n const index: ScaleTypeIndex = {};\n for (const channel of CHANNELS) {\n for (const fieldDefType of keys(TYPE_INDEX)) {\n for (const scaleType of SCALE_TYPES) {\n const key = generateScaleTypeIndexKey(channel, fieldDefType);\n if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType)) {\n index[key] = index[key] || [];\n index[key].push(scaleType);\n }\n }\n }\n }\n return index;\n}\n\nfunction generateScaleTypeIndexKey(channel: Channel, fieldDefType: Type) {\n return channel + '_' + fieldDefType;\n}\n","import {Axis, AXIS_PROPERTIES} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Legend, LEGEND_PROPERTIES} from 'vega-lite/build/src/legend';\nimport {Scale, SCALE_PROPERTIES} from 'vega-lite/build/src/scale';\nimport {EncodingSortField} from 'vega-lite/build/src/sort';\nimport {Flag, flagKeys} from 'vega-lite/build/src/util';\nimport {AutoCountQuery, FieldQuery, ValueQuery} from './query/encoding';\nimport {TransformQuery} from './query/transform';\nimport {Diff} from './util';\n\n/**\n * There are two types of `Property`'s.\n * One is just flat property names.\n * (Try to hover `FlatProp` to see all of them.)\n * Another is an object that describes a parent property (e.g., `scale`) and the child property (e.g., `type`)\n */\nexport type Property = FlatProp | EncodingNestedProp;\nexport type FlatProp = MarkProp | TransformProp | ViewProp | EncodingTopLevelProp;\n\nexport type MarkProp = 'mark' | 'stack'; // FIXME: determine how 'stack' works;\nexport type TransformProp = keyof TransformQuery;\nexport type ViewProp = 'width' | 'height' | 'background' | 'padding' | 'title';\nexport type EncodingTopLevelProp = Diff; // Do not include description since description is simply a metadata\n\nexport type EncodingNestedProp = BinProp | SortProp | ScaleProp | AxisProp | LegendProp;\n\nexport type EncodingNestedChildProp =\n | keyof BinParams\n | keyof EncodingSortField\n | keyof Scale\n | keyof Axis\n | keyof Legend;\n\n/**\n * An object that describes a parent property (e.g., `scale`) and the child property (e.g., `type`)\n */\nexport type BaseEncodingNestedProp = {\n parent: P;\n child: keyof T;\n};\n\nexport type BinProp = BaseEncodingNestedProp<'bin', BinParams>;\nexport type SortProp = BaseEncodingNestedProp<'sort', EncodingSortField>;\nexport type ScaleProp = BaseEncodingNestedProp<'scale', Scale>;\nexport type AxisProp = BaseEncodingNestedProp<'axis', Axis>;\nexport type LegendProp = BaseEncodingNestedProp<'legend', Legend>;\n\nexport function isEncodingNestedProp(p: Property): p is EncodingNestedProp {\n return !!p['parent'];\n}\n\nconst ENCODING_TOPLEVEL_PROP_INDEX: Flag = {\n channel: 1,\n aggregate: 1,\n autoCount: 1,\n bin: 1,\n timeUnit: 1,\n hasFn: 1,\n sort: 1,\n stack: 1,\n field: 1,\n type: 1,\n format: 1,\n scale: 1,\n axis: 1,\n legend: 1,\n value: 1\n};\n\nexport const ENCODING_TOPLEVEL_PROPS = flagKeys(ENCODING_TOPLEVEL_PROP_INDEX);\n\nexport function isEncodingTopLevelProperty(p: Property): p is EncodingTopLevelProp {\n return p in ENCODING_TOPLEVEL_PROP_INDEX;\n}\n\nexport type EncodingNestedPropParent = 'bin' | 'scale' | 'sort' | 'axis' | 'legend';\n\nconst ENCODING_NESTED_PROP_PARENT_INDEX: Flag = {\n bin: 1,\n scale: 1,\n sort: 1,\n axis: 1,\n legend: 1\n};\n\nexport function isEncodingNestedParent(prop: string): prop is EncodingNestedPropParent {\n return ENCODING_NESTED_PROP_PARENT_INDEX[prop as string];\n}\n\n// FIXME -- we should not have to manually specify these\nexport const BIN_CHILD_PROPS: (keyof BinParams)[] = ['maxbins', 'divide', 'extent', 'base', 'step', 'steps', 'minstep'];\nexport const SORT_CHILD_PROPS: (keyof EncodingSortField)[] = ['field', 'op', 'order'];\n\nconst BIN_PROPS = BIN_CHILD_PROPS.map(\n (c): BinProp => {\n return {parent: 'bin', child: c};\n }\n);\n\nexport const SORT_PROPS = SORT_CHILD_PROPS.map(\n (c): SortProp => {\n return {parent: 'sort', child: c};\n }\n);\n\nexport const SCALE_PROPS = SCALE_PROPERTIES.map(\n (c): ScaleProp => {\n return {parent: 'scale', child: c};\n }\n);\n\nconst AXIS_PROPS = AXIS_PROPERTIES.map(\n (c): AxisProp => {\n return {parent: 'axis', child: c};\n }\n);\n\nconst LEGEND_PROPS = LEGEND_PROPERTIES.map(\n (c): LegendProp => {\n return {parent: 'legend', child: c};\n }\n);\n\nexport const ENCODING_NESTED_PROPS = ([] as EncodingNestedProp[]).concat(\n BIN_PROPS,\n SORT_PROPS,\n SCALE_PROPS,\n AXIS_PROPS,\n LEGEND_PROPS\n);\n\nexport const VIEW_PROPS: Property[] = ['width', 'height', 'background', 'padding', 'title'] as Property[];\n\nconst PROP_KEY_DELIMITER = '.';\n\nexport function toKey(p: Property): string {\n if (isEncodingNestedProp(p)) {\n return p.parent + PROP_KEY_DELIMITER + p.child;\n }\n return p;\n}\n\nexport function fromKey(k: string): Property {\n const split = k.split(PROP_KEY_DELIMITER);\n /* istanbul ignore else */\n if (split.length === 1) {\n return k as Property;\n } else if (split.length === 2) {\n return {\n parent: split[0],\n child: split[1]\n } as EncodingNestedProp;\n } else {\n throw 'Invalid property key with ' + split.length + ' dots: ' + k;\n }\n}\n\nconst ENCODING_NESTED_PROP_INDEX = ENCODING_NESTED_PROPS.reduce((i, prop: EncodingNestedProp) => {\n i[prop.parent] = i[prop.parent] || [];\n i[prop.parent][prop.child] = prop;\n return i;\n}, {});\n\n// FIXME consider using a more general method\nexport function getEncodingNestedProp(parent: EncodingTopLevelProp, child: EncodingNestedChildProp) {\n return (ENCODING_NESTED_PROP_INDEX[parent] || {})[child];\n}\n\nexport function isEncodingProperty(p: Property): p is EncodingTopLevelProp | EncodingNestedProp {\n return isEncodingTopLevelProperty(p) || isEncodingNestedProp(p);\n}\n\nexport const ALL_ENCODING_PROPS = ([] as Property[]).concat(ENCODING_TOPLEVEL_PROPS, ENCODING_NESTED_PROPS);\n\nexport const DEFAULT_PROP_PRECEDENCE: Property[] = ([\n 'type', // type is a constraint for field\n 'field',\n\n // Field Transform\n 'bin',\n 'timeUnit',\n 'aggregate',\n 'autoCount',\n\n // Encoding\n 'channel',\n\n // Mark\n 'mark',\n 'stack',\n\n 'scale',\n 'sort',\n 'axis',\n 'legend'\n] as Property[]).concat(BIN_PROPS, SCALE_PROPS, AXIS_PROPS, LEGEND_PROPS, SORT_PROPS);\n\nexport namespace Property {\n export const MARK: 'mark' = 'mark';\n\n export const TRANSFORM: 'transform' = 'transform';\n // Layout\n export const STACK: 'stack' = 'stack';\n\n export const FORMAT: 'format' = 'format';\n\n // TODO: sub parts of stack\n\n // Encoding Properties\n export const CHANNEL: 'channel' = 'channel';\n export const AGGREGATE: 'aggregate' = 'aggregate';\n export const AUTOCOUNT: 'autoCount' = 'autoCount';\n export const BIN: 'bin' = 'bin';\n\n export const HAS_FN: 'hasFn' = 'hasFn';\n export const TIMEUNIT: 'timeUnit' = 'timeUnit';\n export const FIELD: 'field' = 'field';\n export const TYPE: 'type' = 'type';\n\n export const SORT: 'sort' = 'sort';\n\n export const SCALE: 'scale' = 'scale';\n export const AXIS: 'axis' = 'axis';\n\n export const LEGEND: 'legend' = 'legend';\n\n export const WIDTH: 'width' = 'width';\n export const HEIGHT: 'height' = 'height';\n export const BACKGROUND: 'background' = 'background';\n export const PADDING: 'padding' = 'padding';\n export const TITLE: 'title' = 'title';\n}\n","import {toSet} from 'vega-util';\nimport {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {contains, flagKeys} from './util';\nimport {BaseMarkConfig} from './vega.schema';\n\nexport const AREA: 'area' = 'area';\nexport const BAR: 'bar' = 'bar';\nexport const LINE: 'line' = 'line';\nexport const POINT: 'point' = 'point';\nexport const RECT: 'rect' = 'rect';\nexport const RULE: 'rule' = 'rule';\nexport const TEXT: 'text' = 'text';\nexport const TICK: 'tick' = 'tick';\nexport const TRAIL: 'trail' = 'trail';\nexport const CIRCLE: 'circle' = 'circle';\nexport const SQUARE: 'square' = 'square';\nexport const GEOSHAPE: 'geoshape' = 'geoshape';\n\n/**\n * All types of primitive marks.\n */\nexport type Mark =\n | typeof AREA\n | typeof BAR\n | typeof LINE\n | typeof TRAIL\n | typeof POINT\n | typeof TEXT\n | typeof TICK\n | typeof RECT\n | typeof RULE\n | typeof CIRCLE\n | typeof SQUARE\n | typeof GEOSHAPE;\n\n// Using mapped type to declare index, ensuring we always have all marks when we add more.\nconst MARK_INDEX: {[M in Mark]: 1} = {\n area: 1,\n bar: 1,\n line: 1,\n point: 1,\n text: 1,\n tick: 1,\n trail: 1,\n rect: 1,\n geoshape: 1,\n rule: 1,\n circle: 1,\n square: 1\n};\n\nexport function isMark(m: string): m is Mark {\n return !!MARK_INDEX[m];\n}\n\nexport function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail' {\n return contains(['line', 'area', 'trail'], m);\n}\n\nexport const PRIMITIVE_MARKS = flagKeys(MARK_INDEX);\n\nexport interface ColorMixins {\n /**\n * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`.\n *\n * __Default value:__ `\"#4682b4\"`\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface TooltipContent {\n content: 'encoding' | 'data';\n}\n\nexport interface MarkConfig extends ColorMixins, BaseMarkConfig {\n // ========== VL-Specific ==========\n\n /**\n * Whether the mark's color should be used as fill color instead of stroke color.\n *\n * __Default value:__ `false` for `point`, `line` and `rule`; otherwise, `true`.\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n *\n */\n filled?: boolean;\n\n // ========== Overriding Vega ==========\n\n /**\n * The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from.\n *\n * - If `tooltip` is `{\"content\": \"encoding\"}`, then all fields from `encoding` will be used.\n * - If `tooltip` is `{\"content\": \"data\"}`, then all fields that appear in the highlighted data point will be used.\n * - If set to `null`, then no tooltip will be used.\n */\n tooltip?: string | TooltipContent | null;\n\n /**\n * Default size for marks.\n * - For `point`/`circle`/`square`, this represents the pixel area of the marks. For example: in the case of circles, the radius is determined in part by the square root of the size value.\n * - For `bar`, this represents the band size of the bar, in pixels.\n * - For `text`, this represents the font size, in pixels.\n *\n * __Default value:__ `30` for point, circle, square marks; `rangeStep` - 1 for bar marks with discrete dimensions; `5` for bar marks with continuous dimensions; `11` for text marks.\n *\n * @minimum 0\n */\n size?: number;\n\n /**\n * For line and trail marks, this `order` property can be set to `null` or `false` to make the lines use the original order in the data sources.\n */\n order?: null | boolean;\n}\n\nexport interface BarBinSpacingMixins {\n /**\n * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n binSpacing?: number;\n}\n\nexport type AnyMark = CompositeMark | CompositeMarkDef | Mark | MarkDef;\n\nexport function isMarkDef(mark: string | GenericMarkDef): mark is GenericMarkDef {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: AnyMark): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = [\n 'stroke',\n 'strokeWidth',\n 'strokeDash',\n 'strokeDashOffset',\n 'strokeOpacity',\n 'strokeJoin',\n 'strokeMiterLimit'\n];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[] = ['filled', 'color', 'tooltip'];\n\nexport const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: {\n [k in typeof PRIMITIVE_MARKS[0]]?: (keyof MarkConfigMixins[k])[]\n} = {\n area: ['line', 'point'],\n bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n line: ['point'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n tooltip: {content: 'encoding'}\n};\n\nexport interface MarkConfigMixins {\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: AreaConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: LineConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n /** Trail-Specific Config */\n trail?: LineConfig;\n\n /** Geoshape-Specific Config */\n geoshape?: MarkConfig;\n}\n\nexport interface BarConfig extends BarBinSpacingMixins, MarkConfig {\n /**\n * The default size of the bars on continuous scales.\n *\n * __Default value:__ `5`\n *\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The default size of the bars with discrete dimensions. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport type OverlayMarkDef = MarkConfig & MarkDefMixins;\n\nexport interface PointOverlayMixins {\n /**\n * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n *\n * - If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n *\n * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n *\n * - If this property is `false`, no points would be automatically added to line or area marks.\n *\n * __Default value:__ `false`.\n */\n point?: boolean | OverlayMarkDef | 'transparent';\n}\n\nexport interface LineConfig extends MarkConfig, PointOverlayMixins {}\n\nexport interface LineOverlayMixins {\n /**\n * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n *\n * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n *\n * - If this value is `false`, no lines would be automatically added to area marks.\n *\n * __Default value:__ `false`.\n */\n line?: boolean | OverlayMarkDef;\n}\n\nexport interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins {}\n\nexport interface TickThicknessMixins {\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport interface GenericMarkDef {\n /**\n * The mark type. This could a primitive mark type\n * (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`)\n * or a composite mark type (`\"boxplot\"`, `\"errorband\"`, `\"errorbar\"`).\n */\n type: M;\n}\n\nexport interface MarkDefMixins {\n /**\n * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default.\n *\n * __Default value:__ The mark's name. For example, a bar mark will have style `\"bar\"` by default.\n * __Note:__ Any specified style will augment the default style. For example, a bar mark with `\"style\": \"foo\"` will receive from `config.style.bar` and `config.style.foo` (the specified style `\"foo\"` has higher precedence).\n */\n style?: string | string[];\n\n /**\n * Whether a mark be clipped to the enclosing group’s width and height.\n */\n clip?: boolean;\n\n // Offset properties should not be a part of config\n\n /**\n * Offset for x-position.\n */\n xOffset?: number;\n\n /**\n * Offset for y-position.\n */\n yOffset?: number;\n\n /**\n * Offset for x2-position.\n */\n x2Offset?: number;\n\n /**\n * Offset for y2-position.\n */\n y2Offset?: number;\n}\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\nexport interface MarkDef\n extends GenericMarkDef,\n BarBinSpacingMixins,\n MarkConfig,\n PointOverlayMixins,\n LineOverlayMixins,\n TickThicknessMixins,\n MarkDefMixins {}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 5\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport interface TickConfig extends MarkConfig, TickThicknessMixins {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 3/4 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n\nexport function getMarkType(m: string | GenericMarkDef) {\n return isMarkDef(m) ? m.type : m;\n}\n","// DateTime definition object\n\nimport {isNumber} from 'vega-util';\nimport * as log from './log';\nimport {duplicate, keys} from './util';\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of a day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing the minute segment of time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing the second segment (0-59) of a time value\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing the millisecond segment of time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n\n /**\n * A boolean flag indicating if date time is in utc time. If false, the date time is in local time\n */\n utc?: boolean;\n}\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n utc?: boolean;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return (\n !!o &&\n (!!o.year ||\n !!o.quarter ||\n !!o.month ||\n !!o.date ||\n !!o.day ||\n !!o.hours ||\n !!o.minutes ||\n !!o.seconds ||\n !!o.milliseconds)\n );\n}\n\nexport const MONTHS = [\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december'\n];\nexport const SHORT_MONTHS = MONTHS.map(m => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map(d => d.substr(0, 3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1).toString();\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1).toString();\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n if (d.utc) {\n return `utc(${units.join(', ')})`;\n } else {\n return `datetime(${units.join(', ')})`;\n }\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPathWithDatum, Flag, flagKeys} from './util';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' =\n 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE and MONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const MONTHDATEHOURS: 'monthdatehours' = 'monthdatehours';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n export const UTCYEAR: 'utcyear' = 'utcyear';\n export const UTCMONTH: 'utcmonth' = 'utcmonth';\n export const UTCDAY: 'utcday' = 'utcday';\n export const UTCDATE: 'utcdate' = 'utcdate';\n export const UTCHOURS: 'utchours' = 'utchours';\n export const UTCMINUTES: 'utcminutes' = 'utcminutes';\n export const UTCSECONDS: 'utcseconds' = 'utcseconds';\n export const UTCMILLISECONDS: 'utcmilliseconds' = 'utcmilliseconds';\n export const UTCYEARMONTH: 'utcyearmonth' = 'utcyearmonth';\n export const UTCYEARMONTHDATE: 'utcyearmonthdate' = 'utcyearmonthdate';\n export const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours' = 'utcyearmonthdatehours';\n export const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes' = 'utcyearmonthdatehoursminutes';\n export const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds' =\n 'utcyearmonthdatehoursminutesseconds';\n\n // UTCMONTHDATE and UTCMONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year);\n export const UTCMONTHDATE: 'utcmonthdate' = 'utcmonthdate';\n export const UTCMONTHDATEHOURS: 'utcmonthdatehours' = 'utcmonthdatehours';\n export const UTCHOURSMINUTES: 'utchoursminutes' = 'utchoursminutes';\n export const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds' = 'utchoursminutesseconds';\n export const UTCMINUTESSECONDS: 'utcminutesseconds' = 'utcminutesseconds';\n export const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds' = 'utcsecondsmilliseconds';\n export const UTCQUARTER: 'utcquarter' = 'utcquarter';\n export const UTCYEARQUARTER: 'utcyearquarter' = 'utcyearquarter';\n export const UTCQUARTERMONTH: 'utcquartermonth' = 'utcquartermonth';\n export const UTCYEARQUARTERMONTH: 'utcyearquartermonth' = 'utcyearquartermonth';\n}\n\nexport type LocalSingleTimeUnit =\n | typeof TimeUnit.YEAR\n | typeof TimeUnit.QUARTER\n | typeof TimeUnit.MONTH\n | typeof TimeUnit.DAY\n | typeof TimeUnit.DATE\n | typeof TimeUnit.HOURS\n | typeof TimeUnit.MINUTES\n | typeof TimeUnit.SECONDS\n | typeof TimeUnit.MILLISECONDS;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nconst LOCAL_SINGLE_TIMEUNIT_INDEX: Flag = {\n year: 1,\n quarter: 1,\n month: 1,\n day: 1,\n date: 1,\n hours: 1,\n minutes: 1,\n seconds: 1,\n milliseconds: 1\n};\n\nexport const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX);\n\nexport function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit {\n return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type UtcSingleTimeUnit =\n | typeof TimeUnit.UTCYEAR\n | typeof TimeUnit.UTCQUARTER\n | typeof TimeUnit.UTCMONTH\n | typeof TimeUnit.UTCDAY\n | typeof TimeUnit.UTCDATE\n | typeof TimeUnit.UTCHOURS\n | typeof TimeUnit.UTCMINUTES\n | typeof TimeUnit.UTCSECONDS\n | typeof TimeUnit.UTCMILLISECONDS;\n\nconst UTC_SINGLE_TIMEUNIT_INDEX: Flag = {\n utcyear: 1,\n utcquarter: 1,\n utcmonth: 1,\n utcday: 1,\n utcdate: 1,\n utchours: 1,\n utcminutes: 1,\n utcseconds: 1,\n utcmilliseconds: 1\n};\n\nexport function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit {\n return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit;\n\nexport type LocalMultiTimeUnit =\n // Local Time\n | typeof TimeUnit.YEARQUARTER\n | typeof TimeUnit.YEARQUARTERMONTH\n | typeof TimeUnit.YEARMONTH\n | typeof TimeUnit.YEARMONTHDATE\n | typeof TimeUnit.YEARMONTHDATEHOURS\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS\n | typeof TimeUnit.QUARTERMONTH\n | typeof TimeUnit.MONTHDATE\n | typeof TimeUnit.MONTHDATEHOURS\n | typeof TimeUnit.HOURSMINUTES\n | typeof TimeUnit.HOURSMINUTESSECONDS\n | typeof TimeUnit.MINUTESSECONDS\n | typeof TimeUnit.SECONDSMILLISECONDS;\n\nconst LOCAL_MULTI_TIMEUNIT_INDEX: Flag = {\n yearquarter: 1,\n yearquartermonth: 1,\n\n yearmonth: 1,\n yearmonthdate: 1,\n yearmonthdatehours: 1,\n yearmonthdatehoursminutes: 1,\n yearmonthdatehoursminutesseconds: 1,\n\n quartermonth: 1,\n\n monthdate: 1,\n monthdatehours: 1,\n\n hoursminutes: 1,\n hoursminutesseconds: 1,\n\n minutesseconds: 1,\n\n secondsmilliseconds: 1\n};\n\nexport type UtcMultiTimeUnit =\n | typeof TimeUnit.UTCYEARQUARTER\n | typeof TimeUnit.UTCYEARQUARTERMONTH\n | typeof TimeUnit.UTCYEARMONTH\n | typeof TimeUnit.UTCYEARMONTHDATE\n | typeof TimeUnit.UTCYEARMONTHDATEHOURS\n | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS\n | typeof TimeUnit.UTCQUARTERMONTH\n | typeof TimeUnit.UTCMONTHDATE\n | typeof TimeUnit.UTCMONTHDATEHOURS\n | typeof TimeUnit.UTCHOURSMINUTES\n | typeof TimeUnit.UTCHOURSMINUTESSECONDS\n | typeof TimeUnit.UTCMINUTESSECONDS\n | typeof TimeUnit.UTCSECONDSMILLISECONDS;\n\nconst UTC_MULTI_TIMEUNIT_INDEX: Flag = {\n utcyearquarter: 1,\n utcyearquartermonth: 1,\n\n utcyearmonth: 1,\n utcyearmonthdate: 1,\n utcyearmonthdatehours: 1,\n utcyearmonthdatehoursminutes: 1,\n utcyearmonthdatehoursminutesseconds: 1,\n\n utcquartermonth: 1,\n\n utcmonthdate: 1,\n utcmonthdatehours: 1,\n\n utchoursminutes: 1,\n utchoursminutesseconds: 1,\n\n utcminutesseconds: 1,\n\n utcsecondsmilliseconds: 1\n};\n\nexport type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit;\n\nexport type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit;\nexport type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit;\n\nconst UTC_TIMEUNIT_INDEX: Flag = {\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport function isUTCTimeUnit(t: string): t is UtcTimeUnit {\n return !!UTC_TIMEUNIT_INDEX[t];\n}\n\nexport function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit {\n return t.substr(3) as LocalTimeUnit;\n}\n\nexport type TimeUnit = SingleTimeUnit | MultiTimeUnit;\n\nconst TIMEUNIT_INDEX: Flag = {\n ...LOCAL_SINGLE_TIMEUNIT_INDEX,\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...LOCAL_MULTI_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport const TIMEUNITS = flagKeys(TIMEUNIT_INDEX);\n\nexport function isTimeUnit(t: string): t is TimeUnit {\n return !!TIMEUNIT_INDEX[t];\n}\n\ntype DateMethodName = keyof Date;\n\nconst SET_DATE_METHOD: Record = {\n year: 'setFullYear',\n month: 'setMonth',\n date: 'setDate',\n hours: 'setHours',\n minutes: 'setMinutes',\n seconds: 'setSeconds',\n milliseconds: 'setMilliseconds',\n // Day and quarter have their own special cases\n quarter: null,\n day: null\n};\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const isUTC = isUTCTimeUnit(unit);\n const result: Date = isUTC\n ? // start with uniform date\n new Date(Date.UTC(1972, 0, 1, 0, 0, 0, 0)) // 1972 is the first leap year after 1970, the start of unix time\n : new Date(1972, 0, 1, 0, 0, 0, 0);\n for (const timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(unit, timeUnitPart)) {\n switch (timeUnitPart) {\n case TimeUnit.DAY:\n throw new Error(\"Cannot convert to TimeUnits containing 'day'\");\n case TimeUnit.QUARTER: {\n const {getDateMethod, setDateMethod} = dateMethods('month', isUTC);\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result[setDateMethod](Math.floor(date[getDateMethod]() / 3) * 3);\n break;\n }\n default: {\n const {getDateMethod, setDateMethod} = dateMethods(timeUnitPart, isUTC);\n result[setDateMethod](date[getDateMethod]());\n }\n }\n }\n }\n return result;\n}\n\nfunction dateMethods(singleUnit: SingleTimeUnit, isUtc: boolean) {\n const rawSetDateMethod = SET_DATE_METHOD[singleUnit];\n const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod;\n const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3);\n return {setDateMethod, getDateMethod};\n}\n\nexport function getTimeUnitParts(timeUnit: TimeUnit) {\n return TIMEUNIT_PARTS.reduce((parts, part) => {\n if (containsTimeUnit(timeUnit, part)) {\n return [...parts, part];\n }\n return parts;\n }, []);\n}\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n const index = fullTimeUnit.indexOf(timeUnit);\n return (\n index > -1 && (timeUnit !== TimeUnit.SECONDS || index === 0 || fullTimeUnit.charAt(index - 1) !== 'i') // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = accessPathWithDatum(field);\n\n const utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : '';\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(${utc}quarter(${fieldRef})-1)`;\n } else {\n return `${utc}${timeUnit}(${fieldRef})`;\n }\n }\n\n const d = TIMEUNIT_PARTS.reduce(\n (dateExpr: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n dateExpr[tu] = func(tu);\n }\n return dateExpr;\n },\n {} as {[key in SingleTimeUnit]: string}\n );\n\n return dateTimeExpr(d);\n}\n\nexport function getDateTimeComponents(timeUnit: TimeUnit, shortTimeLabels: boolean) {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateComponents: string[] = [];\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n const timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n const dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n return dateTimeComponents;\n}\n\n/**\n * returns the signal expression used for axis labels for a time unit\n */\nexport function formatExpression(\n timeUnit: TimeUnit,\n field: string,\n shortTimeLabels: boolean,\n isUTCScale: boolean\n): string {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateTimeComponents: string[] = getDateTimeComponents(timeUnit, shortTimeLabels);\n let expression = '';\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n\n // We only use utcFormat for utc scale\n // For utc time units, the data is already converted as a part of timeUnit transform.\n // Thus, utc time units should use timeFormat to avoid shifting the time twice.\n if (isUTCScale) {\n expression += `utcFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n } else {\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit {\n if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) {\n log.warn(log.message.dayReplacedWithDate(timeUnit));\n return timeUnit.replace('day', 'date') as TimeUnit;\n }\n return timeUnit;\n}\n","var u = module.exports;\n\n// utility functions\n\nvar FNAME = '__name__';\n\nu.namedfunc = function(name, f) { return (f[FNAME] = name, f); };\n\nu.name = function(f) { return f==null ? null : f[FNAME]; };\n\nu.identity = function(x) { return x; };\n\nu.true = u.namedfunc('true', function() { return true; });\n\nu.false = u.namedfunc('false', function() { return false; });\n\nu.duplicate = function(obj) {\n return JSON.parse(JSON.stringify(obj));\n};\n\nu.equal = function(a, b) {\n return JSON.stringify(a) === JSON.stringify(b);\n};\n\nu.extend = function(obj) {\n for (var x, name, i=1, len=arguments.length; i 1 ?\n function(x, v) {\n for (var i=0; i b || b == null) && a != null ? 1 :\n ((b = b instanceof Date ? +b : b),\n (a = a instanceof Date ? +a : a)) !== a && b === b ? -1 :\n b !== b && a === a ? 1 : 0;\n};\n\nu.numcmp = function(a, b) { return a - b; };\n\nu.stablesort = function(array, sortBy, keyFn) {\n var indices = array.reduce(function(idx, v, i) {\n return (idx[keyFn(v)] = i, idx);\n }, {});\n\n array.sort(function(a, b) {\n var sa = sortBy(a),\n sb = sortBy(b);\n return sa < sb ? -1 : sa > sb ? 1\n : (indices[keyFn(a)] - indices[keyFn(b)]);\n });\n\n return array;\n};\n\n// permutes an array using a Knuth shuffle\nu.permute = function(a) {\n var m = a.length,\n swap,\n i;\n\n while (m) {\n i = Math.floor(Math.random() * m--);\n swap = a[m];\n a[m] = a[i];\n a[i] = swap;\n }\n};\n\n// string functions\n\nu.pad = function(s, length, pos, padchar) {\n padchar = padchar || \" \";\n var d = length - s.length;\n if (d <= 0) return s;\n switch (pos) {\n case 'left':\n return strrep(d, padchar) + s;\n case 'middle':\n case 'center':\n return strrep(Math.floor(d/2), padchar) +\n s + strrep(Math.ceil(d/2), padchar);\n default:\n return s + strrep(d, padchar);\n }\n};\n\nfunction strrep(n, str) {\n var s = \"\", i;\n for (i=0; i {\n [key: string]: T;\n}\n\nexport function contains(array: any[], item: any) {\n return array.indexOf(item) !== -1;\n};\n\nexport function every(arr: T[], f: (item: T, key: number) => boolean) {\n for (let i = 0; i < arr.length; i++) {\n if (!f(arr[i], i)) {\n return false;\n }\n }\n return true;\n};\n\nexport function forEach(obj: any, f: (item: any, key: number|string, i: number)=>void, thisArg?: any) {\n if (obj.forEach) {\n obj.forEach.call(thisArg, f);\n } else {\n for (let k in obj) {\n f.call(thisArg, obj[k], k, obj);\n }\n }\n};\n\nexport function some(arr: T[], f: (item: T, key: number|string, i: number)=>boolean) {\n let i = 0, k;\n for (k in arr) {\n if (f(arr[k], k, i++)) {\n return true;\n }\n }\n return false;\n};\n\nexport function nestedMap(array: any[], f: (item: any)=>any): any[] {\n return array.map((a) => {\n if (isArray(a)) {\n return nestedMap(a, f);\n }\n return f(a);\n });\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: Array, excludedItems: Array) {\n return array.filter(function(item) {\n return !contains(excludedItems, item);\n });\n}\n\nexport type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];\n","import {Axis, AXIS_PROPERTIES} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Channel, COLOR, COLUMN, ROW, SIZE, X, Y} from 'vega-lite/build/src/channel';\nimport {TypedFieldDef} from 'vega-lite/build/src/channeldef';\nimport {Legend, LEGEND_PROPERTIES} from 'vega-lite/build/src/legend';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {Scale, ScaleType, SCALE_PROPERTIES} from 'vega-lite/build/src/scale';\nimport {EncodingSortField, SortOrder} from 'vega-lite/build/src/sort';\nimport {StackOffset} from 'vega-lite/build/src/stack';\nimport {TimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {isEncodingNestedProp, Property} from './property';\nimport {Schema} from './schema';\nimport {extend, isArray} from './util';\n\nexport const SHORT_WILDCARD: SHORT_WILDCARD = '?';\nexport type SHORT_WILDCARD = '?';\n\nexport interface Wildcard {\n name?: string;\n\n /**\n * List of values to enumerate\n */\n enum?: T[];\n}\n\nexport type WildcardProperty = T | Wildcard | SHORT_WILDCARD;\n\nexport interface ExtendedWildcard extends Wildcard {\n [prop: string]: any;\n}\n\nexport function isWildcard(prop: any): prop is Wildcard | SHORT_WILDCARD {\n return isShortWildcard(prop) || isWildcardDef(prop);\n}\n\nexport function isShortWildcard(prop: any): prop is SHORT_WILDCARD {\n return prop === SHORT_WILDCARD;\n}\n\nexport function isWildcardDef(prop: any): prop is Wildcard {\n return prop !== undefined && prop != null && (!!prop.enum || !!prop.name) && !isArray(prop);\n}\n\nexport function initWildcard(\n prop: SHORT_WILDCARD | ExtendedWildcard,\n defaultName: string,\n defaultEnumValues: any[]\n): ExtendedWildcard {\n return extend(\n {},\n {\n name: defaultName,\n enum: defaultEnumValues\n },\n prop === SHORT_WILDCARD ? {} : prop\n );\n}\n\n/**\n * Initial short names from list of full camelCaseNames.\n * For each camelCaseNames, return unique short names based on initial (e.g., `ccn`)\n */\nfunction initNestedPropName(fullNames: string[]) {\n let index = {};\n let has = {};\n for (const fullName of fullNames) {\n const initialIndices = [0];\n for (let i = 0; i < fullName.length; i++) {\n if (fullName.charAt(i).toUpperCase() === fullName.charAt(i)) {\n initialIndices.push(i);\n }\n }\n let shortName = initialIndices\n .map(i => fullName.charAt(i))\n .join('')\n .toLowerCase();\n if (!has[shortName]) {\n index[fullName] = shortName;\n has[shortName] = true;\n continue;\n }\n // If duplicate, add last character and try again!\n if (initialIndices[initialIndices.length - 1] !== fullName.length - 1) {\n shortName = initialIndices\n .concat([fullName.length - 1])\n .map(i => fullName.charAt(i))\n .join('')\n .toLowerCase();\n if (!has[shortName]) {\n index[fullName] = shortName;\n has[shortName] = true;\n continue;\n }\n }\n for (let i = 1; !index[fullName]; i++) {\n let shortNameWithNo = shortName + '_' + i;\n if (!has[shortNameWithNo]) {\n index[fullName] = shortNameWithNo;\n has[shortNameWithNo] = true;\n break;\n }\n }\n }\n return index;\n}\n\nexport const DEFAULT_NAME = {\n mark: 'm',\n channel: 'c',\n aggregate: 'a',\n autoCount: '#',\n hasFn: 'h',\n bin: 'b',\n sort: 'so',\n stack: 'st',\n scale: 's',\n format: 'f',\n axis: 'ax',\n legend: 'l',\n value: 'v',\n\n timeUnit: 'tu',\n field: 'f',\n type: 't',\n\n binProps: {\n maxbins: 'mb',\n min: 'mi',\n max: 'ma',\n base: 'b',\n step: 's',\n steps: 'ss',\n minstep: 'ms',\n divide: 'd'\n },\n sortProps: {\n field: 'f',\n op: 'o',\n order: 'or'\n },\n scaleProps: initNestedPropName(SCALE_PROPERTIES),\n axisProps: initNestedPropName(AXIS_PROPERTIES),\n legendProps: initNestedPropName(LEGEND_PROPERTIES)\n};\n\nexport function getDefaultName(prop: Property) {\n if (isEncodingNestedProp(prop)) {\n return DEFAULT_NAME[prop.parent] + '-' + DEFAULT_NAME[prop.parent + 'Props'][prop.child];\n }\n if (DEFAULT_NAME[prop]) {\n return DEFAULT_NAME[prop];\n }\n /* istanbul ignore next */\n throw new Error('Default name undefined for ' + prop);\n}\n\n/**\n * Generic index for default enum (values to enumerate) of a particular definition type.\n */\nexport type DefEnumIndex = {[P in keyof T]-?: T[P][]};\n\nconst DEFAULT_BOOLEAN_ENUM = [false, true];\n\nexport type EnumIndex = {\n mark: Mark[];\n channel: Channel[];\n autoCount: boolean[];\n hasFn: boolean[];\n} & DefEnumIndex> & {\n sort: (EncodingSortField | SortOrder)[];\n stack: StackOffset[];\n format: string[];\n scale: boolean[];\n axis: boolean[];\n legend: boolean[];\n value: any[];\n\n binProps: Partial>;\n sortProps: Partial>>;\n scaleProps: Partial>;\n axisProps: Partial>;\n legendProps: Partial>;\n };\n\nconst DEFAULT_BIN_PROPS_ENUM: DefEnumIndex = {\n maxbins: [5, 10, 20],\n extent: [undefined],\n base: [10],\n step: [undefined],\n steps: [undefined],\n minstep: [undefined],\n divide: [[5, 2]],\n binned: [false],\n anchor: [undefined],\n nice: [true]\n};\n\nconst DEFAULT_SORT_PROPS: DefEnumIndex> = {\n field: [undefined], // This should be never call and instead read from the schema\n op: ['min', 'mean'],\n order: ['ascending', 'descending']\n};\n\nconst DEFAULT_SCALE_PROPS_ENUM: DefEnumIndex = {\n type: [undefined, ScaleType.LOG],\n domain: [undefined],\n base: [undefined],\n exponent: [1, 2],\n constant: [undefined],\n\n bins: [undefined],\n\n clamp: DEFAULT_BOOLEAN_ENUM,\n nice: DEFAULT_BOOLEAN_ENUM,\n reverse: DEFAULT_BOOLEAN_ENUM,\n round: DEFAULT_BOOLEAN_ENUM,\n zero: DEFAULT_BOOLEAN_ENUM,\n\n padding: [undefined],\n paddingInner: [undefined],\n paddingOuter: [undefined],\n\n interpolate: [undefined],\n\n range: [undefined],\n rangeStep: [17, 21],\n scheme: [undefined]\n};\n\nconst DEFAULT_AXIS_PROPS_ENUM: DefEnumIndex = {\n zindex: [1, 0],\n offset: [undefined],\n orient: [undefined],\n values: [undefined],\n\n bandPosition: [undefined],\n encoding: [undefined],\n\n domain: DEFAULT_BOOLEAN_ENUM,\n domainColor: [undefined],\n domainDash: [undefined],\n domainDashOffset: [undefined],\n domainOpacity: [undefined],\n domainWidth: [undefined],\n\n formatType: [undefined],\n\n grid: DEFAULT_BOOLEAN_ENUM,\n gridColor: [undefined],\n gridDash: [undefined],\n gridDashOffset: [undefined],\n gridOpacity: [undefined],\n gridWidth: [undefined],\n\n format: [undefined],\n labels: DEFAULT_BOOLEAN_ENUM,\n labelAlign: [undefined],\n labelAngle: [undefined],\n labelBaseline: [undefined],\n labelColor: [undefined],\n labelFlushOffset: [undefined],\n labelFont: [undefined],\n labelFontSize: [undefined],\n labelFontStyle: [undefined],\n labelFontWeight: [undefined],\n labelLimit: [undefined],\n labelOpacity: [undefined],\n labelSeparation: [undefined],\n labelOverlap: [undefined],\n labelPadding: [undefined],\n labelBound: [undefined],\n labelFlush: [undefined],\n\n maxExtent: [undefined],\n minExtent: [undefined],\n position: [undefined],\n\n ticks: DEFAULT_BOOLEAN_ENUM,\n tickColor: [undefined],\n tickCount: [undefined],\n tickDash: [undefined],\n tickExtra: [undefined],\n tickDashOffset: [undefined],\n tickMinStep: [undefined],\n tickOffset: [undefined],\n tickOpacity: [undefined],\n tickRound: [undefined],\n tickSize: [undefined],\n tickWidth: [undefined],\n\n title: [undefined],\n titleAlign: [undefined],\n titleAnchor: [undefined],\n titleAngle: [undefined],\n titleBaseline: [undefined],\n titleColor: [undefined],\n titleFont: [undefined],\n titleFontSize: [undefined],\n titleFontStyle: [undefined],\n titleFontWeight: [undefined],\n titleLimit: [undefined],\n titleOpacity: [undefined],\n titlePadding: [undefined],\n titleX: [undefined],\n titleY: [undefined]\n};\n\nconst DEFAULT_LEGEND_PROPS_ENUM: DefEnumIndex = {\n orient: ['left', 'right'],\n format: [undefined],\n type: [undefined],\n values: [undefined],\n zindex: [undefined],\n\n clipHeight: [undefined],\n columnPadding: [undefined],\n columns: [undefined],\n cornerRadius: [undefined],\n direction: [undefined],\n encoding: [undefined],\n fillColor: [undefined],\n formatType: [undefined],\n gridAlign: [undefined],\n offset: [undefined],\n padding: [undefined],\n rowPadding: [undefined],\n strokeColor: [undefined],\n\n labelAlign: [undefined],\n labelBaseline: [undefined],\n labelColor: [undefined],\n labelFont: [undefined],\n labelFontSize: [undefined],\n labelFontStyle: [undefined],\n labelFontWeight: [undefined],\n labelLimit: [undefined],\n labelOffset: [undefined],\n labelOpacity: [undefined],\n labelOverlap: [undefined],\n labelPadding: [undefined],\n labelSeparation: [undefined],\n\n legendX: [undefined],\n legendY: [undefined],\n\n gradientLength: [undefined],\n gradientOpacity: [undefined],\n gradientStrokeColor: [undefined],\n gradientStrokeWidth: [undefined],\n gradientThickness: [undefined],\n\n symbolDash: [undefined],\n symbolDashOffset: [undefined],\n symbolFillColor: [undefined],\n symbolOffset: [undefined],\n symbolOpacity: [undefined],\n symbolSize: [undefined],\n symbolStrokeColor: [undefined],\n symbolStrokeWidth: [undefined],\n symbolType: [undefined],\n\n tickCount: [undefined],\n tickMinStep: [undefined],\n\n title: [undefined],\n titleAnchor: [undefined],\n titleAlign: [undefined],\n titleBaseline: [undefined],\n titleColor: [undefined],\n titleFont: [undefined],\n titleFontSize: [undefined],\n titleFontStyle: [undefined],\n titleFontWeight: [undefined],\n titleLimit: [undefined],\n titleOpacity: [undefined],\n titleOrient: [undefined],\n titlePadding: [undefined]\n};\n\n// Use FullEnumIndex to make sure we have all properties specified here!\nexport const DEFAULT_ENUM_INDEX: EnumIndex = {\n mark: [MARK.POINT, MARK.BAR, MARK.LINE, MARK.AREA, MARK.RECT, MARK.TICK, MARK.TEXT],\n channel: [X, Y, ROW, COLUMN, SIZE, COLOR], // TODO: TEXT\n\n aggregate: [undefined, 'mean'],\n autoCount: DEFAULT_BOOLEAN_ENUM,\n bin: DEFAULT_BOOLEAN_ENUM,\n hasFn: DEFAULT_BOOLEAN_ENUM,\n timeUnit: [undefined, TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.MINUTES, TimeUnit.SECONDS],\n\n field: [undefined], // This is not used as field should be read from schema\n type: [TYPE.NOMINAL, TYPE.ORDINAL, TYPE.QUANTITATIVE, TYPE.TEMPORAL],\n\n sort: ['ascending', 'descending'],\n stack: ['zero', 'normalize', 'center', null],\n value: [undefined],\n\n format: [undefined],\n title: [undefined],\n scale: [true],\n axis: DEFAULT_BOOLEAN_ENUM,\n legend: DEFAULT_BOOLEAN_ENUM,\n\n binProps: DEFAULT_BIN_PROPS_ENUM,\n sortProps: DEFAULT_SORT_PROPS,\n scaleProps: DEFAULT_SCALE_PROPS_ENUM,\n axisProps: DEFAULT_AXIS_PROPS_ENUM,\n legendProps: DEFAULT_LEGEND_PROPS_ENUM\n};\n\n// TODO: rename this to getDefaultEnum\nexport function getDefaultEnumValues(prop: Property, schema: Schema, opt: QueryConfig): any[] {\n if (prop === 'field' || (isEncodingNestedProp(prop) && prop.parent === 'sort' && prop.child === 'field')) {\n // For field, by default enumerate all fields\n return schema.fieldNames();\n }\n\n let val;\n if (isEncodingNestedProp(prop)) {\n val = opt.enum[prop.parent + 'Props'][prop.child];\n } else {\n val = opt.enum[prop];\n }\n\n if (val !== undefined) {\n return val;\n }\n\n /* istanbul ignore next */\n throw new Error('No default enumValues for ' + JSON.stringify(prop));\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Config} from 'vega-lite/build/src/config';\nimport {DEFAULT_PROP_PRECEDENCE, toKey} from './property';\nimport {DEFAULT_ENUM_INDEX, EnumIndex} from './wildcard';\n\n// We name this QueryConfig to avoid confusion with Vega-Lite's Config\nexport interface QueryConfig {\n verbose?: boolean;\n\n defaultSpecConfig?: Config;\n\n propertyPrecedence?: string[];\n\n enum?: Partial;\n\n /** Default ratio for number fields to be considered ordinal */\n numberNominalProportion?: number;\n\n /** Default cutoff for not applying the numberOrdinalProportion inference */\n numberNominalLimit?: number;\n\n // SPECIAL MODE\n /**\n * Allow automatically adding a special count (autoCount) field for plots\n * that contain only discrete fields. In such cases, adding count make the\n * output plots way more meaningful.\n */\n autoAddCount?: boolean;\n\n // CONSTRAINTS\n constraintManuallySpecifiedValue?: boolean;\n // Spec Constraints\n\n hasAppropriateGraphicTypeForMark?: boolean;\n omitAggregate?: boolean;\n omitAggregatePlotWithDimensionOnlyOnFacet?: boolean;\n omitAggregatePlotWithoutDimension?: boolean;\n omitBarLineAreaWithOcclusion?: boolean;\n omitBarTickWithSize?: boolean;\n omitMultipleNonPositionalChannels?: boolean;\n omitRaw?: boolean;\n omitRawContinuousFieldForAggregatePlot?: boolean;\n omitRawWithXYBothOrdinalScaleOrBin?: boolean;\n omitRepeatedField?: boolean;\n omitNonPositionalOrFacetOverPositionalChannels?: boolean;\n omitTableWithOcclusionIfAutoAddCount?: boolean;\n omitVerticalDotPlot?: boolean;\n omitInvalidStackSpec?: boolean;\n omitNonSumStack?: boolean;\n\n preferredBinAxis?: Channel;\n preferredTemporalAxis?: Channel;\n preferredOrdinalAxis?: Channel;\n preferredNominalAxis?: Channel;\n preferredFacet?: Channel;\n\n // Field Encoding Constraints\n minCardinalityForBin?: number;\n maxCardinalityForCategoricalColor?: number;\n maxCardinalityForFacet?: number;\n maxCardinalityForShape?: number;\n timeUnitShouldHaveVariation?: boolean;\n typeMatchesSchemaType?: boolean;\n\n // STYLIZE\n stylize?: boolean;\n smallRangeStepForHighCardinalityOrFacet?: {maxCardinality: number; rangeStep: number};\n nominalColorScaleForHighCardinality?: {maxCardinality: number; palette: string};\n xAxisOnTopForHighYCardinalityWithoutColumn?: {maxCardinality: number};\n\n // EFFECTIVENESS PREFERENCE\n maxGoodCardinalityForColor?: number; // FIXME: revise\n maxGoodCardinalityForFacet?: number; // FIXME: revise\n // HIGH CARDINALITY STRINGS\n minPercentUniqueForKey?: number;\n minCardinalityForKey?: number;\n}\n\nexport const DEFAULT_QUERY_CONFIG: QueryConfig = {\n verbose: false,\n defaultSpecConfig: {\n line: {point: true},\n scale: {useUnaggregatedDomain: true}\n },\n propertyPrecedence: DEFAULT_PROP_PRECEDENCE.map(toKey),\n enum: DEFAULT_ENUM_INDEX,\n\n numberNominalProportion: 0.05,\n numberNominalLimit: 40,\n\n // CONSTRAINTS\n constraintManuallySpecifiedValue: false,\n // Spec Constraints -- See description inside src/constraints/spec.ts\n autoAddCount: false,\n\n hasAppropriateGraphicTypeForMark: true,\n omitAggregate: false,\n omitAggregatePlotWithDimensionOnlyOnFacet: true,\n omitAggregatePlotWithoutDimension: false,\n omitBarLineAreaWithOcclusion: true,\n omitBarTickWithSize: true,\n omitMultipleNonPositionalChannels: true,\n omitRaw: false,\n omitRawContinuousFieldForAggregatePlot: true,\n omitRepeatedField: true,\n omitNonPositionalOrFacetOverPositionalChannels: true,\n omitTableWithOcclusionIfAutoAddCount: true,\n omitVerticalDotPlot: false,\n omitInvalidStackSpec: true,\n omitNonSumStack: true,\n\n preferredBinAxis: CHANNEL.X,\n preferredTemporalAxis: CHANNEL.X,\n preferredOrdinalAxis: CHANNEL.Y, // ordinal on y makes it easier to read.\n preferredNominalAxis: CHANNEL.Y, // nominal on y makes it easier to read.\n preferredFacet: CHANNEL.ROW, // row make it easier to scroll than column\n\n // Field Encoding Constraints -- See description inside src/constraint/field.ts\n minCardinalityForBin: 15,\n maxCardinalityForCategoricalColor: 20,\n maxCardinalityForFacet: 20,\n maxCardinalityForShape: 6,\n timeUnitShouldHaveVariation: true,\n typeMatchesSchemaType: true,\n\n // STYLIZE\n stylize: true,\n smallRangeStepForHighCardinalityOrFacet: {maxCardinality: 10, rangeStep: 12},\n nominalColorScaleForHighCardinality: {maxCardinality: 10, palette: 'category20'},\n xAxisOnTopForHighYCardinalityWithoutColumn: {maxCardinality: 30},\n\n // RANKING PREFERENCE\n maxGoodCardinalityForFacet: 5, // FIXME: revise\n maxGoodCardinalityForColor: 7, // FIXME: revise\n\n // HIGH CARDINALITY STRINGS\n minPercentUniqueForKey: 0.8,\n minCardinalityForKey: 50\n};\n\nexport function extendConfig(opt: QueryConfig) {\n return {\n ...DEFAULT_QUERY_CONFIG,\n ...opt,\n enum: extendEnumIndex(opt.enum)\n };\n}\n\nfunction extendEnumIndex(enumIndex: Partial) {\n const enumOpt: EnumIndex = {\n ...DEFAULT_ENUM_INDEX,\n ...enumIndex,\n binProps: extendNestedEnumIndex(enumIndex, 'bin'),\n scaleProps: extendNestedEnumIndex(enumIndex, 'scale'),\n axisProps: extendNestedEnumIndex(enumIndex, 'axis'),\n legendProps: extendNestedEnumIndex(enumIndex, 'legend')\n };\n return enumOpt;\n}\n\nfunction extendNestedEnumIndex(enumIndex: Partial, prop: 'bin' | 'scale' | 'axis' | 'legend') {\n return {\n ...DEFAULT_ENUM_INDEX[prop + 'Props'],\n ...enumIndex[prop + 'Props']\n };\n}\n","import {AggregateOp} from 'vega';\nimport {isString, toSet} from 'vega-util';\nimport {contains, Flag, flagKeys} from './util';\n\nconst AGGREGATE_OP_INDEX: Flag = {\n argmax: 1,\n argmin: 1,\n average: 1,\n count: 1,\n distinct: 1,\n max: 1,\n mean: 1,\n median: 1,\n min: 1,\n missing: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n stderr: 1,\n stdev: 1,\n stdevp: 1,\n sum: 1,\n valid: 1,\n values: 1,\n variance: 1,\n variancep: 1\n};\n\nexport interface ArgminDef {\n argmin: string;\n}\n\nexport interface ArgmaxDef {\n argmax: string;\n}\n\nexport type Aggregate = AggregateOp | ArgmaxDef | ArgminDef;\n\nexport function isArgminDef(a: Aggregate | string): a is ArgminDef {\n return !!a && !!a['argmin'];\n}\n\nexport function isArgmaxDef(a: Aggregate | string): a is ArgmaxDef {\n return !!a && !!a['argmax'];\n}\n\nexport const AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX);\n\nexport function isAggregateOp(a: string | ArgminDef | ArgmaxDef): a is AggregateOp {\n return isString(a) && !!AGGREGATE_OP_INDEX[a];\n}\n\nexport const COUNTING_OPS: AggregateOp[] = ['count', 'valid', 'missing', 'distinct'];\n\nexport function isCountingAggregateOp(aggregate: string | Aggregate): boolean {\n return aggregate && isString(aggregate) && contains(COUNTING_OPS, aggregate);\n}\n\nexport function isMinMaxOp(aggregate: Aggregate | string): boolean {\n return aggregate && isString(aggregate) && contains(['min', 'max'], aggregate);\n}\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = ['count', 'sum', 'distinct', 'valid', 'missing'];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = ['mean', 'average', 'median', 'q1', 'q3', 'min', 'max'];\n\nexport const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS);\n","import {isBoolean, isObject} from 'vega-util';\nimport {BinParams} from './bin';\nimport {\n Channel,\n COLOR,\n COLUMN,\n FILL,\n FILLOPACITY,\n OPACITY,\n ROW,\n SHAPE,\n SIZE,\n STROKE,\n STROKEOPACITY,\n STROKEWIDTH\n} from './channel';\nimport {normalizeBin} from './channeldef';\nimport {keys, varName} from './util';\n\nexport interface BaseBin {\n /**\n * The number base to use for automatic bin determination (default is base 10).\n *\n * __Default value:__ `10`\n *\n */\n base?: number;\n /**\n * An exact step size to use between bins.\n *\n * __Note:__ If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n *\n * __Default value:__ `[5, 2]`\n *\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n *\n * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels\n *\n * @minimum 2\n */\n maxbins?: number;\n /**\n * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n *\n * __Default Value:__ the minimum bin extent value\n */\n anchor?: number;\n /**\n * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n */\n nice?: boolean;\n}\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface BinParams extends BaseBin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[]; // VgBinTransform uses a different extent so we need to pull this out.\n\n /**\n * When set to true, Vega-Lite treats the input data as already binned.\n */\n binned?: boolean;\n}\n\nexport type Bin = boolean | BinParams | 'binned' | null;\n\n/**\n * Create a key for the bin configuration. Not for prebinned bin.\n */\nexport function binToString(bin: BinParams | true) {\n if (isBoolean(bin)) {\n bin = normalizeBin(bin, undefined);\n }\n return (\n 'bin' +\n keys(bin)\n .map(p => varName(`_${p}_${bin[p]}`))\n .join('')\n );\n}\n\n/**\n * Vega-Lite should bin the data.\n */\nexport function isBinning(bin: BinParams | boolean | 'binned'): bin is BinParams | true {\n return bin === true || (isBinParams(bin) && !bin.binned);\n}\n\n/**\n * The data is already binned and so Vega-Lite should not bin it again.\n */\nexport function isBinned(bin: BinParams | boolean | 'binned'): bin is 'binned' {\n return bin === 'binned' || (isBinParams(bin) && bin.binned);\n}\n\nexport function isBinParams(bin: BinParams | boolean | 'binned'): bin is BinParams {\n return isObject(bin);\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n case COLOR:\n case FILL:\n case STROKE:\n case STROKEWIDTH:\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule [falls through]\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n","import {BinParams} from '../bin';\nimport {ChannelDef, Field, FieldDef, TypedFieldDef} from '../channeldef';\nimport {Header} from '../header';\nimport {EncodingSortField, SortArray, SortOrder} from '../sort';\nimport {StandardType} from '../type';\nimport {BaseSpec, GenericCompositionLayoutWithColumns, ResolveMixins} from './base';\nimport {FacetMapping} from './facet';\nimport {GenericLayerSpec, NormalizedLayerSpec} from './layer';\nimport {GenericUnitSpec, NormalizedUnitSpec} from './unit';\n\nexport interface FacetFieldDef extends TypedFieldDef {\n /**\n * An object defining properties of a facet's header.\n */\n header?: Header;\n\n // Note: `\"sort\"` for facet field def is different from encoding field def as it does not support `SortByEncoding`\n\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: SortArray | SortOrder | EncodingSortField | null;\n}\n\nexport interface FacetMapping {\n /**\n * A field definition for the vertical facet of trellis plots.\n */\n row?: FacetFieldDef;\n\n /**\n * A field definition for the horizontal facet of trellis plots.\n */\n column?: FacetFieldDef;\n}\n\nexport function isFacetMapping(f: FacetFieldDef | FacetMapping): f is FacetMapping {\n return !!f['row'] || !!f['column'];\n}\n\n/**\n * Facet mapping for encoding macro\n */\nexport interface EncodingFacetMapping extends FacetMapping {\n /**\n * A field definition for the (flexible) facet of trellis plots.\n *\n * If either `row` or `column` is specified, this channel will be ignored.\n */\n facet?: FacetFieldDef;\n}\n\nexport function isFacetFieldDef(channelDef: ChannelDef>): channelDef is FacetFieldDef {\n return !!channelDef && !!channelDef['header'];\n}\n\n/**\n * Base interface for a facet specification.\n */\nexport interface GenericFacetSpec, L extends GenericLayerSpec>\n extends BaseSpec,\n GenericCompositionLayoutWithColumns,\n ResolveMixins {\n /**\n * Definition for how to facet the data. One of:\n * 1) [a field definition for faceting the plot by one field](https://vega.github.io/vega-lite/docs/facet.html#field-def)\n * 2) [An object that maps `row` and `column` channels to their field definitions](https://vega.github.io/vega-lite/docs/facet.html#mapping)\n */\n facet: FacetFieldDef | FacetMapping;\n\n /**\n * A specification of the view that gets faceted.\n */\n spec: L | U;\n // TODO: replace this with GenericSpec once we support all cases;\n}\n\n/**\n * A facet specification without any shortcut / expansion syntax\n */\nexport type NormalizedFacetSpec = GenericFacetSpec;\n\nexport function isFacetSpec(spec: BaseSpec): spec is GenericFacetSpec {\n return spec['facet'] !== undefined;\n}\n","// Declaration and utility for variants of a field definition object\nimport {isArray, isBoolean, isNumber, isString} from 'vega-util';\nimport {Aggregate, isAggregateOp, isArgmaxDef, isArgminDef, isCountingAggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {autoMaxBins, Bin, BinParams, binToString, isBinned, isBinning} from './bin';\nimport {Channel, isScaleChannel, isSecondaryRangeChannel, POSITION_SCALE_CHANNELS, rangeType} from './channel';\nimport {CompositeAggregate} from './compositemark';\nimport {Config} from './config';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {FormatMixins, Guide, TitleMixins} from './guide';\nimport {ImputeParams} from './impute';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Predicate} from './predicate';\nimport {Scale} from './scale';\nimport {Sort, SortOrder} from './sort';\nimport {isFacetFieldDef} from './spec/facet';\nimport {StackOffset} from './stack';\nimport {\n getLocalTimeUnit,\n getTimeUnitParts,\n isLocalSingleTimeUnit,\n isUtcSingleTimeUnit,\n normalizeTimeUnit,\n TimeUnit\n} from './timeunit';\nimport {AggregatedFieldDef, WindowFieldDef} from './transform';\nimport {getFullName, QUANTITATIVE, StandardType, Type} from './type';\nimport {contains, flatAccessWithDatum, getFirstDefined, internalField, replacePathInField, titlecase} from './util';\n\nexport type Value = number | string | boolean | null;\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between `0` to `1` for opacity).\n */\n value: V;\n}\n\n/**\n * Generic type for conditional channelDef.\n * F defines the underlying FieldDef type.\n */\n\nexport type ChannelDefWithCondition, V extends Value> =\n | FieldDefWithCondition\n | ValueDefWithCondition;\n\n/**\n * A ValueDef with Condition where either the conition or the value are optional.\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\n\nexport type ValueDefWithCondition, V extends Value = Value> =\n | ValueDefWithOptionalCondition\n | ConditionOnlyDef;\n\nexport type StringValueDefWithCondition = ValueDefWithCondition<\n MarkPropFieldDef,\n string | null\n>;\n\nexport type NumericValueDefWithCondition = ValueDefWithCondition<\n MarkPropFieldDef,\n number\n>;\n\nexport type TypeForShape = 'nominal' | 'ordinal' | 'geojson';\n\nexport type ShapeValueDefWithCondition = StringValueDefWithCondition;\n\nexport type TextValueDefWithCondition = ValueDefWithCondition, Value>;\n\nexport type Conditional | ValueDef> = ConditionalPredicate | ConditionalSelection;\n\nexport type ConditionalPredicate | ValueDef> = {\n /**\n * Predicate for triggering the condition\n */\n test: LogicalOperand;\n} & CD;\n\nexport type ConditionalSelection | ValueDef> = {\n /**\n * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose).\n */\n selection: LogicalOperand;\n} & CD;\n\nexport function isConditionalSelection(c: Conditional): c is ConditionalSelection {\n return c['selection'];\n}\n\nexport interface ConditionValueDefMixins {\n /**\n * One or more value definition(s) with [a selection or a test predicate](https://vega.github.io/vega-lite/docs/condition.html).\n *\n * __Note:__ A field definition's `condition` property can only contain [conditional value definitions](https://vega.github.io/vega-lite/docs/condition.html#value)\n * since Vega-Lite only allows at most one encoded field per encoding channel.\n */\n condition?: Conditional> | Conditional>[];\n}\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\n\nexport type FieldDefWithCondition, V extends Value = Value> = F & ConditionValueDefMixins;\n\nexport type StringFieldDefWithCondition = FieldDefWithCondition<\n MarkPropFieldDef,\n string | null\n>;\n\nexport type NumericFieldDefWithCondition = FieldDefWithCondition<\n MarkPropFieldDef,\n number\n>;\n\nexport type ShapeFieldDefWithCondition = StringFieldDefWithCondition;\n\nexport type TextFieldDefWithCondition = FieldDefWithCondition, Value>;\n\n/**\n * A ValueDef with optional Condition\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\n\nexport interface ValueDefWithOptionalCondition, V extends Value> extends ValueDef {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition?: Conditional | Conditional> | Conditional>[];\n}\n\n/**\n * A Condition only definition.\n * {\n * condition: {field: ...} | {value: ...}\n * }\n */\nexport interface ConditionOnlyDef, V extends Value = Value> {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition: Conditional | Conditional> | Conditional>[];\n}\n\n/**\n * Reference to a repeated value.\n */\nexport interface RepeatRef {\n repeat: 'row' | 'column' | 'repeat';\n}\n\nexport type FieldName = string;\nexport type Field = FieldName | RepeatRef;\n\nexport function isRepeatRef(field: Field): field is RepeatRef {\n return field && !isString(field) && 'repeat' in field;\n}\n\n/** @hide */\nexport type HiddenCompositeAggregate = CompositeAggregate;\n\nexport interface FieldDefBase {\n /**\n * __Required.__ A string defining the name of the field from which to pull a data value\n * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.\n *\n * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `\"field\": \"foo.bar\"` and `\"field\": \"foo['bar']\"`).\n * If field names contain dots or brackets but are not nested, you can use `\\\\` to escape dots and brackets (e.g., `\"a\\\\.b\"` and `\"a\\\\[0\\\\]\"`).\n * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).\n *\n * __Note:__ `field` is not required if `aggregate` is `count`.\n */\n field?: F;\n\n // function\n\n /**\n * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field.\n * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast).\n *\n * __Default value:__ `undefined` (None)\n */\n timeUnit?: TimeUnit;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n *\n * __Default value:__ `undefined` (None)\n */\n aggregate?: Aggregate | HiddenCompositeAggregate;\n\n /**\n * A flag for binning a `quantitative` field, [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params), or indicating that the data for `x` or `y` channel are binned before they are imported into Vega-Lite (`\"binned\"`).\n *\n * - If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied.\n *\n * - If `\"binned\"`, this indicates that the data for the `x` (or `y`) channel are already binned. You can map the bin-start field to `x` (or `y`) and the bin-end field to `x2` (or `y2`). The scale and axis will be formatted similar to binning in Vega-lite. To adjust the axis ticks based on the bin step, you can also set the axis's [`tickMinStep`](https://vega.github.io/vega-lite/docs/axis.html#ticks) property.\n *\n * __Default value:__ `false`\n */\n bin?: B;\n}\n\nexport function toFieldDefBase(fieldDef: TypedFieldDef): FieldDefBase {\n const {field, timeUnit, bin, aggregate} = fieldDef;\n return {\n ...(timeUnit ? {timeUnit} : {}),\n ...(bin ? {bin} : {}),\n ...(aggregate ? {aggregate} : {}),\n field\n };\n}\n\nexport interface TypeMixins {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\n * It can also be a `\"geojson\"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html).\n *\n *\n * __Note:__\n *\n * - Data values for a temporal field can be either a date-time string (e.g., `\"2015-03-07 12:32:17\"`, `\"17:01\"`, `\"2015-03-16\"`. `\"2015\"`) or a timestamp number (e.g., `1552199579097`).\n * - Data `type` describes the semantics of the data rather than the primitive data types (`number`, `string`, etc.). The same primitive data type can have different types of measurement. For example, numeric data can represent quantitative, ordinal, or nominal data.\n * - When using with [`bin`](https://vega.github.io/vega-lite/docs/bin.html), the `type` property can be either `\"quantitative\"` (for using a linear bin scale) or [`\"ordinal\"` (for using an ordinal bin scale)](https://vega.github.io/vega-lite/docs/type.html#cast-bin).\n * - When using with [`timeUnit`](https://vega.github.io/vega-lite/docs/timeunit.html), the `type` property can be either `\"temporal\"` (for using a temporal scale) or [`\"ordinal\"` (for using an ordinal scale)](https://vega.github.io/vega-lite/docs/type.html#cast-bin).\n * - When using with [`aggregate`](https://vega.github.io/vega-lite/docs/aggregate.html), the `type` property refers to the post-aggregation data type. For example, we can calculate count `distinct` of a categorical field `\"cat\"` using `{\"aggregate\": \"distinct\", \"field\": \"cat\", \"type\": \"quantitative\"}`. The `\"type\"` of the aggregate output is `\"quantitative\"`.\n * - Secondary channels (e.g., `x2`, `y2`, `xError`, `yError`) do not have `type` as they have exactly the same type as their primary channels (e.g., `x`, `y`).\n */\n type: T;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport type TypedFieldDef<\n F extends Field,\n T extends Type = Type,\n B extends Bin = boolean | BinParams | 'binned' | null // This is equivalent to Bin but we use the full form so the docs has detailed types\n> = FieldDefBase & TitleMixins & TypeMixins;\n\nexport interface SortableFieldDef<\n F extends Field,\n T extends Type = StandardType,\n B extends Bin = boolean | BinParams | null\n> extends TypedFieldDef {\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort-by-encoding definition](https://vega.github.io/vega-lite/docs/sort.html#sort-by-encoding) for sorting by another encoding channel. (This type of sort definition is not available for `row` and `column` channels.)\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: Sort;\n}\n\nexport function isSortableFieldDef(fieldDef: FieldDef): fieldDef is SortableFieldDef {\n return isTypedFieldDef(fieldDef) && !!fieldDef['sort'];\n}\n\nexport interface ScaleFieldDef<\n F extends Field,\n T extends Type = StandardType,\n B extends Bin = boolean | BinParams | null\n> extends SortableFieldDef {\n /**\n * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.\n *\n * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).\n *\n * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.\n */\n scale?: Scale | null;\n}\n\n/**\n * A field definition of a secondary channel that shares a scale with another primary channel. For example, `x2`, `xError` and `xError2` share the same scale with `x`.\n */\nexport type SecondaryFieldDef = FieldDefBase & TitleMixins; // x2/y2 shouldn't have bin, but we keep bin property for simplicity of the codebase.\n\n/**\n * Field Def without scale (and without bin: \"binned\" support).\n */\nexport type FieldDefWithoutScale = TypedFieldDef;\n\nexport type LatLongFieldDef = FieldDefBase &\n TitleMixins &\n Partial>; // Lat long shouldn't have bin, but we keep bin property for simplicity of the codebase.\n\nexport interface PositionFieldDef\n extends ScaleFieldDef<\n F,\n StandardType,\n boolean | BinParams | 'binned' | null // This is equivalent to Bin but we use the full form so the docs has detailed types\n > {\n /**\n * An object defining properties of axis's gridlines, ticks and labels.\n * If `null`, the axis for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.\n */\n axis?: Axis | null;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * `stack` is only applicable for `x` and `y` channels with continuous domains.\n * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart.\n *\n * `stack` can be one of the following values:\n * - `\"zero\"` or `true`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).\n * - `null` or `false` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions are true:\n * (1) the mark is `bar` or `area`;\n * (2) the stacked measure channel (x or y) has a linear scale;\n * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default.\n */\n stack?: StackOffset | null | boolean;\n\n /**\n * An object defining the properties of the Impute Operation to be applied.\n * The field value of the other positional channel is taken as `key` of the `Impute` Operation.\n * The field of the `color` channel if specified is used as `groupby` of the `Impute` Operation.\n */\n impute?: ImputeParams;\n}\n\n/**\n * Field definition of a mark property, which can contain a legend.\n */\nexport type MarkPropFieldDef = ScaleFieldDef<\n F,\n T,\n boolean | BinParams | null\n> & {\n /**\n * An object defining properties of the legend.\n * If `null`, the legend for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.\n */\n legend?: Legend | null;\n};\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDefWithoutScale {\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDefWithoutScale, FormatMixins {}\n\nexport type FieldDef = SecondaryFieldDef | TypedFieldDef;\nexport type ChannelDef = FieldDef, V extends Value = Value> = ChannelDefWithCondition<\n FD,\n V\n>;\n\nexport function isConditionalDef(\n channelDef: ChannelDef, V>\n): channelDef is ChannelDefWithCondition, V> {\n return !!channelDef && !!channelDef.condition;\n}\n\n/**\n * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef\n */\n\nexport function hasConditionalFieldDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef & {condition: Conditional>} {\n return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition);\n}\n\nexport function hasConditionalValueDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef & {condition: Conditional> | Conditional>[]} {\n return !!channelDef && !!channelDef.condition && (isArray(channelDef.condition) || isValueDef(channelDef.condition));\n}\n\nexport function isFieldDef(\n channelDef: ChannelDef>\n): channelDef is\n | TypedFieldDef\n | SecondaryFieldDef\n | PositionFieldDef\n | ScaleFieldDef\n | MarkPropFieldDef\n | OrderFieldDef\n | TextFieldDef {\n return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isTypedFieldDef(channelDef: ChannelDef>): channelDef is TypedFieldDef {\n return !!channelDef && ((!!channelDef['field'] && !!channelDef['type']) || channelDef['aggregate'] === 'count');\n}\n\nexport function isStringFieldDef(channelDef: ChannelDef>): channelDef is TypedFieldDef {\n return isFieldDef(channelDef) && isString(channelDef.field);\n}\n\nexport function isValueDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\nexport function isScaleFieldDef(channelDef: ChannelDef>): channelDef is ScaleFieldDef {\n return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']);\n}\n\nexport function isPositionFieldDef(\n channelDef: ChannelDef>\n): channelDef is PositionFieldDef {\n return !!channelDef && (!!channelDef['axis'] || !!channelDef['stack'] || !!channelDef['impute']);\n}\n\nexport function isMarkPropFieldDef(\n channelDef: ChannelDef>\n): channelDef is MarkPropFieldDef {\n return !!channelDef && !!channelDef['legend'];\n}\n\nexport function isTextFieldDef(channelDef: ChannelDef>): channelDef is TextFieldDef {\n return !!channelDef && !!channelDef['format'];\n}\n\nexport interface FieldRefOption {\n /** Exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field with datum, parent, or datum.datum (e.g., datum['...'] for Vega Expression */\n expr?: 'datum' | 'parent' | 'datum.datum';\n /** Prepend fn with custom function prefix */\n prefix?: string;\n /** Append suffix to the field ref for bin (default='start') */\n binSuffix?: 'end' | 'range' | 'mid';\n /** Append suffix to the field ref (general) */\n suffix?: string;\n /**\n * Use the field name for `as` in a transform.\n * We will not escape nested accesses because Vega transform outputs cannot be nested.\n */\n forAs?: boolean;\n}\n\nfunction isOpFieldDef(\n fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef\n): fieldDef is WindowFieldDef | AggregatedFieldDef {\n return !!fieldDef['op'];\n}\n\n/**\n * Get a Vega field reference from a Vega-Lite field def.\n */\nexport function vgField(\n fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef,\n opt: FieldRefOption = {}\n): string {\n let field = fieldDef.field;\n const prefix = opt.prefix;\n let suffix = opt.suffix;\n\n let argAccessor = ''; // for accessing argmin/argmax field at the end without getting escaped\n\n if (isCount(fieldDef)) {\n field = internalField('count');\n } else {\n let fn: string;\n\n if (!opt.nofn) {\n if (isOpFieldDef(fieldDef)) {\n fn = fieldDef.op;\n } else {\n const {bin, aggregate, timeUnit} = fieldDef;\n if (isBinning(bin)) {\n fn = binToString(bin);\n suffix = (opt.binSuffix || '') + (opt.suffix || '');\n } else if (aggregate) {\n if (isArgmaxDef(aggregate)) {\n argAccessor = `.${field}`;\n field = `argmax_${aggregate.argmax}`;\n } else if (isArgminDef(aggregate)) {\n argAccessor = `.${field}`;\n field = `argmin_${aggregate.argmin}`;\n } else {\n fn = String(aggregate);\n }\n } else if (timeUnit) {\n fn = String(timeUnit);\n }\n }\n }\n\n if (fn) {\n field = field ? `${fn}_${field}` : fn;\n }\n }\n\n if (suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.forAs) {\n return field;\n } else if (opt.expr) {\n // Expression to access flattened field. No need to escape dots.\n return flatAccessWithDatum(field, opt.expr) + argAccessor;\n } else {\n // We flattened all fields so paths should have become dot.\n return replacePathInField(field) + argAccessor;\n }\n}\n\nexport function isDiscrete(fieldDef: TypedFieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n case 'geojson':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'temporal':\n return false;\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: TypedFieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDefBase) {\n return fieldDef.aggregate === 'count';\n}\n\nexport type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const {field, bin, timeUnit, aggregate} = fieldDef;\n if (aggregate === 'count') {\n return config.countTitle;\n } else if (isBinning(bin)) {\n return `${field} (binned)`;\n } else if (timeUnit) {\n const units = getTimeUnitParts(timeUnit).join('-');\n return `${field} (${units})`;\n } else if (aggregate) {\n if (isArgmaxDef(aggregate)) {\n return `${field} for max ${aggregate.argmax}`;\n } else if (isArgminDef(aggregate)) {\n return `${field} for min ${aggregate.argmin}`;\n } else {\n return `${titlecase(aggregate)} of ${field}`;\n }\n }\n return field;\n}\n\nexport function functionalTitleFormatter(fieldDef: FieldDefBase) {\n const {aggregate, bin, timeUnit, field} = fieldDef;\n if (isArgmaxDef(aggregate)) {\n return `${field} for argmax(${aggregate.argmax})`;\n } else if (isArgminDef(aggregate)) {\n return `${field} for argmin(${aggregate.argmin})`;\n }\n\n const fn = aggregate || timeUnit || (isBinning(bin) && 'bin');\n if (fn) {\n return fn.toUpperCase() + '(' + field + ')';\n } else {\n return field;\n }\n}\n\nexport const defaultTitleFormatter: FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => {\n switch (config.fieldTitle) {\n case 'plain':\n return fieldDef.field;\n case 'functional':\n return functionalTitleFormatter(fieldDef);\n default:\n return verbalTitleFormatter(fieldDef, config);\n }\n};\n\nlet titleFormatter = defaultTitleFormatter;\n\nexport function setTitleFormatter(formatter: FieldTitleFormatter) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(\n fieldDef: TypedFieldDef | SecondaryFieldDef,\n config: Config,\n {allowDisabling, includeDefault = true}: {allowDisabling: boolean; includeDefault?: boolean}\n) {\n const guide = getGuide(fieldDef) || {};\n const guideTitle = guide.title;\n const def = includeDefault ? defaultTitle(fieldDef, config) : undefined;\n\n if (allowDisabling) {\n return getFirstDefined(guideTitle, fieldDef.title, def);\n } else {\n return guideTitle || fieldDef.title || def;\n }\n}\n\nexport function getGuide(fieldDef: TypedFieldDef | SecondaryFieldDef): Guide {\n if (isPositionFieldDef(fieldDef) && fieldDef.axis) {\n return fieldDef.axis;\n } else if (isMarkPropFieldDef(fieldDef) && fieldDef.legend) {\n return fieldDef.legend;\n } else if (isFacetFieldDef(fieldDef) && fieldDef.header) {\n return fieldDef.header;\n }\n return undefined;\n}\n\nexport function defaultTitle(fieldDef: FieldDefBase, config: Config) {\n return titleFormatter(fieldDef, config);\n}\n\nexport function format(fieldDef: TypedFieldDef) {\n if (isTextFieldDef(fieldDef) && fieldDef.format) {\n return fieldDef.format;\n } else {\n const guide = getGuide(fieldDef) || {};\n return guide.format;\n }\n}\n\nexport function defaultType(fieldDef: TypedFieldDef, channel: Channel): Type {\n if (fieldDef.timeUnit) {\n return 'temporal';\n }\n if (isBinning(fieldDef.bin)) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef.\n * @param channelDef\n */\n\nexport function getFieldDef(channelDef: ChannelDef>): FieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\nexport function getTypedFieldDef(channelDef: ChannelDef>): TypedFieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef {\n if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) {\n const primitiveType = isString(channelDef) ? 'string' : isNumber(channelDef) ? 'number' : 'boolean';\n log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef));\n return {value: channelDef};\n }\n\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(channelDef)) {\n return normalizeFieldDef(channelDef, channel);\n } else if (hasConditionalFieldDef(channelDef)) {\n return {\n ...channelDef,\n // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition\n condition: normalizeFieldDef(channelDef.condition, channel) as Conditional>\n };\n }\n return channelDef;\n}\nexport function normalizeFieldDef(fieldDef: FieldDef, channel: Channel) {\n const {aggregate, timeUnit, bin} = fieldDef;\n // Drop invalid aggregate\n if (aggregate && !isAggregateOp(aggregate) && !isArgmaxDef(aggregate) && !isArgminDef(aggregate)) {\n const {aggregate: _, ...fieldDefWithoutAggregate} = fieldDef;\n log.warn(log.message.invalidAggregate(aggregate));\n fieldDef = fieldDefWithoutAggregate;\n }\n\n // Normalize Time Unit\n if (timeUnit) {\n fieldDef = {\n ...fieldDef,\n timeUnit: normalizeTimeUnit(timeUnit)\n };\n }\n\n // Normalize bin\n if (isBinning(bin)) {\n fieldDef = {\n ...fieldDef,\n bin: normalizeBin(bin, channel)\n } as FieldDef;\n }\n\n if (isBinned(bin) && !contains(POSITION_SCALE_CHANNELS, channel)) {\n log.warn(`Channel ${channel} should not be used with \"binned\" bin`);\n }\n\n // Normalize Type\n if (isTypedFieldDef(fieldDef)) {\n const {type} = fieldDef;\n const fullType = getFullName(type);\n if (type !== fullType) {\n // convert short type to full type\n fieldDef = {\n ...fieldDef,\n type: fullType\n };\n }\n if (type !== 'quantitative') {\n if (isCountingAggregateOp(aggregate)) {\n log.warn(log.message.invalidFieldTypeForCountAggregate(type, aggregate));\n fieldDef = {\n ...fieldDef,\n type: 'quantitative'\n };\n }\n }\n } else if (!isSecondaryRangeChannel(channel)) {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef as TypedFieldDef, channel);\n log.warn(log.message.missingFieldType(channel, newType));\n\n fieldDef = {\n ...fieldDef,\n type: newType\n };\n }\n\n if (isTypedFieldDef(fieldDef)) {\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n }\n return fieldDef;\n}\n\nexport function normalizeBin(bin: BinParams | boolean | 'binned', channel: Channel) {\n if (isBoolean(bin)) {\n return {maxbins: autoMaxBins(channel)};\n } else if (bin === 'binned') {\n return {\n binned: true\n };\n } else if (!bin.maxbins && !bin.step) {\n return {...bin, maxbins: autoMaxBins(channel)};\n } else {\n return bin;\n }\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(\n fieldDef: TypedFieldDef,\n channel: Channel\n): {compatible: boolean; warning?: string} {\n const type = fieldDef.type;\n\n if (type === 'geojson' && channel !== 'shape') {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with a geojson data.`\n };\n }\n\n switch (channel) {\n case 'row':\n case 'column':\n case 'facet':\n if (isContinuous(fieldDef)) {\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'fill':\n case 'stroke':\n case 'text':\n case 'detail':\n case 'key':\n case 'tooltip':\n case 'href':\n return COMPATIBLE;\n\n case 'longitude':\n case 'longitude2':\n case 'latitude':\n case 'latitude2':\n if (type !== QUANTITATIVE) {\n return {\n compatible: false,\n warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.`\n };\n }\n return COMPATIBLE;\n\n case 'opacity':\n case 'fillOpacity':\n case 'strokeOpacity':\n case 'strokeWidth':\n case 'size':\n case 'x2':\n case 'y2':\n if (type === 'nominal' && !fieldDef['sort']) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with an unsorted discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (!contains(['ordinal', 'nominal', 'geojson'], fieldDef.type)) {\n return {\n compatible: false,\n warning: 'Shape channel should be used with only either discrete or geojson data.'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n\nexport function isNumberFieldDef(fieldDef: TypedFieldDef) {\n return fieldDef.type === 'quantitative' || isBinning(fieldDef.bin);\n}\n\n/**\n * Check if the field def uses a time format or does not use any format but is temporal (this does not cover field defs that are temporal but use a number format).\n */\nexport function isTimeFormatFieldDef(fieldDef: TypedFieldDef): boolean {\n const formatType =\n (isPositionFieldDef(fieldDef) && fieldDef.axis && fieldDef.axis.formatType) ||\n (isMarkPropFieldDef(fieldDef) && fieldDef.legend && fieldDef.legend.formatType) ||\n (isTextFieldDef(fieldDef) && fieldDef.formatType);\n return formatType === 'time' || (!formatType && isTimeFieldDef(fieldDef));\n}\n\n/**\n * Check if field def has tye `temporal`. If you want to also cover field defs that use a time format, use `isTimeFormatFieldDef`.\n */\nexport function isTimeFieldDef(fieldDef: TypedFieldDef) {\n return fieldDef.type === 'temporal' || !!fieldDef.timeUnit;\n}\n\n/**\n * Getting a value associated with a fielddef.\n * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit)\n */\nexport function valueExpr(\n v: number | string | boolean | DateTime,\n {\n timeUnit,\n type,\n time,\n undefinedIfExprNotRequired\n }: {\n timeUnit: TimeUnit;\n type?: Type;\n time?: boolean;\n undefinedIfExprNotRequired?: boolean;\n }\n): string {\n let expr;\n if (isDateTime(v)) {\n expr = dateTimeExpr(v, true);\n } else if (isString(v) || isNumber(v)) {\n if (timeUnit || type === 'temporal') {\n if (isLocalSingleTimeUnit(timeUnit)) {\n expr = dateTimeExpr({[timeUnit]: v}, true);\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n // FIXME is this really correct?\n expr = valueExpr(v, {timeUnit: getLocalTimeUnit(timeUnit)});\n } else {\n // just pass the string to date function (which will call JS Date.parse())\n expr = `datetime(${JSON.stringify(v)})`;\n }\n }\n }\n if (expr) {\n return time ? `time(${expr})` : expr;\n }\n // number or boolean or normal string\n return undefinedIfExprNotRequired ? undefined : JSON.stringify(v);\n}\n\n/**\n * Standardize value array -- convert each value to Vega expression if applicable\n */\nexport function valueArray(fieldDef: TypedFieldDef, values: (number | string | boolean | DateTime)[]) {\n const {timeUnit, type} = fieldDef;\n return values.map(v => {\n const expr = valueExpr(v, {timeUnit, type, undefinedIfExprNotRequired: true});\n // return signal for the expression if we need an expression\n if (expr !== undefined) {\n return {signal: expr};\n }\n // otherwise just return the original value\n return v;\n });\n}\n\n/**\n * Checks whether a fieldDef for a particular channel requires a computed bin range.\n */\nexport function binRequiresRange(fieldDef: TypedFieldDef, channel: Channel) {\n if (!isBinning(fieldDef.bin)) {\n console.warn('Only use this method with binned field defs');\n return false;\n }\n\n // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels.\n // We could check whether the axis or legend exists (not disabled) but that seems overkill.\n return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type);\n}\n","import {isBinning} from '../../bin';\nimport {Channel, isColorChannel, isScaleChannel, rangeType} from '../../channel';\nimport {TypedFieldDef} from '../../channeldef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, Scale, ScaleType, scaleTypeSupportDataType} from '../../scale';\nimport * as util from '../../util';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport function scaleType(\n specifiedScale: Scale,\n channel: Channel,\n fieldDef: TypedFieldDef,\n mark: Mark\n): ScaleType {\n const defaultScaleType = defaultType(channel, fieldDef, mark);\n const {type} = specifiedScale;\n\n if (!isScaleChannel(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (type !== undefined) {\n // Check if explicitly specified scale type is supported by the channel\n if (!channelSupportScaleType(channel, type)) {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, type, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the data type\n if (!scaleTypeSupportDataType(type, fieldDef.type)) {\n log.warn(log.message.scaleTypeNotWorkWithFieldDef(type, defaultScaleType));\n return defaultScaleType;\n }\n\n return type;\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\n// NOTE: Voyager uses this method.\nfunction defaultType(channel: Channel, fieldDef: TypedFieldDef, mark: Mark): ScaleType {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n if (isColorChannel(channel) || rangeType(channel) === 'discrete') {\n if (channel === 'shape' && fieldDef.type === 'ordinal') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n }\n return 'ordinal';\n }\n\n if (util.contains(['x', 'y'], channel)) {\n if (util.contains(['rect', 'bar', 'rule'], mark)) {\n // The rect/bar mark should fit into a band.\n // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429\n return 'band';\n }\n if (mark === 'bar') {\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n\n case 'temporal':\n if (isColorChannel(channel)) {\n return 'time';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n return 'time';\n\n case 'quantitative':\n if (isColorChannel(channel)) {\n if (isBinning(fieldDef.bin)) {\n return 'bin-ordinal';\n }\n\n return 'linear';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n return 'linear';\n\n case 'geojson':\n return undefined;\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n","import * as TYPE from 'vega-lite/build/src/type';\nimport {Type} from 'vega-lite/build/src/type';\n\nexport namespace ExpandedType {\n export const QUANTITATIVE = TYPE.QUANTITATIVE;\n export const ORDINAL = TYPE.ORDINAL;\n export const TEMPORAL = TYPE.TEMPORAL;\n export const NOMINAL = TYPE.NOMINAL;\n export const KEY: 'key' = 'key';\n}\n\nexport type ExpandedType = Type | typeof ExpandedType.KEY;\n\nexport function isDiscrete(fieldType: any) {\n return fieldType === TYPE.ORDINAL || fieldType === TYPE.NOMINAL || fieldType === ExpandedType.KEY;\n}\n","import { Dict, keys } from './util';\nimport {\n Property, toKey,\n} from './property';\n\nexport interface PropIndexReader {\n has(p: Property): boolean;\n get(p: Property): T;\n}\n\n/**\n * Dictionary that takes property as a key.\n */\nexport class PropIndex implements PropIndexReader {\n private index: Dict;\n\n constructor(i: Dict = null) {\n this.index = i ? { ...i } : {};\n }\n\n public has(p: Property) {\n return toKey(p) in this.index;\n }\n\n public get(p: Property) {\n return this.index[toKey(p)];\n }\n\n public set(p: Property, value: T) {\n this.index[toKey(p)] = value;\n return this;\n }\n\n public setByKey(key: string, value: T) {\n this.index[key] = value;\n }\n\n public map(f: (t: T) => U): PropIndex {\n const i = new PropIndex();\n for (const k in this.index) {\n i.index[k] = f(this.index[k]);\n }\n return i;\n }\n\n public size() {\n return keys(this.index).length;\n }\n\n public duplicate(): PropIndex {\n return new PropIndex(this.index);\n }\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {isArgmaxDef, isArgminDef} from './aggregate';\nimport {isBinning} from './bin';\nimport {Channel, CHANNELS, isChannel, isNonPositionScaleChannel, isSecondaryRangeChannel, supportMark} from './channel';\nimport {\n binRequiresRange,\n ChannelDef,\n Field,\n FieldDef,\n FieldDefWithoutScale,\n getFieldDef,\n getGuide,\n getTypedFieldDef,\n hasConditionalFieldDef,\n isConditionalDef,\n isFieldDef,\n isTypedFieldDef,\n isValueDef,\n LatLongFieldDef,\n normalize,\n normalizeFieldDef,\n NumericFieldDefWithCondition,\n NumericValueDefWithCondition,\n OrderFieldDef,\n PositionFieldDef,\n SecondaryFieldDef,\n ShapeFieldDefWithCondition,\n ShapeValueDefWithCondition,\n StringFieldDefWithCondition,\n StringValueDefWithCondition,\n TextFieldDef,\n TextFieldDefWithCondition,\n TextValueDefWithCondition,\n title,\n TypedFieldDef,\n ValueDef,\n vgField\n} from './channeldef';\nimport {Config} from './config';\nimport * as log from './log';\nimport {Mark} from './mark';\nimport {EncodingFacetMapping} from './spec/facet';\nimport {getDateTimeComponents} from './timeunit';\nimport {AggregatedFieldDef, BinTransform, TimeUnitTransform} from './transform';\nimport {TEMPORAL} from './type';\nimport {keys, some} from './util';\n\nexport interface Encoding {\n /**\n * X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"` without `x2`.\n *\n * The `value` of this channel can be a number or a string `\"width\"`.\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"` without `y2`\n *\n * The `value` of this channel can be a number or a string `\"height\"`.\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n *\n * The `value` of this channel can be a number or a string `\"width\"`.\n */\n // TODO: Ham need to add default behavior\n // `x2` cannot have type as it should have the same type as `x`\n x2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n *\n * The `value` of this channel can be a number or a string `\"height\"`.\n */\n // TODO: Ham need to add default behavior\n // `y2` cannot have type as it should have the same type as `y`\n y2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Longitude position of geographically projected marks.\n */\n longitude?: LatLongFieldDef | ValueDef;\n\n /**\n * Latitude position of geographically projected marks.\n */\n latitude?: LatLongFieldDef | ValueDef;\n\n /**\n * Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // `longitude2` cannot have type as it should have the same type as `longitude`\n longitude2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // `latitude2` cannot have type as it should have the same type as `latitude`\n latitude2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_\n * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored.\n * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).\n */\n color?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Fill color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`).\n */\n fill?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Stroke color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`).\n */\n\n stroke?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property.\n */\n opacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Fill opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `fillOpacity` property.\n */\n fillOpacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Stroke opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `strokeOpacity` property.\n */\n strokeOpacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Stroke width of the marks.\n *\n * __Default value:__ If undefined, the default stroke width depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `strokeWidth` property.\n */\n strokeWidth?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Size of the mark.\n * - For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n * - For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n * - For `\"text\"` – the text's font size.\n * - Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)\n */\n size?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Shape of the mark.\n *\n * 1. For `point` marks the supported values include:\n * - plotting shapes: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, `\"triangle-down\"`, `\"triangle-right\"`, or `\"triangle-left\"`.\n * - the line symbol `\"stroke\"`\n * - centered directional shapes `\"arrow\"`, `\"wedge\"`, or `\"triangle\"`\n * - a custom [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.)\n *\n * 2. For `geoshape` marks it should be a field definition of the geojson data\n *\n * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property. (`\"circle\"` if unset.)\n */\n shape?: ShapeFieldDefWithCondition | ShapeValueDefWithCondition;\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line, trail, and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDefWithoutScale | FieldDefWithoutScale[];\n\n /**\n * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data.\n */\n key?: FieldDefWithoutScale;\n\n /**\n * Text of the `text` mark.\n */\n text?: TextFieldDefWithCondition | TextValueDefWithCondition;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: TextFieldDefWithCondition | TextValueDefWithCondition | TextFieldDef[] | null;\n\n /**\n * A URL to load upon mouse click.\n */\n href?: TextFieldDefWithCondition | TextValueDefWithCondition;\n\n /**\n * Order of the marks.\n * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n * - Otherwise, this `order` channel encodes layer order of the marks.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[] | ValueDef;\n}\n\nexport interface EncodingWithFacet extends Encoding, EncodingFacetMapping {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, fieldDef => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef);\n }\n }\n return false;\n}\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, channel => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, fieldDef => !!fieldDef.aggregate);\n } else {\n const fieldDef = getFieldDef(channelDef);\n return fieldDef && !!fieldDef.aggregate;\n }\n }\n return false;\n });\n}\nexport function extractTransformsFromEncoding(oldEncoding: Encoding, config: Config) {\n const groupby: string[] = [];\n const bins: BinTransform[] = [];\n const timeUnits: TimeUnitTransform[] = [];\n const aggregate: AggregatedFieldDef[] = [];\n const encoding: Encoding = {};\n\n forEach(oldEncoding, (channelDef, channel) => {\n // Extract potential embedded transformations along with remaining properties\n if (isFieldDef(channelDef)) {\n const {field, aggregate: aggOp, timeUnit, bin, ...remaining} = channelDef;\n if (aggOp || timeUnit || bin) {\n const guide = getGuide(channelDef);\n const isTitleDefined = guide && guide.title;\n let newField = vgField(channelDef, {forAs: true});\n const newFieldDef: FieldDef = {\n // Only add title if it doesn't exist\n ...(isTitleDefined ? [] : {title: title(channelDef, config, {allowDisabling: true})}),\n ...remaining,\n // Always overwrite field\n field: newField\n };\n const isPositionChannel: boolean = channel === 'x' || channel === 'y';\n\n if (aggOp) {\n let op: AggregateOp;\n\n if (isArgmaxDef(aggOp)) {\n op = 'argmax';\n newField = vgField({aggregate: 'argmax', field: aggOp.argmax}, {forAs: true});\n newFieldDef.field = `${newField}.${field}`;\n } else if (isArgminDef(aggOp)) {\n op = 'argmin';\n newField = vgField({aggregate: 'argmin', field: aggOp.argmin}, {forAs: true});\n newFieldDef.field = `${newField}.${field}`;\n } else if (aggOp !== 'boxplot' && aggOp !== 'errorbar' && aggOp !== 'errorband') {\n op = aggOp;\n }\n\n if (op) {\n const aggregateEntry: AggregatedFieldDef = {\n op,\n as: newField\n };\n if (field) {\n aggregateEntry.field = field;\n }\n aggregate.push(aggregateEntry);\n }\n } else if (isTypedFieldDef(channelDef) && isBinning(bin)) {\n bins.push({bin, field, as: newField});\n // Add additional groupbys for range and end of bins\n groupby.push(vgField(channelDef, {binSuffix: 'end'}));\n if (binRequiresRange(channelDef, channel)) {\n groupby.push(vgField(channelDef, {binSuffix: 'range'}));\n }\n // Create accompanying 'x2' or 'y2' field if channel is 'x' or 'y' respectively\n if (isPositionChannel) {\n const secondaryChannel: SecondaryFieldDef = {\n field: newField + '_end'\n };\n encoding[channel + '2'] = secondaryChannel;\n }\n newFieldDef.bin = 'binned';\n if (!isSecondaryRangeChannel(channel)) {\n newFieldDef['type'] = 'quantitative';\n }\n } else if (timeUnit) {\n timeUnits.push({timeUnit, field, as: newField});\n\n // Add formatting to appropriate property based on the type of channel we're processing\n const format = getDateTimeComponents(timeUnit, config.axis.shortTimeLabels).join(' ');\n const formatType = isTypedFieldDef(channelDef) && channelDef.type !== TEMPORAL && 'time';\n if (channel === 'text' || channel === 'tooltip') {\n newFieldDef['format'] = newFieldDef['format'] || format;\n if (formatType) {\n newFieldDef['formatType'] = formatType;\n }\n } else if (isNonPositionScaleChannel(channel)) {\n newFieldDef['legend'] = {format, ...(formatType ? {formatType} : {}), ...newFieldDef['legend']};\n } else if (isPositionChannel) {\n newFieldDef['axis'] = {format, ...(formatType ? {formatType} : {}), ...newFieldDef['axis']};\n }\n }\n if (!aggOp) {\n groupby.push(newField);\n }\n // now the field should refer to post-transformed field instead\n encoding[channel] = newFieldDef;\n } else {\n groupby.push(field);\n encoding[channel] = oldEncoding[channel];\n }\n } else {\n // For value def, just copy\n encoding[channel] = oldEncoding[channel];\n }\n });\n\n return {\n bins,\n timeUnits,\n aggregate,\n groupby,\n encoding\n };\n}\n\nexport function markChannelCompatible(encoding: Encoding, channel: Channel, mark: Mark) {\n const markSupported = supportMark(channel, mark);\n if (!markSupported) {\n return false;\n } else if (markSupported === 'binned') {\n const primaryFieldDef = encoding[channel === 'x2' ? 'x' : 'y'];\n\n // circle, point, square and tick only support x2/y2 when their corresponding x/y fieldDef\n // has \"binned\" data and thus need x2/y2 to specify the bin-end field.\n if (isFieldDef(primaryFieldDef) && isFieldDef(encoding[channel]) && primaryFieldDef.bin === 'binned') {\n return true;\n } else {\n return false;\n }\n }\n return true;\n}\n\nexport function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding {\n return keys(encoding).reduce((normalizedEncoding: Encoding, channel: Channel | string) => {\n if (!isChannel(channel)) {\n // Drop invalid channel\n log.warn(log.message.invalidEncodingChannel(channel));\n return normalizedEncoding;\n }\n\n if (!markChannelCompatible(encoding, channel, mark)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, mark));\n return normalizedEncoding;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const fieldDef = getTypedFieldDef(encoding[channel]);\n if (fieldDef && fieldDef.aggregate) {\n log.warn(log.message.LINE_WITH_VARYING_SIZE);\n return normalizedEncoding;\n }\n }\n\n // Drop color if either fill or stroke is specified\n if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding)) {\n log.warn(log.message.droppingColor('encoding', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n return normalizedEncoding;\n }\n\n const channelDef = encoding[channel];\n if (\n channel === 'detail' ||\n (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) ||\n (channel === 'tooltip' && isArray(channelDef))\n ) {\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef]).reduce(\n (defs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n defs.push(normalizeFieldDef(fieldDef, channel));\n }\n return defs;\n },\n []\n );\n }\n } else {\n if (channel === 'tooltip' && channelDef === null) {\n // Preserve null so we can use it to disable tooltip\n normalizedEncoding[channel] = null;\n } else if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) {\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n return normalizedEncoding;\n }\n normalizedEncoding[channel] = normalize(channelDef as ChannelDef, channel);\n }\n return normalizedEncoding;\n }, {});\n}\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n const arr: FieldDef[] = [];\n for (const channel of keys(encoding)) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach(def => {\n if (isFieldDef(def)) {\n arr.push(def);\n } else if (hasConditionalFieldDef(def)) {\n arr.push(def.condition);\n }\n });\n }\n }\n return arr;\n}\n\nexport function forEach(\n mapping: U,\n f: (cd: ChannelDef, c: Channel) => void,\n thisArg?: any\n) {\n if (!mapping) {\n return;\n }\n\n for (const channel of keys(mapping)) {\n const el = mapping[channel];\n if (isArray(el)) {\n el.forEach((channelDef: ChannelDef) => {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, el, channel);\n }\n }\n}\n\nexport function reduce(\n mapping: U,\n f: (acc: any, fd: TypedFieldDef, c: Channel) => U,\n init: T,\n thisArg?: any\n) {\n if (!mapping) {\n return init;\n }\n\n return keys(mapping).reduce((r, channel) => {\n const map = mapping[channel];\n if (isArray(map)) {\n return map.reduce((r1: T, channelDef: ChannelDef) => {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, map, channel);\n }\n }, init);\n}\n","import {isArray, isBoolean} from 'vega-util';\nimport {SUM_OPS} from './aggregate';\nimport {NonPositionChannel, NONPOSITION_CHANNELS, X, X2, Y2} from './channel';\nimport {\n Field,\n getTypedFieldDef,\n isFieldDef,\n isStringFieldDef,\n PositionFieldDef,\n TypedFieldDef,\n vgField\n} from './channeldef';\nimport {channelHasField, Encoding} from './encoding';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag, getFirstDefined} from './util';\n\nexport type StackOffset = 'zero' | 'center' | 'normalize';\n\nconst STACK_OFFSET_INDEX: Flag = {\n zero: 1,\n center: 1,\n normalize: 1\n};\n\nexport function isStackOffset(s: string): s is StackOffset {\n return !!STACK_OFFSET_INDEX[s];\n}\n\nexport interface StackProperties {\n /** Dimension axis of the stack. */\n groupbyChannel: 'x' | 'y';\n\n /** Measure axis of the stack. */\n fieldChannel: 'x' | 'y';\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: TypedFieldDef;\n channel: NonPositionChannel;\n }[];\n\n /**\n * See `\"stack\"` property of Position Field Def.\n */\n offset: StackOffset;\n\n /**\n * Whether this stack will produce impute transform\n */\n impute: boolean;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\nfunction potentialStackedChannel(encoding: Encoding): 'x' | 'y' | undefined {\n const xDef = encoding.x;\n const yDef = encoding.y;\n\n if (isFieldDef(xDef) && isFieldDef(yDef)) {\n if (xDef.type === 'quantitative' && yDef.type === 'quantitative') {\n if (xDef.stack) {\n return 'x';\n } else if (yDef.stack) {\n return 'y';\n }\n // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y\n if (!!xDef.aggregate !== !!yDef.aggregate) {\n return xDef.aggregate ? 'x' : 'y';\n }\n } else if (xDef.type === 'quantitative') {\n return 'x';\n } else if (yDef.type === 'quantitative') {\n return 'y';\n }\n } else if (isFieldDef(xDef) && xDef.type === 'quantitative') {\n return 'x';\n } else if (isFieldDef(yDef) && yDef.type === 'quantitative') {\n return 'y';\n }\n return undefined;\n}\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\nexport function stack(\n m: Mark | MarkDef,\n encoding: Encoding,\n stackConfig: StackOffset,\n opt: {\n disallowNonLinearStack?: boolean; // This option is for CompassQL\n } = {}\n): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n const fieldChannel = potentialStackedChannel(encoding);\n if (!fieldChannel) {\n return null;\n }\n\n const stackedFieldDef = encoding[fieldChannel] as PositionFieldDef;\n const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined;\n\n // Should have grouping level of detail that is different from the dimension field\n const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => {\n // Ignore tooltip in stackBy (https://github.com/vega/vega-lite/issues/4001)\n if (channel !== 'tooltip' && channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach(cDef => {\n const fieldDef = getTypedFieldDef(cDef);\n if (fieldDef.aggregate) {\n return;\n }\n\n // Check whether the channel's field is identical to x/y's field or if the channel is a repeat\n const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined;\n if (\n // if fielddef is a repeat, just include it in the stack by\n !f ||\n // otherwise, the field must be different from x and y fields.\n (f !== dimensionField && f !== stackedField)\n ) {\n sc.push({channel, fieldDef});\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Automatically determine offset\n let offset: StackOffset;\n if (stackedFieldDef.stack !== undefined) {\n if (isBoolean(stackedFieldDef.stack)) {\n offset = stackedFieldDef.stack ? 'zero' : null;\n } else {\n offset = stackedFieldDef.stack;\n }\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n offset = getFirstDefined(stackConfig, 'zero');\n } else {\n offset = stackConfig;\n }\n\n if (!offset || !isStackOffset(offset)) {\n return null;\n }\n\n // warn when stacking non-linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n if (opt.disallowNonLinearStack) {\n return null;\n } else {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n }\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n if (stackedFieldDef.stack !== undefined) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n }\n return null;\n }\n\n // Warn if stacking summative aggregate\n if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) {\n log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate));\n }\n\n return {\n groupbyChannel: dimensionDef ? dimensionChannel : undefined,\n fieldChannel,\n impute: isPathMark(mark),\n stackBy,\n offset\n };\n}\n","import {toMap} from 'datalib/src/util';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Config} from 'vega-lite/build/src/config';\nimport {Data} from 'vega-lite/build/src/data';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec, TopLevel} from 'vega-lite/build/src/spec';\nimport {stack, StackOffset, StackProperties} from 'vega-lite/build/src/stack';\nimport {TitleParams} from 'vega-lite/build/src/title';\nimport {ALL_ENCODING_PROPS, getEncodingNestedProp, isEncodingTopLevelProperty, Property, toKey} from '../property';\nimport {contains, extend, isObject, keys, some, without} from '../util';\nimport {isWildcard, WildcardProperty} from '../wildcard';\nimport {EncodingQuery, isDisabledAutoCountQuery, isEnabledAutoCountQuery, isFieldQuery, toEncoding} from './encoding';\nimport {TransformQuery} from './transform';\n\n/**\n * A \"query\" version of a [Vega-Lite](https://github.com/vega/vega-lite)'s `UnitSpec` (single view specification).\n * This interface and most of its children have `Query` suffixes to hint that their instanced are queries that\n * can contain wildcards to describe a collection of specifications.\n */\nexport interface SpecQuery {\n data?: Data;\n\n // TODO: support mark definition object\n mark: WildcardProperty;\n transform?: TransformQuery[];\n\n /**\n * Array of encoding query mappings.\n * Note: Vega-Lite's `encoding` is an object whose keys are unique encoding channels.\n * However, for CompassQL, the `channel` property of encoding query mappings can be wildcards.\n * Thus the `encoding` object in Vega-Lite is flatten as the `encodings` array in CompassQL.\n */\n encodings: EncodingQuery[];\n\n /**\n * The width of the resulting encodings.\n * __NOTE:__ Does not support wildcards.\n */\n width?: number;\n\n /**\n * The height of the resulting encodings.\n * __NOTE:__ Does not support wildcards.\n */\n height?: number;\n\n /**\n * CSS color property to use as the background of visualization.\n * __NOTE:__ Does not support wildcards.\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the\n * visualization canvas to the data rectangle. If a number, specifies\n * padding for all sides. If an object, the value should have the\n * format {\"left\": 5, \"top\": 5, \"right\": 5, \"bottom\": 5}\n * to specify padding for each side of the visualization.\n *\n * __NOTE:__ Does not support wildcards.\n */\n padding?: number | Object;\n\n /**\n * Title for the plot.\n * __NOTE:__ Does not support wildcards.\n */\n title?: string | TitleParams;\n\n // TODO: make config query (not important at all, only for the sake of completeness.)\n /**\n * Vega-Lite Configuration\n */\n config?: Config;\n}\n\n/**\n * Convert a Vega-Lite's ExtendedUnitSpec into a CompassQL's SpecQuery\n * @param {ExtendedUnitSpec} spec\n * @returns\n */\nexport function fromSpec(spec: TopLevel): SpecQuery {\n return extend(\n spec.data ? {data: spec.data} : {},\n spec.transform ? {transform: spec.transform} : {},\n spec.width ? {width: spec.width} : {},\n spec.height ? {height: spec.height} : {},\n spec.background ? {background: spec.background} : {},\n spec.padding ? {padding: spec.padding} : {},\n spec.title ? {title: spec.title} : {},\n {\n mark: spec.mark,\n encodings: keys(spec.encoding).map((channel: Channel) => {\n let encQ: EncodingQuery = {channel: channel};\n let channelDef = spec.encoding[channel];\n\n for (const prop in channelDef) {\n if (isEncodingTopLevelProperty(prop as Property) && channelDef[prop] !== undefined) {\n // Currently bin, scale, axis, legend only support boolean, but not null.\n // Therefore convert null to false.\n if (contains(['bin', 'scale', 'axis', 'legend'], prop) && channelDef[prop] === null) {\n encQ[prop] = false;\n } else {\n encQ[prop] = channelDef[prop];\n }\n }\n }\n\n if (isFieldQuery(encQ) && encQ.aggregate === 'count' && !encQ.field) {\n encQ.field = '*';\n }\n\n return encQ;\n })\n },\n spec.config ? {config: spec.config} : {}\n );\n}\n\nexport function isAggregate(specQ: SpecQuery) {\n return some(specQ.encodings, (encQ: EncodingQuery) => {\n return (isFieldQuery(encQ) && !isWildcard(encQ.aggregate) && !!encQ.aggregate) || isEnabledAutoCountQuery(encQ);\n });\n}\n\n/**\n * @return The Vega-Lite `StackProperties` object that describes the stack\n * configuration of `specQ`. Returns `null` if this is not stackable.\n */\nexport function getVlStack(specQ: SpecQuery): StackProperties {\n if (!hasRequiredStackProperties(specQ)) {\n return null;\n }\n\n const encoding = toEncoding(specQ.encodings, {schema: null, wildcardMode: 'null'});\n const mark = specQ.mark as Mark;\n\n return stack(mark, encoding, undefined, {disallowNonLinearStack: true});\n}\n\n/**\n * @return The `StackOffset` specified in `specQ`, `undefined` if none\n * is specified.\n */\nexport function getStackOffset(specQ: SpecQuery): StackOffset {\n for (const encQ of specQ.encodings) {\n if (encQ[Property.STACK] !== undefined && !isWildcard(encQ[Property.STACK])) {\n return encQ[Property.STACK];\n }\n }\n return undefined;\n}\n\n/**\n * @return The `Channel` in which `stack` is specified in `specQ`, or\n * `null` if none is specified.\n */\nexport function getStackChannel(specQ: SpecQuery): Channel {\n for (const encQ of specQ.encodings) {\n if (encQ[Property.STACK] !== undefined && !isWildcard(encQ.channel)) {\n return encQ.channel;\n }\n }\n return null;\n}\n\n/**\n * Returns true iff the given SpecQuery has the properties defined\n * to be a potential Stack spec.\n * @param specQ The SpecQuery in question.\n */\nexport function hasRequiredStackProperties(specQ: SpecQuery) {\n // TODO(haldenl): make this leaner, a lot of encQ properties aren't required for stack.\n // TODO(haldenl): check mark, then encodings\n if (isWildcard(specQ.mark)) {\n return false;\n }\n\n const requiredEncodingProps = [\n Property.STACK,\n Property.CHANNEL,\n Property.MARK,\n Property.FIELD,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ];\n const exclude = toMap(without(ALL_ENCODING_PROPS, requiredEncodingProps));\n\n const encodings = specQ.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ));\n for (const encQ of encodings) {\n if (objectContainsWildcard(encQ, {exclude: exclude})) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns true iff the given object does not contain a nested wildcard.\n * @param obj The object in question.\n * @param opt With optional `exclude` property, which defines properties to\n * ignore when testing for wildcards.\n */\n// TODO(haldenl): rename to objectHasWildcard, rename prop to obj\nfunction objectContainsWildcard(obj: any, opt: {exclude?: {[key: string]: 1}} = {}) {\n if (!isObject(obj)) {\n return false;\n }\n\n for (const childProp in obj) {\n if (obj.hasOwnProperty(childProp)) {\n const wildcard = isWildcard(obj[childProp]);\n if ((wildcard && (!opt.exclude || !opt.exclude[childProp])) || objectContainsWildcard(obj[childProp], opt)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Returns true iff the given `specQ` contains a wildcard.\n * @param specQ The `SpecQuery` in question.\n * @param opt With optional `exclude` property, which defines properties to\n * ignore when testing for wildcards.\n */\nexport function hasWildcard(specQ: SpecQuery, opt: {exclude?: Property[]} = {}) {\n const exclude = opt.exclude ? toMap(opt.exclude.map(toKey)) : {};\n if (isWildcard(specQ.mark) && !exclude['mark']) {\n return true;\n }\n\n for (const encQ of specQ.encodings) {\n if (objectContainsWildcard(encQ, exclude)) {\n return true;\n }\n }\n return false;\n}\n","import {isString} from 'datalib/src/util';\nimport {isAggregateOp} from 'vega-lite/build/src/aggregate';\nimport {Channel, isChannel} from 'vega-lite/build/src/channel';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec} from 'vega-lite/build/src/spec';\nimport {StackProperties} from 'vega-lite/build/src/stack';\nimport {isTimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {getFullName} from 'vega-lite/build/src/type';\nimport {\n DEFAULT_PROP_PRECEDENCE,\n EncodingNestedChildProp,\n getEncodingNestedProp,\n isEncodingNestedParent,\n Property,\n SORT_PROPS,\n VIEW_PROPS\n} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Dict, isArray, isBoolean, keys} from '../util';\nimport {isShortWildcard, isWildcard, SHORT_WILDCARD} from '../wildcard';\nimport {\n EncodingQuery,\n FieldQuery,\n FieldQueryBase,\n isAutoCountQuery,\n isDisabledAutoCountQuery,\n isEnabledAutoCountQuery,\n isFieldQuery,\n isValueQuery\n} from './encoding';\nimport {fromSpec, getVlStack, SpecQuery} from './spec';\n\nexport type Replacer = (s: string) => string;\n\nexport function getReplacerIndex(replaceIndex: PropIndex>): PropIndex {\n return replaceIndex.map(r => getReplacer(r));\n}\n\nexport function getReplacer(replace: Dict): Replacer {\n return (s: string) => {\n if (replace[s] !== undefined) {\n return replace[s];\n }\n return s;\n };\n}\n\nexport function value(v: any, replacer: Replacer): any {\n if (isWildcard(v)) {\n // Return the enum array if it's a full wildcard, or just return SHORT_WILDCARD for short ones.\n if (!isShortWildcard(v) && v.enum) {\n return SHORT_WILDCARD + JSON.stringify(v.enum);\n } else {\n return SHORT_WILDCARD;\n }\n }\n if (replacer) {\n return replacer(v);\n }\n return v;\n}\n\nexport function replace(v: any, replacer: Replacer): any {\n if (replacer) {\n return replacer(v);\n }\n return v;\n}\n\nexport const REPLACE_NONE = new PropIndex();\n\nexport const INCLUDE_ALL: PropIndex =\n // FIXME: remove manual TRANSFORM concat once we really support enumerating transform.\n []\n .concat(DEFAULT_PROP_PRECEDENCE, SORT_PROPS, [Property.TRANSFORM, Property.STACK], VIEW_PROPS)\n .reduce((pi, prop: Property) => pi.set(prop, true), new PropIndex());\n\nexport function vlSpec(\n vlspec: FacetedUnitSpec,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n) {\n const specQ = fromSpec(vlspec);\n return spec(specQ, include, replace);\n}\n\nexport const PROPERTY_SUPPORTED_CHANNELS = {\n axis: {x: true, y: true, row: true, column: true},\n legend: {color: true, opacity: true, size: true, shape: true},\n scale: {x: true, y: true, color: true, opacity: true, row: true, column: true, size: true, shape: true},\n sort: {x: true, y: true, path: true, order: true},\n stack: {x: true, y: true}\n};\n\n/**\n * Returns a shorthand for a spec query\n * @param specQ a spec query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function spec(\n specQ: SpecQuery,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n): string {\n const parts: string[] = [];\n\n if (include.get(Property.MARK)) {\n parts.push(value(specQ.mark, replace.get(Property.MARK)));\n }\n\n if (specQ.transform && specQ.transform.length > 0) {\n parts.push('transform:' + JSON.stringify(specQ.transform));\n }\n\n let stack: StackProperties;\n if (include.get(Property.STACK)) {\n stack = getVlStack(specQ);\n }\n\n if (specQ.encodings) {\n const encodings = specQ.encodings\n .reduce((encQs, encQ) => {\n // Exclude encoding mapping with autoCount=false as they are basically disabled.\n if (!isDisabledAutoCountQuery(encQ)) {\n let str;\n if (!!stack && encQ.channel === stack.fieldChannel) {\n str = encoding({...encQ, stack: stack.offset}, include, replace);\n } else {\n str = encoding(encQ, include, replace);\n }\n if (str) {\n // only add if the shorthand isn't an empty string.\n encQs.push(str);\n }\n }\n return encQs;\n }, [])\n .sort() // sort at the end to ignore order\n .join('|');\n\n if (encodings) {\n parts.push(encodings);\n }\n }\n\n for (let viewProp of VIEW_PROPS) {\n const propString = viewProp.toString();\n if (include.get(viewProp) && !!specQ[propString]) {\n const value = specQ[propString];\n parts.push(`${propString}=${JSON.stringify(value)}`);\n }\n }\n\n return parts.join('|');\n}\n\n/**\n * Returns a shorthand for an encoding query\n * @param encQ an encoding query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function encoding(\n encQ: EncodingQuery,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n): string {\n const parts = [];\n if (include.get(Property.CHANNEL)) {\n parts.push(value(encQ.channel, replace.get(Property.CHANNEL)));\n }\n\n if (isFieldQuery(encQ)) {\n const fieldDefStr = fieldDef(encQ, include, replace);\n\n if (fieldDefStr) {\n parts.push(fieldDefStr);\n }\n } else if (isValueQuery(encQ)) {\n parts.push(encQ.value);\n } else if (isAutoCountQuery(encQ)) {\n parts.push('autocount()');\n }\n\n return parts.join(':');\n}\n\n/**\n * Returns a field definition shorthand for an encoding query\n * @param encQ an encoding query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function fieldDef(\n encQ: EncodingQuery,\n include: PropIndex = INCLUDE_ALL,\n replacer: PropIndex = REPLACE_NONE\n): string {\n if (include.get(Property.AGGREGATE) && isDisabledAutoCountQuery(encQ)) {\n return '-';\n }\n\n const fn = func(encQ, include, replacer);\n const props = fieldDefProps(encQ, include, replacer);\n\n let fieldAndParams;\n if (isFieldQuery(encQ)) {\n // field\n fieldAndParams = include.get('field') ? value(encQ.field, replacer.get('field')) : '...';\n // type\n if (include.get(Property.TYPE)) {\n if (isWildcard(encQ.type)) {\n fieldAndParams += ',' + value(encQ.type, replacer.get(Property.TYPE));\n } else {\n const typeShort = ((encQ.type || TYPE.QUANTITATIVE) + '').substr(0, 1);\n fieldAndParams += ',' + value(typeShort, replacer.get(Property.TYPE));\n }\n }\n // encoding properties\n fieldAndParams += props\n .map(p => {\n let val = p.value instanceof Array ? '[' + p.value + ']' : p.value;\n return ',' + p.key + '=' + val;\n })\n .join('');\n } else if (isAutoCountQuery(encQ)) {\n fieldAndParams = '*,q';\n }\n\n if (!fieldAndParams) {\n return null;\n }\n if (fn) {\n let fnPrefix = isString(fn) ? fn : SHORT_WILDCARD + (keys(fn).length > 0 ? JSON.stringify(fn) : '');\n\n return fnPrefix + '(' + fieldAndParams + ')';\n }\n return fieldAndParams;\n}\n\n/**\n * Return function part of\n */\nfunction func(fieldQ: FieldQuery, include: PropIndex, replacer: PropIndex): string | Object {\n if (include.get(Property.AGGREGATE) && fieldQ.aggregate && !isWildcard(fieldQ.aggregate)) {\n return replace(fieldQ.aggregate, replacer.get(Property.AGGREGATE));\n } else if (include.get(Property.AGGREGATE) && isEnabledAutoCountQuery(fieldQ)) {\n // autoCount is considered a part of aggregate\n return replace('count', replacer.get(Property.AGGREGATE));\n } else if (include.get(Property.TIMEUNIT) && fieldQ.timeUnit && !isWildcard(fieldQ.timeUnit)) {\n return replace(fieldQ.timeUnit, replacer.get(Property.TIMEUNIT));\n } else if (include.get(Property.BIN) && fieldQ.bin && !isWildcard(fieldQ.bin)) {\n return 'bin';\n } else {\n let fn: any = null;\n for (const prop of [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN]) {\n const val = fieldQ[prop];\n if (include.get(prop) && fieldQ[prop] && isWildcard(val)) {\n // assign fnEnumIndex[prop] = array of enum values or just \"?\" if it is SHORT_WILDCARD\n fn = fn || {};\n fn[prop] = isShortWildcard(val) ? val : val.enum;\n }\n }\n if (fn && fieldQ.hasFn) {\n fn.hasFn = true;\n }\n return fn;\n }\n}\n\n/**\n * Return key-value of parameters of field defs\n */\nfunction fieldDefProps(fieldQ: FieldQuery, include: PropIndex, replacer: PropIndex) {\n /** Encoding properties e.g., Scale, Axis, Legend */\n const props: {key: string; value: boolean | Object}[] = [];\n\n // Parameters of function such as bin will be just top-level properties\n if (!isBoolean(fieldQ.bin) && !isShortWildcard(fieldQ.bin)) {\n const bin = fieldQ.bin;\n for (const child in bin) {\n const prop = getEncodingNestedProp('bin', child as EncodingNestedChildProp);\n if (prop && include.get(prop) && bin[child] !== undefined) {\n props.push({\n key: child,\n value: value(bin[child], replacer.get(prop))\n });\n }\n }\n // Sort to make sure that parameter are ordered consistently\n props.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n for (const parent of [Property.SCALE, Property.SORT, Property.STACK, Property.AXIS, Property.LEGEND]) {\n if (!isWildcard(fieldQ.channel) && !PROPERTY_SUPPORTED_CHANNELS[parent][fieldQ.channel as Channel]) {\n continue;\n }\n\n if (include.get(parent) && fieldQ[parent] !== undefined) {\n const parentValue = fieldQ[parent];\n if (isBoolean(parentValue) || parentValue === null) {\n // `scale`, `axis`, `legend` can be false/null.\n props.push({\n key: parent + '',\n value: parentValue || false // return true or false (false if null)\n });\n } else if (isString(parentValue)) {\n // `sort` can be a string (ascending/descending).\n props.push({\n key: parent + '',\n value: replace(JSON.stringify(parentValue), replacer.get(parent))\n });\n } else {\n let nestedPropChildren = [];\n for (const child in parentValue) {\n const nestedProp = getEncodingNestedProp(parent, child as EncodingNestedChildProp);\n if (nestedProp && include.get(nestedProp) && parentValue[child] !== undefined) {\n nestedPropChildren.push({\n key: child,\n value: value(parentValue[child], replacer.get(nestedProp))\n });\n }\n }\n\n if (nestedPropChildren.length > 0) {\n const nestedPropObject = nestedPropChildren\n .sort((a, b) => a.key.localeCompare(b.key))\n .reduce((o, item) => {\n o[item.key] = item.value;\n return o;\n }, {});\n\n // Sort to make sure that parameter are ordered consistently\n props.push({\n key: parent + '',\n value: JSON.stringify(nestedPropObject)\n });\n }\n }\n }\n }\n return props;\n}\n\nexport function parse(shorthand: string): SpecQuery {\n // TODO(https://github.com/uwdata/compassql/issues/259):\n // Do not split directly, but use an upgraded version of `getClosingBraceIndex()`\n let splitShorthand = shorthand.split('|');\n\n let specQ: SpecQuery = {\n mark: splitShorthand[0] as Mark,\n encodings: [] as EncodingQuery[]\n };\n\n for (let i = 1; i < splitShorthand.length; i++) {\n let part = splitShorthand[i];\n const splitPart = splitWithTail(part, ':', 1);\n const splitPartKey = splitPart[0];\n const splitPartValue = splitPart[1];\n\n if (isChannel(splitPartKey) || splitPartKey === '?') {\n const encQ = shorthandParser.encoding(splitPartKey, splitPartValue);\n specQ.encodings.push(encQ);\n continue;\n }\n\n if (splitPartKey === 'transform') {\n specQ.transform = JSON.parse(splitPartValue);\n continue;\n }\n }\n\n return specQ;\n}\n\n/**\n * Split a string n times into substrings with the specified delimiter and return them as an array.\n * @param str The string to be split\n * @param delim The delimiter string used to separate the string\n * @param number The value used to determine how many times the string is split\n */\nexport function splitWithTail(str: string, delim: string, count: number): string[] {\n let result = [];\n let lastIndex = 0;\n\n for (let i = 0; i < count; i++) {\n let indexOfDelim = str.indexOf(delim, lastIndex);\n\n if (indexOfDelim !== -1) {\n result.push(str.substring(lastIndex, indexOfDelim));\n lastIndex = indexOfDelim + 1;\n } else {\n break;\n }\n }\n\n result.push(str.substr(lastIndex));\n\n // If the specified count is greater than the number of delimiters that exist in the string,\n // an empty string will be pushed count minus number of delimiter occurence times.\n if (result.length !== count + 1) {\n while (result.length !== count + 1) {\n result.push('');\n }\n }\n\n return result;\n}\n\nexport namespace shorthandParser {\n export function encoding(channel: Channel | SHORT_WILDCARD, fieldDefShorthand: string): EncodingQuery {\n let encQMixins =\n fieldDefShorthand.indexOf('(') !== -1\n ? fn(fieldDefShorthand)\n : rawFieldDef(splitWithTail(fieldDefShorthand, ',', 2));\n return {\n channel,\n ...encQMixins\n };\n }\n\n export function rawFieldDef(fieldDefPart: string[]): FieldQueryBase {\n const fieldQ: FieldQueryBase = {};\n fieldQ.field = fieldDefPart[0];\n fieldQ.type = getFullName(fieldDefPart[1].toUpperCase()) || '?';\n\n let partParams = fieldDefPart[2];\n let closingBraceIndex = 0;\n let i = 0;\n\n while (i < partParams.length) {\n let propEqualSignIndex = partParams.indexOf('=', i);\n let parsedValue;\n if (propEqualSignIndex !== -1) {\n let prop = partParams.substring(i, propEqualSignIndex);\n if (partParams[i + prop.length + 1] === '{') {\n let openingBraceIndex = i + prop.length + 1;\n closingBraceIndex = getClosingIndex(openingBraceIndex, partParams, '}');\n const value = partParams.substring(openingBraceIndex, closingBraceIndex + 1);\n parsedValue = JSON.parse(value);\n\n // index after next comma\n i = closingBraceIndex + 2;\n } else if (partParams[i + prop.length + 1] === '[') {\n // find closing square bracket\n let openingBracketIndex = i + prop.length + 1;\n let closingBracketIndex = getClosingIndex(openingBracketIndex, partParams, ']');\n const value = partParams.substring(openingBracketIndex, closingBracketIndex + 1);\n parsedValue = JSON.parse(value);\n\n // index after next comma\n i = closingBracketIndex + 2;\n } else {\n let propIndex = i;\n // Substring until the next comma (or end of the string)\n let nextCommaIndex = partParams.indexOf(',', i + prop.length);\n if (nextCommaIndex === -1) {\n nextCommaIndex = partParams.length;\n }\n // index after next comma\n i = nextCommaIndex + 1;\n\n parsedValue = JSON.parse(partParams.substring(propIndex + prop.length + 1, nextCommaIndex));\n }\n\n if (isEncodingNestedParent(prop)) {\n fieldQ[prop] = parsedValue;\n } else {\n // prop is a property of the aggregation function such as bin\n fieldQ.bin = fieldQ.bin || {};\n fieldQ.bin[prop] = parsedValue;\n }\n } else {\n // something is wrong with the format of the partParams\n // exits loop if don't have then infintie loop\n break;\n }\n }\n return fieldQ;\n }\n\n export function getClosingIndex(openingBraceIndex: number, str: string, closingChar: string): number {\n for (let i = openingBraceIndex; i < str.length; i++) {\n if (str[i] === closingChar) {\n return i;\n }\n }\n }\n\n export function fn(fieldDefShorthand: string): FieldQueryBase {\n const fieldQ: FieldQueryBase = {};\n // Aggregate, Bin, TimeUnit as wildcard case\n if (fieldDefShorthand[0] === '?') {\n let closingBraceIndex = getClosingIndex(1, fieldDefShorthand, '}');\n\n let fnEnumIndex = JSON.parse(fieldDefShorthand.substring(1, closingBraceIndex + 1));\n\n for (let encodingProperty in fnEnumIndex) {\n if (isArray(fnEnumIndex[encodingProperty])) {\n fieldQ[encodingProperty] = {enum: fnEnumIndex[encodingProperty]};\n } else {\n // Definitely a `SHORT_WILDCARD`\n fieldQ[encodingProperty] = fnEnumIndex[encodingProperty];\n }\n }\n\n return {\n ...fieldQ,\n ...rawFieldDef(\n splitWithTail(fieldDefShorthand.substring(closingBraceIndex + 2, fieldDefShorthand.length - 1), ',', 2)\n )\n };\n } else {\n let func = fieldDefShorthand.substring(0, fieldDefShorthand.indexOf('('));\n let insideFn = fieldDefShorthand.substring(func.length + 1, fieldDefShorthand.length - 1);\n let insideFnParts = splitWithTail(insideFn, ',', 2);\n\n if (isAggregateOp(func)) {\n return {\n aggregate: func,\n ...rawFieldDef(insideFnParts)\n };\n } else if (isTimeUnit(func)) {\n return {\n timeUnit: func,\n ...rawFieldDef(insideFnParts)\n };\n } else if (func === 'bin') {\n return {\n bin: {},\n ...rawFieldDef(insideFnParts)\n };\n }\n }\n }\n}\n","import {isObject} from 'datalib/src/util';\nimport {AggregateOp} from 'vega';\nimport {Axis} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport * as vlChannelDef from 'vega-lite/build/src/channeldef';\nimport {ValueDef} from 'vega-lite/build/src/channeldef';\nimport {scaleType as compileScaleType} from 'vega-lite/build/src/compile/scale/type';\nimport {Encoding} from 'vega-lite/build/src/encoding';\nimport {Legend} from 'vega-lite/build/src/legend';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {Scale} from 'vega-lite/build/src/scale';\nimport {EncodingSortField, SortOrder} from 'vega-lite/build/src/sort';\nimport {StackOffset} from 'vega-lite/build/src/stack';\nimport {TimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {Type as VLType} from 'vega-lite/build/src/type';\nimport {FlatProp, isEncodingNestedParent, Property} from '../property';\nimport {Schema} from '../schema';\nimport {isWildcard, SHORT_WILDCARD, Wildcard, WildcardProperty} from '../wildcard';\nimport {ExpandedType} from './expandedtype';\nimport {PROPERTY_SUPPORTED_CHANNELS} from './shorthand';\n\nexport type EncodingQuery = FieldQuery | ValueQuery | AutoCountQuery;\n\nexport interface EncodingQueryBase {\n channel: WildcardProperty;\n\n description?: string;\n}\n\nexport interface ValueQuery extends EncodingQueryBase {\n value: WildcardProperty;\n}\n\nexport function isValueQuery(encQ: EncodingQuery): encQ is ValueQuery {\n return encQ !== null && encQ !== undefined && encQ['value'] !== undefined;\n}\n\nexport function isFieldQuery(encQ: EncodingQuery): encQ is FieldQuery {\n return encQ !== null && encQ !== undefined && (encQ['field'] || encQ['aggregate'] === 'count');\n}\n\nexport function isAutoCountQuery(encQ: EncodingQuery): encQ is AutoCountQuery {\n return encQ !== null && encQ !== undefined && 'autoCount' in encQ;\n}\n\nexport function isDisabledAutoCountQuery(encQ: EncodingQuery) {\n return isAutoCountQuery(encQ) && encQ.autoCount === false;\n}\n\nexport function isEnabledAutoCountQuery(encQ: EncodingQuery) {\n return isAutoCountQuery(encQ) && encQ.autoCount === true;\n}\n\n/**\n * A special encoding query that gets added internally if the `config.autoCount` flag is on. See SpecQueryModel.build for its generation.\n *\n * __Note:__ this type of query should not be specified by users.\n */\nexport interface AutoCountQuery extends EncodingQueryBase {\n /**\n * A count function that gets added internally if the config.autoCount flag in on.\n * This allows us to add one extra encoding mapping if needed when the query produces\n * plot that only have discrete fields.\n * In such cases, adding count make the output plots way more meaningful.\n */\n autoCount: WildcardProperty;\n type: 'quantitative';\n}\n\nexport interface FieldQueryBase {\n // FieldDef\n aggregate?: WildcardProperty;\n timeUnit?: WildcardProperty;\n\n /**\n * Special flag for enforcing that the field should have a fuction (one of timeUnit, bin, or aggregate).\n *\n * For example, if you enumerate both bin and aggregate then you need `undefined` for both.\n *\n * ```\n * {aggregate: {enum: [undefined, 'mean', 'sum']}, bin: {enum: [false, true]}}\n * ```\n *\n * This would enumerate a fieldDef with \"mean\", \"sum\", bin:true, and no function at all.\n * If you want only \"mean\", \"sum\", bin:true, then use `hasFn: true`\n *\n * ```\n * {aggregate: {enum: [undefined, 'mean', 'sum']}, bin: {enum: [false, true]}, hasFn: true}\n * ```\n */\n hasFn?: boolean;\n\n bin?: boolean | BinQuery | SHORT_WILDCARD;\n scale?: boolean | ScaleQuery | SHORT_WILDCARD;\n\n sort?: SortOrder | EncodingSortField;\n stack?: StackOffset | SHORT_WILDCARD;\n\n field?: WildcardProperty;\n type?: WildcardProperty;\n\n axis?: boolean | AxisQuery | SHORT_WILDCARD;\n legend?: boolean | LegendQuery | SHORT_WILDCARD;\n\n format?: string;\n}\n\nexport type FieldQuery = EncodingQueryBase & FieldQueryBase;\n\n// Using Mapped Type from TS2.1 to declare query for an object without nested property\n// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#mapped-types\nexport type FlatQuery = {[P in keyof T]: WildcardProperty};\n\nexport type FlatQueryWithEnableFlag = (Wildcard | {}) & FlatQuery;\n\nexport type BinQuery = FlatQueryWithEnableFlag;\nexport type ScaleQuery = FlatQueryWithEnableFlag;\nexport type AxisQuery = FlatQueryWithEnableFlag;\nexport type LegendQuery = FlatQueryWithEnableFlag;\n\nconst DEFAULT_PROPS = [\n Property.AGGREGATE,\n Property.BIN,\n Property.TIMEUNIT,\n Property.FIELD,\n Property.TYPE,\n Property.SCALE,\n Property.SORT,\n Property.AXIS,\n Property.LEGEND,\n Property.STACK,\n Property.FORMAT\n];\n\nexport interface ConversionParams {\n schema?: Schema;\n props?: FlatProp[];\n wildcardMode?: 'skip' | 'null';\n}\n\nexport function toEncoding(encQs: EncodingQuery[], params: ConversionParams): Encoding {\n const {wildcardMode = 'skip'} = params;\n let encoding: Encoding = {};\n\n for (const encQ of encQs) {\n if (isDisabledAutoCountQuery(encQ)) {\n continue; // Do not include this in the output.\n }\n\n const {channel} = encQ;\n\n // if channel is a wildcard, return null\n if (isWildcard(channel)) {\n throw new Error('Cannot convert wildcard channel to a fixed channel');\n }\n const channelDef = isValueQuery(encQ) ? toValueDef(encQ) : toFieldDef(encQ, params);\n\n if (channelDef === null) {\n if (params.wildcardMode === 'null') {\n // contains invalid property (e.g., wildcard, thus cannot return a proper spec.)\n return null;\n }\n continue;\n }\n // Otherwise, we can set the channelDef\n encoding[channel] = channelDef;\n }\n return encoding;\n}\n\nexport function toValueDef(valueQ: ValueQuery): ValueDef {\n const {value} = valueQ;\n if (isWildcard(value)) {\n return null;\n }\n return {value};\n}\n\nexport function toFieldDef(\n encQ: FieldQuery | AutoCountQuery,\n params: ConversionParams = {}\n): vlChannelDef.TypedFieldDef {\n const {props = DEFAULT_PROPS, schema, wildcardMode = 'skip'} = params;\n\n if (isFieldQuery(encQ)) {\n const fieldDef = {} as vlChannelDef.TypedFieldDef;\n for (const prop of props) {\n let encodingProperty = encQ[prop];\n if (isWildcard(encodingProperty)) {\n if (wildcardMode === 'skip') continue;\n return null;\n }\n\n if (encodingProperty !== undefined) {\n // if the channel supports this prop\n const isSupportedByChannel =\n !PROPERTY_SUPPORTED_CHANNELS[prop] || PROPERTY_SUPPORTED_CHANNELS[prop][encQ.channel as Channel];\n if (!isSupportedByChannel) {\n continue;\n }\n\n if (isEncodingNestedParent(prop) && isObject(encodingProperty)) {\n encodingProperty = {...encodingProperty}; // Make a shallow copy first\n for (const childProp in encodingProperty) {\n // ensure nested properties are not wildcard before assigning to field def\n if (isWildcard(encodingProperty[childProp])) {\n if (wildcardMode === 'null') {\n return null;\n }\n delete encodingProperty[childProp]; // skip\n }\n }\n }\n\n if (prop === 'bin' && encodingProperty === false) {\n continue;\n } else if (prop === 'type' && encodingProperty === 'key') {\n fieldDef.type = 'nominal';\n } else {\n fieldDef[prop] = encodingProperty;\n }\n }\n\n if (prop === Property.SCALE && schema && encQ.type === TYPE.ORDINAL) {\n const scale = encQ.scale;\n const {ordinalDomain} = schema.fieldSchema(encQ.field as string);\n\n if (scale !== null && ordinalDomain) {\n fieldDef[Property.SCALE] = {\n domain: ordinalDomain,\n // explicitly specfied domain property should override ordinalDomain\n ...(isObject(scale) ? scale : {})\n };\n }\n }\n }\n return fieldDef;\n } else {\n if (encQ.autoCount === false) {\n throw new Error(`Cannot convert {autoCount: false} into a field def`);\n } else {\n return {\n aggregate: 'count',\n field: '*',\n type: 'quantitative'\n };\n }\n }\n}\n\n/**\n * Is a field query continuous field?\n * This method is applicable only for fieldQuery without wildcard\n */\nexport function isContinuous(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n return vlChannelDef.isContinuous(toFieldDef(encQ, {props: ['bin', 'timeUnit', 'field', 'type']}));\n }\n return isAutoCountQuery(encQ);\n}\n\nexport function isMeasure(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n return !isDimension(encQ) && encQ.type !== 'temporal';\n }\n return isAutoCountQuery(encQ);\n}\n\n/**\n * Is a field query discrete field?\n * This method is applicable only for fieldQuery without wildcard\n */\nexport function isDimension(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n const fieldDef = toFieldDef(encQ, {props: ['bin', 'timeUnit', 'type']});\n return vlChannelDef.isDiscrete(fieldDef) || !!fieldDef.timeUnit;\n }\n return false;\n}\n\n/**\n * Returns the true scale type of an encoding.\n * @returns {ScaleType} If the scale type was not specified, it is inferred from the encoding's TYPE.\n * @returns {undefined} If the scale type was not specified and Type (or TimeUnit if applicable) is a Wildcard, there is no clear scale type\n */\n\nexport function scaleType(fieldQ: FieldQuery) {\n const scale: ScaleQuery = fieldQ.scale === true || fieldQ.scale === SHORT_WILDCARD ? {} : fieldQ.scale || {};\n\n const {type, channel, timeUnit, bin} = fieldQ;\n\n // HACK: All of markType, and scaleConfig only affect\n // sub-type of ordinal to quantitative scales (point or band)\n // Currently, most of scaleType usage in CompassQL doesn't care about this subtle difference.\n // Thus, instead of making this method requiring the global mark,\n // we will just call it with mark = undefined .\n // Thus, currently, we will always get a point scale unless a CompassQuery specifies band.\n const markType: Mark = undefined;\n\n if (isWildcard(scale.type) || isWildcard(type) || isWildcard(channel) || isWildcard(bin)) {\n return undefined;\n }\n\n // If scale type is specified, then use scale.type\n if (scale.type) {\n return scale.type;\n }\n\n // if type is fixed and it's not temporal, we can ignore time unit.\n if (type === 'temporal' && isWildcard(timeUnit)) {\n return undefined;\n }\n\n // if type is fixed and it's not quantitative, we can ignore bin\n if (type === 'quantitative' && isWildcard(bin)) {\n return undefined;\n }\n\n let vegaLiteType: VLType = type === ExpandedType.KEY ? 'nominal' : type;\n\n const fieldDef = {\n type: vegaLiteType,\n timeUnit: timeUnit as TimeUnit,\n bin: bin as BinParams\n };\n return compileScaleType({type: scale.type}, channel, fieldDef, markType);\n}\n","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) :\n factory((global.d3_time = {}));\n}(this, function (exports) { 'use strict';\n\n var t0 = new Date;\n var t1 = new Date;\n function newInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = new Date(+date)), date;\n }\n\n interval.floor = interval;\n\n interval.round = function(date) {\n var d0 = new Date(+date),\n d1 = new Date(date - 1);\n floori(d0), floori(d1), offseti(d1, 1);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.ceil = function(date) {\n return floori(date = new Date(date - 1)), offseti(date, 1), date;\n };\n\n interval.offset = function(date, step) {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = function(start, stop, step) {\n var range = [];\n start = new Date(start - 1);\n stop = new Date(+stop);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n offseti(start, 1), floori(start);\n if (start < stop) range.push(new Date(+start));\n while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start));\n return range;\n };\n\n interval.filter = function(test) {\n return newInterval(function(date) {\n while (floori(date), !test(date)) date.setTime(date - 1);\n }, function(date, step) {\n while (--step >= 0) while (offseti(date, 1), !test(date));\n });\n };\n\n if (count) {\n interval.count = function(start, end) {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = function(step) {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? function(d) { return field(d) % step === 0; }\n : function(d) { return interval.count(0, d) % step === 0; });\n };\n }\n\n return interval;\n };\n\n var millisecond = newInterval(function() {\n // noop\n }, function(date, step) {\n date.setTime(+date + step);\n }, function(start, end) {\n return end - start;\n });\n\n // An optimized implementation for this simple case.\n millisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return newInterval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n };\n\n var second = newInterval(function(date) {\n date.setMilliseconds(0);\n }, function(date, step) {\n date.setTime(+date + step * 1e3);\n }, function(start, end) {\n return (end - start) / 1e3;\n }, function(date) {\n return date.getSeconds();\n });\n\n var minute = newInterval(function(date) {\n date.setSeconds(0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 6e4);\n }, function(start, end) {\n return (end - start) / 6e4;\n }, function(date) {\n return date.getMinutes();\n });\n\n var hour = newInterval(function(date) {\n date.setMinutes(0, 0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 36e5);\n }, function(start, end) {\n return (end - start) / 36e5;\n }, function(date) {\n return date.getHours();\n });\n\n var day = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5;\n }, function(date) {\n return date.getDate() - 1;\n });\n\n function weekday(i) {\n return newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5;\n });\n }\n\n var sunday = weekday(0);\n var monday = weekday(1);\n var tuesday = weekday(2);\n var wednesday = weekday(3);\n var thursday = weekday(4);\n var friday = weekday(5);\n var saturday = weekday(6);\n\n var month = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setDate(1);\n }, function(date, step) {\n date.setMonth(date.getMonth() + step);\n }, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n }, function(date) {\n return date.getMonth();\n });\n\n var year = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setMonth(0, 1);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n }, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n }, function(date) {\n return date.getFullYear();\n });\n\n var utcSecond = newInterval(function(date) {\n date.setUTCMilliseconds(0);\n }, function(date, step) {\n date.setTime(+date + step * 1e3);\n }, function(start, end) {\n return (end - start) / 1e3;\n }, function(date) {\n return date.getUTCSeconds();\n });\n\n var utcMinute = newInterval(function(date) {\n date.setUTCSeconds(0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 6e4);\n }, function(start, end) {\n return (end - start) / 6e4;\n }, function(date) {\n return date.getUTCMinutes();\n });\n\n var utcHour = newInterval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 36e5);\n }, function(start, end) {\n return (end - start) / 36e5;\n }, function(date) {\n return date.getUTCHours();\n });\n\n var utcDay = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n }, function(start, end) {\n return (end - start) / 864e5;\n }, function(date) {\n return date.getUTCDate() - 1;\n });\n\n function utcWeekday(i) {\n return newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / 6048e5;\n });\n }\n\n var utcSunday = utcWeekday(0);\n var utcMonday = utcWeekday(1);\n var utcTuesday = utcWeekday(2);\n var utcWednesday = utcWeekday(3);\n var utcThursday = utcWeekday(4);\n var utcFriday = utcWeekday(5);\n var utcSaturday = utcWeekday(6);\n\n var utcMonth = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCDate(1);\n }, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n }, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n }, function(date) {\n return date.getUTCMonth();\n });\n\n var utcYear = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCMonth(0, 1);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n }, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n }, function(date) {\n return date.getUTCFullYear();\n });\n\n var milliseconds = millisecond.range;\n var seconds = second.range;\n var minutes = minute.range;\n var hours = hour.range;\n var days = day.range;\n var sundays = sunday.range;\n var mondays = monday.range;\n var tuesdays = tuesday.range;\n var wednesdays = wednesday.range;\n var thursdays = thursday.range;\n var fridays = friday.range;\n var saturdays = saturday.range;\n var weeks = sunday.range;\n var months = month.range;\n var years = year.range;\n\n var utcMillisecond = millisecond;\n var utcMilliseconds = milliseconds;\n var utcSeconds = utcSecond.range;\n var utcMinutes = utcMinute.range;\n var utcHours = utcHour.range;\n var utcDays = utcDay.range;\n var utcSundays = utcSunday.range;\n var utcMondays = utcMonday.range;\n var utcTuesdays = utcTuesday.range;\n var utcWednesdays = utcWednesday.range;\n var utcThursdays = utcThursday.range;\n var utcFridays = utcFriday.range;\n var utcSaturdays = utcSaturday.range;\n var utcWeeks = utcSunday.range;\n var utcMonths = utcMonth.range;\n var utcYears = utcYear.range;\n\n var version = \"0.1.1\";\n\n exports.version = version;\n exports.milliseconds = milliseconds;\n exports.seconds = seconds;\n exports.minutes = minutes;\n exports.hours = hours;\n exports.days = days;\n exports.sundays = sundays;\n exports.mondays = mondays;\n exports.tuesdays = tuesdays;\n exports.wednesdays = wednesdays;\n exports.thursdays = thursdays;\n exports.fridays = fridays;\n exports.saturdays = saturdays;\n exports.weeks = weeks;\n exports.months = months;\n exports.years = years;\n exports.utcMillisecond = utcMillisecond;\n exports.utcMilliseconds = utcMilliseconds;\n exports.utcSeconds = utcSeconds;\n exports.utcMinutes = utcMinutes;\n exports.utcHours = utcHours;\n exports.utcDays = utcDays;\n exports.utcSundays = utcSundays;\n exports.utcMondays = utcMondays;\n exports.utcTuesdays = utcTuesdays;\n exports.utcWednesdays = utcWednesdays;\n exports.utcThursdays = utcThursdays;\n exports.utcFridays = utcFridays;\n exports.utcSaturdays = utcSaturdays;\n exports.utcWeeks = utcWeeks;\n exports.utcMonths = utcMonths;\n exports.utcYears = utcYears;\n exports.millisecond = millisecond;\n exports.second = second;\n exports.minute = minute;\n exports.hour = hour;\n exports.day = day;\n exports.sunday = sunday;\n exports.monday = monday;\n exports.tuesday = tuesday;\n exports.wednesday = wednesday;\n exports.thursday = thursday;\n exports.friday = friday;\n exports.saturday = saturday;\n exports.week = sunday;\n exports.month = month;\n exports.year = year;\n exports.utcSecond = utcSecond;\n exports.utcMinute = utcMinute;\n exports.utcHour = utcHour;\n exports.utcDay = utcDay;\n exports.utcSunday = utcSunday;\n exports.utcMonday = utcMonday;\n exports.utcTuesday = utcTuesday;\n exports.utcWednesday = utcWednesday;\n exports.utcThursday = utcThursday;\n exports.utcFriday = utcFriday;\n exports.utcSaturday = utcSaturday;\n exports.utcWeek = utcSunday;\n exports.utcMonth = utcMonth;\n exports.utcYear = utcYear;\n exports.interval = newInterval;\n\n}));","var d3_time = require('d3-time');\n\nvar tempDate = new Date(),\n baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD\n utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0);\n\nfunction date(d) {\n return (tempDate.setTime(+d), tempDate);\n}\n\n// create a time unit entry\nfunction entry(type, date, unit, step, min, max) {\n var e = {\n type: type,\n date: date,\n unit: unit\n };\n if (step) {\n e.step = step;\n } else {\n e.minstep = 1;\n }\n if (min != null) e.min = min;\n if (max != null) e.max = max;\n return e;\n}\n\nfunction create(type, unit, base, step, min, max) {\n return entry(type,\n function(d) { return unit.offset(base, d); },\n function(d) { return unit.count(base, d); },\n step, min, max);\n}\n\nvar locale = [\n create('second', d3_time.second, baseDate),\n create('minute', d3_time.minute, baseDate),\n create('hour', d3_time.hour, baseDate),\n create('day', d3_time.day, baseDate, [1, 7]),\n create('month', d3_time.month, baseDate, [1, 3, 6]),\n create('year', d3_time.year, baseDate),\n\n // periodic units\n entry('seconds',\n function(d) { return new Date(1970, 0, 1, 0, 0, d); },\n function(d) { return date(d).getSeconds(); },\n null, 0, 59\n ),\n entry('minutes',\n function(d) { return new Date(1970, 0, 1, 0, d); },\n function(d) { return date(d).getMinutes(); },\n null, 0, 59\n ),\n entry('hours',\n function(d) { return new Date(1970, 0, 1, d); },\n function(d) { return date(d).getHours(); },\n null, 0, 23\n ),\n entry('weekdays',\n function(d) { return new Date(1970, 0, 4+d); },\n function(d) { return date(d).getDay(); },\n [1], 0, 6\n ),\n entry('dates',\n function(d) { return new Date(1970, 0, d); },\n function(d) { return date(d).getDate(); },\n [1], 1, 31\n ),\n entry('months',\n function(d) { return new Date(1970, d % 12, 1); },\n function(d) { return date(d).getMonth(); },\n [1], 0, 11\n )\n];\n\nvar utc = [\n create('second', d3_time.utcSecond, utcBaseDate),\n create('minute', d3_time.utcMinute, utcBaseDate),\n create('hour', d3_time.utcHour, utcBaseDate),\n create('day', d3_time.utcDay, utcBaseDate, [1, 7]),\n create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]),\n create('year', d3_time.utcYear, utcBaseDate),\n\n // periodic units\n entry('seconds',\n function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); },\n function(d) { return date(d).getUTCSeconds(); },\n null, 0, 59\n ),\n entry('minutes',\n function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); },\n function(d) { return date(d).getUTCMinutes(); },\n null, 0, 59\n ),\n entry('hours',\n function(d) { return new Date(Date.UTC(1970, 0, 1, d)); },\n function(d) { return date(d).getUTCHours(); },\n null, 0, 23\n ),\n entry('weekdays',\n function(d) { return new Date(Date.UTC(1970, 0, 4+d)); },\n function(d) { return date(d).getUTCDay(); },\n [1], 0, 6\n ),\n entry('dates',\n function(d) { return new Date(Date.UTC(1970, 0, d)); },\n function(d) { return date(d).getUTCDate(); },\n [1], 1, 31\n ),\n entry('months',\n function(d) { return new Date(Date.UTC(1970, d % 12, 1)); },\n function(d) { return date(d).getUTCMonth(); },\n [1], 0, 11\n )\n];\n\nvar STEPS = [\n [31536e6, 5], // 1-year\n [7776e6, 4], // 3-month\n [2592e6, 4], // 1-month\n [12096e5, 3], // 2-week\n [6048e5, 3], // 1-week\n [1728e5, 3], // 2-day\n [864e5, 3], // 1-day\n [432e5, 2], // 12-hour\n [216e5, 2], // 6-hour\n [108e5, 2], // 3-hour\n [36e5, 2], // 1-hour\n [18e5, 1], // 30-minute\n [9e5, 1], // 15-minute\n [3e5, 1], // 5-minute\n [6e4, 1], // 1-minute\n [3e4, 0], // 30-second\n [15e3, 0], // 15-second\n [5e3, 0], // 5-second\n [1e3, 0] // 1-second\n];\n\nfunction find(units, span, minb, maxb) {\n var step = STEPS[0], i, n, bins;\n\n for (i=1, n=STEPS.length; i step[0]) {\n bins = span / step[0];\n if (bins > maxb) {\n return units[STEPS[i-1][1]];\n }\n if (bins >= minb) {\n return units[step[1]];\n }\n }\n }\n return units[STEPS[n-1][1]];\n}\n\nfunction toUnitMap(units) {\n var map = {}, i, n;\n for (i=0, n=units.length; i maxb) { step *= base; }\n\n // decrease step size if allowed\n for (i=0; i= minstep && span / v <= maxb) step = v;\n }\n }\n\n // update precision, min and max\n v = Math.log(step);\n precision = v >= 0 ? 0 : ~~(-v / logb) + 1;\n eps = Math.pow(base, -precision - 1);\n min = Math.min(min, Math.floor(min / step + eps) * step);\n max = Math.ceil(max / step) * step;\n\n return {\n start: min,\n stop: max,\n step: step,\n unit: {precision: precision},\n value: value,\n index: index\n };\n}\n\nfunction bisect(a, x, lo, hi) {\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (util.cmp(a[mid], x) < 0) { lo = mid + 1; }\n else { hi = mid; }\n }\n return lo;\n}\n\nfunction value(v) {\n return this.step * Math.floor(v / this.step + EPSILON);\n}\n\nfunction index(v) {\n return Math.floor((v - this.start) / this.step + EPSILON);\n}\n\nfunction date_value(v) {\n return this.unit.date(value.call(this, v));\n}\n\nfunction date_index(v) {\n return index.call(this, this.unit.unit(v));\n}\n\nbins.date = function(opt) {\n if (!opt) { throw Error(\"Missing date binning options.\"); }\n\n // find time step, then bin\n var units = opt.utc ? time.utc : time,\n dmin = opt.min,\n dmax = opt.max,\n maxb = opt.maxbins || 20,\n minb = opt.minbins || 4,\n span = (+dmax) - (+dmin),\n unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb),\n spec = bins({\n min: unit.min != null ? unit.min : unit.unit(dmin),\n max: unit.max != null ? unit.max : unit.unit(dmax),\n maxbins: maxb,\n minstep: unit.minstep,\n steps: unit.step\n });\n\n spec.unit = unit;\n spec.index = date_index;\n if (!opt.raw) spec.value = date_value;\n return spec;\n};\n\nmodule.exports = bins;\n","var util = require('../util');\n\nvar TYPES = '__types__';\n\nvar PARSERS = {\n boolean: util.boolean,\n integer: util.number,\n number: util.number,\n date: util.date,\n string: function(x) { return x == null || x === '' ? null : x + ''; }\n};\n\nvar TESTS = {\n boolean: function(x) { return x==='true' || x==='false' || util.isBoolean(x); },\n integer: function(x) { return TESTS.number(x) && (x=+x) === ~~x; },\n number: function(x) { return !isNaN(+x) && !util.isDate(x); },\n date: function(x) { return !isNaN(Date.parse(x)); }\n};\n\nfunction annotation(data, types) {\n if (!types) return data && data[TYPES] || null;\n data[TYPES] = types;\n}\n\nfunction fieldNames(datum) {\n return util.keys(datum);\n}\n\nfunction bracket(fieldName) {\n return '[' + fieldName + ']';\n}\n\nfunction type(values, f) {\n values = util.array(values);\n f = util.$(f);\n var v, i, n;\n\n // if data array has type annotations, use them\n if (values[TYPES]) {\n v = f(values[TYPES]);\n if (util.isString(v)) return v;\n }\n\n for (i=0, n=values.length; !util.isValid(v) && i stop) range.push(j);\n else while ((j = start + step * ++i) < stop) range.push(j);\n return range;\n};\n\ngen.random = {};\n\ngen.random.uniform = function(min, max) {\n if (max === undefined) {\n max = min === undefined ? 1 : min;\n min = 0;\n }\n var d = max - min;\n var f = function() {\n return min + d * Math.random();\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n return (x >= min && x <= max) ? 1/d : 0;\n };\n f.cdf = function(x) {\n return x < min ? 0 : x > max ? 1 : (x - min) / d;\n };\n f.icdf = function(p) {\n return (p >= 0 && p <= 1) ? min + p*d : NaN;\n };\n return f;\n};\n\ngen.random.integer = function(a, b) {\n if (b === undefined) {\n b = a;\n a = 0;\n }\n var d = b - a;\n var f = function() {\n return a + Math.floor(d * Math.random());\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n return (x === Math.floor(x) && x >= a && x < b) ? 1/d : 0;\n };\n f.cdf = function(x) {\n var v = Math.floor(x);\n return v < a ? 0 : v >= b ? 1 : (v - a + 1) / d;\n };\n f.icdf = function(p) {\n return (p >= 0 && p <= 1) ? a - 1 + Math.floor(p*d) : NaN;\n };\n return f;\n};\n\ngen.random.normal = function(mean, stdev) {\n mean = mean || 0;\n stdev = stdev || 1;\n var next;\n var f = function() {\n var x = 0, y = 0, rds, c;\n if (next !== undefined) {\n x = next;\n next = undefined;\n return x;\n }\n do {\n x = Math.random()*2-1;\n y = Math.random()*2-1;\n rds = x*x + y*y;\n } while (rds === 0 || rds > 1);\n c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform\n next = mean + y*c*stdev;\n return mean + x*c*stdev;\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n var exp = Math.exp(Math.pow(x-mean, 2) / (-2 * Math.pow(stdev, 2)));\n return (1 / (stdev * Math.sqrt(2*Math.PI))) * exp;\n };\n f.cdf = function(x) {\n // Approximation from West (2009)\n // Better Approximations to Cumulative Normal Functions\n var cd,\n z = (x - mean) / stdev,\n Z = Math.abs(z);\n if (Z > 37) {\n cd = 0;\n } else {\n var sum, exp = Math.exp(-Z*Z/2);\n if (Z < 7.07106781186547) {\n sum = 3.52624965998911e-02 * Z + 0.700383064443688;\n sum = sum * Z + 6.37396220353165;\n sum = sum * Z + 33.912866078383;\n sum = sum * Z + 112.079291497871;\n sum = sum * Z + 221.213596169931;\n sum = sum * Z + 220.206867912376;\n cd = exp * sum;\n sum = 8.83883476483184e-02 * Z + 1.75566716318264;\n sum = sum * Z + 16.064177579207;\n sum = sum * Z + 86.7807322029461;\n sum = sum * Z + 296.564248779674;\n sum = sum * Z + 637.333633378831;\n sum = sum * Z + 793.826512519948;\n sum = sum * Z + 440.413735824752;\n cd = cd / sum;\n } else {\n sum = Z + 0.65;\n sum = Z + 4 / sum;\n sum = Z + 3 / sum;\n sum = Z + 2 / sum;\n sum = Z + 1 / sum;\n cd = exp / sum / 2.506628274631;\n }\n }\n return z > 0 ? 1 - cd : cd;\n };\n f.icdf = function(p) {\n // Approximation of Probit function using inverse error function.\n if (p <= 0 || p >= 1) return NaN;\n var x = 2*p - 1,\n v = (8 * (Math.PI - 3)) / (3 * Math.PI * (4-Math.PI)),\n a = (2 / (Math.PI*v)) + (Math.log(1 - Math.pow(x,2)) / 2),\n b = Math.log(1 - (x*x)) / v,\n s = (x > 0 ? 1 : -1) * Math.sqrt(Math.sqrt((a*a) - b) - a);\n return mean + stdev * Math.SQRT2 * s;\n };\n return f;\n};\n\ngen.random.bootstrap = function(domain, smooth) {\n // Generates a bootstrap sample from a set of observations.\n // Smooth bootstrapping adds random zero-centered noise to the samples.\n var val = domain.filter(util.isValid),\n len = val.length,\n err = smooth ? gen.random.normal(0, smooth) : null;\n var f = function() {\n return val[~~(Math.random()*len)] + (err ? err() : 0);\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n return f;\n};","var util = require('./util');\nvar type = require('./import/type');\nvar gen = require('./generate');\n\nvar stats = module.exports;\n\n// Collect unique values.\n// Output: an array of unique values, in first-observed order\nstats.unique = function(values, f, results) {\n f = util.$(f);\n results = results || [];\n var u = {}, v, i, n;\n for (i=0, n=values.length; i 0 ? Math.pow(mean, 1/c) : 0;\n return mean;\n};\n\n// Compute the harmonic mean of an array of numbers.\nstats.mean.harmonic = function(values, f) {\n f = util.$(f);\n var mean = 0, c, n, v, i;\n for (i=0, c=0, n=values.length; i b) b = v;\n }\n }\n return [a, b];\n};\n\n// Find the integer indices of the minimum and maximum values.\nstats.extent.index = function(values, f) {\n f = util.$(f);\n var x = -1, y = -1, a, b, v, i, n = values.length;\n for (i=0; i b) { b = v; y = i; }\n }\n }\n return [x, y];\n};\n\n// Compute the dot product of two arrays of numbers.\nstats.dot = function(values, a, b) {\n var sum = 0, i, v;\n if (!b) {\n if (values.length !== a.length) {\n throw Error('Array lengths must match.');\n }\n for (i=0; i -1 && p !== v) {\n mu = 1 + (i-1 + tie) / 2;\n for (; tie -1) {\n mu = 1 + (n-1 + tie) / 2;\n for (; tie max) max = x;\n delta = x - mean;\n mean = mean + delta / (++valid);\n M2 = M2 + delta * (x - mean);\n vals.push(x);\n }\n }\n M2 = M2 / (valid - 1);\n sd = Math.sqrt(M2);\n\n // sort values for median and iqr\n vals.sort(util.cmp);\n\n return {\n type: type(values, f),\n unique: u,\n count: values.length,\n valid: valid,\n missing: missing,\n distinct: distinct,\n min: min,\n max: max,\n mean: mean,\n stdev: sd,\n median: (v = stats.quantile(vals, 0.5)),\n q1: stats.quantile(vals, 0.25),\n q3: stats.quantile(vals, 0.75),\n modeskew: sd === 0 ? 0 : (mean - v) / sd\n };\n};\n\n// Compute profiles for all variables in a data set.\nstats.summary = function(data, fields) {\n fields = fields || util.keys(data[0]);\n var s = fields.map(function(f) {\n var p = stats.profile(data, util.$(f));\n return (p.field = f, p);\n });\n return (s.__summary__ = true, s);\n};\n","import dlBin_ from 'datalib/src/bins/bins';\nimport {inferAll} from 'datalib/src/import/type';\nimport {summary} from 'datalib/src/stats';\nimport {autoMaxBins} from 'vega-lite/build/src/bin';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {containsTimeUnit, convert, TimeUnit, TIMEUNIT_PARTS} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from './config';\nimport {BinQuery, EncodingQuery, FieldQuery, isAutoCountQuery} from './query/encoding';\nimport {ExpandedType} from './query/expandedtype';\nimport {cmp, duplicate, extend, keys} from './util';\n\nconst dlBin = dlBin_;\n\n/**\n * Table Schema Field Descriptor interface\n * see: https://specs.frictionlessdata.io/table-schema/\n */\nexport interface TableSchemaFieldDescriptor {\n /* name of field **/\n name: string;\n\n /* A nicer human readable label or title for the field **/\n title?: string;\n\n /* number, integer, string, datetime */\n type: PrimitiveType;\n\n /* A string specifying a format */\n format?: string;\n\n /* A description for the field */\n description?: string;\n}\n\n/**\n * Field Schema\n */\nexport interface FieldSchema extends TableSchemaFieldDescriptor {\n vlType?: ExpandedType;\n\n index?: number;\n // Need to keep original index for re-exporting TableSchema\n originalIndex?: number;\n\n stats: DLFieldProfile;\n binStats?: {[maxbins: string]: DLFieldProfile};\n timeStats?: {[timeUnit: string]: DLFieldProfile};\n\n // array of valid input values (fields)\n ordinalDomain?: string[];\n}\n\n/**\n * Table Schema\n * see: https://specs.frictionlessdata.io/table-schema/\n */\nexport interface TableSchema {\n fields: F[];\n missingValues?: string[];\n primaryKey?: string | string[];\n foreignKeys?: object[];\n}\n\n/**\n * Build a Schema object.\n *\n * @param data - a set of raw data in the same format that Vega-Lite / Vega takes\n * Basically, it's an array in the form of:\n *\n * [\n * {a: 1, b:2},\n * {a: 2, b:3},\n * ...\n * ]\n *\n * @return a Schema object\n */\nexport function build(\n data: any,\n opt: QueryConfig = {},\n tableSchema: TableSchema = {fields: []}\n): Schema {\n opt = extend({}, DEFAULT_QUERY_CONFIG, opt);\n\n // create profiles for each variable\n let summaries: DLFieldProfile[] = summary(data);\n let types = inferAll(data); // inferAll does stronger type inference than summary\n\n let tableSchemaFieldIndex = tableSchema.fields.reduce((m, field: TableSchemaFieldDescriptor) => {\n m[field.name] = field;\n return m;\n }, {});\n\n let fieldSchemas: FieldSchema[] = summaries.map(function(fieldProfile, index) {\n const name: string = fieldProfile.field;\n // In Table schema, 'date' doesn't include time so use 'datetime'\n const type: PrimitiveType = types[name] === 'date' ? PrimitiveType.DATETIME : (types[name] as any);\n let distinct: number = fieldProfile.distinct;\n let vlType: ExpandedType;\n\n if (type === PrimitiveType.NUMBER) {\n vlType = TYPE.QUANTITATIVE;\n } else if (type === PrimitiveType.INTEGER) {\n // use ordinal or nominal when cardinality of integer type is relatively low and the distinct values are less than an amount specified in options\n if (distinct < opt.numberNominalLimit && distinct / fieldProfile.count < opt.numberNominalProportion) {\n vlType = TYPE.NOMINAL;\n } else {\n vlType = TYPE.QUANTITATIVE;\n }\n } else if (type === PrimitiveType.DATETIME) {\n vlType = TYPE.TEMPORAL;\n // need to get correct min/max of date data because datalib's summary method does not\n // calculate this correctly for date types.\n fieldProfile.min = new Date(data[0][name]);\n fieldProfile.max = new Date(data[0][name]);\n for (const dataEntry of data) {\n const time = new Date(dataEntry[name]).getTime();\n if (time < (fieldProfile.min as Date).getTime()) {\n fieldProfile.min = new Date(time);\n }\n if (time > (fieldProfile.max as Date).getTime()) {\n fieldProfile.max = new Date(time);\n }\n }\n } else {\n vlType = TYPE.NOMINAL;\n }\n\n if (\n vlType === TYPE.NOMINAL &&\n distinct / fieldProfile.count > opt.minPercentUniqueForKey &&\n fieldProfile.count > opt.minCardinalityForKey\n ) {\n vlType = ExpandedType.KEY;\n }\n\n let fieldSchema = {\n name: name,\n // Need to keep original index for re-exporting TableSchema\n originalIndex: index,\n vlType: vlType,\n type: type,\n stats: fieldProfile,\n timeStats: {} as {[timeUnit: string]: DLFieldProfile},\n binStats: {} as {[key: string]: DLFieldProfile}\n };\n\n // extend field schema with table schema field - if present\n const orgFieldSchema = tableSchemaFieldIndex[fieldSchema.name];\n fieldSchema = extend(fieldSchema, orgFieldSchema);\n\n return fieldSchema;\n });\n\n // calculate preset bins for quantitative and temporal data\n for (let fieldSchema of fieldSchemas) {\n if (fieldSchema.vlType === TYPE.QUANTITATIVE) {\n for (let maxbins of opt.enum.binProps.maxbins) {\n fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats);\n }\n } else if (fieldSchema.vlType === TYPE.TEMPORAL) {\n for (let unit of opt.enum.timeUnit) {\n if (unit !== undefined) {\n fieldSchema.timeStats[unit] = timeSummary(unit, fieldSchema.stats);\n }\n }\n }\n }\n\n const derivedTableSchema: TableSchema = {\n ...tableSchema,\n fields: fieldSchemas\n };\n\n return new Schema(derivedTableSchema);\n}\n\n// order the field schema when we construct a new Schema\n// this orders the fields in the UI\nconst order = {\n nominal: 0,\n key: 1,\n ordinal: 2,\n temporal: 3,\n quantitative: 4\n};\n\nexport class Schema {\n private _tableSchema: TableSchema;\n private _fieldSchemaIndex: {[field: string]: FieldSchema};\n\n constructor(tableSchema: TableSchema) {\n this._tableSchema = tableSchema;\n\n tableSchema.fields.sort(function(a: FieldSchema, b: FieldSchema) {\n // first order by vlType: nominal < temporal < quantitative < ordinal\n if (order[a.vlType] < order[b.vlType]) {\n return -1;\n } else if (order[a.vlType] > order[b.vlType]) {\n return 1;\n } else {\n // then order by field (alphabetically)\n return a.name.localeCompare(b.name);\n }\n });\n\n // Add index for sorting\n tableSchema.fields.forEach((fieldSchema, index) => (fieldSchema.index = index));\n\n this._fieldSchemaIndex = tableSchema.fields.reduce((m, fieldSchema: FieldSchema) => {\n m[fieldSchema.name] = fieldSchema;\n return m;\n }, {});\n }\n\n /** @return a list of the field names (for enumerating). */\n public fieldNames() {\n return this._tableSchema.fields.map(fieldSchema => fieldSchema.name);\n }\n\n /** @return a list of FieldSchemas */\n public get fieldSchemas() {\n return this._tableSchema.fields;\n }\n\n public fieldSchema(fieldName: string) {\n return this._fieldSchemaIndex[fieldName];\n }\n\n public tableSchema() {\n // the fieldschemas are re-arranged\n // but this is not allowed in table schema.\n // so we will re-order based on original index.\n const tableSchema = duplicate(this._tableSchema);\n tableSchema.fields.sort((a, b) => a.originalIndex - b.originalIndex);\n return tableSchema;\n }\n\n /**\n * @return primitive type of the field if exist, otherwise return null\n */\n public primitiveType(fieldName: string) {\n return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].type : null;\n }\n\n /**\n * @return vlType of measturement of the field if exist, otherwise return null\n */\n public vlType(fieldName: string) {\n return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].vlType : null;\n }\n\n /** @return cardinality of the field associated with encQ, null if it doesn't exist.\n * @param augmentTimeUnitDomain - TimeUnit field domains will not be augmented if explicitly set to false.\n */\n public cardinality(fieldQ: FieldQuery, augmentTimeUnitDomain: boolean = true, excludeInvalid: boolean = false) {\n const fieldSchema = this._fieldSchemaIndex[fieldQ.field as string];\n if (fieldQ.aggregate || (isAutoCountQuery(fieldQ) && fieldQ.autoCount)) {\n return 1;\n } else if (fieldQ.bin) {\n // encQ.bin will either be a boolean or a BinQuery\n let bin: BinQuery;\n if (typeof fieldQ.bin === 'boolean') {\n // autoMaxBins defaults to 10 if channel is Wildcard\n bin = {\n maxbins: autoMaxBins(fieldQ.channel as Channel)\n };\n } else if (fieldQ.bin === '?') {\n bin = {\n enum: [true, false]\n };\n } else {\n bin = fieldQ.bin;\n }\n const maxbins: any = bin.maxbins;\n if (!fieldSchema.binStats[maxbins]) {\n // need to calculate\n fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats);\n }\n // don't need to worry about excludeInvalid here because invalid values don't affect linearly binned field's cardinality\n return fieldSchema.binStats[maxbins].distinct;\n } else if (fieldQ.timeUnit) {\n if (augmentTimeUnitDomain) {\n switch (fieldQ.timeUnit) {\n // TODO: this should not always be the case once Vega-Lite supports turning off domain augmenting (VL issue #1385)\n case TimeUnit.SECONDS:\n return 60;\n case TimeUnit.MINUTES:\n return 60;\n case TimeUnit.HOURS:\n return 24;\n case TimeUnit.DAY:\n return 7;\n case TimeUnit.DATE:\n return 31;\n case TimeUnit.MONTH:\n return 12;\n case TimeUnit.QUARTER:\n return 4;\n case TimeUnit.MILLISECONDS:\n return 1000;\n }\n }\n let unit = fieldQ.timeUnit as string;\n let timeStats = fieldSchema.timeStats;\n // if the cardinality for the timeUnit is not cached, calculate it\n if (!timeStats || !timeStats[unit]) {\n timeStats = {\n ...timeStats,\n [unit]: timeSummary(fieldQ.timeUnit as TimeUnit, fieldSchema.stats)\n };\n }\n\n if (excludeInvalid) {\n return timeStats[unit].distinct - invalidCount(timeStats[unit].unique, ['Invalid Date', null]);\n } else {\n return timeStats[unit].distinct;\n }\n } else {\n if (fieldSchema) {\n if (excludeInvalid) {\n return fieldSchema.stats.distinct - invalidCount(fieldSchema.stats.unique, [NaN, null]);\n } else {\n return fieldSchema.stats.distinct;\n }\n } else {\n return null;\n }\n }\n }\n\n /**\n * Given an EncodingQuery with a timeUnit, returns true if the date field\n * has multiple distinct values for all parts of the timeUnit. Returns undefined\n * if the timeUnit is undefined.\n * i.e.\n * ('yearmonth', [Jan 1 2000, Feb 2 2000] returns false)\n * ('yearmonth', [Jan 1 2000, Feb 2 2001] returns true)\n */\n public timeUnitHasVariation(fieldQ: FieldQuery): boolean {\n if (!fieldQ.timeUnit) {\n return;\n }\n\n // if there is no variation in `date`, there should not be variation in `day`\n if (fieldQ.timeUnit === TimeUnit.DAY) {\n const dateEncQ: EncodingQuery = extend({}, fieldQ, {timeUnit: TimeUnit.DATE});\n if (this.cardinality(dateEncQ, false, true) <= 1) {\n return false;\n }\n }\n\n let fullTimeUnit = fieldQ.timeUnit;\n for (let timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(fullTimeUnit as TimeUnit, timeUnitPart)) {\n // Create a clone of encQ, but with singleTimeUnit\n const singleUnitEncQ = extend({}, fieldQ, {timeUnit: timeUnitPart});\n if (this.cardinality(singleUnitEncQ, false, true) <= 1) {\n return false;\n }\n }\n }\n return true;\n }\n\n public domain(fieldQueryParts: {field: string}): any[] {\n // TODO: differentiate for field with bin / timeUnit\n const fieldSchema = this._fieldSchemaIndex[fieldQueryParts.field as string];\n let domain: any[] = keys(fieldSchema.stats.unique);\n if (fieldSchema.vlType === TYPE.QUANTITATIVE) {\n // return [min, max], coerced into number types\n return [+fieldSchema.stats.min, +fieldSchema.stats.max];\n } else if (fieldSchema.type === PrimitiveType.DATETIME) {\n // return [min, max] dates\n return [fieldSchema.stats.min, fieldSchema.stats.max];\n } else if (fieldSchema.type === PrimitiveType.INTEGER || fieldSchema.type === PrimitiveType.NUMBER) {\n // coerce non-quantitative numerical data into number type\n domain = domain.map(x => +x);\n return domain.sort(cmp);\n } else if (fieldSchema.vlType === TYPE.ORDINAL && fieldSchema.ordinalDomain) {\n return fieldSchema.ordinalDomain;\n }\n\n return domain\n .map(x => {\n // Convert 'null' to null as it is encoded similarly in datalib.\n // This is wrong when it is a string 'null' but that rarely happens.\n return x === 'null' ? null : x;\n })\n .sort(cmp);\n }\n\n /**\n * @return a Summary corresponding to the field of the given EncodingQuery\n */\n public stats(fieldQ: FieldQuery) {\n // TODO: differentiate for field with bin / timeUnit vs without\n const fieldSchema = this._fieldSchemaIndex[fieldQ.field as string];\n return fieldSchema ? fieldSchema.stats : null;\n }\n}\n\n/**\n * @return a summary of the binning scheme determined from the given max number of bins\n */\nfunction binSummary(maxbins: number, summary: DLFieldProfile): DLFieldProfile {\n const bin = dlBin({\n min: summary.min,\n max: summary.max,\n maxbins: maxbins\n });\n\n // start with summary, pre-binning\n const result = extend({}, summary);\n result.unique = binUnique(bin, summary.unique);\n result.distinct = (bin.stop - bin.start) / bin.step;\n result.min = bin.start;\n result.max = bin.stop;\n\n return result;\n}\n\n/** @return a modified version of the passed summary with unique and distinct set according to the timeunit.\n * Maps 'null' (string) keys to the null value and invalid dates to 'Invalid Date' in the unique dictionary.\n */\nfunction timeSummary(timeunit: TimeUnit, summary: DLFieldProfile): DLFieldProfile {\n const result = extend({}, summary);\n\n let unique: {[value: string]: number} = {};\n keys(summary.unique).forEach(function(dateString) {\n // don't convert null value because the Date constructor will actually convert it to a date\n let date: Date = dateString === 'null' ? null : new Date(dateString);\n // at this point, `date` is either the null value, a valid Date object, or \"Invalid Date\" which is a Date\n let key: string;\n if (date === null) {\n key = null;\n } else if (isNaN(date.getTime())) {\n key = 'Invalid Date';\n } else {\n key = (timeunit === TimeUnit.DAY ? date.getDay() : convert(timeunit, date)).toString();\n }\n unique[key] = (unique[key] || 0) + summary.unique[dateString];\n });\n\n result.unique = unique;\n result.distinct = keys(unique).length;\n\n return result;\n}\n\n/**\n * @return a new unique object based off of the old unique count and a binning scheme\n */\nfunction binUnique(bin: any, oldUnique: any) {\n const newUnique = {};\n for (let value in oldUnique) {\n let bucket: number;\n if (value === null) {\n bucket = null;\n } else if (isNaN(Number(value))) {\n bucket = NaN;\n } else {\n bucket = bin.value(Number(value)) as number;\n }\n newUnique[bucket] = (newUnique[bucket] || 0) + oldUnique[value];\n }\n return newUnique;\n}\n\n/** @return the number of items in list that occur as keys of unique */\nfunction invalidCount(unique: {}, list: any[]) {\n return list.reduce(function(prev, cur) {\n return unique[cur] ? prev + 1 : prev;\n }, 0);\n}\n\nexport enum PrimitiveType {\n STRING = 'string' as any,\n NUMBER = 'number' as any,\n INTEGER = 'integer' as any,\n BOOLEAN = 'boolean' as any,\n DATETIME = 'datetime' as any\n}\n","import {QueryConfig} from '../config';\nimport {isEncodingNestedProp, Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\nimport { every} from '../util';\n\nimport {EncodingQueryBase} from '../query/encoding';\n\n/**\n * Abstract interface for a constraint.\n */\nexport interface AbstractConstraint {\n name: string;\n description: string;\n properties: Property[];\n\n /**\n * Whether this constraint requires all specified properties types to be specific\n * in order to call satisfy function.\n */\n allowWildcardForProperties: boolean;\n\n /**\n * Whether this constraint is strict (not optional).\n */\n strict: boolean;\n}\n\n/**\n * Abstract model for a constraint.\n */\nexport class AbstractConstraintModel {\n protected constraint: AbstractConstraint;\n\n constructor(constraint: AbstractConstraint) {\n this.constraint = constraint;\n }\n\n public name(): string {\n return this.constraint.name;\n }\n\n public description(): string {\n return this.constraint.description;\n }\n\n public properties(): Property[] {\n return this.constraint.properties;\n }\n\n public strict(): boolean {\n return this.constraint.strict;\n }\n}\n\n/**\n * Collection of constraints for a single encoding mapping.\n */\n\n/** A method for satisfying whether the provided encoding query satisfy the constraint. */\nexport interface EncodingConstraintChecker {\n (encQ: E, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig): boolean;\n}\n\nexport class EncodingConstraintModel extends AbstractConstraintModel {\n constructor(constraint: EncodingConstraint) {\n super(constraint);\n }\n\n public hasAllRequiredPropertiesSpecific(encQ: E): boolean {\n return every(this.constraint.properties, (prop: Property) => {\n\n if (isEncodingNestedProp(prop)) {\n let parent = prop.parent;\n let child = prop.child;\n\n if (!encQ[parent]) {\n return true;\n }\n\n return !isWildcard(encQ[parent][child]);\n }\n\n if (!encQ[prop]) {\n return true;\n }\n\n return !isWildcard(encQ[prop]);\n });\n }\n\n public satisfy(encQ: E, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig): boolean {\n // TODO: Re-order logic to optimize the \"allowWildcardForProperties\" check\n if (!this.constraint.allowWildcardForProperties) {\n // TODO: extract as a method and do unit test\n\n if (!this.hasAllRequiredPropertiesSpecific(encQ)) {\n return true;\n }\n }\n return (this.constraint as EncodingConstraint).satisfy(encQ, schema, encWildcardIndex, opt);\n }\n}\n\n/** Constraint for a single encoding mapping */\nexport interface EncodingConstraint extends AbstractConstraint {\n /** Method for checking if the encoding query satisfies this constraint. */\n satisfy: EncodingConstraintChecker;\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {channelCompatibility, TypedFieldDef} from 'vega-lite/build/src/channeldef';\nimport {\n channelScalePropertyIncompatability,\n hasDiscreteDomain,\n Scale,\n ScaleType,\n scaleTypeSupportProperty\n} from 'vega-lite/build/src/scale';\nimport {isLocalSingleTimeUnit, isUtcSingleTimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {getEncodingNestedProp, Property, SCALE_PROPS} from '../property';\nimport {PropIndex} from '../propindex';\nimport {AutoCountQuery, FieldQuery, isFieldQuery, ScaleQuery, scaleType, toFieldDef} from '../query/encoding';\nimport {ExpandedType, isDiscrete} from '../query/expandedtype';\nimport {PrimitiveType, Schema} from '../schema';\nimport {contains} from '../util';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {EncodingConstraint, EncodingConstraintModel} from './base';\n\nexport const FIELD_CONSTRAINTS: EncodingConstraintModel[] = [\n {\n name: 'aggregateOpSupportedByType',\n description: 'Aggregate function should be supported by data type.',\n properties: [Property.TYPE, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.aggregate) {\n return !isDiscrete(fieldQ.type);\n }\n // TODO: some aggregate function are actually supported by ordinal\n return true; // no aggregate is okay with any type.\n }\n },\n {\n name: 'asteriskFieldWithCountOnly',\n description: 'Field=\"*\" should be disallowed except aggregate=\"count\"',\n properties: [Property.FIELD, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n return (fieldQ.field === '*') === (fieldQ.aggregate === 'count');\n }\n },\n {\n name: 'minCardinalityForBin',\n description: 'binned quantitative field should not have too low cardinality',\n properties: [Property.BIN, Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.bin && fieldQ.type === TYPE.QUANTITATIVE) {\n // We remove bin so schema can infer the raw unbinned cardinality.\n let fieldQwithoutBin: FieldQuery = {\n channel: fieldQ.channel,\n field: fieldQ.field,\n type: fieldQ.type\n };\n return schema.cardinality(fieldQwithoutBin) >= opt.minCardinalityForBin;\n }\n return true;\n }\n },\n {\n name: 'binAppliedForQuantitative',\n description: 'bin should be applied to quantitative field only.',\n properties: [Property.TYPE, Property.BIN],\n allowWildcardForProperties: false,\n strict: true, // FIXME VL2.0 actually support ordinal type for bin\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.bin) {\n // If binned, the type must be quantitative\n return fieldQ.type === TYPE.QUANTITATIVE;\n }\n return true;\n }\n },\n {\n name: 'channelFieldCompatible',\n description: `encoding channel's range type be compatible with channel type.`,\n properties: [Property.CHANNEL, Property.TYPE, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n const fieldDef: TypedFieldDef = {\n field: 'f', // actual field doesn't really matter here\n ...toFieldDef(fieldQ, {schema, props: ['bin', 'timeUnit', 'type']})\n };\n\n const {compatible} = channelCompatibility(fieldDef, fieldQ.channel as Channel);\n\n if (compatible) {\n return true;\n } else {\n // In VL, facet's field def must be discrete (O/N), but in CompassQL we can relax this a bit.\n const isFacet = fieldQ.channel === 'row' || fieldQ.channel === 'column';\n\n if (isFacet && (isLocalSingleTimeUnit(fieldDef.timeUnit) || isUtcSingleTimeUnit(fieldDef.timeUnit))) {\n return true;\n }\n return false;\n }\n }\n },\n {\n name: 'hasFn',\n description: 'A field with as hasFn flag should have one of aggregate, timeUnit, or bin.',\n properties: [Property.AGGREGATE, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.hasFn) {\n return !!fieldQ.aggregate || !!fieldQ.bin || !!fieldQ.timeUnit;\n }\n return true;\n }\n },\n {\n name: 'omitScaleZeroWithBinnedField',\n description: 'Do not use scale zero with binned field',\n properties: [Property.SCALE, getEncodingNestedProp('scale', 'zero'), Property.BIN],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.bin && fieldQ.scale) {\n if ((fieldQ.scale as ScaleQuery).zero === true) {\n return false;\n }\n }\n return true;\n }\n },\n {\n name: 'onlyOneTypeOfFunction',\n description: 'Only of of aggregate, autoCount, timeUnit, or bin should be applied at the same time.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery | AutoCountQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (isFieldQuery(fieldQ)) {\n const numFn =\n (!isWildcard(fieldQ.aggregate) && !!fieldQ.aggregate ? 1 : 0) +\n (!isWildcard(fieldQ.bin) && !!fieldQ.bin ? 1 : 0) +\n (!isWildcard(fieldQ.timeUnit) && !!fieldQ.timeUnit ? 1 : 0);\n return numFn <= 1;\n }\n // For autoCount there is always only one type of function\n return true;\n }\n },\n {\n name: 'timeUnitAppliedForTemporal',\n description: 'Time unit should be applied to temporal field only.',\n properties: [Property.TYPE, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.timeUnit && fieldQ.type !== TYPE.TEMPORAL) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'timeUnitShouldHaveVariation',\n description: 'A particular time unit should be applied only if they produce unique values.',\n properties: [Property.TIMEUNIT, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.timeUnit && fieldQ.type === TYPE.TEMPORAL) {\n if (!encWildcardIndex.has('timeUnit') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n return schema.timeUnitHasVariation(fieldQ);\n }\n return true;\n }\n },\n {\n name: 'scalePropertiesSupportedByScaleType',\n description: 'Scale properties must be supported by correct scale type',\n properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.TYPE]),\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.scale) {\n const scale: ScaleQuery = fieldQ.scale as ScaleQuery;\n\n // If fieldQ.type is an Wildcard and scale.type is undefined, it is equivalent\n // to scale type is Wildcard. If scale type is an Wildcard, we do not yet know\n // what the scale type is, and thus can ignore the constraint.\n\n const sType = scaleType(fieldQ);\n\n if (sType === undefined || sType === null) {\n // If still ambiguous, doesn't check the constraint\n return true;\n }\n\n for (let scaleProp in scale) {\n if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') {\n // ignore type and properties of wildcards\n continue;\n }\n const sProp = scaleProp as keyof Scale;\n if (sType === 'point') {\n // HACK: our current implementation of scaleType() can return point\n // when the scaleType is a band since we didn't pass all parameter to Vega-Lite's scale type method.\n if (!scaleTypeSupportProperty('point', sProp) && !scaleTypeSupportProperty('band', sProp)) {\n return false;\n }\n } else if (!scaleTypeSupportProperty(sType, sProp)) {\n return false;\n }\n }\n }\n return true;\n }\n },\n {\n name: 'scalePropertiesSupportedByChannel',\n description: 'Not all scale properties are supported by all encoding channels',\n properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.CHANNEL]),\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ) {\n let channel: Channel = fieldQ.channel as Channel;\n let scale: ScaleQuery = fieldQ.scale as ScaleQuery;\n if (channel && !isWildcard(channel) && scale) {\n if (channel === 'row' || channel === 'column') {\n // row / column do not have scale\n return false;\n }\n for (let scaleProp in scale) {\n if (!scale.hasOwnProperty(scaleProp)) continue;\n if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') {\n // ignore type and properties of wildcards\n continue;\n }\n let isSupported = channelScalePropertyIncompatability(channel, scaleProp as keyof Scale) === undefined;\n if (!isSupported) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'typeMatchesPrimitiveType',\n description: \"Data type should be supported by field's primitive type.\",\n properties: [Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.field === '*') {\n return true;\n }\n\n const primitiveType = schema.primitiveType(fieldQ.field as string);\n const type = fieldQ.type;\n\n if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n\n switch (primitiveType) {\n case PrimitiveType.BOOLEAN:\n case PrimitiveType.STRING:\n return type !== TYPE.QUANTITATIVE && type !== TYPE.TEMPORAL;\n case PrimitiveType.NUMBER:\n case PrimitiveType.INTEGER:\n return type !== TYPE.TEMPORAL;\n case PrimitiveType.DATETIME:\n // TODO: add NOMINAL, ORDINAL support after we support this in Vega-Lite\n return type === TYPE.TEMPORAL;\n case null:\n // field does not exist in the schema\n return false;\n }\n throw new Error('Not implemented');\n }\n },\n {\n name: 'typeMatchesSchemaType',\n description: \"Enumerated data type of a field should match the field's type in the schema.\",\n properties: [Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n\n if (fieldQ.field === '*') {\n return fieldQ.type === TYPE.QUANTITATIVE;\n }\n\n return schema.vlType(fieldQ.field as string) === fieldQ.type;\n }\n },\n {\n name: 'maxCardinalityForCategoricalColor',\n description: 'Categorical channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n // TODO: missing case where ordinal / temporal use categorical color\n // (once we do so, need to add Property.BIN, Property.TIMEUNIT)\n if (fieldQ.channel === CHANNEL.COLOR && (fieldQ.type === TYPE.NOMINAL || fieldQ.type === ExpandedType.KEY)) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForCategoricalColor;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'maxCardinalityForFacet',\n description: 'Row/column channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.channel === CHANNEL.ROW || fieldQ.channel === CHANNEL.COLUMN) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForFacet;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'maxCardinalityForShape',\n description: 'Shape channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.channel === CHANNEL.SHAPE) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForShape;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'dataTypeAndFunctionMatchScaleType',\n description: 'Scale type must match data type',\n properties: [\n Property.TYPE,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TIMEUNIT,\n Property.BIN\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.scale) {\n const type = fieldQ.type;\n const sType = scaleType(fieldQ);\n\n if (isDiscrete(type)) {\n return sType === undefined || hasDiscreteDomain(sType);\n } else if (type === TYPE.TEMPORAL) {\n if (!fieldQ.timeUnit) {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType);\n } else {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType) || hasDiscreteDomain(sType);\n }\n } else if (type === TYPE.QUANTITATIVE) {\n if (fieldQ.bin) {\n return contains([ScaleType.LINEAR, undefined], sType);\n } else {\n return contains(\n [\n ScaleType.LOG,\n ScaleType.POW,\n ScaleType.SQRT,\n ScaleType.QUANTILE,\n ScaleType.QUANTIZE,\n ScaleType.LINEAR,\n undefined\n ],\n sType\n );\n }\n }\n }\n return true;\n }\n },\n {\n name: 'stackIsOnlyUsedWithXY',\n description: 'stack should only be allowed for x and y channels',\n properties: [Property.STACK, Property.CHANNEL],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (!!fieldQ.stack) {\n return fieldQ.channel === CHANNEL.X || fieldQ.channel === CHANNEL.Y;\n }\n return true;\n }\n }\n].map((ec: EncodingConstraint) => new EncodingConstraintModel(ec));\n\nexport const FIELD_CONSTRAINT_INDEX: {\n [name: string]: EncodingConstraintModel;\n} = FIELD_CONSTRAINTS.reduce((m, ec: EncodingConstraintModel) => {\n m[ec.name()] = ec;\n return m;\n}, {});\n\nexport const FIELD_CONSTRAINTS_BY_PROPERTY = FIELD_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n // Initialize array and use it\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n return index;\n}, new PropIndex[]>());\n","import {QueryConfig} from '../config';\nimport {Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\nimport {contains} from '../util';\n\nimport {ValueQuery} from '../query/encoding';\nimport {EncodingConstraintModel, EncodingConstraint} from './base';\n\nexport const VALUE_CONSTRAINTS: EncodingConstraintModel[] = [\n {\n name: 'doesNotSupportConstantValue',\n description: 'row, column, x, y, order, and detail should not work with constant values.',\n properties: [Property.TYPE, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (valueQ: ValueQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n\n return !(contains(['row', 'column', 'x', 'y', 'detail', 'order'], valueQ.channel));\n }\n }\n].map((ec: EncodingConstraint) => new EncodingConstraintModel(ec));\n\nexport const VALUE_CONSTRAINT_INDEX: {[name: string]: EncodingConstraintModel} =\n VALUE_CONSTRAINTS.reduce((m, ec: EncodingConstraintModel) => {\n m[ec.name()] = ec;\n return m;\n }, {});\n\nexport const VALUE_CONSTRAINTS_BY_PROPERTY =\n VALUE_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n\n return index;\n }, new PropIndex[]>());\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {Property} from '../property';\nimport {Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\n\nimport {isValueQuery} from '../query/encoding';\nimport {FIELD_CONSTRAINTS_BY_PROPERTY} from './field';\nimport {VALUE_CONSTRAINTS_BY_PROPERTY} from './value';\n\n/**\n * Check all encoding constraints for a particular property and index tuple\n */\nexport function checkEncoding(prop: Property, wildcard: Wildcard, index: number,\n specM: SpecQueryModel, schema: Schema, opt: QueryConfig): string {\n\n // Check encoding constraint\n const encodingConstraints = FIELD_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n const encQ = specM.getEncodingQueryByIndex(index);\n\n for (const c of encodingConstraints) {\n // Check if the constraint is enabled\n if (c.strict() || !!opt[c.name()]) {\n // For strict constraint, or enabled non-strict, check the constraints\n\n const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt);\n if (!satisfy) {\n let violatedConstraint = '(enc) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n\n const valueContraints = VALUE_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n\n for (const c of valueContraints) {\n // Check if the constraint is enabled\n if ((c.strict() || !!opt[c.name()]) && isValueQuery(encQ)) {\n // For strict constraint, or enabled non-strict, check the constraints\n const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt);\n if (!satisfy) {\n let violatedConstraint = '(enc) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n return null;\n}\n","import {SUM_OPS} from 'vega-lite/build/src/aggregate';\nimport * as CHANNEL from 'vega-lite/build/src/channel';\nimport {NONPOSITION_CHANNELS, supportMark} from 'vega-lite/build/src/channel';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {ScaleType} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {getEncodingNestedProp, isEncodingNestedProp, isEncodingProperty, Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {\n EncodingQuery,\n FieldQuery,\n isAutoCountQuery,\n isDimension,\n isDisabledAutoCountQuery,\n isEnabledAutoCountQuery,\n isFieldQuery,\n isMeasure,\n isValueQuery,\n ScaleQuery,\n scaleType\n} from '../query/encoding';\nimport {ExpandedType} from '../query/expandedtype';\nimport {Schema} from '../schema';\nimport {contains, every, some} from '../util';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {AbstractConstraint, AbstractConstraintModel} from './base';\n\nconst NONPOSITION_CHANNELS_INDEX = NONPOSITION_CHANNELS.reduce((m, channel) => {\n m[channel] = true;\n return m;\n}, {});\n\nexport interface SpecConstraintChecker {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): boolean;\n}\n\nexport class SpecConstraintModel extends AbstractConstraintModel {\n constructor(specConstraint: SpecConstraint) {\n super(specConstraint);\n }\n\n public hasAllRequiredPropertiesSpecific(specM: SpecQueryModel): boolean {\n return every(this.constraint.properties, prop => {\n if (prop === Property.MARK) {\n return !isWildcard(specM.getMark());\n }\n\n // TODO: transform\n\n if (isEncodingNestedProp(prop)) {\n let parent = prop.parent;\n let child = prop.child;\n\n return every(specM.getEncodings(), encQ => {\n if (!encQ[parent]) {\n return true;\n }\n\n return !isWildcard(encQ[parent][child]);\n });\n }\n\n if (!isEncodingProperty(prop)) {\n throw new Error('UNIMPLEMENTED');\n }\n\n return every(specM.getEncodings(), encQ => {\n if (!encQ[prop]) {\n return true;\n }\n return !isWildcard(encQ[prop]);\n });\n });\n }\n\n public satisfy(specM: SpecQueryModel, schema: Schema, opt: QueryConfig) {\n // TODO: Re-order logic to optimize the \"allowWildcardForProperties\" check\n if (!this.constraint.allowWildcardForProperties) {\n if (!this.hasAllRequiredPropertiesSpecific(specM)) {\n return true;\n }\n }\n\n return (this.constraint as SpecConstraint).satisfy(specM, schema, opt);\n }\n}\n\nexport interface SpecConstraint extends AbstractConstraint {\n /** Method for checking if the spec query satisfies this constraint. */\n satisfy: SpecConstraintChecker;\n}\n\nexport const SPEC_CONSTRAINTS: SpecConstraintModel[] = [\n {\n name: 'noRepeatedChannel',\n description: 'Each encoding channel should only be used once.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n let usedChannel = {};\n\n // channel for all encodings should be valid\n return every(specM.getEncodings(), encQ => {\n if (!isWildcard(encQ.channel)) {\n // If channel is specified, it should no be used already\n if (usedChannel[encQ.channel]) {\n return false;\n }\n usedChannel[encQ.channel] = true;\n return true;\n }\n return true; // unspecified channel is valid\n });\n }\n },\n {\n name: 'alwaysIncludeZeroInScaleWithBarMark',\n description: 'Do not recommend bar mark if scale does not start at zero',\n properties: [\n Property.MARK,\n Property.SCALE,\n getEncodingNestedProp('scale', 'zero'),\n Property.CHANNEL,\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n const encodings = specM.getEncodings();\n\n if (mark === MARK.BAR) {\n for (let encQ of encodings) {\n if (\n isFieldQuery(encQ) &&\n (encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) &&\n encQ.type === TYPE.QUANTITATIVE &&\n (encQ.scale && (encQ.scale as ScaleQuery).zero === false)\n ) {\n // TODO: zero shouldn't be manually specified\n return false;\n }\n }\n }\n\n return true;\n }\n },\n {\n name: 'autoAddCount',\n description:\n 'Automatically adding count only for plots with only ordinal, binned quantitative, or temporal with timeunit fields.',\n properties: [Property.BIN, Property.TIMEUNIT, Property.TYPE, Property.AUTOCOUNT],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const hasAutoCount = some(specM.getEncodings(), (encQ: EncodingQuery) => isEnabledAutoCountQuery(encQ));\n\n if (hasAutoCount) {\n // Auto count should only be applied if all fields are nominal, ordinal, temporal with timeUnit, binned quantitative, or autoCount\n return every(specM.getEncodings(), (encQ: EncodingQuery) => {\n if (isValueQuery(encQ)) {\n return true;\n }\n\n if (isAutoCountQuery(encQ)) {\n return true;\n }\n\n switch (encQ.type) {\n case TYPE.QUANTITATIVE:\n return !!encQ.bin;\n case TYPE.TEMPORAL:\n return !!encQ.timeUnit;\n case TYPE.ORDINAL:\n case ExpandedType.KEY:\n case TYPE.NOMINAL:\n return true;\n }\n /* istanbul ignore next */\n throw new Error('Unsupported Type');\n });\n } else {\n const autoCountEncIndex = specM.wildcardIndex.encodingIndicesByProperty.get('autoCount') || [];\n const neverHaveAutoCount = every(autoCountEncIndex, (index: number) => {\n let encQ = specM.getEncodingQueryByIndex(index);\n return isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount);\n });\n if (neverHaveAutoCount) {\n // If the query surely does not have autoCount\n // then one of the field should be\n // (1) unbinned quantitative\n // (2) temporal without time unit\n // (3) nominal or ordinal field\n // or at least have potential to be (still ambiguous).\n return some(specM.getEncodings(), (encQ: EncodingQuery) => {\n if ((isFieldQuery(encQ) || isAutoCountQuery(encQ)) && encQ.type === TYPE.QUANTITATIVE) {\n if (isDisabledAutoCountQuery(encQ)) {\n return false;\n } else {\n return isFieldQuery(encQ) && (!encQ.bin || isWildcard(encQ.bin));\n }\n } else if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) {\n return !encQ.timeUnit || isWildcard(encQ.timeUnit);\n }\n return false; // nominal or ordinal\n });\n }\n }\n\n return true; // no auto count, no constraint\n }\n },\n {\n name: 'channelPermittedByMarkType',\n description: 'Each encoding channel should be supported by the mark type',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: true, // only require mark\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n // if mark is unspecified, no need to check\n if (isWildcard(mark)) return true;\n\n // TODO: can optimize this to detect only what's the changed property if needed.\n return every(specM.getEncodings(), encQ => {\n // channel unspecified, no need to check\n if (isWildcard(encQ.channel)) return true;\n\n return !!supportMark(encQ.channel, mark as Mark);\n });\n }\n },\n {\n name: 'hasAllRequiredChannelsForMark',\n description: 'All required channels for the specified mark should be specified',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n switch (mark) {\n case MARK.AREA:\n case MARK.LINE:\n return specM.channelUsed(CHANNEL.X) && specM.channelUsed(CHANNEL.Y);\n case MARK.TEXT:\n return specM.channelUsed(CHANNEL.TEXT);\n case MARK.BAR:\n case MARK.CIRCLE:\n case MARK.SQUARE:\n case MARK.TICK:\n case MARK.RULE:\n case MARK.RECT:\n return specM.channelUsed(CHANNEL.X) || specM.channelUsed(CHANNEL.Y);\n case MARK.POINT:\n // This allows generating a point plot if channel was not a wildcard.\n return (\n !specM.wildcardIndex.hasProperty(Property.CHANNEL) ||\n specM.channelUsed(CHANNEL.X) ||\n specM.channelUsed(CHANNEL.Y)\n );\n }\n /* istanbul ignore next */\n throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + JSON.stringify(mark));\n }\n },\n {\n name: 'omitAggregate',\n description: 'Omit aggregate plots.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (specM.isAggregate()) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'omitAggregatePlotWithDimensionOnlyOnFacet',\n description: 'Omit aggregate plots with dimensions only on facets as that leads to inefficient use of space.',\n properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n let hasNonFacetDim = false,\n hasDim = false,\n hasEnumeratedFacetDim = false;\n specM.specQuery.encodings.forEach((encQ, index) => {\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) return; // skip unused field\n\n // FieldQuery & !encQ.aggregate\n if (isFieldQuery(encQ) && !encQ.aggregate) {\n // isDimension\n hasDim = true;\n if (contains([CHANNEL.ROW, CHANNEL.COLUMN], encQ.channel)) {\n if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL)) {\n hasEnumeratedFacetDim = true;\n }\n } else {\n hasNonFacetDim = true;\n }\n }\n });\n if (hasDim && !hasNonFacetDim) {\n if (hasEnumeratedFacetDim || opt.constraintManuallySpecifiedValue) {\n return false;\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitAggregatePlotWithoutDimension',\n description: 'Aggregate plots without dimension should be omitted',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.BIN, Property.TIMEUNIT, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (specM.isAggregate()) {\n // TODO relax\n return some(specM.getEncodings(), (encQ: EncodingQuery) => {\n if (isDimension(encQ) || (isFieldQuery(encQ) && encQ.type === 'temporal')) {\n return true;\n }\n return false;\n });\n }\n return true;\n }\n },\n {\n // TODO: we can be smarter and check if bar has occlusion based on profiling statistics\n name: 'omitBarLineAreaWithOcclusion',\n description: \"Don't use bar, line or area to visualize raw plot as they often lead to occlusion.\",\n properties: [Property.MARK, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (contains([MARK.BAR, MARK.LINE, MARK.AREA], specM.getMark())) {\n return specM.isAggregate();\n }\n return true;\n }\n },\n {\n name: 'omitBarTickWithSize',\n description: 'Do not map field to size channel with bar and tick mark',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n const mark = specM.getMark();\n if (contains([MARK.TICK, MARK.BAR], mark)) {\n if (specM.channelEncodingField(CHANNEL.SIZE)) {\n if (opt.constraintManuallySpecifiedValue) {\n // If size is used and we constraintManuallySpecifiedValue,\n // then the spec violates this constraint.\n return false;\n } else {\n // Otherwise have to search for the size channel and check if it is enumerated\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (encQ.channel === CHANNEL.SIZE) {\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n // If enumerated, then this is bad\n return false;\n } else {\n // If it's manually specified, no need to continue searching, just return.\n return true;\n }\n }\n }\n }\n }\n }\n return true; // skip\n }\n },\n {\n name: 'omitBarAreaForLogScale',\n description: \"Do not use bar and area mark for x and y's log scale\",\n properties: [\n Property.MARK,\n Property.CHANNEL,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n const encodings = specM.getEncodings();\n\n // TODO: mark or scale type should be enumerated\n if (mark === MARK.AREA || mark === MARK.BAR) {\n for (let encQ of encodings) {\n if (isFieldQuery(encQ) && ((encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) && encQ.scale)) {\n let sType = scaleType(encQ);\n\n if (sType === ScaleType.LOG) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitMultipleNonPositionalChannels',\n description:\n 'Unless manually specified, do not use multiple non-positional encoding channel to avoid over-encoding.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n // have to use specM.specQuery.encodings insetad of specM.getEncodings()\n // since specM.getEncodings() remove encQ with autoCount===false from the array\n // and thus might shift the index\n const encodings = specM.specQuery.encodings;\n let nonPositionChannelCount = 0;\n let hasEnumeratedNonPositionChannel = false;\n\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) {\n continue; // ignore skipped encoding\n }\n\n const channel = encQ.channel;\n if (!isWildcard(channel)) {\n if (NONPOSITION_CHANNELS_INDEX[channel + '']) {\n nonPositionChannelCount += 1;\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n hasEnumeratedNonPositionChannel = true;\n }\n if (\n nonPositionChannelCount > 1 &&\n (hasEnumeratedNonPositionChannel || opt.constraintManuallySpecifiedValue)\n ) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitNonPositionalOrFacetOverPositionalChannels',\n description: 'Do not use non-positional channels unless all positional channels are used',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n const encodings = specM.specQuery.encodings;\n let hasNonPositionalChannelOrFacet = false;\n let hasEnumeratedNonPositionOrFacetChannel = false;\n let hasX = false,\n hasY = false;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) {\n continue; // ignore skipped encoding\n }\n\n const channel = encQ.channel;\n if (channel === CHANNEL.X) {\n hasX = true;\n } else if (channel === CHANNEL.Y) {\n hasY = true;\n } else if (!isWildcard(channel)) {\n // All non positional channel / Facet\n hasNonPositionalChannelOrFacet = true;\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n hasEnumeratedNonPositionOrFacetChannel = true;\n }\n }\n }\n\n if (\n hasEnumeratedNonPositionOrFacetChannel ||\n (opt.constraintManuallySpecifiedValue && hasNonPositionalChannelOrFacet)\n ) {\n return hasX && hasY;\n }\n return true;\n }\n },\n {\n name: 'omitRaw',\n description: 'Omit raw plots.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (!specM.isAggregate()) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'omitRawContinuousFieldForAggregatePlot',\n description:\n 'Aggregate plot should not use raw continuous field as group by values. ' +\n '(Quantitative should be binned. Temporal should have time unit.)',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN, Property.TYPE],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) continue; // skip unused encoding\n\n // TODO: aggregate for ordinal and temporal\n\n if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) {\n // Temporal fields should have timeUnit or is still a wildcard\n if (\n !encQ.timeUnit &&\n (specM.wildcardIndex.hasEncodingProperty(i, Property.TIMEUNIT) || opt.constraintManuallySpecifiedValue)\n ) {\n return false;\n }\n }\n if (encQ.type === TYPE.QUANTITATIVE) {\n if (isFieldQuery(encQ) && !encQ.bin && !encQ.aggregate) {\n // If Raw Q\n if (\n specM.wildcardIndex.hasEncodingProperty(i, Property.BIN) ||\n specM.wildcardIndex.hasEncodingProperty(i, Property.AGGREGATE) ||\n specM.wildcardIndex.hasEncodingProperty(i, Property.AUTOCOUNT)\n ) {\n // and it's raw from enumeration\n return false;\n }\n if (opt.constraintManuallySpecifiedValue) {\n // or if we constraintManuallySpecifiedValue\n return false;\n }\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitRawDetail',\n description: 'Do not use detail channel with raw plot.',\n properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n return true;\n }\n return every(specM.specQuery.encodings, (encQ, index) => {\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) return true; // ignore autoCount field\n\n if (encQ.channel === CHANNEL.DETAIL) {\n // Detail channel for raw plot is not good, except when its enumerated\n // or when it's manually specified but we constraintManuallySpecifiedValue.\n if (\n specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL) ||\n opt.constraintManuallySpecifiedValue\n ) {\n return false;\n }\n }\n return true;\n });\n }\n },\n {\n name: 'omitRepeatedField',\n description: 'Each field should be mapped to only one channel',\n properties: [Property.FIELD],\n allowWildcardForProperties: true,\n strict: false, // over-encoding is sometimes good, but let's turn it off by default\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n let fieldUsed = {};\n let fieldEnumerated = {};\n\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n\n if (isValueQuery(encQ) || isAutoCountQuery(encQ)) continue;\n\n let field;\n if (encQ.field && !isWildcard(encQ.field)) {\n field = encQ.field as string;\n }\n if (isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount)) {\n field = 'count_*';\n }\n\n if (field) {\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.FIELD)) {\n fieldEnumerated[field] = true;\n }\n // When the field is specified previously,\n // if it is enumerated (either previously or in this encQ)\n // or if the opt.constraintManuallySpecifiedValue is true,\n // then it violates the constraint.\n\n if (fieldUsed[field]) {\n if (fieldEnumerated[field] || opt.constraintManuallySpecifiedValue) {\n return false;\n }\n }\n\n fieldUsed[field] = true;\n }\n }\n return true;\n }\n },\n // TODO: omitShapeWithBin\n {\n name: 'omitVerticalDotPlot',\n description: 'Do not output vertical dot plot.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const encodings = specM.getEncodings();\n if (encodings.length === 1 && encodings[0].channel === CHANNEL.Y) {\n return false;\n }\n return true;\n }\n },\n // EXPENSIVE CONSTRAINTS -- check them later!\n {\n name: 'hasAppropriateGraphicTypeForMark',\n description: 'Has appropriate graphic type for mark',\n properties: [\n Property.CHANNEL,\n Property.MARK,\n Property.TYPE,\n Property.TIMEUNIT,\n Property.BIN,\n Property.AGGREGATE,\n Property.AUTOCOUNT\n ],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n switch (mark) {\n case MARK.AREA:\n case MARK.LINE:\n if (specM.isAggregate()) {\n // TODO: refactor based on profiling statistics\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsMeasure = isMeasure(xEncQ);\n const yIsMeasure = isMeasure(yEncQ);\n\n // for aggregate line / area, we need at least one group-by axis and one measure axis.\n return (\n xEncQ &&\n yEncQ &&\n xIsMeasure !== yIsMeasure &&\n // and the dimension axis should not be nominal\n // TODO: make this clause optional\n\n !(isFieldQuery(xEncQ) && !xIsMeasure && contains(['nominal', 'key'], xEncQ.type)) &&\n !(isFieldQuery(yEncQ) && !yIsMeasure && contains(['nominal', 'key'], yEncQ.type))\n );\n // TODO: allow connected scatterplot\n }\n return true;\n case MARK.TEXT:\n // FIXME correctly when we add text\n return true;\n case MARK.BAR:\n case MARK.TICK:\n // Bar and tick should not use size.\n if (specM.channelEncodingField(CHANNEL.SIZE)) {\n return false;\n } else {\n // Tick and Bar should have one and only one measure\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsMeasure = isMeasure(xEncQ);\n const yIsMeasure = isMeasure(yEncQ);\n if (xIsMeasure !== yIsMeasure) {\n return true;\n }\n return false;\n }\n case MARK.RECT:\n // Until CompassQL supports layering, it only makes sense for\n // rect to encode DxD or 1xD (otherwise just use bar).\n // Furthermore, color should only be used in a 'heatmap' fashion\n // (with a measure field).\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsDimension = isDimension(xEncQ);\n const yIsDimension = isDimension(yEncQ);\n\n const colorEncQ = specM.getEncodingQueryByChannel(CHANNEL.COLOR);\n const colorIsQuantitative = isMeasure(colorEncQ);\n const colorIsOrdinal = isFieldQuery(colorEncQ) ? colorEncQ.type === TYPE.ORDINAL : false;\n\n const correctChannels =\n (xIsDimension && yIsDimension) ||\n (xIsDimension && !specM.channelUsed(CHANNEL.Y)) ||\n (yIsDimension && !specM.channelUsed(CHANNEL.X));\n\n const correctColor = !colorEncQ || (colorEncQ && (colorIsQuantitative || colorIsOrdinal));\n\n return correctChannels && correctColor;\n case MARK.CIRCLE:\n case MARK.POINT:\n case MARK.SQUARE:\n case MARK.RULE:\n return true;\n }\n /* istanbul ignore next */\n throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + mark);\n }\n },\n {\n name: 'omitInvalidStackSpec',\n description: 'If stack is specified, must follow Vega-Lite stack rules',\n properties: [\n Property.STACK,\n Property.FIELD,\n Property.CHANNEL,\n Property.MARK,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (!specM.wildcardIndex.hasProperty(Property.STACK)) {\n return true;\n }\n\n const stackProps = specM.getVlStack();\n if (stackProps === null && specM.getStackOffset() !== null) {\n return false;\n }\n\n if (stackProps.fieldChannel !== specM.getStackChannel()) {\n return false;\n }\n\n return true;\n }\n },\n {\n name: 'omitNonSumStack',\n description: 'Stack specifications that use non-summative aggregates should be omitted (even implicit ones)',\n properties: [\n Property.CHANNEL,\n Property.MARK,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const specStack = specM.getVlStack();\n if (specStack != null) {\n const stackParentEncQ = specM.getEncodingQueryByChannel(specStack.fieldChannel) as FieldQuery;\n if (!contains(SUM_OPS, stackParentEncQ.aggregate)) {\n return false;\n }\n }\n return true;\n }\n },\n {\n name: 'omitTableWithOcclusionIfAutoAddCount',\n description:\n 'Plots without aggregation or autocount where x and y are both discrete should be omitted if autoAddCount is enabled as they often lead to occlusion',\n properties: [\n Property.CHANNEL,\n Property.TYPE,\n Property.TIMEUNIT,\n Property.BIN,\n Property.AGGREGATE,\n Property.AUTOCOUNT\n ],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (opt.autoAddCount) {\n const xEncQ = specM.getEncodingQueryByChannel('x');\n const yEncQ = specM.getEncodingQueryByChannel('y');\n\n if ((!isFieldQuery(xEncQ) || isDimension(xEncQ)) && (!isFieldQuery(yEncQ) || isDimension(yEncQ))) {\n if (!specM.isAggregate()) {\n return false;\n } else {\n return every(specM.getEncodings(), encQ => {\n let channel = encQ.channel;\n\n if (\n channel !== CHANNEL.X &&\n channel !== CHANNEL.Y &&\n channel !== CHANNEL.ROW &&\n channel !== CHANNEL.COLUMN\n ) {\n // Non-position fields should not be unaggreated fields\n if (isFieldQuery(encQ) && !encQ.aggregate) {\n return false;\n }\n }\n return true;\n });\n }\n }\n }\n return true;\n }\n }\n].map(sc => new SpecConstraintModel(sc));\n\n// For testing\nexport const SPEC_CONSTRAINT_INDEX: {[name: string]: SpecConstraintModel} = SPEC_CONSTRAINTS.reduce(\n (m: any, c: SpecConstraintModel) => {\n m[c.name()] = c;\n return m;\n },\n {}\n);\n\nconst SPEC_CONSTRAINTS_BY_PROPERTY = SPEC_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n // Initialize array and use it\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n return index;\n}, new PropIndex());\n\n/**\n * Check all encoding constraints for a particular property and index tuple\n */\nexport function checkSpec(\n prop: Property,\n wildcard: Wildcard,\n specM: SpecQueryModel,\n schema: Schema,\n opt: QueryConfig\n): string {\n // Check encoding constraint\n const specConstraints = SPEC_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n\n for (const c of specConstraints) {\n // Check if the constraint is enabled\n if (c.strict() || !!opt[c.name()]) {\n // For strict constraint, or enabled non-strict, check the constraints\n\n const satisfy = c.satisfy(specM, schema, opt);\n if (!satisfy) {\n let violatedConstraint = '(spec) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n return null;\n}\n","import {Mark} from 'vega-lite/build/src/mark';\n\nimport {QueryConfig} from './config';\nimport {checkEncoding} from './constraint/encoding';\nimport {checkSpec} from './constraint/spec';\nimport {WildcardIndex} from './wildcardindex';\nimport {SpecQueryModel} from './model';\nimport {Property, ENCODING_TOPLEVEL_PROPS, ENCODING_NESTED_PROPS} from './property';\nimport {PropIndex} from './propindex';\nimport {Wildcard} from './wildcard';\nimport {Schema} from './schema';\nimport {isValueQuery, isDisabledAutoCountQuery} from './query/encoding';\n\nconst ENUMERATOR_INDEX = new PropIndex();\n\nexport interface Enumerator {\n (answerSets: SpecQueryModel[], specM: SpecQueryModel): SpecQueryModel[];\n}\n\nexport function getEnumerator(prop: Property) {\n return ENUMERATOR_INDEX.get(prop);\n}\n\nexport interface EnumeratorFactory {\n (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator;\n}\n\nENUMERATOR_INDEX.set('mark', (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator => {\n return (answerSet, specM: SpecQueryModel) => {\n const markWildcard = specM.getMark() as Wildcard;\n\n // enumerate the value\n markWildcard.enum.forEach((mark) => {\n specM.setMark(mark);\n // Check spec constraint\n const violatedSpecConstraint = checkSpec('mark', wildcardIndex.mark, specM, schema, opt);\n if (!violatedSpecConstraint) {\n // emit\n answerSet.push(specM.duplicate());\n }\n });\n\n // Reset to avoid side effect\n specM.resetMark();\n\n return answerSet;\n };\n});\n\nENCODING_TOPLEVEL_PROPS.forEach((prop) => {\n ENUMERATOR_INDEX.set(prop, EncodingPropertyGeneratorFactory(prop));\n});\n\nENCODING_NESTED_PROPS.forEach((nestedProp) => {\n ENUMERATOR_INDEX.set(nestedProp, EncodingPropertyGeneratorFactory(nestedProp));\n});\n\n/**\n * @param prop property type.\n * @return an answer set reducer factory for the given prop.\n */\nexport function EncodingPropertyGeneratorFactory(prop: Property): EnumeratorFactory {\n /**\n * @return as reducer that takes a specQueryModel as input and output an answer set array.\n */\n return (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator => {\n\n return (answerSet: SpecQueryModel[], specM: SpecQueryModel) => {\n // index of encoding mappings that require enumeration\n const indices = wildcardIndex.encodingIndicesByProperty.get(prop);\n\n function enumerate(jobIndex: number) {\n if (jobIndex === indices.length) {\n // emit and terminate\n answerSet.push(specM.duplicate());\n return;\n }\n const index = indices[jobIndex];\n const wildcard: Wildcard = wildcardIndex.encodings[index].get(prop);\n const encQ = specM.getEncodingQueryByIndex(index);\n const propWildcard = specM.getEncodingProperty(index, prop);\n\n if (isValueQuery(encQ) || (\n // TODO: encQ.exclude\n // If this encoding query is an excluded autoCount, there is no point enumerating other properties\n // for this encoding query because they will be excluded anyway.\n // Thus, we can just move on to the next encoding to enumerate.\n (isDisabledAutoCountQuery(encQ)) ||\n // nested encoding property might have its parent set to false\n // therefore, we no longer have to enumerate them\n !propWildcard\n )\n ) { // TODO: encQ.excluded\n enumerate(jobIndex + 1);\n } else {\n wildcard.enum.forEach((propVal) => {\n if (propVal === null) {\n // our duplicate() method use JSON.stringify, parse and thus can accidentally\n // convert undefined in an array into null\n propVal = undefined;\n }\n specM.setEncodingProperty(index, prop, propVal, wildcard);\n\n // Check encoding constraint\n const violatedEncodingConstraint = checkEncoding(prop, wildcard, index, specM, schema, opt);\n if (violatedEncodingConstraint) {\n return; // do not keep searching\n }\n // Check spec constraint\n const violatedSpecConstraint = checkSpec(prop, wildcard, specM, schema, opt);\n if (violatedSpecConstraint) {\n return; // do not keep searching\n }\n // If qualify all of the constraints, keep enumerating\n enumerate(jobIndex + 1);\n });\n\n // Reset to avoid side effect\n specM.resetEncodingProperty(index, prop, wildcard);\n }\n }\n\n // start enumerating from 0\n enumerate(0);\n\n return answerSet;\n };\n };\n}\n","import {isArray, isObject} from 'datalib/src/util';\n\nimport {getReplacerIndex} from './shorthand';\nimport {Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Dict,keys} from '../util';\n\n\nexport interface ExtendedGroupBy {\n property: string;\n replace?: Dict;\n}\n\nexport const REPLACE_BLANK_FIELDS: Dict = {'*': ''};\nexport const REPLACE_XY_CHANNELS: Dict = {x: 'xy', y: 'xy'};\nexport const REPLACE_FACET_CHANNELS: Dict = {row: 'facet', column: 'facet'};\nexport const REPLACE_MARK_STYLE_CHANNELS: Dict = {color: 'style', opacity: 'style', shape: 'style', size: 'style'};\n\nexport function isExtendedGroupBy(g: string | ExtendedGroupBy): g is ExtendedGroupBy {\n return isObject(g) && !!g['property'];\n}\n\nexport type GroupBy = string | Array;\n\nexport interface Nest {\n groupBy: GroupBy;\n orderGroupBy?: string | string[];\n}\n\n\nexport function parseGroupBy(groupBy: Array,\n include?: PropIndex,\n replaceIndex?: PropIndex>\n ) {\n\n include = include || new PropIndex();\n replaceIndex = replaceIndex || new PropIndex>();\n\n groupBy.forEach((grpBy: string | ExtendedGroupBy) => {\n if (isExtendedGroupBy(grpBy)) {\n include.setByKey(grpBy.property, true);\n replaceIndex.setByKey(grpBy.property, grpBy.replace);\n } else {\n include.setByKey(grpBy, true);\n }\n });\n\n return {\n include: include,\n replaceIndex: replaceIndex,\n replacer: getReplacerIndex(replaceIndex)\n };\n}\n\nexport function toString(groupBy: GroupBy): string {\n if (isArray(groupBy)) {\n return groupBy.map((g: string | ExtendedGroupBy) => {\n if (isExtendedGroupBy(g)) {\n if (g.replace) {\n let replaceIndex = keys(g.replace).reduce((index, valFrom) => {\n const valTo = g.replace[valFrom];\n (index[valTo] = index[valTo] || []).push(valFrom);\n return index;\n }, {});\n\n return g.property + '[' + keys(replaceIndex).map((valTo) => {\n const valsFrom = replaceIndex[valTo].sort();\n return valsFrom.join(',') + '=>' + valTo;\n }).join(';') + ']';\n }\n return g.property;\n }\n return g;\n }).join(',');\n } else {\n return groupBy;\n }\n}\n\nexport const GROUP_BY_FIELD_TRANSFORM = [\n Property.FIELD, Property.TYPE,\n Property.AGGREGATE, Property.BIN, Property.TIMEUNIT, Property.STACK\n];\n\nexport const GROUP_BY_ENCODING = (GROUP_BY_FIELD_TRANSFORM as Array).concat([\n {\n property: Property.CHANNEL,\n replace: {\n 'x': 'xy', 'y': 'xy',\n 'color': 'style', 'size': 'style', 'shape': 'style', 'opacity': 'style',\n 'row': 'facet', 'column': 'facet'\n }\n }\n]);\n\n","import {isArray} from 'datalib/src/util';\nimport {SpecQueryModel, SpecQueryModelGroup} from './model';\nimport {Property} from './property';\nimport {PropIndex} from './propindex';\nimport {GROUP_BY_ENCODING, GROUP_BY_FIELD_TRANSFORM, Nest, parseGroupBy} from './query/groupby';\nimport {Replacer, spec as specShorthand} from './query/shorthand';\nimport {SpecQuery} from './query/spec';\nimport {Dict} from './util';\n\n/**\n * Registry for all possible grouping key functions.\n */\nlet groupRegistry: Dict<(specM: SpecQuery) => string> = {};\n\n/**\n * Add a grouping function to the registry.\n */\nexport function registerKeyFn(name: string, keyFn: (specM: SpecQuery) => string) {\n groupRegistry[name] = keyFn;\n}\n\nexport const FIELD = 'field';\nexport const FIELD_TRANSFORM = 'fieldTransform';\nexport const ENCODING = 'encoding';\nexport const SPEC = 'spec';\n\n/**\n * Group the input spec query model by a key function registered in the group registry\n * @return\n */\nexport function nest(specModels: SpecQueryModel[], queryNest: Nest[]): SpecQueryModelGroup {\n if (queryNest) {\n const rootGroup: SpecQueryModelGroup = {\n name: '',\n path: '',\n items: []\n };\n let groupIndex: Dict = {};\n\n // global `includes` and `replaces` will get augmented by each level's groupBy.\n // Upper level's `groupBy` will get cascaded to lower-level groupBy.\n // `replace` can be overriden in a lower-level to support different grouping.\n let includes: Array> = [];\n let replaces: Array>> = [];\n let replacers: Array> = [];\n\n for (let l = 0; l < queryNest.length; l++) {\n includes.push(l > 0 ? includes[l - 1].duplicate() : new PropIndex());\n replaces.push(l > 0 ? replaces[l - 1].duplicate() : new PropIndex>());\n\n const groupBy = queryNest[l].groupBy;\n if (isArray(groupBy)) {\n // If group is array, it's an array of extended group by that need to be parsed\n let parsedGroupBy = parseGroupBy(groupBy, includes[l], replaces[l]);\n replacers.push(parsedGroupBy.replacer);\n }\n }\n\n // With includes and replacers, now we can construct the nesting tree\n\n specModels.forEach(specM => {\n let path = '';\n let group: SpecQueryModelGroup = rootGroup;\n for (let l = 0; l < queryNest.length; l++) {\n const groupBy = (group.groupBy = queryNest[l].groupBy);\n group.orderGroupBy = queryNest[l].orderGroupBy;\n\n const key = isArray(groupBy)\n ? specShorthand(specM.specQuery, includes[l], replacers[l])\n : groupRegistry[groupBy](specM.specQuery);\n\n path += '/' + key;\n if (!groupIndex[path]) {\n // this item already exists on the path\n groupIndex[path] = {\n name: key,\n path: path,\n items: []\n };\n\n group.items.push(groupIndex[path]);\n }\n group = groupIndex[path];\n }\n group.items.push(specM);\n });\n return rootGroup;\n } else {\n // no nesting, just return a flat group\n return {\n name: '',\n path: '',\n items: specModels\n };\n }\n}\n\n// TODO: move this to groupBy, rename properly, and export\nconst GROUP_BY_FIELD = [Property.FIELD];\nconst PARSED_GROUP_BY_FIELD = parseGroupBy(GROUP_BY_FIELD);\n\nexport function getGroupByKey(specM: SpecQuery, groupBy: string) {\n return groupRegistry[groupBy](specM);\n}\n\nregisterKeyFn(FIELD, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_FIELD.include, PARSED_GROUP_BY_FIELD.replacer);\n});\n\nexport const PARSED_GROUP_BY_FIELD_TRANSFORM = parseGroupBy(GROUP_BY_FIELD_TRANSFORM);\n\nregisterKeyFn(FIELD_TRANSFORM, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_FIELD_TRANSFORM.include, PARSED_GROUP_BY_FIELD_TRANSFORM.replacer);\n});\n\nexport const PARSED_GROUP_BY_ENCODING = parseGroupBy(GROUP_BY_ENCODING);\n\nregisterKeyFn(ENCODING, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_ENCODING.include, PARSED_GROUP_BY_ENCODING.replacer);\n});\n\nregisterKeyFn(SPEC, (specQ: SpecQuery) => JSON.stringify(specQ));\n","import {Mark} from 'vega-lite/build/src/mark';\n\nimport {Wildcard} from './wildcard';\nimport {Property, isEncodingProperty} from './property';\nimport {PropIndex} from './propindex';\n\n\nexport interface EncodingsWildcardIndex {\n [index: number]: PropIndex>;\n}\n\nexport class WildcardIndex {\n private _mark: Wildcard;\n // TODO: transform\n\n /**\n * Dictionary mapping encoding index to an encoding wildcard index.\n */\n\n private _encodings: EncodingsWildcardIndex;\n private _encodingIndicesByProperty: PropIndex;\n\n constructor() {\n this._mark = undefined;\n this._encodings = {};\n this._encodingIndicesByProperty = new PropIndex();\n }\n\n public setEncodingProperty(index: number, prop: Property, wildcard: Wildcard) {\n const encodingsIndex = this._encodings;\n\n // Init encoding index and set prop\n const encIndex = encodingsIndex[index] = encodingsIndex[index] || new PropIndex>();\n encIndex.set(prop, wildcard);\n\n // Initialize indicesByProperty[prop] and add index\n const indicesByProp = this._encodingIndicesByProperty;\n indicesByProp.set(prop, (indicesByProp.get(prop) || []));\n indicesByProp.get(prop).push(index);\n\n return this;\n }\n\n public hasEncodingProperty(index: number, prop: Property) {\n return !!this._encodings[index] && this._encodings[index].has(prop);\n }\n\n public hasProperty(prop: Property) {\n if (isEncodingProperty(prop)) {\n return this.encodingIndicesByProperty.has(prop);\n } else if (prop === 'mark') {\n return !!this.mark;\n }\n /* istanbul ignore next */\n throw new Error('Unimplemented for property ' + prop);\n }\n\n public isEmpty() {\n return !this.mark && this.encodingIndicesByProperty.size() === 0;\n }\n\n public setMark(mark: Wildcard) {\n this._mark = mark;\n return this;\n }\n\n public get mark() {\n return this._mark;\n }\n\n public get encodings() {\n return this._encodings;\n }\n\n public get encodingIndicesByProperty() {\n return this._encodingIndicesByProperty;\n }\n}\n","import {isString} from 'datalib/src/util';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Data} from 'vega-lite/build/src/data';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec, TopLevel} from 'vega-lite/build/src/spec';\nimport {StackOffset, StackProperties} from 'vega-lite/build/src/stack';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {getGroupByKey} from './nest';\nimport {\n ENCODING_NESTED_PROPS,\n ENCODING_TOPLEVEL_PROPS,\n isEncodingNestedParent,\n isEncodingNestedProp,\n Property\n} from './property';\nimport {\n AutoCountQuery,\n EncodingQuery,\n isAutoCountQuery,\n isDisabledAutoCountQuery,\n isFieldQuery,\n toEncoding\n} from './query/encoding';\nimport {ExtendedGroupBy, parseGroupBy} from './query/groupby';\nimport {spec as specShorthand} from './query/shorthand';\nimport {getStackChannel, getStackOffset, getVlStack, isAggregate, SpecQuery} from './query/spec';\nimport {RankingScore} from './ranking/ranking';\nimport {ResultTree} from './result';\nimport {Schema} from './schema';\nimport {Dict, duplicate, extend} from './util';\nimport {getDefaultEnumValues, getDefaultName, initWildcard, isWildcard, SHORT_WILDCARD, Wildcard} from './wildcard';\nimport {WildcardIndex} from './wildcardindex';\n\n/**\n * Internal class for specQuery that provides helper for the enumeration process.\n */\nexport class SpecQueryModel {\n private _spec: SpecQuery;\n\n /** channel => EncodingQuery */\n private _channelFieldCount: Dict;\n private _wildcardIndex: WildcardIndex;\n private _assignedWildcardIndex: Dict;\n private _schema: Schema;\n private _opt: QueryConfig;\n\n private _rankingScore: Dict = {};\n\n /**\n * Build a WildcardIndex by detecting wildcards\n * in the input specQuery and replacing short wildcards (\"?\")\n * with full ones (objects with `name` and `enum` values).\n *\n * @return a SpecQueryModel that wraps the specQuery and the WildcardIndex.\n */\n public static build(specQ: SpecQuery, schema: Schema, opt: QueryConfig): SpecQueryModel {\n let wildcardIndex: WildcardIndex = new WildcardIndex();\n // mark\n if (isWildcard(specQ.mark)) {\n const name = getDefaultName(Property.MARK);\n specQ.mark = initWildcard(specQ.mark, name, opt.enum.mark);\n wildcardIndex.setMark(specQ.mark);\n }\n\n // TODO: transform\n\n // encodings\n specQ.encodings.forEach((encQ, index) => {\n if (isAutoCountQuery(encQ)) {\n // This is only for testing purpose\n console.warn('A field with autoCount should not be included as autoCount meant to be an internal object.');\n\n encQ.type = TYPE.QUANTITATIVE; // autoCount is always quantitative\n }\n\n if (isFieldQuery(encQ) && encQ.type === undefined) {\n // type is optional -- we automatically augment wildcard if not specified\n encQ.type = SHORT_WILDCARD;\n }\n\n // For each property of the encodingQuery, enumerate\n ENCODING_TOPLEVEL_PROPS.forEach(prop => {\n if (isWildcard(encQ[prop])) {\n // Assign default wildcard name and enum values.\n const defaultWildcardName = getDefaultName(prop) + index;\n const defaultEnumValues = getDefaultEnumValues(prop, schema, opt);\n const wildcard = (encQ[prop] = initWildcard(encQ[prop], defaultWildcardName, defaultEnumValues));\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, prop, wildcard);\n }\n });\n\n // For each nested property of the encoding query (e.g., encQ.bin.maxbins)\n ENCODING_NESTED_PROPS.forEach(prop => {\n const propObj = encQ[prop.parent]; // the property object e.g., encQ.bin\n if (propObj) {\n const child = prop.child;\n if (isWildcard(propObj[child])) {\n // Assign default wildcard name and enum values.\n const defaultWildcardName = getDefaultName(prop) + index;\n const defaultEnumValues = getDefaultEnumValues(prop, schema, opt);\n const wildcard = (propObj[child] = initWildcard(propObj[child], defaultWildcardName, defaultEnumValues));\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, prop, wildcard);\n }\n }\n });\n });\n\n // AUTO COUNT\n // Add Auto Count Field\n if (opt.autoAddCount) {\n const channel: Wildcard = {\n name: getDefaultName(Property.CHANNEL) + specQ.encodings.length,\n enum: getDefaultEnumValues(Property.CHANNEL, schema, opt)\n };\n const autoCount: Wildcard = {\n name: getDefaultName(Property.AUTOCOUNT) + specQ.encodings.length,\n enum: [false, true]\n };\n const countEncQ: AutoCountQuery = {\n channel,\n autoCount,\n type: TYPE.QUANTITATIVE\n };\n specQ.encodings.push(countEncQ);\n\n const index = specQ.encodings.length - 1;\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, Property.CHANNEL, channel);\n wildcardIndex.setEncodingProperty(index, Property.AUTOCOUNT, autoCount);\n }\n\n return new SpecQueryModel(specQ, wildcardIndex, schema, opt, {});\n }\n\n constructor(\n spec: SpecQuery,\n wildcardIndex: WildcardIndex,\n schema: Schema,\n opt: QueryConfig,\n wildcardAssignment: Dict\n ) {\n this._spec = spec;\n this._channelFieldCount = spec.encodings.reduce(\n (m, encQ) => {\n if (!isWildcard(encQ.channel) && (!isAutoCountQuery(encQ) || encQ.autoCount !== false)) {\n m[encQ.channel + ''] = 1;\n }\n return m;\n },\n {} as Dict\n );\n\n this._wildcardIndex = wildcardIndex;\n this._assignedWildcardIndex = wildcardAssignment;\n this._opt = opt;\n this._schema = schema;\n }\n\n public get wildcardIndex() {\n return this._wildcardIndex;\n }\n\n public get schema() {\n return this._schema;\n }\n\n public get specQuery() {\n return this._spec;\n }\n\n public duplicate(): SpecQueryModel {\n return new SpecQueryModel(\n duplicate(this._spec),\n this._wildcardIndex,\n this._schema,\n this._opt,\n duplicate(this._assignedWildcardIndex)\n );\n }\n\n public setMark(mark: Mark) {\n const name = this._wildcardIndex.mark.name;\n this._assignedWildcardIndex[name] = this._spec.mark = mark;\n }\n\n public resetMark() {\n const wildcard = (this._spec.mark = this._wildcardIndex.mark);\n delete this._assignedWildcardIndex[wildcard.name];\n }\n\n public getMark() {\n return this._spec.mark;\n }\n\n public getEncodingProperty(index: number, prop: Property) {\n const encQ = this._spec.encodings[index];\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n return encQ[prop.parent][prop.child];\n }\n return encQ[prop]; // encoding property (non-nested)\n }\n\n public setEncodingProperty(index: number, prop: Property, value: any, wildcard: Wildcard) {\n const encQ = this._spec.encodings[index];\n\n if (prop === Property.CHANNEL && encQ.channel && !isWildcard(encQ.channel)) {\n // If there is an old channel\n this._channelFieldCount[encQ.channel as Channel]--;\n }\n\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n encQ[prop.parent][prop.child] = value;\n } else if (isEncodingNestedParent(prop) && value === true) {\n encQ[prop] = extend(\n {},\n encQ[prop], // copy all existing properties\n {enum: undefined, name: undefined} // except name and values to it no longer an wildcard\n );\n } else {\n // encoding property (non-nested)\n encQ[prop] = value;\n }\n\n this._assignedWildcardIndex[wildcard.name] = value;\n\n if (prop === Property.CHANNEL) {\n // If there is a new channel, make sure it exists and add it to the count.\n this._channelFieldCount[value] = (this._channelFieldCount[value] || 0) + 1;\n }\n }\n\n public resetEncodingProperty(index: number, prop: Property, wildcard: Wildcard) {\n const encQ = this._spec.encodings[index];\n if (prop === Property.CHANNEL) {\n this._channelFieldCount[encQ.channel as Channel]--;\n }\n\n // reset it to wildcard\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n encQ[prop.parent][prop.child] = wildcard;\n } else {\n // encoding property (non-nested)\n encQ[prop] = wildcard;\n }\n\n // add remove value that is reset from the assignment map\n delete this._assignedWildcardIndex[wildcard.name];\n }\n\n public channelUsed(channel: Channel) {\n // do not include encoding that has autoCount = false because it is not a part of the output spec.\n return this._channelFieldCount[channel] > 0;\n }\n\n public channelEncodingField(channel: Channel) {\n const encodingQuery = this.getEncodingQueryByChannel(channel);\n return isFieldQuery(encodingQuery);\n }\n\n public getEncodings(): EncodingQuery[] {\n // do not include encoding that has autoCount = false because it is not a part of the output spec.\n return this._spec.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ));\n }\n\n public getEncodingQueryByChannel(channel: Channel) {\n for (let specEncoding of this._spec.encodings) {\n if (specEncoding.channel === channel) {\n return specEncoding;\n }\n }\n return undefined;\n }\n\n public getEncodingQueryByIndex(i: number) {\n return this._spec.encodings[i];\n }\n\n public isAggregate() {\n return isAggregate(this._spec);\n }\n\n /**\n * @return The Vega-Lite `StackProperties` object that describes the stack\n * configuration of `this`. Returns `null` if this is not stackable.\n */\n public getVlStack(): StackProperties {\n return getVlStack(this._spec);\n }\n\n /**\n * @return The `StackOffset` specified in `this`, `undefined` if none\n * is specified.\n */\n public getStackOffset(): StackOffset {\n return getStackOffset(this._spec);\n }\n\n /**\n * @return The `Channel` in which `stack` is specified in `this`, or\n * `null` if none is specified.\n */\n public getStackChannel(): Channel {\n return getStackChannel(this._spec);\n }\n\n public toShorthand(groupBy?: string | (string | ExtendedGroupBy)[]): string {\n if (groupBy) {\n if (isString(groupBy)) {\n return getGroupByKey(this.specQuery, groupBy);\n }\n const parsedGroupBy = parseGroupBy(groupBy);\n return specShorthand(this._spec, parsedGroupBy.include, parsedGroupBy.replacer);\n }\n return specShorthand(this._spec);\n }\n\n /**\n * Convert a query to a Vega-Lite spec if it is completed.\n * @return a Vega-Lite spec if completed, null otherwise.\n */\n public toSpec(data?: Data): TopLevel {\n if (isWildcard(this._spec.mark)) return null;\n\n let spec: any = {};\n data = data || this._spec.data;\n if (data) {\n spec.data = data;\n }\n\n if (this._spec.transform) {\n spec.transform = this._spec.transform;\n }\n\n spec.mark = this._spec.mark as Mark;\n spec.encoding = toEncoding(this.specQuery.encodings, {schema: this._schema, wildcardMode: 'null'});\n\n if (this._spec.width) {\n spec.width = this._spec.width;\n }\n if (this._spec.height) {\n spec.height = this._spec.height;\n }\n if (this._spec.background) {\n spec.background = this._spec.background;\n }\n if (this._spec.padding) {\n spec.padding = this._spec.padding;\n }\n if (this._spec.title) {\n spec.title = this._spec.title;\n }\n\n if (spec.encoding === null) {\n return null;\n }\n if (this._spec.config || this._opt.defaultSpecConfig)\n spec.config = extend({}, this._opt.defaultSpecConfig, this._spec.config);\n\n return spec;\n }\n\n public getRankingScore(rankingName: string) {\n return this._rankingScore[rankingName];\n }\n\n public setRankingScore(rankingName: string, score: RankingScore) {\n this._rankingScore[rankingName] = score;\n }\n}\nexport type SpecQueryModelGroup = ResultTree;\n","import {Query} from './query';\nimport {Nest} from './groupby';\nimport {duplicate} from '../util';\n\n/**\n * Normalize the non-nested version of the query\n * (basically when you have a `groupBy`)\n * to a standardize nested.\n */\nexport function normalize(q: Query): Query {\n if (q.groupBy) {\n let nest: Nest = {\n groupBy: q.groupBy\n };\n\n if (q.orderBy) {\n nest.orderGroupBy = q.orderBy;\n }\n\n let normalizedQ: Query = {\n spec: duplicate(q.spec), // We will cause side effect to q.spec in SpecQueryModel.build\n nest: [nest],\n };\n\n if (q.chooseBy) {\n normalizedQ.chooseBy = q.chooseBy;\n }\n\n if (q.config) {\n normalizedQ.config = q.config;\n }\n\n return normalizedQ;\n }\n return duplicate(q); // We will cause side effect to q.spec in SpecQueryModel.build\n}\n","import {GroupBy} from './query/groupby';\n\n/**\n * An ordered tree structure for storing query results.\n */\nexport interface ResultTree {\n name: string;\n path: string;\n items: (ResultTree | T)[];\n groupBy?: GroupBy;\n orderGroupBy?: string | string[];\n}\n\nexport function isResultTree(item: ResultTree | T): item is ResultTree {\n return (>item).items !== undefined;\n}\n\nexport function getTopResultTreeItem(specQuery: ResultTree): T {\n let topItem = specQuery.items[0];\n while (topItem && isResultTree(topItem)) {\n topItem = topItem.items[0];\n }\n return topItem;\n}\n\nexport function mapLeaves(group: ResultTree, f: (item: T) => U): ResultTree {\n return {\n ...group,\n items: group.items.map(item => (isResultTree(item) ? mapLeaves(item, f) : f(item)))\n };\n}\n","import {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {Dict} from '../../util';\n\n\nexport abstract class Scorer {\n public readonly type: string;\n public readonly scoreIndex: Dict;\n constructor(type: string) {\n this.type = type;\n this.scoreIndex = this.initScore();\n }\n\n protected abstract initScore(): Dict;\n\n protected getFeatureScore(feature: string): FeatureScore {\n const type = this.type;\n const score = this.scoreIndex[feature];\n if (score !== undefined) {\n return {type, feature, score};\n }\n return undefined;\n }\n\n public abstract getScore(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[];\n}\n","import {hasDiscreteDomain} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {FieldQuery, scaleType} from '../../query/encoding';\nimport {ExpandedType} from '../../query/expandedtype';\n\n/**\n * Finer grained data types that takes binning and timeUnit into account.\n */\nexport enum ExtendedType {\n Q = TYPE.QUANTITATIVE as any,\n BIN_Q = ('bin_' + TYPE.QUANTITATIVE) as any,\n T = TYPE.TEMPORAL as any,\n\n /**\n * Time Unit Temporal Field with time scale.\n */\n TIMEUNIT_T = 'timeUnit_time' as any,\n /**\n * Time Unit Temporal Field with ordinal scale.\n */\n TIMEUNIT_O = ('timeUnit_' + TYPE.ORDINAL) as any,\n O = TYPE.ORDINAL as any,\n N = TYPE.NOMINAL as any,\n K = ExpandedType.KEY as any,\n NONE = '-' as any\n}\n\nexport const Q = ExtendedType.Q;\nexport const BIN_Q = ExtendedType.BIN_Q;\nexport const T = ExtendedType.T;\nexport const TIMEUNIT_T = ExtendedType.TIMEUNIT_T;\nexport const TIMEUNIT_O = ExtendedType.TIMEUNIT_O;\nexport const O = ExtendedType.O;\nexport const N = ExtendedType.N;\nexport const K = ExtendedType.K;\nexport const NONE = ExtendedType.NONE;\n\nexport function getExtendedType(fieldQ: FieldQuery): ExtendedType {\n if (fieldQ.bin) {\n return ExtendedType.BIN_Q;\n } else if (fieldQ.timeUnit) {\n const sType = scaleType(fieldQ);\n return hasDiscreteDomain(sType) ? ExtendedType.TIMEUNIT_O : ExtendedType.TIMEUNIT_T;\n }\n return fieldQ.type as ExtendedType;\n}\n","/**\n * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based)\n */\n\nimport * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {EncodingQuery, isAutoCountQuery, isFieldQuery} from '../../query/encoding';\nimport {Schema} from '../../schema';\nimport {Dict} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\nimport {BIN_Q, ExtendedType, getExtendedType, N, O, T, TIMEUNIT_O, TIMEUNIT_T} from './type';\n\n/**\n * Effectiveness Score for preferred axis.\n */\nexport class AxisScorer extends Scorer {\n constructor() {\n super('Axis');\n }\n protected initScore(opt: QueryConfig = {}) {\n opt = {...DEFAULT_QUERY_CONFIG, ...opt};\n let score: Dict = {};\n\n const preferredAxes = [\n {\n feature: BIN_Q,\n opt: 'preferredBinAxis'\n },\n {\n feature: T,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: TIMEUNIT_T,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: TIMEUNIT_O,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: O,\n opt: 'preferredOrdinalAxis'\n },\n {\n feature: N,\n opt: 'preferredNominalAxis'\n }\n ];\n\n preferredAxes.forEach(pAxis => {\n if (opt[pAxis.opt] === CHANNEL.X) {\n // penalize the other axis\n score[pAxis.feature + '_' + CHANNEL.Y] = -0.01;\n } else if (opt[pAxis.opt] === CHANNEL.Y) {\n // penalize the other axis\n score[pAxis.feature + '_' + CHANNEL.X] = -0.01;\n }\n });\n\n return score;\n }\n\n public featurize(type: ExtendedType, channel: Channel) {\n return type + '_' + channel;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n return specM.getEncodings().reduce((features, encQ: EncodingQuery) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const type = getExtendedType(encQ);\n const feature = this.featurize(type, encQ.channel as Channel);\n const featureScore = this.getFeatureScore(feature);\n\n if (featureScore) {\n features.push(featureScore);\n }\n }\n return features;\n }, []);\n }\n}\n","import {Dict} from '../../util';\nimport {Scorer} from './base';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {EncodingQuery, isFieldQuery, isAutoCountQuery} from '../../query/encoding';\n\n/**\n * Penalize if facet channels are the only dimensions\n */\nexport class DimensionScorer extends Scorer {\n constructor() {\n super('Dimension');\n }\n\n protected initScore() {\n return {\n row: -2,\n column: -2,\n color: 0,\n opacity: 0,\n size: 0,\n shape: 0\n } as Dict;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n if (specM.isAggregate()) {\n specM.getEncodings().reduce((maxFScore, encQ: EncodingQuery) => {\n if (isAutoCountQuery(encQ) || (isFieldQuery(encQ) && !encQ.aggregate)) { // isDimension\n const featureScore = this.getFeatureScore(encQ.channel + '');\n if (featureScore && featureScore.score > maxFScore.score) {\n return featureScore;\n }\n }\n return maxFScore;\n }, {type: 'Dimension', feature: 'No Dimension', score: -5});\n }\n return [];\n }\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {EncodingQuery, isAutoCountQuery, isFieldQuery} from '../../query/encoding';\nimport {Schema} from '../../schema';\nimport {Dict} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\n\n/**\n * Effective Score for preferred facet\n */\nexport class FacetScorer extends Scorer {\n constructor() {\n super('Facet');\n }\n protected initScore(opt?: QueryConfig) {\n opt = {...DEFAULT_QUERY_CONFIG, ...opt};\n let score: Dict = {};\n\n if (opt.preferredFacet === CHANNEL.ROW) {\n // penalize the other axis\n score[CHANNEL.COLUMN] = -0.01;\n } else if (opt.preferredFacet === CHANNEL.COLUMN) {\n // penalize the other axis\n score[CHANNEL.ROW] = -0.01;\n }\n\n return score;\n }\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n return specM.getEncodings().reduce((features, encQ: EncodingQuery) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const featureScore = this.getFeatureScore(encQ.channel as string);\n if (featureScore) {\n features.push(featureScore);\n }\n }\n return features;\n }, []);\n }\n}\n","import {Dict} from '../../util';\nimport {Scorer} from './base';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {isFieldQuery, isAutoCountQuery} from '../../query/encoding';\n\n/**\n * Effectivenss score that penalize size for bar and tick\n */\nexport class SizeChannelScorer extends Scorer {\n constructor() {\n super('SizeChannel');\n }\n\n protected initScore() {\n return {\n bar_size: -2,\n tick_size: -2\n } as Dict;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n const mark = specM.getMark();\n return specM.getEncodings().reduce((featureScores, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const feature = mark + '_' + encQ.channel;\n const featureScore = this.getFeatureScore(feature);\n if (featureScore) {\n featureScores.push(featureScore);\n }\n }\n return featureScores;\n }, []);\n }\n}\n","\n\n\nimport {QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {fieldDef as fieldDefShorthand} from '../../query/shorthand';\nimport {EncodingQuery, isFieldQuery, isAutoCountQuery} from '../../query/encoding';\nimport {Dict, extend, forEach, keys, contains} from '../../util';\n\nimport {Schema} from '../../schema';\nimport {FeatureScore} from '../ranking';\nimport {BIN_Q, TIMEUNIT_T, TIMEUNIT_O, Q, N, O, T, ExtendedType, getExtendedType, K} from './type';\n\n\nimport {Scorer} from './base';\nimport {Channel} from 'vega-lite/build/src/channel';\n\n\n\nexport const TERRIBLE = -10;\n\n/**\n * Effectiveness score for relationship between\n * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based)\n */\nexport class TypeChannelScorer extends Scorer {\n constructor() {\n super('TypeChannel');\n }\n protected initScore() {\n let SCORE = {} as Dict;\n\n // Continuous Quantitative / Temporal Fields\n const CONTINUOUS_TYPE_CHANNEL_SCORE = {\n x: 0,\n y: 0,\n size: -0.575,\n color: -0.725, // Middle between -0.7 and -0.75\n text: -2,\n opacity: -3,\n\n shape: TERRIBLE,\n row: TERRIBLE,\n column: TERRIBLE,\n detail: 2 * TERRIBLE\n };\n\n [Q, T, TIMEUNIT_T].forEach((type) => {\n keys(CONTINUOUS_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(type, channel)] = CONTINUOUS_TYPE_CHANNEL_SCORE[channel];\n });\n });\n\n // Discretized Quantitative / Temporal Fields / Ordinal\n\n const ORDERED_TYPE_CHANNEL_SCORE = extend({}, CONTINUOUS_TYPE_CHANNEL_SCORE, {\n row: -0.75,\n column: -0.75,\n\n shape: -3.1,\n text: -3.2,\n detail: -4\n });\n\n [BIN_Q, TIMEUNIT_O, O].forEach((type) => {\n keys(ORDERED_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(type, channel)] = ORDERED_TYPE_CHANNEL_SCORE[channel];\n });\n });\n\n const NOMINAL_TYPE_CHANNEL_SCORE = {\n x: 0,\n y: 0,\n color: -0.6, // TODO: make it adjustable based on preference (shape is better for black and white)\n shape: -0.65,\n row: -0.7,\n column: -0.7,\n text: -0.8,\n\n detail: -2,\n size: -3,\n opacity: -3.1,\n };\n\n keys(NOMINAL_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(N, channel)] = NOMINAL_TYPE_CHANNEL_SCORE[channel];\n SCORE[this.featurize(K, channel)] =\n // Putting key on position or detail isn't terrible\n contains(['x', 'y', 'detail'], channel) ? -1 :\n NOMINAL_TYPE_CHANNEL_SCORE[channel] - 2;\n });\n\n return SCORE;\n }\n\n public featurize(type: ExtendedType, channel: Channel) {\n return type + '_' + channel;\n }\n\n public getScore(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[] {\n const encodingQueryByField = specM.getEncodings().reduce((m, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const fieldKey = fieldDefShorthand(encQ);\n (m[fieldKey] = m[fieldKey] || []).push(encQ);\n }\n return m;\n }, {});\n\n const features: FeatureScore[] = [];\n\n forEach(encodingQueryByField, (encQs: EncodingQuery[]) => {\n const bestFieldFeature = encQs.reduce((best: FeatureScore, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const type = getExtendedType(encQ);\n const feature = this.featurize(type, encQ.channel as Channel);\n const featureScore = this.getFeatureScore(feature);\n\n if (best === null || featureScore.score > best.score) {\n return featureScore;\n }\n }\n return best;\n }, null);\n\n features.push(bestFieldFeature);\n\n // TODO: add plus for over-encoding of one field\n });\n return features;\n }\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {Dict, forEach} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\nimport {BIN_Q, ExtendedType, getExtendedType, K, N, NONE, O, Q, T, TIMEUNIT_O, TIMEUNIT_T} from './type';\n\nexport class MarkScorer extends Scorer {\n constructor() {\n super('Mark');\n }\n\n protected initScore() {\n return init();\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n let mark = specM.getMark() as Mark;\n if (mark === MARK.CIRCLE || mark === MARK.SQUARE) {\n mark = MARK.POINT;\n }\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const xType = xEncQ ? getExtendedType(xEncQ) : NONE;\n\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const yType = yEncQ ? getExtendedType(yEncQ) : NONE;\n\n const isOccluded = !specM.isAggregate(); // FIXME\n\n const feature = xType + '_' + yType + '_' + isOccluded + '_' + mark;\n const featureScore = this.getFeatureScore(feature);\n\n if (featureScore) {\n return [featureScore];\n }\n console.error('feature score missing for', feature);\n return [];\n }\n}\n\nexport function featurize(xType: ExtendedType, yType: ExtendedType, hasOcclusion: boolean, mark: Mark) {\n return xType + '_' + yType + '_' + hasOcclusion + '_' + mark;\n}\n\nfunction init() {\n const MEASURES = [Q, T];\n const DISCRETE = [BIN_Q, TIMEUNIT_O, O, N, K];\n const DISCRETE_OR_NONE = DISCRETE.concat([NONE]);\n\n let SCORE = {} as Dict;\n // QxQ\n MEASURES.forEach(xType => {\n MEASURES.forEach(yType => {\n // has occlusion\n const occludedQQMark = {\n point: 0,\n text: -0.2,\n tick: -0.5,\n rect: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedQQMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n\n // no occlusion\n // TODO: possible to use connected scatter plot\n const noOccludedQQMark = {\n point: 0,\n text: -0.2,\n tick: -0.5,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(noOccludedQQMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n });\n });\n\n // DxQ, QxD\n MEASURES.forEach(xType => {\n // HAS OCCLUSION\n DISCRETE_OR_NONE.forEach(yType => {\n const occludedDimensionMeasureMark = {\n tick: 0,\n point: -0.2,\n text: -0.5,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedDimensionMeasureMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n // also do the inverse\n const feature2 = featurize(yType, xType, true, mark);\n SCORE[feature2] = score;\n });\n });\n\n [TIMEUNIT_T].forEach(yType => {\n const occludedDimensionMeasureMark = {\n // For Time Dimension with time scale, tick is not good\n point: 0,\n text: -0.5,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedDimensionMeasureMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n // also do the inverse\n const feature2 = featurize(yType, xType, true, mark);\n SCORE[feature2] = score;\n });\n });\n\n // NO OCCLUSION\n [NONE, N, O, K].forEach(yType => {\n const noOccludedQxN = {\n bar: 0,\n point: -0.2,\n tick: -0.25,\n text: -0.3,\n // Line / Area can mislead trend for N\n line: -2, // FIXME line vs area?\n area: -2,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxN, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n\n [BIN_Q].forEach(yType => {\n const noOccludedQxBinQ = {\n bar: 0,\n point: -0.2,\n tick: -0.25,\n text: -0.3,\n // Line / Area isn't the best fit for bin\n line: -0.5, // FIXME line vs area?\n area: -0.5,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxBinQ, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n\n [TIMEUNIT_T, TIMEUNIT_O].forEach(yType => {\n // For aggregate / surely no occlusion plot, Temporal with time or ordinal\n // are not that different.\n const noOccludedQxBinQ = {\n line: 0,\n area: -0.1,\n bar: -0.2,\n point: -0.3,\n tick: -0.35,\n text: -0.4,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxBinQ, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n });\n\n [TIMEUNIT_T].forEach(xType => {\n [TIMEUNIT_T].forEach(yType => {\n // has occlusion\n const ttMark = {\n point: 0,\n rect: -0.1, // assuming rect will be small\n text: -0.5,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n // No difference between has occlusion and no occlusion\n // as most of the time, it will be the occluded case.\n forEach(ttMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n forEach(ttMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n });\n\n DISCRETE_OR_NONE.forEach(yType => {\n // has occlusion\n const tdMark = {\n tick: 0,\n point: -0.2,\n text: -0.5,\n rect: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n // No difference between has occlusion and no occlusion\n // as most of the time, it will be the occluded case.\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(yType, xType, true, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(yType, xType, false, mark);\n SCORE[feature] = score;\n });\n });\n });\n\n // DxD\n // Note: We use for loop here because using forEach sometimes leads to a mysterious bug\n for (const xType of DISCRETE_OR_NONE) {\n for (const yType of DISCRETE_OR_NONE) {\n // has occlusion\n const ddMark = {\n point: 0,\n rect: 0,\n text: -0.1,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n\n forEach(ddMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n\n // same for no occlusion.\n forEach(ddMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n }\n }\n\n return SCORE;\n}\n","import {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {RankingScore, FeatureScore} from '../ranking';\nimport {AxisScorer} from './axis';\nimport {DimensionScorer} from './dimension';\nimport {FacetScorer} from './facet';\nimport {SizeChannelScorer} from './sizechannel';\nimport {TypeChannelScorer} from './typechannel';\nimport {MarkScorer} from './mark';\n\nconst SCORERS = [\n new AxisScorer(),\n new DimensionScorer(),\n new FacetScorer(),\n new MarkScorer(),\n new SizeChannelScorer(),\n new TypeChannelScorer()\n];\n\n// TODO: x/y, row/column preference\n// TODO: stacking\n// TODO: Channel, Cardinality\n// TODO: Penalize over encoding\nexport function effectiveness(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore {\n const features = SCORERS.reduce((f, scorer) => {\n const scores = scorer.getScore(specM, schema, opt);\n return f.concat(scores);\n }, [] as FeatureScore[]);\n\n return {\n score: features.reduce((s, f) => {\n return s + f.score;\n }, 0),\n features: features\n };\n}\n","import * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {EncodingQuery, isDimension, isEnabledAutoCountQuery, isFieldQuery} from '../query/encoding';\nimport {Schema} from '../schema';\nimport {some} from '../util';\nimport {FeatureScore, RankingScore} from './ranking';\n\nexport const name = 'aggregationQuality';\n\nexport function score(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore {\n const feature = aggregationQualityFeature(specM, schema, opt);\n return {\n score: feature.score,\n features: [feature]\n };\n}\n\nfunction aggregationQualityFeature(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore {\n const encodings = specM.getEncodings();\n if (specM.isAggregate()) {\n const isRawContinuous = (encQ: EncodingQuery) => {\n return (\n isFieldQuery(encQ) &&\n ((encQ.type === TYPE.QUANTITATIVE && !encQ.bin && !encQ.aggregate) ||\n (encQ.type === TYPE.TEMPORAL && !encQ.timeUnit))\n );\n };\n\n if (some(encodings, isRawContinuous)) {\n // These are plots that pollute continuous fields as dimension.\n // They are often intermediate visualizations rather than what users actually want.\n return {\n type: name,\n score: 0.1,\n feature: 'Aggregate with raw continuous'\n };\n }\n\n if (some(encodings, encQ => isFieldQuery(encQ) && isDimension(encQ))) {\n let hasCount = some(encodings, (encQ: EncodingQuery) => {\n return (isFieldQuery(encQ) && encQ.aggregate === 'count') || isEnabledAutoCountQuery(encQ);\n });\n let hasBin = some(encodings, (encQ: EncodingQuery) => {\n return isFieldQuery(encQ) && !!encQ.bin;\n });\n\n if (hasCount) {\n // If there is count, we might add additional count field, making it a little less simple\n // then when we just apply aggregate to Q field\n return {\n type: name,\n score: 0.8,\n feature: 'Aggregate with count'\n };\n } else if (hasBin) {\n // This is not as good as binning all the Q and show heatmap\n return {\n type: name,\n score: 0.7,\n feature: 'Aggregate with bin but without count'\n };\n } else {\n return {\n type: name,\n score: 0.9,\n feature: 'Aggregate without count and without bin'\n };\n }\n }\n // no dimension -- often not very useful\n return {\n type: name,\n score: 0.3,\n feature: 'Aggregate without dimension'\n };\n } else {\n if (some(encodings, encQ => isFieldQuery(encQ) && !isDimension(encQ))) {\n // raw plots with measure -- simplest of all!\n return {\n type: name,\n score: 1,\n feature: 'Raw with measure'\n };\n }\n // raw plots with no measure -- often a lot of occlusion\n return {\n type: name,\n score: 0.2,\n feature: 'Raw without measure'\n };\n }\n}\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {Schema} from '../schema';\nimport {isFieldQuery} from '../query/encoding';\n\nimport {RankingScore, FeatureScore} from './ranking';\n\nexport const name = 'fieldOrder';\n\n/**\n * Return ranking score based on indices of encoded fields in the schema.\n * If there are multiple fields, prioritize field on the lower indices of encodings.\n *\n * For example, to compare two specs with two encodings each,\n * first we compare the field on the 0-th index\n * and only compare the field on the 1-th index only if the fields on the 0-th index are the same.\n */\nexport function score(specM: SpecQueryModel, schema: Schema, _: QueryConfig): RankingScore {\n const fieldWildcardIndices = specM.wildcardIndex.encodingIndicesByProperty.get('field');\n if (!fieldWildcardIndices) {\n return {\n score: 0,\n features: []\n };\n }\n\n const encodings = specM.specQuery.encodings;\n const numFields = schema.fieldSchemas.length;\n\n const features: FeatureScore[] = [];\n let totalScore = 0, base = 1;\n\n for (let i = fieldWildcardIndices.length - 1; i >= 0; i--) {\n const index = fieldWildcardIndices[i];\n const encoding = encodings[index];\n\n // Skip ValueQuery as we only care about order of fields.\n let field;\n\n if (isFieldQuery(encoding)) {\n field = encoding.field as string;\n } else { // ignore ValueQuery / AutoCountQuery\n continue;\n }\n\n const fieldWildcard = specM.wildcardIndex.encodings[index].get('field');\n const fieldIndex = schema.fieldSchema(field).index;\n // reverse order field with lower index should get higher score and come first\n const score = - fieldIndex * base;\n totalScore += score;\n\n features.push({\n score: score,\n type: 'fieldOrder',\n feature: `field ${fieldWildcard.name} is ${field} (#${fieldIndex} in the schema)`\n });\n\n base *= numFields;\n }\n\n return {\n score: totalScore,\n features: features\n };\n}\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel, SpecQueryModelGroup} from '../model';\nimport {getTopResultTreeItem} from '../result';\nimport {Query} from '../query/query';\nimport {Dict} from '../util';\nimport {Schema} from '../schema';\nimport {effectiveness} from './effectiveness';\n\nexport * from './effectiveness';\nimport * as aggregation from './aggregation';\nimport * as fieldOrder from './fieldorder';\n\nexport {aggregation, fieldOrder};\n\nexport interface RankingScore {\n score: number;\n features: FeatureScore[];\n}\n\nexport interface FeatureScore {\n score: number;\n type: string;\n feature: string;\n}\n\nexport interface FeatureInitializer {\n (): Dict;\n}\n\nexport interface Featurizer {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[];\n}\n\nexport interface FeatureFactory {\n type: string;\n init: FeatureInitializer;\n getScore: Featurizer;\n}\n\nexport interface RankingFunction {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore;\n}\n\n/**\n * Registry for all encoding ranking functions\n */\nlet rankingRegistry: Dict = {};\n\n/**\n * Add an ordering function to the registry.\n */\nexport function register(name: string, keyFn: RankingFunction) {\n rankingRegistry[name] = keyFn;\n}\n\nexport function get(name: string) {\n return rankingRegistry[name];\n}\n\nexport function rank(group: SpecQueryModelGroup, query: Query, schema: Schema, level: number): SpecQueryModelGroup {\n if (!query.nest || level === query.nest.length) {\n if (query.orderBy || query.chooseBy) {\n group.items.sort(comparatorFactory(query.orderBy || query.chooseBy, schema, query.config));\n if (query.chooseBy) {\n if (group.items.length > 0) {\n // for chooseBy -- only keep the top-item\n group.items.splice(1);\n }\n }\n }\n } else {\n // sort lower-level nodes first because our ranking takes top-item in the subgroup\n group.items.forEach((subgroup) => {\n rank(subgroup as SpecQueryModelGroup, query, schema, level + 1);\n });\n if (query.nest[level].orderGroupBy) {\n group.items.sort(groupComparatorFactory(query.nest[level].orderGroupBy, schema, query.config));\n }\n }\n return group;\n}\n\nexport function comparatorFactory(name: string | string[], schema: Schema, opt: QueryConfig) {\n return (m1: SpecQueryModel, m2: SpecQueryModel) => {\n if (name instanceof Array) {\n return getScoreDifference(name, m1, m2, schema, opt);\n } else {\n return getScoreDifference([name], m1, m2, schema, opt);\n }\n };\n}\n\nexport function groupComparatorFactory(name: string | string[], schema: Schema, opt: QueryConfig): (g1: SpecQueryModelGroup, g2: SpecQueryModelGroup) => number {\n return (g1: SpecQueryModelGroup, g2: SpecQueryModelGroup): number => {\n const m1 = getTopResultTreeItem(g1);\n const m2 = getTopResultTreeItem(g2);\n if (name instanceof Array) {\n return getScoreDifference(name, m1, m2, schema, opt);\n } else {\n return getScoreDifference([name], m1, m2, schema, opt);\n }\n };\n}\n\nfunction getScoreDifference(name: string[], m1: SpecQueryModel, m2: SpecQueryModel, schema: Schema, opt: QueryConfig): number {\n for (let rankingName of name) {\n let scoreDifference = getScore(m2, rankingName, schema, opt).score - getScore(m1, rankingName, schema, opt).score;\n if (scoreDifference !== 0) {\n return scoreDifference;\n }\n }\n return 0;\n}\n\nexport function getScore(model: SpecQueryModel, rankingName: string, schema: Schema, opt: QueryConfig) {\n if (model.getRankingScore(rankingName) !== undefined) {\n return model.getRankingScore(rankingName);\n }\n const fn = get(rankingName);\n const score = fn(model, schema, opt);\n model.setRankingScore(rankingName, score);\n return score;\n}\n\nexport const EFFECTIVENESS = 'effectiveness';\nregister(EFFECTIVENESS, effectiveness);\n\nregister(aggregation.name, aggregation.score);\nregister(fieldOrder.name, fieldOrder.score);\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {hasDiscreteDomain} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {SpecQueryModel} from './model';\nimport {AxisQuery, EncodingQuery, isFieldQuery, ScaleQuery, scaleType} from './query/encoding';\nimport {ExpandedType} from './query/expandedtype';\nimport {Schema} from './schema';\nimport {Dict} from './util';\n\nexport function stylize(answerSet: SpecQueryModel[], schema: Schema, opt: QueryConfig): SpecQueryModel[] {\n let encQIndex: Dict = {};\n answerSet = answerSet.map(function(specM) {\n if (opt.smallRangeStepForHighCardinalityOrFacet) {\n specM = smallRangeStepForHighCardinalityOrFacet(specM, schema, encQIndex, opt);\n }\n\n if (opt.nominalColorScaleForHighCardinality) {\n specM = nominalColorScaleForHighCardinality(specM, schema, encQIndex, opt);\n }\n\n if (opt.xAxisOnTopForHighYCardinalityWithoutColumn) {\n specM = xAxisOnTopForHighYCardinalityWithoutColumn(specM, schema, encQIndex, opt);\n }\n return specM;\n });\n\n return answerSet;\n}\n\nexport function smallRangeStepForHighCardinalityOrFacet(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n [CHANNEL.ROW, CHANNEL.Y, CHANNEL.COLUMN, CHANNEL.X].forEach(channel => {\n encQIndex[channel] = specM.getEncodingQueryByChannel(channel);\n });\n\n const yEncQ = encQIndex[CHANNEL.Y];\n if (yEncQ !== undefined && isFieldQuery(yEncQ)) {\n if (\n encQIndex[CHANNEL.ROW] ||\n schema.cardinality(yEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality\n ) {\n // We check for undefined rather than\n // yEncQ.scale = yEncQ.scale || {} to cover the case where\n // yEncQ.scale has been set to false/null.\n // This prevents us from incorrectly overriding scale and\n // assigning a rangeStep when scale is set to false.\n if (yEncQ.scale === undefined) {\n yEncQ.scale = {};\n }\n\n // We do not want to assign a rangeStep if scale is set to false\n // and we only apply this if the scale is (or can be) an ordinal scale.\n const yScaleType = scaleType(yEncQ);\n if (yEncQ.scale && (yScaleType === undefined || hasDiscreteDomain(yScaleType))) {\n if (!(yEncQ.scale as ScaleQuery).rangeStep) {\n (yEncQ.scale as ScaleQuery).rangeStep = 12;\n }\n }\n }\n }\n\n const xEncQ = encQIndex[CHANNEL.X];\n if (isFieldQuery(xEncQ)) {\n if (\n encQIndex[CHANNEL.COLUMN] ||\n schema.cardinality(xEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality\n ) {\n // Just like y, we don't want to do this if scale is null/false\n if (xEncQ.scale === undefined) {\n xEncQ.scale = {};\n }\n\n // We do not want to assign a rangeStep if scale is set to false\n // and we only apply this if the scale is (or can be) an ordinal scale.\n const xScaleType = scaleType(xEncQ);\n if (xEncQ.scale && (xScaleType === undefined || hasDiscreteDomain(xScaleType))) {\n if (!(xEncQ.scale as ScaleQuery).rangeStep) {\n (xEncQ.scale as ScaleQuery).rangeStep = 12;\n }\n }\n }\n }\n\n return specM;\n}\n\nexport function nominalColorScaleForHighCardinality(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n encQIndex[CHANNEL.COLOR] = specM.getEncodingQueryByChannel(CHANNEL.COLOR);\n\n const colorEncQ = encQIndex[CHANNEL.COLOR];\n if (\n isFieldQuery(colorEncQ) &&\n colorEncQ !== undefined &&\n (colorEncQ.type === TYPE.NOMINAL || colorEncQ.type === ExpandedType.KEY) &&\n schema.cardinality(colorEncQ) > opt.nominalColorScaleForHighCardinality.maxCardinality\n ) {\n if (colorEncQ.scale === undefined) {\n colorEncQ.scale = {};\n }\n\n if (colorEncQ.scale) {\n if (!(colorEncQ.scale as ScaleQuery).range) {\n (colorEncQ.scale as ScaleQuery).scheme = opt.nominalColorScaleForHighCardinality.palette;\n }\n }\n }\n\n return specM;\n}\n\nexport function xAxisOnTopForHighYCardinalityWithoutColumn(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n [CHANNEL.COLUMN, CHANNEL.X, CHANNEL.Y].forEach(channel => {\n encQIndex[channel] = specM.getEncodingQueryByChannel(channel);\n });\n\n if (encQIndex[CHANNEL.COLUMN] === undefined) {\n const xEncQ = encQIndex[CHANNEL.X];\n const yEncQ = encQIndex[CHANNEL.Y];\n if (\n isFieldQuery(xEncQ) &&\n isFieldQuery(yEncQ) &&\n yEncQ !== undefined &&\n yEncQ.field &&\n hasDiscreteDomain(scaleType(yEncQ))\n ) {\n if (xEncQ !== undefined) {\n if (schema.cardinality(yEncQ) > opt.xAxisOnTopForHighYCardinalityWithoutColumn.maxCardinality) {\n if (xEncQ.axis === undefined) {\n xEncQ.axis = {};\n }\n\n if (xEncQ.axis && !(xEncQ.axis as AxisQuery).orient) {\n (xEncQ.axis as AxisQuery).orient = 'top';\n }\n }\n }\n }\n }\n\n return specM;\n}\n","\nimport {QueryConfig, DEFAULT_QUERY_CONFIG} from './config';\nimport {getEnumerator} from './enumerator';\nimport {SpecQueryModel} from './model';\nimport {fromKey} from'./property';\nimport {SpecQuery} from './query/spec';\nimport {Schema} from './schema';\nimport {stylize} from './stylize';\n\nexport function generate(specQ: SpecQuery, schema: Schema, opt: QueryConfig = DEFAULT_QUERY_CONFIG) {\n // 1. Build a SpecQueryModel, which also contains wildcardIndex\n const specM = SpecQueryModel.build(specQ, schema, opt);\n const wildcardIndex = specM.wildcardIndex;\n\n // 2. Enumerate each of the properties based on propPrecedence.\n\n let answerSet = [specM]; // Initialize Answer Set with only the input spec query.\n opt.propertyPrecedence.forEach((propKey) => {\n const prop = fromKey(propKey);\n // If the original specQuery contains wildcard for this prop\n if (wildcardIndex.hasProperty(prop)) {\n // update answerset\n const enumerator = getEnumerator(prop);\n const reducer = enumerator(wildcardIndex, schema, opt);\n answerSet = answerSet.reduce(reducer, []);\n }\n });\n\n if (opt.stylize) {\n if ((opt.nominalColorScaleForHighCardinality !== null) ||\n (opt.smallRangeStepForHighCardinalityOrFacet !== null) ||\n (opt.xAxisOnTopForHighYCardinalityWithoutColumn !== null)) {\n return stylize(answerSet, schema, opt);\n }\n }\n\n return answerSet;\n}\n","import {DEFAULT_QUERY_CONFIG, QueryConfig} from './config';\nimport {generate} from './generate';\nimport {SpecQueryModelGroup} from './model';\nimport {nest} from './nest';\nimport {normalize} from './query/normalize';\nimport {Query} from './query/query';\nimport {rank} from './ranking/ranking';\nimport {Schema} from './schema';\n\nexport function recommend(q: Query, schema: Schema, config?: QueryConfig): {query: Query, result: SpecQueryModelGroup} {\n // 1. Normalize non-nested `groupBy` to always have `groupBy` inside `nest`\n // and merge config with the following precedence\n // query.config > config > DEFAULT_QUERY_CONFIG\n q = {\n ...normalize(q),\n config: {\n ...DEFAULT_QUERY_CONFIG,\n ...config,\n ...q.config\n }\n };\n // 2. Generate\n const answerSet = generate(q.spec, schema, q.config);\n const nestedAnswerSet = nest(answerSet, q.nest);\n const result = rank(nestedAnswerSet, q, schema, 0);\n\n return {\n query: q,\n result: result\n };\n}\n","/// \n\nimport * as config from './config';\nimport * as constraint from './constraint';\nimport * as enumerate from './enumerator';\nimport * as wildcard from './wildcard';\nimport * as model from './model';\nimport * as nest from './nest';\nimport * as property from './property';\nimport * as query from './query';\nimport * as ranking from './ranking/ranking';\nimport * as result from './result';\nimport * as schema from './schema';\nimport * as util from './util';\n\nexport {generate} from './generate';\nexport {recommend} from './recommend';\n\nexport {\n version\n} from './package.json';\n\nexport {config, constraint, enumerate, wildcard, model, nest, property, query, ranking, result, schema, util};\n"],"names":["stringValue","Error","clone_","stableStringify","log.message","TYPE.ORDINAL","TYPE.NOMINAL","TYPE.TEMPORAL","TYPE.QUANTITATIVE","CHANNEL.X","CHANNEL.Y","CHANNEL.SIZE","CHANNEL.STROKEWIDTH","CHANNEL.OPACITY","CHANNEL.FILLOPACITY","CHANNEL.STROKEOPACITY","CHANNEL.COLOR","CHANNEL.FILL","CHANNEL.STROKE","CHANNEL.SHAPE","TEXT","log.warn","contains","some","isArray","extend","MARK.POINT","MARK.BAR","MARK.LINE","MARK.AREA","MARK.RECT","MARK.TICK","MARK.TEXT","CHANNEL.ROW","defaultType","util.contains","isDiscrete","keys","toMap","isObject","value","spec","isString","isBoolean","isContinuous","vlChannelDef.isContinuous","vlChannelDef.isDiscrete","scaleType","compileScaleType","this","d3_time","gen","type","dlBin_","summary","inferAll","duplicate","cmp","CHANNEL.COLUMN","CHANNEL.TEXT","MARK.CIRCLE","MARK.SQUARE","MARK.RULE","CHANNEL.DETAIL","specShorthand","normalize","fieldDefShorthand","name","score","aggregation.name","aggregation.score","fieldOrder.name","fieldOrder.score","generate"],"mappings":"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"} \ No newline at end of file diff --git a/build/compassql.min.js b/build/compassql.min.js new file mode 100644 index 00000000..290dc478 --- /dev/null +++ b/build/compassql.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).cql={})}(this,function(e){"use strict";function t(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);it&&l(),s=t=n+1):"]"===r&&(s||o("Access path missing open bracket: "+e),s>0&&l(),s=0,t=n+1):n>t?l():t=n+1}return s&&o("Access path missing closing bracket: "+e),a&&o("Access path missing closing quote: "+e),n>t&&(n++,l()),i}var s=Array.isArray;function c(e){return e===Object(e)}function u(e){return"string"==typeof e}function l(e){return s(e)?"["+e.map(l)+"]":c(e)||u(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}var d=[];(function(e,t){var n=a(e),r="return _["+n.map(l).join("][")+"];";i(Function("_",r),[e=1===n.length?n[0]:e],t||e)})("id"),i(function(e){return e},d,"identity"),i(function(){return 0},d,"zero"),i(function(){return 1},d,"one"),i(function(){return!0},d,"true"),i(function(){return!1},d,"false");function f(e,t,n){var r=[t].concat([].slice.call(n));console[e](...r)}var p=0,h=1,g=2,m=3,y=4;function v(e){return"boolean"==typeof e}function E(e){for(var t={},n=0,r=e.length;nr(e)).join(",")})`};const b=r;function T(e,t){return e.indexOf(t)>-1}const S=Object.keys;function C(e){return S(e)}function A(...e){for(const t of e)if(void 0!==t)return t}const N="row",w="column",O="facet",x="x",I="y",M="x2",k="y2",U="latitude",F="longitude",D="latitude2",_="longitude2",P="color",R="fill",L="stroke",$="shape",B="size",W="opacity",H="fillOpacity",G="strokeOpacity",j="strokeWidth",z="text",q="order",Y="detail",Q="key",V="tooltip",K="href",J=Object.assign({x:1,y:1,x2:1,y2:1},{longitude:1,longitude2:1,latitude:1,latitude2:1},{color:1,fill:1,stroke:1,opacity:1,fillOpacity:1,strokeOpacity:1,strokeWidth:1,size:1,shape:1,order:1,text:1,detail:1,key:1,tooltip:1,href:1});function X(e){return"color"===e||"fill"===e||"stroke"===e}const Z=Object.assign({},J,{row:1,column:1,facet:1}),ee=C(Z);t(Z,["order","detail"]),t(Z,["order","detail","row","column","facet"]);const te=t(J,["x","y","x2","y2","latitude","longitude","latitude2","longitude2"]),ne=C(te),re={x:1,y:1},ie=(C(re),t(te,["text","tooltip","href","detail","key","order"])),oe=Object.assign({},re,ie);function ae(e){return!!oe[e]}function se(e,t){return function(e){switch(e){case P:case R:case L:case Y:case Q:case V:case K:case q:case W:case H:case G:case j:case O:case N:case w:return{point:"always",tick:"always",rule:"always",circle:"always",square:"always",bar:"always",rect:"always",line:"always",trail:"always",area:"always",text:"always",geoshape:"always"};case x:case I:case U:case F:return{point:"always",tick:"always",rule:"always",circle:"always",square:"always",bar:"always",rect:"always",line:"always",trail:"always",area:"always",text:"always"};case M:case k:case D:case _:return{rule:"always",bar:"always",rect:"always",area:"always",circle:"binned",point:"binned",square:"binned",tick:"binned"};case B:return{point:"always",tick:"always",rule:"always",circle:"always",square:"always",bar:"always",text:"always",line:"always",trail:"always"};case $:return{point:"always",geoshape:"always"};case z:return{text:"always"}}}(e)[t]}function ce(e){switch(e){case x:case I:case B:case j:case W:case H:case G:case M:case k:return;case O:case N:case w:case $:case z:case V:case K:return"discrete";case P:case R:case L:return"flexible";case U:case F:case D:case _:case Y:case Q:case q:return}throw new Error("rangeType not implemented for "+e)}const ue={orient:1,bandPosition:1,domain:1,domainColor:1,domainDash:1,domainDashOffset:1,domainOpacity:1,domainWidth:1,format:1,formatType:1,grid:1,gridColor:1,gridDash:1,gridDashOffset:1,gridOpacity:1,gridWidth:1,labelAlign:1,labelAngle:1,labelBaseline:1,labelBound:1,labelColor:1,labelFlush:1,labelFlushOffset:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labels:1,labelSeparation:1,maxExtent:1,minExtent:1,offset:1,position:1,tickColor:1,tickCount:1,tickDash:1,tickDashOffset:1,tickExtra:1,tickMinStep:1,tickOffset:1,tickOpacity:1,tickRound:1,ticks:1,tickSize:1,tickWidth:1,title:1,titleAlign:1,titleAnchor:1,titleAngle:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleOpacity:1,titlePadding:1,titleX:1,titleY:1,values:1,zindex:1},le=Object.assign({},ue,{encoding:1}),de=(Object.assign({gridScale:1,scale:1},ue,{encode:1}),C(le)),fe={clipHeight:1,columnPadding:1,columns:1,cornerRadius:1,direction:1,fillColor:1,format:1,formatType:1,gradientLength:1,gradientOpacity:1,gradientStrokeColor:1,gradientStrokeWidth:1,gradientThickness:1,gridAlign:1,labelAlign:1,labelBaseline:1,labelColor:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labelSeparation:1,legendX:1,legendY:1,offset:1,orient:1,padding:1,rowPadding:1,strokeColor:1,symbolDash:1,symbolDashOffset:1,symbolFillColor:1,symbolOffset:1,symbolOpacity:1,symbolSize:1,symbolStrokeColor:1,symbolStrokeWidth:1,symbolType:1,tickCount:1,tickMinStep:1,title:1,titleAlign:1,titleAnchor:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleOpacity:1,titleOrient:1,titlePadding:1,type:1,values:1,zindex:1},pe=(Object.assign({},fe,{opacity:1,shape:1,stroke:1,fill:1,size:1,strokeWidth:1,encode:1}),C(fe));const he=Object.freeze({INVALID_SPEC:"Invalid spec",FIT_NON_SINGLE:'Autosize "fit" only works for single views and layered views.',CANNOT_FIX_RANGE_STEP_WITH_FIT:'Cannot use a fixed value of "rangeStep" when "autosize" is "fit".',cannotProjectOnChannelWithoutField:function(e){return`Cannot project a selection on encoding channel "${e}", which has no field.`},nearestNotSupportForContinuous:function(e){return`The "nearest" transform is not supported for ${e} marks.`},selectionNotSupported:function(e){return`Selection not supported for ${e} yet`},selectionNotFound:function(e){return`Cannot find a selection named "${e}"`},SCALE_BINDINGS_CONTINUOUS:"Scale bindings are currently only supported for scales with unbinned, continuous domains.",NO_INIT_SCALE_BINDINGS:"Selections bound to scales cannot be separately initialized.",noSuchRepeatedValue:function(e){return`Unknown repeated value "${e}".`},columnsNotSupportByRowCol:function(e){return`The "columns" property cannot be used when "${e}" has nested row/column.`},CONCAT_CANNOT_SHARE_AXIS:"Axes cannot be shared in concatenated views yet (https://github.com/vega/vega-lite/issues/2415).",REPEAT_CANNOT_SHARE_AXIS:"Axes cannot be shared in repeated views yet (https://github.com/vega/vega-lite/issues/2415).",unrecognizedParse:function(e){return`Unrecognized parse "${e}".`},differentParse:function(e,t,n){return`An ancestor parsed field "${e}" as ${n} but a child wants to parse the field as ${t}.`},invalidTransformIgnored:function(e){return`Ignoring an invalid transform: ${b(e)}.`},NO_FIELDS_NEEDS_AS:'If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.',encodingOverridden:function(e){return`Layer's shared ${e.join(",")} channel ${1===e.length?"is":"are"} overriden`},projectionOverridden:function(e){const{parentProjection:t,projection:n}=e;return`Layer's shared projection ${b(t)} is overridden by a child projection ${b(n)}.`},primitiveChannelDef:function(e,t,n){return`Channel ${e} is a ${t}. Converted to {value: ${b(n)}}.`},invalidFieldType:function(e){return`Invalid field type "${e}"`},nonZeroScaleUsedWithLengthMark:function(e,t,n){return`A ${n.scaleType?`${n.scaleType} scale`:n.zeroFalse?"scale with zero=false":"scale with custom domain that excludes zero"} is used to encode ${e}'s ${t}. This can be misleading as the ${"x"===t?"width":"height"} of the ${e} can be arbitrary based on the scale domain. You may want to use point mark instead.`},invalidFieldTypeForCountAggregate:function(e,t){return`Invalid field type "${e}" for aggregate: "${t}", using "quantitative" instead.`},invalidAggregate:function(e){return`Invalid aggregation operator "${e}"`},missingFieldType:function(e,t){return`Missing type for channel "${e}", using "${t}" instead.`},droppingColor:function(e,t){const{fill:n,stroke:r}=t;return`Dropping color ${e} as the plot also has `+(n&&r?"fill and stroke":n?"fill":"stroke")},emptyFieldDef:function(e,t){return`Dropping ${b(e)} from channel "${t}" since it does not contain data field or value.`},latLongDeprecated:function(e,t,n){return`${e}-encoding with type ${t} is deprecated. Replacing with ${n}-encoding.`},LINE_WITH_VARYING_SIZE:"Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.",incompatibleChannel:function(e,t,n){return`${e} dropped as it is incompatible with "${t}"${n?` when ${n}`:""}.`},invalidEncodingChannel:function(e){return`${e}-encoding is dropped as ${e} is not a valid encoding channel.`},facetChannelShouldBeDiscrete:function(e){return`${e} encoding should be discrete (ordinal / nominal / binned).`},facetChannelDropped:function(e){return`Facet encoding dropped as ${e.join(" and ")} ${e.length>1?"are":"is"} also specified.`},discreteChannelCannotEncode:function(e,t){return`Using discrete channel "${e}" to encode "${t}" field can be misleading as it does not encode ${"ordinal"===t?"order":"magnitude"}.`},BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL:"Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.",lineWithRange:function(e,t){return`Line mark is for continuous lines and thus cannot be used with ${e&&t?"x2 and y2":e?"x2":"y2"}. We will use the rule mark (line segments) instead.`},orientOverridden:function(e,t){return`Specified orient "${e}" overridden with "${t}"`},CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN:"custom domain scale cannot be unioned with default field-based domain",cannotUseScalePropertyWithNonColor:function(e){return`Cannot use the scale property "${e}" with non-color channel.`},unaggregateDomainHasNoEffectForRawField:function(e){return`Using unaggregated domain with raw field has no effect (${b(e)}).`},unaggregateDomainWithNonSharedDomainOp:function(e){return`Unaggregated domain not applicable for "${e}" since it produces values outside the origin domain of the source data.`},unaggregatedDomainWithLogScale:function(e){return`Unaggregated domain is currently unsupported for log scale (${b(e)}).`},cannotApplySizeToNonOrientedMark:function(e){return`Cannot apply size to non-oriented mark "${e}".`},rangeStepDropped:function(e){return`rangeStep for "${e}" is dropped as top-level ${"x"===e?"width":"height"} is provided.`},scaleTypeNotWorkWithChannel:function(e,t,n){return`Channel "${e}" does not work with "${t}" scale. We are using "${n}" scale instead.`},scaleTypeNotWorkWithFieldDef:function(e,t){return`FieldDef does not work with "${e}" scale. We are using "${t}" scale instead.`},scalePropertyNotWorkWithScaleType:function(e,t,n){return`${n}-scale's "${t}" is dropped as it does not work with ${e} scale.`},scaleTypeNotWorkWithMark:function(e,t){return`Scale type "${t}" does not work with mark "${e}".`},mergeConflictingProperty:function(e,t,n,r){return`Conflicting ${t.toString()} property "${e.toString()}" (${b(n)} and ${b(r)}). Using ${b(n)}.`},independentScaleMeansIndependentGuide:function(e){return`Setting the scale to be independent for "${e}" means we also have to set the guide (axis or legend) to be independent.`},domainSortDropped:function(e){return`Dropping sort property ${b(e)} as unioned domains only support boolean or op 'count'.`},UNABLE_TO_MERGE_DOMAINS:"Unable to merge domains",MORE_THAN_ONE_SORT:"Domains that should be unioned has conflicting sort properties. Sort will be set to true.",INVALID_CHANNEL_FOR_AXIS:"Invalid channel for axis.",cannotStackRangedMark:function(e){return`Cannot stack "${e}" if there is already "${e}2"`},cannotStackNonLinearScale:function(e){return`Cannot stack non-linear scale (${e})`},stackNonSummativeAggregate:function(e){return`Stacking is applied even though the aggregate function is non-summative ("${e}")`},invalidTimeUnit:function(e,t){return`Invalid ${e}: ${b(t)}`},dayReplacedWithDate:function(e){return`Time unit "${e}" is not supported. We are replacing it with ${e.replace("day","date")}.`},droppedDay:function(e){return`Dropping day from datetime ${b(e)} as day cannot be combined with other units.`},errorBarCenterAndExtentAreNotNeeded:function(e,t){return`${t?"extent ":""}${t&&e?"and ":""}${e?"center ":""}${t&&e?"are ":"is "}not needed when data are aggregated.`},errorBarCenterIsUsedWithWrongExtent:function(e,t,n){return`${e} is not usually used with ${t} for ${n}.`},errorBarContinuousAxisHasCustomizedAggregate:function(e,t){return`Continuous axis should not have customized aggregation function ${e}; ${t} already agregates the axis.`},errorBarCenterIsNotNeeded:function(e,t){return`Center is not needed to be specified in ${t} when extent is ${e}.`},errorBand1DNotSupport:function(e){return`1D error band does not support ${e}`},channelRequiredForBinned:function(e){return`Channel ${e} is required for "binned" bin`},domainRequiredForThresholdScale:function(e){return`Domain for ${e} is required for threshold scale`}}),ge=(ye=g||p,{level:function(e){return arguments.length?(ye=+e,this):ye},error:function(){return ye>=h&&f(me||"error","ERROR",arguments),this},warn:function(){return ye>=g&&f(me||"warn","WARN",arguments),this},info:function(){return ye>=m&&f(me||"log","INFO",arguments),this},debug:function(){return ye>=y&&f(me||"log","DEBUG",arguments),this}});var me,ye;let ve=ge;function Ee(...e){ve.warn.apply(ve,arguments)}const be={quantitative:1,ordinal:1,temporal:1,nominal:1,geojson:1},Te="quantitative",Se="ordinal",Ce="temporal",Ae="nominal",Ne="geojson";function we(e){if(e)switch(e=e.toLowerCase()){case"q":case Te:return"quantitative";case"t":case Ce:return"temporal";case"o":case Se:return"ordinal";case"n":case Ae:return"nominal";case Ne:return"geojson"}}var Oe;!function(e){e.LINEAR="linear",e.LOG="log",e.POW="pow",e.SQRT="sqrt",e.SYMLOG="symlog",e.TIME="time",e.UTC="utc",e.QUANTILE="quantile",e.QUANTIZE="quantize",e.THRESHOLD="threshold",e.BIN_ORDINAL="bin-ordinal",e.ORDINAL="ordinal",e.POINT="point",e.BAND="band"}(Oe||(Oe={}));const xe=S({linear:"numeric",log:"numeric",pow:"numeric",sqrt:"numeric",symlog:"numeric",time:"time",utc:"time",ordinal:"ordinal","bin-ordinal":"bin-ordinal",point:"ordinal-position",band:"ordinal-position",quantile:"discretizing",quantize:"discretizing",threshold:"discretizing"}),Ie=["linear","log","pow","sqrt","symlog","time","utc"],Me=E(Ie),ke=E(["quantile","quantize","threshold"]),Ue=E(Ie.concat(["quantile","quantize","threshold"])),Fe=E(["ordinal","bin-ordinal","point","band"]);function De(e){return e in Fe}function _e(e){return e in Me}const Pe={type:1,domain:1,range:1,rangeStep:1,scheme:1,bins:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,constant:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},Re=C(Pe);t(Pe,["type","domain","range","rangeStep","scheme"]),function(){const e={};for(const t of ee)for(const n of S(be))for(const r of xe){const i=He(t,n);We(t,r)&&Be(r,n)&&(e[i]=e[i]||[],e[i].push(r))}}();function Le(e,t){switch(t){case"type":case"domain":case"reverse":case"range":return!0;case"scheme":case"interpolate":return!T(["point","band","identity"],e);case"bins":return!T(["point","band","identity","ordinal"],e);case"round":return _e(e)||"band"===e||"point"===e;case"padding":return _e(e)||T(["point","band"],e);case"paddingOuter":case"rangeStep":return T(["point","band"],e);case"paddingInner":return"band"===e;case"clamp":return _e(e);case"nice":return _e(e)||"quantize"===e||"threshold"===e;case"exponent":return"pow"===e;case"base":return"log"===e;case"constant":return"symlog"===e;case"zero":return e in Ue&&!T(["log","time","utc","threshold","quantile"],e)}throw new Error(`Invalid scale property ${t}.`)}function $e(e,t){switch(t){case"interpolate":case"scheme":return X(e)?void 0:he.cannotUseScalePropertyWithNonColor(e);case"type":case"bins":case"domain":case"range":case"base":case"exponent":case"constant":case"nice":case"padding":case"paddingInner":case"paddingOuter":case"rangeStep":case"reverse":case"round":case"clamp":case"zero":return}throw new Error(`Invalid scale property "${t}".`)}function Be(e,t){return T([Se,Ae],t)?void 0===e||De(e):t===Ce?T([Oe.TIME,Oe.UTC,void 0],e):t!==Te||T([Oe.LOG,Oe.POW,Oe.SQRT,Oe.SYMLOG,Oe.QUANTILE,Oe.QUANTIZE,Oe.THRESHOLD,Oe.LINEAR,void 0],e)}function We(e,t){switch(e){case x:case I:return _e(t)||T(["band","point"],t);case B:case j:case W:case H:case G:return _e(t)||t in ke||T(["band","point"],t);case P:case R:case L:return"band"!==t;case $:return"ordinal"===t}return!1}function He(e,t){return e+"_"+t}function Ge(e){return!!e.parent}const je={channel:1,aggregate:1,autoCount:1,bin:1,timeUnit:1,hasFn:1,sort:1,stack:1,field:1,type:1,format:1,scale:1,axis:1,legend:1,value:1},ze=C(je);function qe(e){return e in je}const Ye={bin:1,scale:1,sort:1,axis:1,legend:1};function Qe(e){return Ye[e]}const Ve=["maxbins","divide","extent","base","step","steps","minstep"],Ke=["field","op","order"],Je=Ve.map(e=>({parent:"bin",child:e})),Xe=Ke.map(e=>({parent:"sort",child:e})),Ze=Re.map(e=>({parent:"scale",child:e})),et=de.map(e=>({parent:"axis",child:e})),tt=pe.map(e=>({parent:"legend",child:e})),nt=[].concat(Je,Xe,Ze,et,tt),rt=["width","height","background","padding","title"],it=".";function ot(e){return Ge(e)?e.parent+it+e.child:e}function at(e){const t=e.split(it);if(1===t.length)return e;if(2===t.length)return{parent:t[0],child:t[1]};throw"Invalid property key with "+t.length+" dots: "+e}const st=nt.reduce((e,t)=>(e[t.parent]=e[t.parent]||[],e[t.parent][t.child]=t,e),{});function ct(e,t){return(st[e]||{})[t]}function ut(e){return qe(e)||Ge(e)}const lt=[].concat(ze,nt),dt=["type","field","bin","timeUnit","aggregate","autoCount","channel","mark","stack","scale","sort","axis","legend"].concat(Je,Ze,et,tt,Xe);var ft;!function(e){e.MARK="mark",e.TRANSFORM="transform",e.STACK="stack",e.FORMAT="format",e.CHANNEL="channel",e.AGGREGATE="aggregate",e.AUTOCOUNT="autoCount",e.BIN="bin",e.HAS_FN="hasFn",e.TIMEUNIT="timeUnit",e.FIELD="field",e.TYPE="type",e.SORT="sort",e.SCALE="scale",e.AXIS="axis",e.LEGEND="legend",e.WIDTH="width",e.HEIGHT="height",e.BACKGROUND="background",e.PADDING="padding",e.TITLE="title"}(ft||(ft={}));var pt=Object.freeze({isEncodingNestedProp:Ge,ENCODING_TOPLEVEL_PROPS:ze,isEncodingTopLevelProperty:qe,isEncodingNestedParent:Qe,BIN_CHILD_PROPS:Ve,SORT_CHILD_PROPS:Ke,SORT_PROPS:Xe,SCALE_PROPS:Ze,ENCODING_NESTED_PROPS:nt,VIEW_PROPS:rt,toKey:ot,fromKey:at,getEncodingNestedProp:ct,isEncodingProperty:ut,ALL_ENCODING_PROPS:lt,DEFAULT_PROP_PRECEDENCE:dt,get Property(){return ft}});const ht="area",gt="bar",mt="point",yt="circle",vt="square";function Et(e){return T(["line","area","trail"],e)}E(C({area:1,bar:1,line:1,point:1,text:1,tick:1,trail:1,rect:1,geoshape:1,rule:1,circle:1,square:1}));const bt=["january","february","march","april","may","june","july","august","september","october","november","december"],Tt=(bt.map(e=>e.substr(0,3)),["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]);Tt.map(e=>e.substr(0,3));var St;!function(e){e.YEAR="year",e.MONTH="month",e.DAY="day",e.DATE="date",e.HOURS="hours",e.MINUTES="minutes",e.SECONDS="seconds",e.MILLISECONDS="milliseconds",e.YEARMONTH="yearmonth",e.YEARMONTHDATE="yearmonthdate",e.YEARMONTHDATEHOURS="yearmonthdatehours",e.YEARMONTHDATEHOURSMINUTES="yearmonthdatehoursminutes",e.YEARMONTHDATEHOURSMINUTESSECONDS="yearmonthdatehoursminutesseconds",e.MONTHDATE="monthdate",e.MONTHDATEHOURS="monthdatehours",e.HOURSMINUTES="hoursminutes",e.HOURSMINUTESSECONDS="hoursminutesseconds",e.MINUTESSECONDS="minutesseconds",e.SECONDSMILLISECONDS="secondsmilliseconds",e.QUARTER="quarter",e.YEARQUARTER="yearquarter",e.QUARTERMONTH="quartermonth",e.YEARQUARTERMONTH="yearquartermonth",e.UTCYEAR="utcyear",e.UTCMONTH="utcmonth",e.UTCDAY="utcday",e.UTCDATE="utcdate",e.UTCHOURS="utchours",e.UTCMINUTES="utcminutes",e.UTCSECONDS="utcseconds",e.UTCMILLISECONDS="utcmilliseconds",e.UTCYEARMONTH="utcyearmonth",e.UTCYEARMONTHDATE="utcyearmonthdate",e.UTCYEARMONTHDATEHOURS="utcyearmonthdatehours",e.UTCYEARMONTHDATEHOURSMINUTES="utcyearmonthdatehoursminutes",e.UTCYEARMONTHDATEHOURSMINUTESSECONDS="utcyearmonthdatehoursminutesseconds",e.UTCMONTHDATE="utcmonthdate",e.UTCMONTHDATEHOURS="utcmonthdatehours",e.UTCHOURSMINUTES="utchoursminutes",e.UTCHOURSMINUTESSECONDS="utchoursminutesseconds",e.UTCMINUTESSECONDS="utcminutesseconds",e.UTCSECONDSMILLISECONDS="utcsecondsmilliseconds",e.UTCQUARTER="utcquarter",e.UTCYEARQUARTER="utcyearquarter",e.UTCQUARTERMONTH="utcquartermonth",e.UTCYEARQUARTERMONTH="utcyearquartermonth"}(St||(St={}));const Ct={year:1,quarter:1,month:1,day:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1},At=C(Ct);function Nt(e){return!!Ct[e]}const wt={utcyear:1,utcquarter:1,utcmonth:1,utcday:1,utcdate:1,utchours:1,utcminutes:1,utcseconds:1,utcmilliseconds:1};function Ot(e){return!!wt[e]}const xt={utcyearquarter:1,utcyearquartermonth:1,utcyearmonth:1,utcyearmonthdate:1,utcyearmonthdatehours:1,utcyearmonthdatehoursminutes:1,utcyearmonthdatehoursminutesseconds:1,utcquartermonth:1,utcmonthdate:1,utcmonthdatehours:1,utchoursminutes:1,utchoursminutesseconds:1,utcminutesseconds:1,utcsecondsmilliseconds:1},It=Object.assign({},wt,xt);const Mt=Object.assign({},Ct,wt,{yearquarter:1,yearquartermonth:1,yearmonth:1,yearmonthdate:1,yearmonthdatehours:1,yearmonthdatehoursminutes:1,yearmonthdatehoursminutesseconds:1,quartermonth:1,monthdate:1,monthdatehours:1,hoursminutes:1,hoursminutesseconds:1,minutesseconds:1,secondsmilliseconds:1},xt);const kt={year:"setFullYear",month:"setMonth",date:"setDate",hours:"setHours",minutes:"setMinutes",seconds:"setSeconds",milliseconds:"setMilliseconds",quarter:null,day:null};function Ut(e,t){const n=!!It[e];const r=n?new Date(Date.UTC(1972,0,1,0,0,0,0)):new Date(1972,0,1,0,0,0,0);for(const i of At)if(Dt(e,i))switch(i){case St.DAY:throw new Error("Cannot convert to TimeUnits containing 'day'");case St.QUARTER:{const{getDateMethod:e,setDateMethod:i}=Ft("month",n);r[i](3*Math.floor(t[e]()/3));break}default:{const{getDateMethod:e,setDateMethod:o}=Ft(i,n);r[o](t[e]())}}return r}function Ft(e,t){const n=kt[e];return{setDateMethod:t?"setUTC"+n.substr(3):n,getDateMethod:"get"+(t?"UTC":"")+n.substr(3)}}function Dt(e,t){const n=e.indexOf(t);return n>-1&&(t!==St.SECONDS||0===n||"i"!==e.charAt(n-1))}var _t=n(function(e){var t=e.exports;t.namedfunc=function(e,t){return t.__name__=e,t},t.name=function(e){return null==e?null:e.__name__},t.identity=function(e){return e},t.true=t.namedfunc("true",function(){return!0}),t.false=t.namedfunc("false",function(){return!1}),t.duplicate=function(e){return JSON.parse(JSON.stringify(e))},t.equal=function(e,t){return JSON.stringify(e)===JSON.stringify(t)},t.extend=function(e){for(var t,n,r=1,i=arguments.length;r1?function(e,t){for(var r=0;rt||null==t)&&null!=e?1:(t=t instanceof Date?+t:t,(e=e instanceof Date?+e:e)!==e&&t==t?-1:t!=t&&e==e?1:0)},t.numcmp=function(e,t){return e-t},t.stablesort=function(e,t,n){var r=e.reduce(function(e,t,r){return e[n(t)]=r,e},{});return e.sort(function(e,i){var o=t(e),a=t(i);return oa?1:r[n(e)]-r[n(i)]}),e},t.permute=function(e){for(var t,n,r=e.length;r;)n=Math.floor(Math.random()*r--),t=e[r],e[r]=e[n],e[n]=t},t.pad=function(e,t,n,r){r=r||" ";var o=t-e.length;if(o<=0)return e;switch(n){case"left":return i(o,r)+e;case"middle":case"center":return i(Math.floor(o/2),r)+e+i(Math.ceil(o/2),r);default:return e+i(o,r)}},t.truncate=function(e,t,n,r,i){var a=e.length;if(a<=t)return e;i=void 0!==i?String(i):"…";var s=Math.max(0,t-i.length);switch(n){case"left":return i+(r?o(e,s,1):e.slice(a-s));case"middle":case"center":var c=Math.ceil(s/2),u=Math.floor(s/2);return(r?o(e,c):e.slice(0,c))+i+(r?o(e,u,1):e.slice(a-u));default:return(r?o(e,s):e.slice(0,s))+i}};var a=/([\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF])/}),Pt=_t.isArray,Rt=_t.cmp,Lt=_t.keys,$t=_t.duplicate,Bt=_t.extend,Wt=_t.isObject,Ht=_t.isBoolean,Gt=_t.toMap,jt=_t.isString;function zt(e,t){return-1!==e.indexOf(t)}function qt(e,t){for(let n=0;nPt(t)?e(t,n):n(t))},without:Vt,cmp:Rt,keys:Lt,duplicate:$t,extend:Bt,isObject:Wt,isBoolean:Ht,toMap:Gt});const Jt="?";function Xt(e){return Zt(e)||en(e)}function Zt(e){return e===Jt}function en(e){return!(void 0===e||null==e||!e.enum&&!e.name||Pt(e))}function tn(e,t,n){return Bt({},{name:t,enum:n},e===Jt?{}:e)}function nn(e){let t={},n={};for(const r of e){const e=[0];for(let t=0;tr.charAt(e)).join("").toLowerCase();if(n[i])if(e[e.length-1]===r.length-1||n[i=e.concat([r.length-1]).map(e=>r.charAt(e)).join("").toLowerCase()])for(let e=1;!t[r];e++){let o=i+"_"+e;if(!n[o]){t[r]=o,n[o]=!0;break}}else t[r]=i,n[i]=!0;else t[r]=i,n[i]=!0}return t}const rn={mark:"m",channel:"c",aggregate:"a",autoCount:"#",hasFn:"h",bin:"b",sort:"so",stack:"st",scale:"s",format:"f",axis:"ax",legend:"l",value:"v",timeUnit:"tu",field:"f",type:"t",binProps:{maxbins:"mb",min:"mi",max:"ma",base:"b",step:"s",steps:"ss",minstep:"ms",divide:"d"},sortProps:{field:"f",op:"o",order:"or"},scaleProps:nn(Re),axisProps:nn(de),legendProps:nn(pe)};function on(e){if(Ge(e))return rn[e.parent]+"-"+rn[e.parent+"Props"][e.child];if(rn[e])return rn[e];throw new Error("Default name undefined for "+e)}const an=[!1,!0],sn={maxbins:[5,10,20],extent:[void 0],base:[10],step:[void 0],steps:[void 0],minstep:[void 0],divide:[[5,2]],binned:[!1],anchor:[void 0],nice:[!0]},cn={field:[void 0],op:["min","mean"],order:["ascending","descending"]},un={type:[void 0,Oe.LOG],domain:[void 0],base:[void 0],exponent:[1,2],constant:[void 0],bins:[void 0],clamp:an,nice:an,reverse:an,round:an,zero:an,padding:[void 0],paddingInner:[void 0],paddingOuter:[void 0],interpolate:[void 0],range:[void 0],rangeStep:[17,21],scheme:[void 0]},ln={zindex:[1,0],offset:[void 0],orient:[void 0],values:[void 0],bandPosition:[void 0],encoding:[void 0],domain:an,domainColor:[void 0],domainDash:[void 0],domainDashOffset:[void 0],domainOpacity:[void 0],domainWidth:[void 0],formatType:[void 0],grid:an,gridColor:[void 0],gridDash:[void 0],gridDashOffset:[void 0],gridOpacity:[void 0],gridWidth:[void 0],format:[void 0],labels:an,labelAlign:[void 0],labelAngle:[void 0],labelBaseline:[void 0],labelColor:[void 0],labelFlushOffset:[void 0],labelFont:[void 0],labelFontSize:[void 0],labelFontStyle:[void 0],labelFontWeight:[void 0],labelLimit:[void 0],labelOpacity:[void 0],labelSeparation:[void 0],labelOverlap:[void 0],labelPadding:[void 0],labelBound:[void 0],labelFlush:[void 0],maxExtent:[void 0],minExtent:[void 0],position:[void 0],ticks:an,tickColor:[void 0],tickCount:[void 0],tickDash:[void 0],tickExtra:[void 0],tickDashOffset:[void 0],tickMinStep:[void 0],tickOffset:[void 0],tickOpacity:[void 0],tickRound:[void 0],tickSize:[void 0],tickWidth:[void 0],title:[void 0],titleAlign:[void 0],titleAnchor:[void 0],titleAngle:[void 0],titleBaseline:[void 0],titleColor:[void 0],titleFont:[void 0],titleFontSize:[void 0],titleFontStyle:[void 0],titleFontWeight:[void 0],titleLimit:[void 0],titleOpacity:[void 0],titlePadding:[void 0],titleX:[void 0],titleY:[void 0]},dn={orient:["left","right"],format:[void 0],type:[void 0],values:[void 0],zindex:[void 0],clipHeight:[void 0],columnPadding:[void 0],columns:[void 0],cornerRadius:[void 0],direction:[void 0],encoding:[void 0],fillColor:[void 0],formatType:[void 0],gridAlign:[void 0],offset:[void 0],padding:[void 0],rowPadding:[void 0],strokeColor:[void 0],labelAlign:[void 0],labelBaseline:[void 0],labelColor:[void 0],labelFont:[void 0],labelFontSize:[void 0],labelFontStyle:[void 0],labelFontWeight:[void 0],labelLimit:[void 0],labelOffset:[void 0],labelOpacity:[void 0],labelOverlap:[void 0],labelPadding:[void 0],labelSeparation:[void 0],legendX:[void 0],legendY:[void 0],gradientLength:[void 0],gradientOpacity:[void 0],gradientStrokeColor:[void 0],gradientStrokeWidth:[void 0],gradientThickness:[void 0],symbolDash:[void 0],symbolDashOffset:[void 0],symbolFillColor:[void 0],symbolOffset:[void 0],symbolOpacity:[void 0],symbolSize:[void 0],symbolStrokeColor:[void 0],symbolStrokeWidth:[void 0],symbolType:[void 0],tickCount:[void 0],tickMinStep:[void 0],title:[void 0],titleAnchor:[void 0],titleAlign:[void 0],titleBaseline:[void 0],titleColor:[void 0],titleFont:[void 0],titleFontSize:[void 0],titleFontStyle:[void 0],titleFontWeight:[void 0],titleLimit:[void 0],titleOpacity:[void 0],titleOrient:[void 0],titlePadding:[void 0]},fn={mark:[mt,gt,"line",ht,"rect","tick","text"],channel:[x,I,N,w,B,P],aggregate:[void 0,"mean"],autoCount:an,bin:an,hasFn:an,timeUnit:[void 0,St.YEAR,St.MONTH,St.MINUTES,St.SECONDS],field:[void 0],type:[Ae,Se,Te,Ce],sort:["ascending","descending"],stack:["zero","normalize","center",null],value:[void 0],format:[void 0],title:[void 0],scale:[!0],axis:an,legend:an,binProps:sn,sortProps:cn,scaleProps:un,axisProps:ln,legendProps:dn};function pn(e,t,n){if("field"===e||Ge(e)&&"sort"===e.parent&&"field"===e.child)return t.fieldNames();let r;if(void 0!==(r=Ge(e)?n.enum[e.parent+"Props"][e.child]:n.enum[e]))return r;throw new Error("No default enumValues for "+JSON.stringify(e))}var hn=Object.freeze({SHORT_WILDCARD:Jt,isWildcard:Xt,isShortWildcard:Zt,isWildcardDef:en,initWildcard:tn,DEFAULT_NAME:rn,getDefaultName:on,DEFAULT_ENUM_INDEX:fn,getDefaultEnumValues:pn});const gn={verbose:!1,defaultSpecConfig:{line:{point:!0},scale:{useUnaggregatedDomain:!0}},propertyPrecedence:dt.map(ot),enum:fn,numberNominalProportion:.05,numberNominalLimit:40,constraintManuallySpecifiedValue:!1,autoAddCount:!1,hasAppropriateGraphicTypeForMark:!0,omitAggregate:!1,omitAggregatePlotWithDimensionOnlyOnFacet:!0,omitAggregatePlotWithoutDimension:!1,omitBarLineAreaWithOcclusion:!0,omitBarTickWithSize:!0,omitMultipleNonPositionalChannels:!0,omitRaw:!1,omitRawContinuousFieldForAggregatePlot:!0,omitRepeatedField:!0,omitNonPositionalOrFacetOverPositionalChannels:!0,omitTableWithOcclusionIfAutoAddCount:!0,omitVerticalDotPlot:!1,omitInvalidStackSpec:!0,omitNonSumStack:!0,preferredBinAxis:x,preferredTemporalAxis:x,preferredOrdinalAxis:I,preferredNominalAxis:I,preferredFacet:N,minCardinalityForBin:15,maxCardinalityForCategoricalColor:20,maxCardinalityForFacet:20,maxCardinalityForShape:6,timeUnitShouldHaveVariation:!0,typeMatchesSchemaType:!0,stylize:!0,smallRangeStepForHighCardinalityOrFacet:{maxCardinality:10,rangeStep:12},nominalColorScaleForHighCardinality:{maxCardinality:10,palette:"category20"},xAxisOnTopForHighYCardinalityWithoutColumn:{maxCardinality:30},maxGoodCardinalityForFacet:5,maxGoodCardinalityForColor:7,minPercentUniqueForKey:.8,minCardinalityForKey:50};function mn(e,t){return Object.assign({},fn[t+"Props"],e[t+"Props"])}var yn=Object.freeze({DEFAULT_QUERY_CONFIG:gn,extendConfig:function(e){return Object.assign({},gn,e,{enum:(t=e.enum,Object.assign({},fn,t,{binProps:mn(t,"bin"),scaleProps:mn(t,"scale"),axisProps:mn(t,"axis"),legendProps:mn(t,"legend")}))});var t}});const vn={argmax:1,argmin:1,average:1,count:1,distinct:1,max:1,mean:1,median:1,min:1,missing:1,q1:1,q3:1,ci0:1,ci1:1,stderr:1,stdev:1,stdevp:1,sum:1,valid:1,values:1,variance:1,variancep:1};function En(e){return!!e&&!!e.argmin}function bn(e){return!!e&&!!e.argmax}function Tn(e){return u(e)&&!!vn[e]}const Sn=["count","sum","distinct","valid","missing"];E(["mean","average","median","q1","q3","min","max"]);function Cn(e){return!0===e||An(e)&&!e.binned}function An(e){return c(e)}function Nn(e){switch(e){case N:case w:case B:case P:case R:case L:case j:case W:case H:case G:case $:return 6;default:return 10}}function wn(e){return!!e&&!!e.condition&&!s(e.condition)&&On(e.condition)}function On(e){return!(!e||!e.field&&"count"!==e.aggregate)}function xn(e){return On(e)&&u(e.field)}function In(e,t={}){let n=e.field;const r=t.prefix;let i=t.suffix,o="";if(Un(e))n=function(e){return 0===e.indexOf("__")}(s="count")?s:`__${s}`;else{let r;if(!t.nofn)if(function(e){return!!e.op}(e))r=e.op;else{const{bin:a,aggregate:s,timeUnit:c}=e;Cn(a)?(r=function(e){return v(e)&&(e=Dn(e,void 0)),"bin"+S(e).map(t=>(function(e){const t=e.replace(/\W/g,"_");return(e.match(/^\d+/)?"_":"")+t})(`_${t}_${e[t]}`)).join("")}(a),i=(t.binSuffix||"")+(t.suffix||"")):s?bn(s)?(o=`.${n}`,n=`argmax_${s.argmax}`):En(s)?(o=`.${n}`,n=`argmin_${s.argmin}`):r=String(s):c&&(r=String(c))}r&&(n=n?`${r}_${n}`:r)}var s;return i&&(n=`${n}_${i}`),r&&(n=`${r}_${n}`),t.forAs?n:t.expr?function(e,t="datum"){return`${t}[${l(a(e).join("."))}]`}(n,t.expr)+o:`${a(n).map(e=>e.replace(".","\\.")).join("\\.")}`+o}function Mn(e){switch(e.type){case"nominal":case"ordinal":case"geojson":return!0;case"quantitative":return!!e.bin;case"temporal":return!1}throw new Error(he.invalidFieldType(e.type))}function kn(e){return!Mn(e)}function Un(e){return"count"===e.aggregate}function Fn(e){return On(e)?e:wn(e)?e.condition:void 0}function Dn(e,t){return v(e)?{maxbins:Nn(t)}:"binned"===e?{binned:!0}:e.maxbins||e.step?e:Object.assign({},e,{maxbins:Nn(t)})}const _n={compatible:!0};function Pn(e,t){const n=e.type;if("geojson"===n&&"shape"!==t)return{compatible:!1,warning:`Channel ${t} should not be used with a geojson data.`};switch(t){case"row":case"column":case"facet":return kn(e)?{compatible:!1,warning:he.facetChannelShouldBeDiscrete(t)}:_n;case"x":case"y":case"color":case"fill":case"stroke":case"text":case"detail":case"key":case"tooltip":case"href":return _n;case"longitude":case"longitude2":case"latitude":case"latitude2":return n!==Te?{compatible:!1,warning:`Channel ${t} should be used with a quantitative field only, not ${e.type} field.`}:_n;case"opacity":case"fillOpacity":case"strokeOpacity":case"strokeWidth":case"size":case"x2":case"y2":return"nominal"!==n||e.sort?_n:{compatible:!1,warning:`Channel ${t} should not be used with an unsorted discrete field.`};case"shape":return T(["ordinal","nominal","geojson"],e.type)?_n:{compatible:!1,warning:"Shape channel should be used with only either discrete or geojson data."};case"order":return"nominal"!==e.type||"sort"in e?_n:{compatible:!1,warning:"Channel order is inappropriate for nominal field, which has no inherent order."}}throw new Error("channelCompatability not implemented for channel "+t)}var Rn;function Ln(e,t,n,r){const i=function(e,t,n){switch(t.type){case"nominal":case"ordinal":if(X(e)||"discrete"===ce(e))return"shape"===e&&"ordinal"===t.type&&Ee(he.discreteChannelCannotEncode(e,"ordinal")),"ordinal";if(T(["x","y"],e)){if(T(["rect","bar","rule"],n))return"band";if("bar"===n)return"band"}return"point";case"temporal":return X(e)?"time":"discrete"===ce(e)?(Ee(he.discreteChannelCannotEncode(e,"temporal")),"ordinal"):"time";case"quantitative":return X(e)?Cn(t.bin)?"bin-ordinal":"linear":"discrete"===ce(e)?(Ee(he.discreteChannelCannotEncode(e,"quantitative")),"ordinal"):"linear";case"geojson":return}throw new Error(he.invalidFieldType(t.type))}(t,n,r),{type:o}=e;return ae(t)?void 0!==o?We(t,o)?Be(o,n.type)?o:(Ee(he.scaleTypeNotWorkWithFieldDef(o,i)),i):(Ee(he.scaleTypeNotWorkWithChannel(t,o,i)),i):i:null}function $n(e){return e===Se||e===Ae||e===Rn.KEY}!function(e){e.QUANTITATIVE=Te,e.ORDINAL=Se,e.TEMPORAL=Ce,e.NOMINAL=Ae,e.KEY="key"}(Rn||(Rn={}));class Bn{constructor(e=null){this.index=e?Object.assign({},e):{}}has(e){return ot(e)in this.index}get(e){return this.index[ot(e)]}set(e,t){return this.index[ot(e)]=t,this}setByKey(e,t){this.index[e]=t}map(e){const t=new Bn;for(const n in this.index)t.index[n]=e(this.index[n]);return t}size(){return Lt(this.index).length}duplicate(){return new Bn(this.index)}}function Wn(e,t){const n=e&&e[t];return!!n&&(s(n)?function(e,t){let n=0;for(const[r,i]of e.entries())if(t(i,r,n++))return!0;return!1}(n,e=>!!e.field):On(n)||wn(n))}const Hn={zero:1,center:1,normalize:1};const Gn=[gt,ht,"rule",mt,yt,vt,"line","text","tick"],jn=[gt,ht];function zn(e,t,n,r={}){const i=function(e){return e.type}(e)?e.type:e;if(!T(Gn,i))return null;const o=function(e){const t=e.x,n=e.y;if(On(t)&&On(n))if("quantitative"===t.type&&"quantitative"===n.type){if(t.stack)return"x";if(n.stack)return"y";if(!!t.aggregate!=!!n.aggregate)return t.aggregate?"x":"y"}else{if("quantitative"===t.type)return"x";if("quantitative"===n.type)return"y"}else{if(On(t)&&"quantitative"===t.type)return"x";if(On(n)&&"quantitative"===n.type)return"y"}}(t);if(!o)return null;const a=t[o],c=xn(a)?In(a,{}):void 0,u="x"===o?"y":"x",l=t[u],d=xn(l)?In(l,{}):void 0,f=ne.reduce((e,n)=>{if("tooltip"!==n&&Wn(t,n)){const r=t[n];(s(r)?r:[r]).forEach(t=>{const r=Fn(t);if(r.aggregate)return;const i=xn(r)?In(r,{}):void 0;(!i||i!==d&&i!==c)&&e.push({channel:n,fieldDef:r})})}return e},[]);if(0===f.length)return null;let p;if(!(p=void 0!==a.stack?v(a.stack)?a.stack?"zero":null:a.stack:T(jn,i)?A(n,"zero"):n)||!Hn[p])return null;if(a.scale&&a.scale.type&&a.scale.type!==Oe.LINEAR){if(r.disallowNonLinearStack)return null;Ee(he.cannotStackNonLinearScale(a.scale.type))}return Wn(t,o===x?M:k)?(void 0!==a.stack&&Ee(he.cannotStackRangedMark(o)),null):(a.aggregate&&!T(Sn,a.aggregate)&&Ee(he.stackNonSummativeAggregate(a.aggregate)),{groupbyChannel:l?u:void 0,fieldChannel:o,impute:Et(i),stackBy:f,offset:p})}function qn(e){return Bt(e.data?{data:e.data}:{},e.transform?{transform:e.transform}:{},e.width?{width:e.width}:{},e.height?{height:e.height}:{},e.background?{background:e.background}:{},e.padding?{padding:e.padding}:{},e.title?{title:e.title}:{},{mark:e.mark,encodings:Lt(e.encoding).map(t=>{let n={channel:t},r=e.encoding[t];for(const e in r)qe(e)&&void 0!==r[e]&&(zt(["bin","scale","axis","legend"],e)&&null===r[e]?n[e]=!1:n[e]=r[e]);return hr(n)&&"count"===n.aggregate&&!n.field&&(n.field="*"),n})},e.config?{config:e.config}:{})}function Yn(e){return Qt(e.encodings,e=>hr(e)&&!Xt(e.aggregate)&&!!e.aggregate||yr(e))}function Qn(e){if(!Jn(e))return null;const t=Er(e.encodings,{schema:null,wildcardMode:"null"});return zn(e.mark,t,void 0,{disallowNonLinearStack:!0})}function Vn(e){for(const t of e.encodings)if(void 0!==t[ft.STACK]&&!Xt(t[ft.STACK]))return t[ft.STACK]}function Kn(e){for(const t of e.encodings)if(void 0!==t[ft.STACK]&&!Xt(t.channel))return t.channel;return null}function Jn(e){if(Xt(e.mark))return!1;const t=[ft.STACK,ft.CHANNEL,ft.MARK,ft.FIELD,ft.AGGREGATE,ft.AUTOCOUNT,ft.SCALE,ct("scale","type"),ft.TYPE],n=Gt(Vt(lt,t)),r=e.encodings.filter(e=>!mr(e));for(const e of r)if(Xn(e,{exclude:n}))return!1;return!0}function Xn(e,t={}){if(!Wt(e))return!1;for(const n in e)if(e.hasOwnProperty(n)){if(Xt(e[n])&&(!t.exclude||!t.exclude[n])||Xn(e[n],t))return!0}return!1}var Zn=Object.freeze({fromSpec:qn,isAggregate:Yn,getVlStack:Qn,getStackOffset:Vn,getStackChannel:Kn,hasRequiredStackProperties:Jn,hasWildcard:function(e,t={}){const n=t.exclude?Gt(t.exclude.map(ot)):{};if(Xt(e.mark)&&!n.mark)return!0;for(const t of e.encodings)if(Xn(t,n))return!0;return!1}});function er(e){return e.map(e=>tr(e))}function tr(e){return t=>void 0!==e[t]?e[t]:t}function nr(e,t){return Xt(e)?!Zt(e)&&e.enum?Jt+JSON.stringify(e.enum):Jt:t?t(e):e}function rr(e,t){return t?t(e):e}const ir=new Bn,or=[].concat(dt,Xe,[ft.TRANSFORM,ft.STACK],rt).reduce((e,t)=>e.set(t,!0),new Bn);const ar={axis:{x:!0,y:!0,row:!0,column:!0},legend:{color:!0,opacity:!0,size:!0,shape:!0},scale:{x:!0,y:!0,color:!0,opacity:!0,row:!0,column:!0,size:!0,shape:!0},sort:{x:!0,y:!0,path:!0,order:!0},stack:{x:!0,y:!0}};function sr(e,t=or,n=ir){const r=[];let i;if(t.get(ft.MARK)&&r.push(nr(e.mark,n.get(ft.MARK))),e.transform&&e.transform.length>0&&r.push("transform:"+JSON.stringify(e.transform)),t.get(ft.STACK)&&(i=Qn(e)),e.encodings){const o=e.encodings.reduce((e,r)=>{if(!mr(r)){let o;(o=i&&r.channel===i.fieldChannel?cr(Object.assign({},r,{stack:i.offset}),t,n):cr(r,t,n))&&e.push(o)}return e},[]).sort().join("|");o&&r.push(o)}for(let n of rt){const i=n.toString();if(t.get(n)&&e[i]){const t=e[i];r.push(`${i}=${JSON.stringify(t)}`)}}return r.join("|")}function cr(e,t=or,n=ir){const r=[];if(t.get(ft.CHANNEL)&&r.push(nr(e.channel,n.get(ft.CHANNEL))),hr(e)){const i=ur(e,t,n);i&&r.push(i)}else pr(e)?r.push(e.value):gr(e)&&r.push("autocount()");return r.join(":")}function ur(e,t=or,n=ir){if(t.get(ft.AGGREGATE)&&mr(e))return"-";const r=function(e,t,n){if(t.get(ft.AGGREGATE)&&e.aggregate&&!Xt(e.aggregate))return rr(e.aggregate,n.get(ft.AGGREGATE));if(t.get(ft.AGGREGATE)&&yr(e))return rr("count",n.get(ft.AGGREGATE));if(t.get(ft.TIMEUNIT)&&e.timeUnit&&!Xt(e.timeUnit))return rr(e.timeUnit,n.get(ft.TIMEUNIT));if(t.get(ft.BIN)&&e.bin&&!Xt(e.bin))return"bin";{let n=null;for(const r of[ft.AGGREGATE,ft.AUTOCOUNT,ft.TIMEUNIT,ft.BIN]){const i=e[r];t.get(r)&&e[r]&&Xt(i)&&((n=n||{})[r]=Zt(i)?i:i.enum)}return n&&e.hasFn&&(n.hasFn=!0),n}}(e,t,n),i=function(e,t,n){const r=[];if(!Ht(e.bin)&&!Zt(e.bin)){const i=e.bin;for(const e in i){const o=ct("bin",e);o&&t.get(o)&&void 0!==i[e]&&r.push({key:e,value:nr(i[e],n.get(o))})}r.sort((e,t)=>e.key.localeCompare(t.key))}for(const i of[ft.SCALE,ft.SORT,ft.STACK,ft.AXIS,ft.LEGEND])if((Xt(e.channel)||ar[i][e.channel])&&t.get(i)&&void 0!==e[i]){const o=e[i];if(Ht(o)||null===o)r.push({key:i+"",value:o||!1});else if(jt(o))r.push({key:i+"",value:rr(JSON.stringify(o),n.get(i))});else{let e=[];for(const r in o){const a=ct(i,r);a&&t.get(a)&&void 0!==o[r]&&e.push({key:r,value:nr(o[r],n.get(a))})}if(e.length>0){const t=e.sort((e,t)=>e.key.localeCompare(t.key)).reduce((e,t)=>(e[t.key]=t.value,e),{});r.push({key:i+"",value:JSON.stringify(t)})}}}return r}(e,t,n);let o;if(hr(e)){if(o=t.get("field")?nr(e.field,n.get("field")):"...",t.get(ft.TYPE))if(Xt(e.type))o+=","+nr(e.type,n.get(ft.TYPE));else{o+=","+nr(((e.type||Te)+"").substr(0,1),n.get(ft.TYPE))}o+=i.map(e=>{let t=e.value instanceof Array?"["+e.value+"]":e.value;return","+e.key+"="+t}).join("")}else gr(e)&&(o="*,q");if(!o)return null;if(r){return(jt(r)?r:Jt+(Lt(r).length>0?JSON.stringify(r):""))+"("+o+")"}return o}function lr(e,t,n){let r=[],i=0;for(let o=0;o0))return o;for(i(t,1),e(t),t=0;)for(;i(e,1),!t(e););})},o&&(s.count=function(r,i){return t.setTime(+r),n.setTime(+i),e(t),e(n),Math.floor(o(t,n))},s.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?s.filter(a?function(t){return a(t)%e==0}:function(t){return s.count(0,t)%e==0}):s:null}),s}var i=r(function(){},function(e,t){e.setTime(+e+t)},function(e,t){return t-e});i.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?r(function(t){t.setTime(Math.floor(t/e)*e)},function(t,n){t.setTime(+t+n*e)},function(t,n){return(n-t)/e}):i:null};var o=r(function(e){e.setMilliseconds(0)},function(e,t){e.setTime(+e+1e3*t)},function(e,t){return(t-e)/1e3},function(e){return e.getSeconds()}),a=r(function(e){e.setSeconds(0,0)},function(e,t){e.setTime(+e+6e4*t)},function(e,t){return(t-e)/6e4},function(e){return e.getMinutes()}),s=r(function(e){e.setMinutes(0,0,0)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getHours()}),c=r(function(e){e.setHours(0,0,0,0)},function(e,t){e.setDate(e.getDate()+t)},function(e,t){return(t-e-6e4*(t.getTimezoneOffset()-e.getTimezoneOffset()))/864e5},function(e){return e.getDate()-1});function u(e){return r(function(t){t.setHours(0,0,0,0),t.setDate(t.getDate()-(t.getDay()+7-e)%7)},function(e,t){e.setDate(e.getDate()+7*t)},function(e,t){return(t-e-6e4*(t.getTimezoneOffset()-e.getTimezoneOffset()))/6048e5})}var l=u(0),d=u(1),f=u(2),p=u(3),h=u(4),g=u(5),m=u(6),y=r(function(e){e.setHours(0,0,0,0),e.setDate(1)},function(e,t){e.setMonth(e.getMonth()+t)},function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())},function(e){return e.getMonth()}),v=r(function(e){e.setHours(0,0,0,0),e.setMonth(0,1)},function(e,t){e.setFullYear(e.getFullYear()+t)},function(e,t){return t.getFullYear()-e.getFullYear()},function(e){return e.getFullYear()}),E=r(function(e){e.setUTCMilliseconds(0)},function(e,t){e.setTime(+e+1e3*t)},function(e,t){return(t-e)/1e3},function(e){return e.getUTCSeconds()}),b=r(function(e){e.setUTCSeconds(0,0)},function(e,t){e.setTime(+e+6e4*t)},function(e,t){return(t-e)/6e4},function(e){return e.getUTCMinutes()}),T=r(function(e){e.setUTCMinutes(0,0,0)},function(e,t){e.setTime(+e+36e5*t)},function(e,t){return(t-e)/36e5},function(e){return e.getUTCHours()}),S=r(function(e){e.setUTCHours(0,0,0,0)},function(e,t){e.setUTCDate(e.getUTCDate()+t)},function(e,t){return(t-e)/864e5},function(e){return e.getUTCDate()-1});function C(e){return r(function(t){t.setUTCHours(0,0,0,0),t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7)},function(e,t){e.setUTCDate(e.getUTCDate()+7*t)},function(e,t){return(t-e)/6048e5})}var A=C(0),N=C(1),w=C(2),O=C(3),x=C(4),I=C(5),M=C(6),k=r(function(e){e.setUTCHours(0,0,0,0),e.setUTCDate(1)},function(e,t){e.setUTCMonth(e.getUTCMonth()+t)},function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())},function(e){return e.getUTCMonth()}),U=r(function(e){e.setUTCHours(0,0,0,0),e.setUTCMonth(0,1)},function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)},function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()},function(e){return e.getUTCFullYear()}),F=i.range,D=o.range,_=a.range,P=s.range,R=c.range,L=l.range,$=d.range,B=f.range,W=p.range,H=h.range,G=g.range,j=m.range,z=l.range,q=y.range,Y=v.range,Q=i,V=F,K=E.range,J=b.range,X=T.range,Z=S.range,ee=A.range,te=N.range,ne=w.range,re=O.range,ie=x.range,oe=I.range,ae=M.range,se=A.range,ce=k.range,ue=U.range;e.version="0.1.1",e.milliseconds=F,e.seconds=D,e.minutes=_,e.hours=P,e.days=R,e.sundays=L,e.mondays=$,e.tuesdays=B,e.wednesdays=W,e.thursdays=H,e.fridays=G,e.saturdays=j,e.weeks=z,e.months=q,e.years=Y,e.utcMillisecond=Q,e.utcMilliseconds=V,e.utcSeconds=K,e.utcMinutes=J,e.utcHours=X,e.utcDays=Z,e.utcSundays=ee,e.utcMondays=te,e.utcTuesdays=ne,e.utcWednesdays=re,e.utcThursdays=ie,e.utcFridays=oe,e.utcSaturdays=ae,e.utcWeeks=se,e.utcMonths=ce,e.utcYears=ue,e.millisecond=i,e.second=o,e.minute=a,e.hour=s,e.day=c,e.sunday=l,e.monday=d,e.tuesday=f,e.wednesday=p,e.thursday=h,e.friday=g,e.saturday=m,e.week=l,e.month=y,e.year=v,e.utcSecond=E,e.utcMinute=b,e.utcHour=T,e.utcDay=S,e.utcSunday=A,e.utcMonday=N,e.utcTuesday=w,e.utcWednesday=O,e.utcThursday=x,e.utcFriday=I,e.utcSaturday=M,e.utcWeek=A,e.utcMonth=k,e.utcYear=U,e.interval=r}(t)}),Or=new Date,xr=new Date(0,0,1).setFullYear(0),Ir=new Date(Date.UTC(0,0,1)).setUTCFullYear(0);function Mr(e){return Or.setTime(+e),Or}function kr(e,t,n,r,i,o){var a={type:e,date:t,unit:n};return r?a.step=r:a.minstep=1,null!=i&&(a.min=i),null!=o&&(a.max=o),a}function Ur(e,t,n,r,i,o){return kr(e,function(e){return t.offset(n,e)},function(e){return t.count(n,e)},r,i,o)}var Fr=[Ur("second",wr.second,xr),Ur("minute",wr.minute,xr),Ur("hour",wr.hour,xr),Ur("day",wr.day,xr,[1,7]),Ur("month",wr.month,xr,[1,3,6]),Ur("year",wr.year,xr),kr("seconds",function(e){return new Date(1970,0,1,0,0,e)},function(e){return Mr(e).getSeconds()},null,0,59),kr("minutes",function(e){return new Date(1970,0,1,0,e)},function(e){return Mr(e).getMinutes()},null,0,59),kr("hours",function(e){return new Date(1970,0,1,e)},function(e){return Mr(e).getHours()},null,0,23),kr("weekdays",function(e){return new Date(1970,0,4+e)},function(e){return Mr(e).getDay()},[1],0,6),kr("dates",function(e){return new Date(1970,0,e)},function(e){return Mr(e).getDate()},[1],1,31),kr("months",function(e){return new Date(1970,e%12,1)},function(e){return Mr(e).getMonth()},[1],0,11)],Dr=[Ur("second",wr.utcSecond,Ir),Ur("minute",wr.utcMinute,Ir),Ur("hour",wr.utcHour,Ir),Ur("day",wr.utcDay,Ir,[1,7]),Ur("month",wr.utcMonth,Ir,[1,3,6]),Ur("year",wr.utcYear,Ir),kr("seconds",function(e){return new Date(Date.UTC(1970,0,1,0,0,e))},function(e){return Mr(e).getUTCSeconds()},null,0,59),kr("minutes",function(e){return new Date(Date.UTC(1970,0,1,0,e))},function(e){return Mr(e).getUTCMinutes()},null,0,59),kr("hours",function(e){return new Date(Date.UTC(1970,0,1,e))},function(e){return Mr(e).getUTCHours()},null,0,23),kr("weekdays",function(e){return new Date(Date.UTC(1970,0,4+e))},function(e){return Mr(e).getUTCDay()},[1],0,6),kr("dates",function(e){return new Date(Date.UTC(1970,0,e))},function(e){return Mr(e).getUTCDate()},[1],1,31),kr("months",function(e){return new Date(Date.UTC(1970,e%12,1))},function(e){return Mr(e).getUTCMonth()},[1],0,11)],_r=[[31536e6,5],[7776e6,4],[2592e6,4],[12096e5,3],[6048e5,3],[1728e5,3],[864e5,3],[432e5,2],[216e5,2],[108e5,2],[36e5,2],[18e5,1],[9e5,1],[3e5,1],[6e4,1],[3e4,0],[15e3,0],[5e3,0],[1e3,0]];function Pr(e){var t,n,r={};for(t=0,n=e.length;t(s=_r[i])[0]){if((a=t/s[0])>r)return e[_r[i-1][1]];if(a>=n)return e[s[1]]}return e[_r[o-1][1]]}(e,t,n,r)},r}var Rr=Pr(Fr),Lr=Pr(Dr);Rr.utc=Lr;var $r=1e-15;function Br(e){if(!e)throw Error("Missing binning options.");var t,n,r,i,o,a,s,c=e.maxbins||15,u=e.base||10,l=Math.log(u),d=e.div||[5,2],f=e.min,p=e.max,h=p-f;if(e.step)t=e.step;else if(e.steps)t=e.steps[Math.min(e.steps.length-1,function(e,t,n,r){for(;n>>1;_t.cmp(e[i],t)<0?n=i+1:r=i}return n}(e.steps,h/c,0,e.steps.length))];else{for(n=Math.ceil(Math.log(c)/l),r=e.minstep||0,t=Math.max(r,Math.pow(u,Math.round(Math.log(h)/l)-n));Math.ceil(h/t)>c;)t*=u;for(a=0;a=r&&h/o<=c&&(t=o)}return i=(o=Math.log(t))>=0?0:1+~~(-o/l),s=Math.pow(u,-i-1),{start:f=Math.min(f,Math.floor(f/t+s)*t),stop:p=Math.ceil(p/t)*t,step:t,unit:{precision:i},value:Wr,index:Hr}}function Wr(e){return this.step*Math.floor(e/this.step+$r)}function Hr(e){return Math.floor((e-this.start)/this.step+$r)}function Gr(e){return this.unit.date(Wr.call(this,e))}function jr(e){return Hr.call(this,this.unit.unit(e))}Br.date=function(e){if(!e)throw Error("Missing date binning options.");var t=e.utc?Rr.utc:Rr,n=e.min,r=e.max,i=e.maxbins||20,o=e.minbins||4,a=+r-+n,s=e.unit?t[e.unit]:t.find(a,o,i),c=Br({min:null!=s.min?s.min:s.unit(n),max:null!=s.max?s.max:s.unit(r),maxbins:i,minstep:s.minstep,steps:s.step});return c.unit=s,c.index=jr,e.raw||(c.value=Gr),c};var zr=Br,qr="__types__",Yr={boolean:_t.boolean,integer:_t.number,number:_t.number,date:_t.date,string:function(e){return null==e||""===e?null:e+""}},Qr={boolean:function(e){return"true"===e||"false"===e||_t.isBoolean(e)},integer:function(e){return Qr.number(e)&&(e=+e)==~~e},number:function(e){return!isNaN(+e)&&!_t.isDate(e)},date:function(e){return!isNaN(Date.parse(e))}};function Vr(e){return _t.keys(e)}function Kr(e){return"["+e+"]"}function Jr(e,t){var n,r,i;if(e=_t.array(e),t=_t.$(t),e[qr]&&(n=t(e[qr]),_t.isString(n)))return n;for(r=0,i=e.length;!_t.isValid(n)&&rt;)i.push(r);else for(;(r=e+n*++o)=e&&t<=n?1/r:0},i.cdf=function(t){return tn?1:(t-e)/r},i.icdf=function(t){return t>=0&&t<=1?e+t*r:NaN},i},t.random.integer=function(e,n){void 0===n&&(n=e,e=0);var r=n-e,i=function(){return e+Math.floor(r*Math.random())};return i.samples=function(e){return t.zeros(e).map(i)},i.pdf=function(t){return t===Math.floor(t)&&t>=e&&t=n?1:(i-e+1)/r},i.icdf=function(t){return t>=0&&t<=1?e-1+Math.floor(t*r):NaN},i},t.random.normal=function(e,n){var r;e=e||0,n=n||1;var i=function(){var t,i,o=0,a=0;if(void 0!==r)return o=r,r=void 0,o;do{t=(o=2*Math.random()-1)*o+(a=2*Math.random()-1)*a}while(0===t||t>1);return i=Math.sqrt(-2*Math.log(t)/t),r=e+a*i*n,e+o*i*n};return i.samples=function(e){return t.zeros(e).map(i)},i.pdf=function(t){var r=Math.exp(Math.pow(t-e,2)/(-2*Math.pow(n,2)));return 1/(n*Math.sqrt(2*Math.PI))*r},i.cdf=function(t){var r,i=(t-e)/n,o=Math.abs(i);if(o>37)r=0;else{var a=Math.exp(-o*o/2);o<7.07106781186547?(r=a*((((((.0352624965998911*o+.700383064443688)*o+6.37396220353165)*o+33.912866078383)*o+112.079291497871)*o+221.213596169931)*o+220.206867912376),r/=((((((.0883883476483184*o+1.75566716318264)*o+16.064177579207)*o+86.7807322029461)*o+296.564248779674)*o+637.333633378831)*o+793.826512519948)*o+440.413735824752):r=a/(o+1/(o+2/(o+3/(o+4/(o+.65)))))/2.506628274631}return i>0?1-r:r},i.icdf=function(t){if(t<=0||t>=1)return NaN;var r=2*t-1,i=8*(Math.PI-3)/(3*Math.PI*(4-Math.PI)),o=2/(Math.PI*i)+Math.log(1-Math.pow(r,2))/2,a=Math.log(1-r*r)/i,s=(r>0?1:-1)*Math.sqrt(Math.sqrt(o*o-a)-o);return e+n*Math.SQRT2*s},i},t.random.bootstrap=function(e,n){var r=e.filter(_t.isValid),i=r.length,o=n?t.random.normal(0,n):null,a=function(){return r[~~(Math.random()*i)]+(o?o():0)};return a.samples=function(e){return t.zeros(e).map(a)},a}}),ni=n(function(e){var t=e.exports;function n(e,n,r){var i=e&&e.nullh||0,o=ti.random.normal(0,1),a=t.mean(n,r),s=t.stdev(n,r)/Math.sqrt(t.count.valid(n,r));if(0===s)return a-i==0?1:0;var c=(a-i)/s;return 2*o.cdf(-Math.abs(c))}function r(e,n,r,i){var o,a=i?n.map(_t.$(r)):n,s=i?n.map(_t.$(i)):r,c=t.count(a),u=t.count(s),l=Array();if(c!==u)throw Error("Array lengths must match.");for(o=0;o0?Math.pow(a,1/n):0},t.mean.harmonic=function(e,t){t=_t.$(t);var n,r,i,o,a=0;for(o=0,n=0,r=e.length;or&&(r=i));return[n,r]},t.extent.index=function(e,t){t=_t.$(t);var n,r,i,o,a=-1,s=-1,c=e.length;for(o=0;or&&(r=i,s=o));return[a,s]},t.dot=function(e,t,n){var r,i,o=0;if(n)for(t=_t.$(t),n=_t.$(n),r=0;r-1&&u!==r){for(i=1+(n-1+c)/2;c-1)for(i=1+(a-1+c)/2;cp)&&(p=s),h+=(r=s-c)*(s-(c+=r/++u)),g.push(s));return h/=u-1,i=Math.sqrt(h),g.sort(_t.cmp),{type:Zr(e,n),unique:m,count:e.length,valid:u,missing:l,distinct:d,min:f,max:p,mean:c,stdev:i,median:a=t.quantile(g,.5),q1:t.quantile(g,.25),q3:t.quantile(g,.75),modeskew:0===i?0:(c-a)/i}},t.summary=function(e,n){var r=(n=n||_t.keys(e[0])).map(function(n){var r=t.profile(e,_t.$(n));return r.field=n,r});return r.__summary__=!0,r}}).summary;const ri=zr;const ii={nominal:0,key:1,ordinal:2,temporal:3,quantitative:4};class oi{constructor(e){this._tableSchema=e,e.fields.sort(function(e,t){return ii[e.vlType]ii[t.vlType]?1:e.name.localeCompare(t.name)}),e.fields.forEach((e,t)=>e.index=t),this._fieldSchemaIndex=e.fields.reduce((e,t)=>(e[t.name]=t,e),{})}fieldNames(){return this._tableSchema.fields.map(e=>e.name)}get fieldSchemas(){return this._tableSchema.fields}fieldSchema(e){return this._fieldSchemaIndex[e]}tableSchema(){const e=$t(this._tableSchema);return e.fields.sort((e,t)=>e.originalIndex-t.originalIndex),e}primitiveType(e){return this._fieldSchemaIndex[e]?this._fieldSchemaIndex[e].type:null}vlType(e){return this._fieldSchemaIndex[e]?this._fieldSchemaIndex[e].vlType:null}cardinality(e,t=!0,n=!1){const r=this._fieldSchemaIndex[e.field];if(e.aggregate||gr(e)&&e.autoCount)return 1;if(e.bin){let t;const n=(t="boolean"==typeof e.bin?{maxbins:Nn(e.channel)}:"?"===e.bin?{enum:[!0,!1]}:e.bin).maxbins;return r.binStats[n]||(r.binStats[n]=ai(n,r.stats)),r.binStats[n].distinct}if(e.timeUnit){if(t)switch(e.timeUnit){case St.SECONDS:case St.MINUTES:return 60;case St.HOURS:return 24;case St.DAY:return 7;case St.DATE:return 31;case St.MONTH:return 12;case St.QUARTER:return 4;case St.MILLISECONDS:return 1e3}let i=e.timeUnit,o=r.timeStats;return o&&o[i]||(o=Object.assign({},o,{[i]:si(e.timeUnit,r.stats)})),n?o[i].distinct-ci(o[i].unique,["Invalid Date",null]):o[i].distinct}return r?n?r.stats.distinct-ci(r.stats.unique,[NaN,null]):r.stats.distinct:null}timeUnitHasVariation(e){if(!e.timeUnit)return;if(e.timeUnit===St.DAY){const t=Bt({},e,{timeUnit:St.DATE});if(this.cardinality(t,!1,!0)<=1)return!1}let t=e.timeUnit;for(let n of At)if(Dt(t,n)){const t=Bt({},e,{timeUnit:n});if(this.cardinality(t,!1,!0)<=1)return!1}return!0}domain(e){const t=this._fieldSchemaIndex[e.field];let n=Lt(t.stats.unique);return t.vlType===Te?[+t.stats.min,+t.stats.max]:t.type===ui.DATETIME?[t.stats.min,t.stats.max]:t.type===ui.INTEGER||t.type===ui.NUMBER?(n=n.map(e=>+e)).sort(Rt):t.vlType===Se&&t.ordinalDomain?t.ordinalDomain:n.map(e=>"null"===e?null:e).sort(Rt)}stats(e){const t=this._fieldSchemaIndex[e.field];return t?t.stats:null}}function ai(e,t){const n=ri({min:t.min,max:t.max,maxbins:e}),r=Bt({},t);return r.unique=function(e,t){const n={};for(let r in t){let i;i=null===r?null:isNaN(Number(r))?NaN:e.value(Number(r)),n[i]=(n[i]||0)+t[r]}return n}(n,t.unique),r.distinct=(n.stop-n.start)/n.step,r.min=n.start,r.max=n.stop,r}function si(e,t){const n=Bt({},t);let r={};return Lt(t.unique).forEach(function(n){let i,o="null"===n?null:new Date(n);i=null===o?null:isNaN(o.getTime())?"Invalid Date":(e===St.DAY?o.getDay():Ut(e,o)).toString(),r[i]=(r[i]||0)+t.unique[n]}),n.unique=r,n.distinct=Lt(r).length,n}function ci(e,t){return t.reduce(function(t,n){return e[n]?t+1:t},0)}var ui;!function(e){e[e.STRING="string"]="STRING",e[e.NUMBER="number"]="NUMBER",e[e.INTEGER="integer"]="INTEGER",e[e.BOOLEAN="boolean"]="BOOLEAN",e[e.DATETIME="datetime"]="DATETIME"}(ui||(ui={}));var li=Object.freeze({build:function(e,t={},n={fields:[]}){t=Bt({},gn,t);let r=ni(e),i=ei(e),o=n.fields.reduce((e,t)=>(e[t.name]=t,e),{}),a=r.map(function(n,r){const a=n.field,s="date"===i[a]?ui.DATETIME:i[a];let c,u=n.distinct;if(s===ui.NUMBER)c=Te;else if(s===ui.INTEGER)c=un.max.getTime()&&(n.max=new Date(e))}}else c=Ae;c===Ae&&u/n.count>t.minPercentUniqueForKey&&n.count>t.minCardinalityForKey&&(c=Rn.KEY);let l={name:a,originalIndex:r,vlType:c,type:s,stats:n,timeStats:{},binStats:{}};const d=o[l.name];return l=Bt(l,d)});for(let e of a)if(e.vlType===Te)for(let n of t.enum.binProps.maxbins)e.binStats[n]=ai(n,e.stats);else if(e.vlType===Ce)for(let n of t.enum.timeUnit)void 0!==n&&(e.timeStats[n]=si(n,e.stats));const s=Object.assign({},n,{fields:a});return new oi(s)},Schema:oi,get PrimitiveType(){return ui}});class di{constructor(e){this.constraint=e}name(){return this.constraint.name}description(){return this.constraint.description}properties(){return this.constraint.properties}strict(){return this.constraint.strict}}class fi extends di{constructor(e){super(e)}hasAllRequiredPropertiesSpecific(e){return qt(this.constraint.properties,t=>{if(Ge(t)){let n=t.parent,r=t.child;return!e[n]||!Xt(e[n][r])}return!e[t]||!Xt(e[t])})}satisfy(e,t,n,r){return!this.constraint.allowWildcardForProperties&&!this.hasAllRequiredPropertiesSpecific(e)||this.constraint.satisfy(e,t,n,r)}}const pi=[{name:"aggregateOpSupportedByType",description:"Aggregate function should be supported by data type.",properties:[ft.TYPE,ft.AGGREGATE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!e.aggregate||!$n(e.type)},{name:"asteriskFieldWithCountOnly",description:'Field="*" should be disallowed except aggregate="count"',properties:[ft.FIELD,ft.AGGREGATE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>"*"===e.field==("count"===e.aggregate)},{name:"minCardinalityForBin",description:"binned quantitative field should not have too low cardinality",properties:[ft.BIN,ft.FIELD,ft.TYPE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>{if(e.bin&&e.type===Te){let n={channel:e.channel,field:e.field,type:e.type};return t.cardinality(n)>=r.minCardinalityForBin}return!0}},{name:"binAppliedForQuantitative",description:"bin should be applied to quantitative field only.",properties:[ft.TYPE,ft.BIN],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!e.bin||e.type===Te},{name:"channelFieldCompatible",description:"encoding channel's range type be compatible with channel type.",properties:[ft.CHANNEL,ft.TYPE,ft.BIN,ft.TIMEUNIT],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>{const i=Object.assign({field:"f"},Tr(e,{schema:t,props:["bin","timeUnit","type"]})),{compatible:o}=Pn(i,e.channel);if(o)return!0;return!("row"!==e.channel&&"column"!==e.channel||!Nt(i.timeUnit)&&!Ot(i.timeUnit))}},{name:"hasFn",description:"A field with as hasFn flag should have one of aggregate, timeUnit, or bin.",properties:[ft.AGGREGATE,ft.BIN,ft.TIMEUNIT],allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n,r)=>!e.hasFn||(!!e.aggregate||!!e.bin||!!e.timeUnit)},{name:"omitScaleZeroWithBinnedField",description:"Do not use scale zero with binned field",properties:[ft.SCALE,ct("scale","zero"),ft.BIN],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!e.bin||!e.scale||!0!==e.scale.zero},{name:"onlyOneTypeOfFunction",description:"Only of of aggregate, autoCount, timeUnit, or bin should be applied at the same time.",properties:[ft.AGGREGATE,ft.AUTOCOUNT,ft.TIMEUNIT,ft.BIN],allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n,r)=>{if(hr(e)){return(!Xt(e.aggregate)&&e.aggregate?1:0)+(!Xt(e.bin)&&e.bin?1:0)+(!Xt(e.timeUnit)&&e.timeUnit?1:0)<=1}return!0}},{name:"timeUnitAppliedForTemporal",description:"Time unit should be applied to temporal field only.",properties:[ft.TYPE,ft.TIMEUNIT],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!e.timeUnit||e.type===Ce},{name:"timeUnitShouldHaveVariation",description:"A particular time unit should be applied only if they produce unique values.",properties:[ft.TIMEUNIT,ft.TYPE],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n,r)=>!e.timeUnit||e.type!==Ce||(!n.has("timeUnit")&&!r.constraintManuallySpecifiedValue||t.timeUnitHasVariation(e))},{name:"scalePropertiesSupportedByScaleType",description:"Scale properties must be supported by correct scale type",properties:[].concat(Ze,[ft.SCALE,ft.TYPE]),allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n,r)=>{if(e.scale){const t=e.scale,n=Ar(e);if(null==n)return!0;for(let e in t){if("type"===e||"name"===e||"enum"===e)continue;const t=e;if("point"===n){if(!Le("point",t)&&!Le("band",t))return!1}else if(!Le(n,t))return!1}}return!0}},{name:"scalePropertiesSupportedByChannel",description:"Not all scale properties are supported by all encoding channels",properties:[].concat(Ze,[ft.SCALE,ft.CHANNEL]),allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n,r)=>{if(e){let t=e.channel,n=e.scale;if(t&&!Xt(t)&&n){if("row"===t||"column"===t)return!1;for(let e in n){if(!n.hasOwnProperty(e))continue;if("type"===e||"name"===e||"enum"===e)continue;if(!(void 0===$e(t,e)))return!1}}}return!0}},{name:"typeMatchesPrimitiveType",description:"Data type should be supported by field's primitive type.",properties:[ft.FIELD,ft.TYPE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>{if("*"===e.field)return!0;const i=t.primitiveType(e.field),o=e.type;if(!n.has("field")&&!n.has("type")&&!r.constraintManuallySpecifiedValue)return!0;switch(i){case ui.BOOLEAN:case ui.STRING:return o!==Te&&o!==Ce;case ui.NUMBER:case ui.INTEGER:return o!==Ce;case ui.DATETIME:return o===Ce;case null:return!1}throw new Error("Not implemented")}},{name:"typeMatchesSchemaType",description:"Enumerated data type of a field should match the field's type in the schema.",properties:[ft.FIELD,ft.TYPE],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n,r)=>!(n.has("field")||n.has("type")||r.constraintManuallySpecifiedValue)||("*"===e.field?e.type===Te:t.vlType(e.field)===e.type)},{name:"maxCardinalityForCategoricalColor",description:"Categorical channel should not have too high cardinality",properties:[ft.CHANNEL,ft.FIELD],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n,r)=>e.channel!==P||e.type!==Ae&&e.type!==Rn.KEY||t.cardinality(e)<=r.maxCardinalityForCategoricalColor},{name:"maxCardinalityForFacet",description:"Row/column channel should not have too high cardinality",properties:[ft.CHANNEL,ft.FIELD,ft.BIN,ft.TIMEUNIT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n,r)=>e.channel!==N&&e.channel!==w||t.cardinality(e)<=r.maxCardinalityForFacet},{name:"maxCardinalityForShape",description:"Shape channel should not have too high cardinality",properties:[ft.CHANNEL,ft.FIELD,ft.BIN,ft.TIMEUNIT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n,r)=>e.channel!==$||t.cardinality(e)<=r.maxCardinalityForShape},{name:"dataTypeAndFunctionMatchScaleType",description:"Scale type must match data type",properties:[ft.TYPE,ft.SCALE,ct("scale","type"),ft.TIMEUNIT,ft.BIN],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>{if(e.scale){const t=e.type,n=Ar(e);if($n(t))return void 0===n||De(n);if(t===Ce)return e.timeUnit?zt([Oe.TIME,Oe.UTC,void 0],n)||De(n):zt([Oe.TIME,Oe.UTC,void 0],n);if(t===Te)return e.bin?zt([Oe.LINEAR,void 0],n):zt([Oe.LOG,Oe.POW,Oe.SQRT,Oe.QUANTILE,Oe.QUANTIZE,Oe.LINEAR,void 0],n)}return!0}},{name:"stackIsOnlyUsedWithXY",description:"stack should only be allowed for x and y channels",properties:[ft.STACK,ft.CHANNEL],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!e.stack||(e.channel===x||e.channel===I)}].map(e=>new fi(e)),hi=(pi.reduce((e,t)=>(e[t.name()]=t,e),{}),pi.reduce((e,t)=>{for(const n of t.properties())e.set(n,e.get(n)||[]),e.get(n).push(t);return e},new Bn)),gi=[{name:"doesNotSupportConstantValue",description:"row, column, x, y, order, and detail should not work with constant values.",properties:[ft.TYPE,ft.AGGREGATE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n,r)=>!zt(["row","column","x","y","detail","order"],e.channel)}].map(e=>new fi(e)),mi=(gi.reduce((e,t)=>(e[t.name()]=t,e),{}),gi.reduce((e,t)=>{for(const n of t.properties())e.set(n,e.get(n)||[]),e.get(n).push(t);return e},new Bn));function yi(e,t,n,r,i,o){const a=hi.get(e)||[],s=r.getEncodingQueryByIndex(n);for(const e of a)if(e.strict()||o[e.name()]){if(!e.satisfy(s,i,r.wildcardIndex.encodings[n],o)){let n="(enc) "+e.name();return o.verbose&&console.log(n+" failed with "+r.toShorthand()+" for "+t.name),n}}const c=mi.get(e)||[];for(const e of c)if((e.strict()||o[e.name()])&&pr(s)){if(!e.satisfy(s,i,r.wildcardIndex.encodings[n],o)){let n="(enc) "+e.name();return o.verbose&&console.log(n+" failed with "+r.toShorthand()+" for "+t.name),n}}return null}var vi=Object.freeze({checkEncoding:yi});const Ei=ne.reduce((e,t)=>(e[t]=!0,e),{});class bi extends di{constructor(e){super(e)}hasAllRequiredPropertiesSpecific(e){return qt(this.constraint.properties,t=>{if(t===ft.MARK)return!Xt(e.getMark());if(Ge(t)){let n=t.parent,r=t.child;return qt(e.getEncodings(),e=>!e[n]||!Xt(e[n][r]))}if(!ut(t))throw new Error("UNIMPLEMENTED");return qt(e.getEncodings(),e=>!e[t]||!Xt(e[t]))})}satisfy(e,t,n){return!this.constraint.allowWildcardForProperties&&!this.hasAllRequiredPropertiesSpecific(e)||this.constraint.satisfy(e,t,n)}}const Ti=[{name:"noRepeatedChannel",description:"Each encoding channel should only be used once.",properties:[ft.CHANNEL],allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n)=>{let r={};return qt(e.getEncodings(),e=>!!Xt(e.channel)||!r[e.channel]&&(r[e.channel]=!0,!0))}},{name:"alwaysIncludeZeroInScaleWithBarMark",description:"Do not recommend bar mark if scale does not start at zero",properties:[ft.MARK,ft.SCALE,ct("scale","zero"),ft.CHANNEL,ft.TYPE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n)=>{const r=e.getMark(),i=e.getEncodings();if(r===gt)for(let e of i)if(hr(e)&&(e.channel===x||e.channel===I)&&e.type===Te&&e.scale&&!1===e.scale.zero)return!1;return!0}},{name:"autoAddCount",description:"Automatically adding count only for plots with only ordinal, binned quantitative, or temporal with timeunit fields.",properties:[ft.BIN,ft.TIMEUNIT,ft.TYPE,ft.AUTOCOUNT],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>{if(Qt(e.getEncodings(),e=>yr(e)))return qt(e.getEncodings(),e=>{if(pr(e))return!0;if(gr(e))return!0;switch(e.type){case Te:return!!e.bin;case Ce:return!!e.timeUnit;case Se:case Rn.KEY:case Ae:return!0}throw new Error("Unsupported Type")});if(qt(e.wildcardIndex.encodingIndicesByProperty.get("autoCount")||[],t=>{let n=e.getEncodingQueryByIndex(t);return gr(n)&&!Xt(n.autoCount)}))return Qt(e.getEncodings(),e=>(hr(e)||gr(e))&&e.type===Te?!mr(e)&&(hr(e)&&(!e.bin||Xt(e.bin))):!(!hr(e)||e.type!==Ce)&&(!e.timeUnit||Xt(e.timeUnit)));return!0}},{name:"channelPermittedByMarkType",description:"Each encoding channel should be supported by the mark type",properties:[ft.CHANNEL,ft.MARK],allowWildcardForProperties:!0,strict:!0,satisfy:(e,t,n)=>{const r=e.getMark();return!!Xt(r)||qt(e.getEncodings(),e=>!!Xt(e.channel)||!!se(e.channel,r))}},{name:"hasAllRequiredChannelsForMark",description:"All required channels for the specified mark should be specified",properties:[ft.CHANNEL,ft.MARK],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n)=>{const r=e.getMark();switch(r){case ht:case"line":return e.channelUsed(x)&&e.channelUsed(I);case"text":return e.channelUsed(z);case gt:case yt:case vt:case"tick":case"rule":case"rect":return e.channelUsed(x)||e.channelUsed(I);case mt:return!e.wildcardIndex.hasProperty(ft.CHANNEL)||e.channelUsed(x)||e.channelUsed(I)}throw new Error("hasAllRequiredChannelsForMark not implemented for mark"+JSON.stringify(r))}},{name:"omitAggregate",description:"Omit aggregate plots.",properties:[ft.AGGREGATE,ft.AUTOCOUNT],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>!e.isAggregate()},{name:"omitAggregatePlotWithDimensionOnlyOnFacet",description:"Omit aggregate plots with dimensions only on facets as that leads to inefficient use of space.",properties:[ft.CHANNEL,ft.AGGREGATE,ft.AUTOCOUNT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>{if(e.isAggregate()){let t=!1,r=!1,i=!1;if(e.specQuery.encodings.forEach((n,o)=>{pr(n)||mr(n)||hr(n)&&!n.aggregate&&(r=!0,zt([N,w],n.channel)?e.wildcardIndex.hasEncodingProperty(o,ft.CHANNEL)&&(i=!0):t=!0)}),r&&!t&&(i||n.constraintManuallySpecifiedValue))return!1}return!0}},{name:"omitAggregatePlotWithoutDimension",description:"Aggregate plots without dimension should be omitted",properties:[ft.AGGREGATE,ft.AUTOCOUNT,ft.BIN,ft.TIMEUNIT,ft.TYPE],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>!e.isAggregate()||Qt(e.getEncodings(),e=>!!(Cr(e)||hr(e)&&"temporal"===e.type))},{name:"omitBarLineAreaWithOcclusion",description:"Don't use bar, line or area to visualize raw plot as they often lead to occlusion.",properties:[ft.MARK,ft.AGGREGATE,ft.AUTOCOUNT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>!zt([gt,"line",ht],e.getMark())||e.isAggregate()},{name:"omitBarTickWithSize",description:"Do not map field to size channel with bar and tick mark",properties:[ft.CHANNEL,ft.MARK],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>{const r=e.getMark();if(zt(["tick",gt],r)&&e.channelEncodingField(B)){if(n.constraintManuallySpecifiedValue)return!1;{const t=e.specQuery.encodings;for(let n=0;n{const r=e.getMark(),i=e.getEncodings();if(r===ht||r===gt)for(let e of i)if(hr(e)&&(e.channel===x||e.channel===I)&&e.scale){if(Ar(e)===Oe.LOG)return!1}return!0}},{name:"omitMultipleNonPositionalChannels",description:"Unless manually specified, do not use multiple non-positional encoding channel to avoid over-encoding.",properties:[ft.CHANNEL],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>{const r=e.specQuery.encodings;let i=0,o=!1;for(let t=0;t1&&(o||n.constraintManuallySpecifiedValue)))return!1}return!0}},{name:"omitNonPositionalOrFacetOverPositionalChannels",description:"Do not use non-positional channels unless all positional channels are used",properties:[ft.CHANNEL],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>{const r=e.specQuery.encodings;let i=!1,o=!1,a=!1,s=!1;for(let t=0;t!!e.isAggregate()},{name:"omitRawContinuousFieldForAggregatePlot",description:"Aggregate plot should not use raw continuous field as group by values. (Quantitative should be binned. Temporal should have time unit.)",properties:[ft.AGGREGATE,ft.AUTOCOUNT,ft.TIMEUNIT,ft.BIN,ft.TYPE],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>{if(e.isAggregate()){const t=e.specQuery.encodings;for(let r=0;r!!e.isAggregate()||qt(e.specQuery.encodings,(t,r)=>!(!pr(t)&&!mr(t))||(t.channel!==Y||!e.wildcardIndex.hasEncodingProperty(r,ft.CHANNEL)&&!n.constraintManuallySpecifiedValue))},{name:"omitRepeatedField",description:"Each field should be mapped to only one channel",properties:[ft.FIELD],allowWildcardForProperties:!0,strict:!1,satisfy:(e,t,n)=>{let r={},i={};const o=e.specQuery.encodings;for(let t=0;t{const r=e.getEncodings();return 1!==r.length||r[0].channel!==I}},{name:"hasAppropriateGraphicTypeForMark",description:"Has appropriate graphic type for mark",properties:[ft.CHANNEL,ft.MARK,ft.TYPE,ft.TIMEUNIT,ft.BIN,ft.AGGREGATE,ft.AUTOCOUNT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>{const r=e.getMark();switch(r){case ht:case"line":if(e.isAggregate()){const t=e.getEncodingQueryByChannel(x),n=e.getEncodingQueryByChannel(I),r=Sr(t),i=Sr(n);return t&&n&&r!==i&&!(hr(t)&&!r&&zt(["nominal","key"],t.type))&&!(hr(n)&&!i&&zt(["nominal","key"],n.type))}return!0;case"text":return!0;case gt:case"tick":if(e.channelEncodingField(B))return!1;{const t=e.getEncodingQueryByChannel(x),n=e.getEncodingQueryByChannel(I);return Sr(t)!==Sr(n)}case"rect":const t=e.getEncodingQueryByChannel(x),n=e.getEncodingQueryByChannel(I),i=Cr(t),o=Cr(n),a=e.getEncodingQueryByChannel(P),s=Sr(a),c=!!hr(a)&&a.type===Se,u=i&&o||i&&!e.channelUsed(I)||o&&!e.channelUsed(x),l=!a||a&&(s||c);return u&&l;case yt:case mt:case vt:case"rule":return!0}throw new Error("hasAllRequiredChannelsForMark not implemented for mark"+r)}},{name:"omitInvalidStackSpec",description:"If stack is specified, must follow Vega-Lite stack rules",properties:[ft.STACK,ft.FIELD,ft.CHANNEL,ft.MARK,ft.AGGREGATE,ft.AUTOCOUNT,ft.SCALE,ct("scale","type"),ft.TYPE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n)=>{if(!e.wildcardIndex.hasProperty(ft.STACK))return!0;const r=e.getVlStack();return(null!==r||null===e.getStackOffset())&&r.fieldChannel===e.getStackChannel()}},{name:"omitNonSumStack",description:"Stack specifications that use non-summative aggregates should be omitted (even implicit ones)",properties:[ft.CHANNEL,ft.MARK,ft.AGGREGATE,ft.AUTOCOUNT,ft.SCALE,ct("scale","type"),ft.TYPE],allowWildcardForProperties:!1,strict:!0,satisfy:(e,t,n)=>{const r=e.getVlStack();if(null!=r){const t=e.getEncodingQueryByChannel(r.fieldChannel);if(!zt(Sn,t.aggregate))return!1}return!0}},{name:"omitTableWithOcclusionIfAutoAddCount",description:"Plots without aggregation or autocount where x and y are both discrete should be omitted if autoAddCount is enabled as they often lead to occlusion",properties:[ft.CHANNEL,ft.TYPE,ft.TIMEUNIT,ft.BIN,ft.AGGREGATE,ft.AUTOCOUNT],allowWildcardForProperties:!1,strict:!1,satisfy:(e,t,n)=>{if(n.autoAddCount){const t=e.getEncodingQueryByChannel("x"),n=e.getEncodingQueryByChannel("y");if((!hr(t)||Cr(t))&&(!hr(n)||Cr(n)))return!!e.isAggregate()&&qt(e.getEncodings(),e=>{let t=e.channel;return!(t!==x&&t!==I&&t!==N&&t!==w&&hr(e)&&!e.aggregate)})}return!0}}].map(e=>new bi(e)),Si=Ti.reduce((e,t)=>(e[t.name()]=t,e),{}),Ci=Ti.reduce((e,t)=>{for(const n of t.properties())e.set(n,e.get(n)||[]),e.get(n).push(t);return e},new Bn);function Ai(e,t,n,r,i){const o=Ci.get(e)||[];for(const e of o)if(e.strict()||i[e.name()]){if(!e.satisfy(n,r,i)){let r="(spec) "+e.name();return i.verbose&&console.log(r+" failed with "+n.toShorthand()+" for "+t.name),r}}return null}var Ni=Object.freeze({SpecConstraintModel:bi,SPEC_CONSTRAINTS:Ti,SPEC_CONSTRAINT_INDEX:Si,checkSpec:Ai}),wi=Object.freeze({encoding:vi,spec:Ni});const Oi=new Bn;function xi(e){return Oi.get(e)}function Ii(e){return(t,n,r)=>(i,o)=>{const a=t.encodingIndicesByProperty.get(e);return function s(c){if(c===a.length)return void i.push(o.duplicate());const u=a[c],l=t.encodings[u].get(e),d=o.getEncodingQueryByIndex(u),f=o.getEncodingProperty(u,e);pr(d)||mr(d)||!f?s(c+1):(l.enum.forEach(t=>{null===t&&(t=void 0),o.setEncodingProperty(u,e,t,l),yi(e,l,u,o,n,r)||Ai(e,l,o,n,r)||s(c+1)}),o.resetEncodingProperty(u,e,l))}(0),i}}Oi.set("mark",(e,t,n)=>(r,i)=>{return i.getMark().enum.forEach(o=>{i.setMark(o),Ai("mark",e.mark,i,t,n)||r.push(i.duplicate())}),i.resetMark(),r}),ze.forEach(e=>{Oi.set(e,Ii(e))}),nt.forEach(e=>{Oi.set(e,Ii(e))});var Mi=Object.freeze({getEnumerator:xi,EncodingPropertyGeneratorFactory:Ii});function ki(e){return Wt(e)&&!!e.property}function Ui(e,t,n){return t=t||new Bn,n=n||new Bn,e.forEach(e=>{ki(e)?(t.setByKey(e.property,!0),n.setByKey(e.property,e.replace)):t.setByKey(e,!0)}),{include:t,replaceIndex:n,replacer:er(n)}}const Fi=[ft.FIELD,ft.TYPE,ft.AGGREGATE,ft.BIN,ft.TIMEUNIT,ft.STACK],Di=Fi.concat([{property:ft.CHANNEL,replace:{x:"xy",y:"xy",color:"style",size:"style",shape:"style",opacity:"style",row:"facet",column:"facet"}}]);var _i=Object.freeze({REPLACE_BLANK_FIELDS:{"*":""},REPLACE_XY_CHANNELS:{x:"xy",y:"xy"},REPLACE_FACET_CHANNELS:{row:"facet",column:"facet"},REPLACE_MARK_STYLE_CHANNELS:{color:"style",opacity:"style",shape:"style",size:"style"},isExtendedGroupBy:ki,parseGroupBy:Ui,toString:function(e){return Pt(e)?e.map(e=>{if(ki(e)){if(e.replace){let t=Lt(e.replace).reduce((t,n)=>{const r=e.replace[n];return(t[r]=t[r]||[]).push(n),t},{});return e.property+"["+Lt(t).map(e=>t[e].sort().join(",")+"=>"+e).join(";")+"]"}return e.property}return e}).join(","):e},GROUP_BY_FIELD_TRANSFORM:Fi,GROUP_BY_ENCODING:Di});let Pi={};function Ri(e,t){Pi[e]=t}function Li(e,t){if(t){const n={name:"",path:"",items:[]};let r={},i=[],o=[],a=[];for(let e=0;e0?i[e-1].duplicate():new Bn),o.push(e>0?o[e-1].duplicate():new Bn);const n=t[e].groupBy;if(Pt(n)){let t=Ui(n,i[e],o[e]);a.push(t.replacer)}}return e.forEach(e=>{let o="",s=n;for(let n=0;nsr(e,$i.include,$i.replacer));const Wi=Ui(Fi);Ri("fieldTransform",e=>sr(e,Wi.include,Wi.replacer));const Hi=Ui(Di);Ri("encoding",e=>sr(e,Hi.include,Hi.replacer)),Ri("spec",e=>JSON.stringify(e));var Gi=Object.freeze({registerKeyFn:Ri,FIELD:"field",FIELD_TRANSFORM:"fieldTransform",ENCODING:"encoding",SPEC:"spec",nest:Li,getGroupByKey:Bi,PARSED_GROUP_BY_FIELD_TRANSFORM:Wi,PARSED_GROUP_BY_ENCODING:Hi});class ji{constructor(){this._mark=void 0,this._encodings={},this._encodingIndicesByProperty=new Bn}setEncodingProperty(e,t,n){const r=this._encodings;(r[e]=r[e]||new Bn).set(t,n);const i=this._encodingIndicesByProperty;return i.set(t,i.get(t)||[]),i.get(t).push(e),this}hasEncodingProperty(e,t){return!!this._encodings[e]&&this._encodings[e].has(t)}hasProperty(e){if(ut(e))return this.encodingIndicesByProperty.has(e);if("mark"===e)return!!this.mark;throw new Error("Unimplemented for property "+e)}isEmpty(){return!this.mark&&0===this.encodingIndicesByProperty.size()}setMark(e){return this._mark=e,this}get mark(){return this._mark}get encodings(){return this._encodings}get encodingIndicesByProperty(){return this._encodingIndicesByProperty}}class zi{constructor(e,t,n,r,i){this._rankingScore={},this._spec=e,this._channelFieldCount=e.encodings.reduce((e,t)=>(Xt(t.channel)||gr(t)&&!1===t.autoCount||(e[t.channel+""]=1),e),{}),this._wildcardIndex=t,this._assignedWildcardIndex=i,this._opt=r,this._schema=n}static build(e,t,n){let r=new ji;if(Xt(e.mark)){const t=on(ft.MARK);e.mark=tn(e.mark,t,n.enum.mark),r.setMark(e.mark)}if(e.encodings.forEach((e,i)=>{gr(e)&&(console.warn("A field with autoCount should not be included as autoCount meant to be an internal object."),e.type=Te),hr(e)&&void 0===e.type&&(e.type=Jt),ze.forEach(o=>{if(Xt(e[o])){const a=on(o)+i,s=pn(o,t,n),c=e[o]=tn(e[o],a,s);r.setEncodingProperty(i,o,c)}}),nt.forEach(o=>{const a=e[o.parent];if(a){const e=o.child;if(Xt(a[e])){const s=on(o)+i,c=pn(o,t,n),u=a[e]=tn(a[e],s,c);r.setEncodingProperty(i,o,u)}}})}),n.autoAddCount){const i={name:on(ft.CHANNEL)+e.encodings.length,enum:pn(ft.CHANNEL,t,n)},o={name:on(ft.AUTOCOUNT)+e.encodings.length,enum:[!1,!0]},a={channel:i,autoCount:o,type:Te};e.encodings.push(a);const s=e.encodings.length-1;r.setEncodingProperty(s,ft.CHANNEL,i),r.setEncodingProperty(s,ft.AUTOCOUNT,o)}return new zi(e,r,t,n,{})}get wildcardIndex(){return this._wildcardIndex}get schema(){return this._schema}get specQuery(){return this._spec}duplicate(){return new zi($t(this._spec),this._wildcardIndex,this._schema,this._opt,$t(this._assignedWildcardIndex))}setMark(e){const t=this._wildcardIndex.mark.name;this._assignedWildcardIndex[t]=this._spec.mark=e}resetMark(){const e=this._spec.mark=this._wildcardIndex.mark;delete this._assignedWildcardIndex[e.name]}getMark(){return this._spec.mark}getEncodingProperty(e,t){const n=this._spec.encodings[e];return Ge(t)?n[t.parent][t.child]:n[t]}setEncodingProperty(e,t,n,r){const i=this._spec.encodings[e];t===ft.CHANNEL&&i.channel&&!Xt(i.channel)&&this._channelFieldCount[i.channel]--,Ge(t)?i[t.parent][t.child]=n:Qe(t)&&!0===n?i[t]=Bt({},i[t],{enum:void 0,name:void 0}):i[t]=n,this._assignedWildcardIndex[r.name]=n,t===ft.CHANNEL&&(this._channelFieldCount[n]=(this._channelFieldCount[n]||0)+1)}resetEncodingProperty(e,t,n){const r=this._spec.encodings[e];t===ft.CHANNEL&&this._channelFieldCount[r.channel]--,Ge(t)?r[t.parent][t.child]=n:r[t]=n,delete this._assignedWildcardIndex[n.name]}channelUsed(e){return this._channelFieldCount[e]>0}channelEncodingField(e){return hr(this.getEncodingQueryByChannel(e))}getEncodings(){return this._spec.encodings.filter(e=>!mr(e))}getEncodingQueryByChannel(e){for(let t of this._spec.encodings)if(t.channel===e)return t}getEncodingQueryByIndex(e){return this._spec.encodings[e]}isAggregate(){return Yn(this._spec)}getVlStack(){return Qn(this._spec)}getStackOffset(){return Vn(this._spec)}getStackChannel(){return Kn(this._spec)}toShorthand(e){if(e){if(jt(e))return Bi(this.specQuery,e);const t=Ui(e);return sr(this._spec,t.include,t.replacer)}return sr(this._spec)}toSpec(e){if(Xt(this._spec.mark))return null;let t={};return(e=e||this._spec.data)&&(t.data=e),this._spec.transform&&(t.transform=this._spec.transform),t.mark=this._spec.mark,t.encoding=Er(this.specQuery.encodings,{schema:this._schema,wildcardMode:"null"}),this._spec.width&&(t.width=this._spec.width),this._spec.height&&(t.height=this._spec.height),this._spec.background&&(t.background=this._spec.background),this._spec.padding&&(t.padding=this._spec.padding),this._spec.title&&(t.title=this._spec.title),null===t.encoding?null:((this._spec.config||this._opt.defaultSpecConfig)&&(t.config=Bt({},this._opt.defaultSpecConfig,this._spec.config)),t)}getRankingScore(e){return this._rankingScore[e]}setRankingScore(e,t){this._rankingScore[e]=t}}var qi=Object.freeze({SpecQueryModel:zi}),Yi=Object.freeze({});function Qi(e){if(e.groupBy){let t={groupBy:e.groupBy};e.orderBy&&(t.orderGroupBy=e.orderBy);let n={spec:$t(e.spec),nest:[t]};return e.chooseBy&&(n.chooseBy=e.chooseBy),e.config&&(n.config=e.config),n}return $t(e)}var Vi=Object.freeze({encoding:Nr,groupBy:_i,shorthand:fr,spec:Zn,transform:Yi,normalize:Qi});function Ki(e){return void 0!==e.items}function Ji(e){let t=e.items[0];for(;t&&Ki(t);)t=t.items[0];return t}var Xi,Zi=Object.freeze({isResultTree:Ki,getTopResultTreeItem:Ji,mapLeaves:function e(t,n){return Object.assign({},t,{items:t.items.map(t=>Ki(t)?e(t,n):n(t))})}});class eo{constructor(e){this.type=e,this.scoreIndex=this.initScore()}getFeatureScore(e){const t=this.type,n=this.scoreIndex[e];if(void 0!==n)return{type:t,feature:e,score:n}}}!function(e){e[e.Q=Te]="Q",e[e.BIN_Q="bin_"+Te]="BIN_Q",e[e.T=Ce]="T",e[e.TIMEUNIT_T="timeUnit_time"]="TIMEUNIT_T",e[e.TIMEUNIT_O="timeUnit_"+Se]="TIMEUNIT_O",e[e.O=Se]="O",e[e.N=Ae]="N",e[e.K=Rn.KEY]="K",e[e.NONE="-"]="NONE"}(Xi||(Xi={}));const to=Xi.Q,no=Xi.BIN_Q,ro=Xi.T,io=Xi.TIMEUNIT_T,oo=Xi.TIMEUNIT_O,ao=Xi.O,so=Xi.N,co=Xi.K,uo=Xi.NONE;function lo(e){if(e.bin)return Xi.BIN_Q;if(e.timeUnit){return De(Ar(e))?Xi.TIMEUNIT_O:Xi.TIMEUNIT_T}return e.type}const fo=-10;function po(e,t,n,r){return e+"_"+t+"_"+n+"_"+r}const ho=[new class extends eo{constructor(){super("Axis")}initScore(e={}){e=Object.assign({},gn,e);let t={};return[{feature:no,opt:"preferredBinAxis"},{feature:ro,opt:"preferredTemporalAxis"},{feature:io,opt:"preferredTemporalAxis"},{feature:oo,opt:"preferredTemporalAxis"},{feature:ao,opt:"preferredOrdinalAxis"},{feature:so,opt:"preferredNominalAxis"}].forEach(n=>{e[n.opt]===x?t[n.feature+"_"+I]=-.01:e[n.opt]===I&&(t[n.feature+"_"+x]=-.01)}),t}featurize(e,t){return e+"_"+t}getScore(e,t,n){return e.getEncodings().reduce((e,t)=>{if(hr(t)||gr(t)){const n=lo(t),r=this.featurize(n,t.channel),i=this.getFeatureScore(r);i&&e.push(i)}return e},[])}},new class extends eo{constructor(){super("Dimension")}initScore(){return{row:-2,column:-2,color:0,opacity:0,size:0,shape:0}}getScore(e,t,n){return e.isAggregate()&&e.getEncodings().reduce((e,t)=>{if(gr(t)||hr(t)&&!t.aggregate){const n=this.getFeatureScore(t.channel+"");if(n&&n.score>e.score)return n}return e},{type:"Dimension",feature:"No Dimension",score:-5}),[]}},new class extends eo{constructor(){super("Facet")}initScore(e){let t={};return(e=Object.assign({},gn,e)).preferredFacet===N?t[w]=-.01:e.preferredFacet===w&&(t[N]=-.01),t}getScore(e,t,n){return e.getEncodings().reduce((e,t)=>{if(hr(t)||gr(t)){const n=this.getFeatureScore(t.channel);n&&e.push(n)}return e},[])}},new class extends eo{constructor(){super("Mark")}initScore(){return function(){const e=[to,ro],t=[no,oo,ao,so,co].concat([uo]);let n={};e.forEach(t=>{e.forEach(e=>{Yt({point:0,text:-.2,tick:-.5,rect:-1,bar:-2,line:-2,area:-2,rule:-2.5},(r,i)=>{const o=po(t,e,!0,i);n[o]=r}),Yt({point:0,text:-.2,tick:-.5,bar:-2,line:-2,area:-2,rule:-2.5},(r,i)=>{const o=po(t,e,!1,i);n[o]=r})})}),e.forEach(e=>{t.forEach(t=>{Yt({tick:0,point:-.2,text:-.5,bar:-2,line:-2,area:-2,rule:-2.5},(r,i)=>{const o=po(e,t,!0,i);n[o]=r;const a=po(t,e,!0,i);n[a]=r})}),[io].forEach(t=>{Yt({point:0,text:-.5,tick:-1,bar:-2,line:-2,area:-2,rule:-2.5},(r,i)=>{const o=po(e,t,!0,i);n[o]=r;const a=po(t,e,!0,i);n[a]=r})}),[uo,so,ao,co].forEach(t=>{Yt({bar:0,point:-.2,tick:-.25,text:-.3,line:-2,area:-2,rule:-2.5},(r,i)=>{const o=po(e,t,!1,i);n[o]=r;const a=po(t,e,!1,i);n[a]=r})}),[no].forEach(t=>{Yt({bar:0,point:-.2,tick:-.25,text:-.3,line:-.5,area:-.5,rule:-2.5},(r,i)=>{const o=po(e,t,!1,i);n[o]=r;const a=po(t,e,!1,i);n[a]=r})}),[io,oo].forEach(t=>{Yt({line:0,area:-.1,bar:-.2,point:-.3,tick:-.35,text:-.4,rule:-2.5},(r,i)=>{const o=po(e,t,!1,i);n[o]=r;const a=po(t,e,!1,i);n[a]=r})})}),[io].forEach(e=>{[io].forEach(t=>{const r={point:0,rect:-.1,text:-.5,tick:-1,bar:-2,line:-2,area:-2,rule:-2.5};Yt(r,(r,i)=>{const o=po(e,t,!0,i);n[o]=r}),Yt(r,(r,i)=>{const o=po(e,t,!1,i);n[o]=r})}),t.forEach(t=>{const r={tick:0,point:-.2,text:-.5,rect:-1,bar:-2,line:-2,area:-2,rule:-2.5};Yt(r,(r,i)=>{const o=po(e,t,!0,i);n[o]=r}),Yt(r,(r,i)=>{const o=po(t,e,!0,i);n[o]=r}),Yt(r,(r,i)=>{const o=po(e,t,!1,i);n[o]=r}),Yt(r,(r,i)=>{const o=po(t,e,!1,i);n[o]=r})})});for(const e of t)for(const r of t){const t={point:0,rect:0,text:-.1,tick:-1,bar:-2,line:-2,area:-2,rule:-2.5};Yt(t,(t,i)=>{const o=po(e,r,!0,i);n[o]=t}),Yt(t,(t,i)=>{const o=po(e,r,!1,i);n[o]=t})}return n}()}getScore(e,t,n){let r=e.getMark();r!==yt&&r!==vt||(r=mt);const i=e.getEncodingQueryByChannel(x),o=i?lo(i):uo,a=e.getEncodingQueryByChannel(I),s=o+"_"+(a?lo(a):uo)+"_"+!e.isAggregate()+"_"+r,c=this.getFeatureScore(s);return c?[c]:(console.error("feature score missing for",s),[])}},new class extends eo{constructor(){super("SizeChannel")}initScore(){return{bar_size:-2,tick_size:-2}}getScore(e,t,n){const r=e.getMark();return e.getEncodings().reduce((e,t)=>{if(hr(t)||gr(t)){const n=r+"_"+t.channel,i=this.getFeatureScore(n);i&&e.push(i)}return e},[])}},new class extends eo{constructor(){super("TypeChannel")}initScore(){let e={};const t={x:0,y:0,size:-.575,color:-.725,text:-2,opacity:-3,shape:fo,row:fo,column:fo,detail:2*fo};[to,ro,io].forEach(n=>{Lt(t).forEach(r=>{e[this.featurize(n,r)]=t[r]})});const n=Bt({},t,{row:-.75,column:-.75,shape:-3.1,text:-3.2,detail:-4});[no,oo,ao].forEach(t=>{Lt(n).forEach(r=>{e[this.featurize(t,r)]=n[r]})});const r={x:0,y:0,color:-.6,shape:-.65,row:-.7,column:-.7,text:-.8,detail:-2,size:-3,opacity:-3.1};return Lt(r).forEach(t=>{e[this.featurize(so,t)]=r[t],e[this.featurize(co,t)]=zt(["x","y","detail"],t)?-1:r[t]-2}),e}featurize(e,t){return e+"_"+t}getScore(e,t,n){const r=e.getEncodings().reduce((e,t)=>{if(hr(t)||gr(t)){const n=ur(t);(e[n]=e[n]||[]).push(t)}return e},{}),i=[];return Yt(r,e=>{const t=e.reduce((e,t)=>{if(hr(t)||gr(t)){const n=lo(t),r=this.featurize(n,t.channel),i=this.getFeatureScore(r);if(null===e||i.score>e.score)return i}return e},null);i.push(t)}),i}}];function go(e,t,n){const r=ho.reduce((r,i)=>{const o=i.getScore(e,t,n);return r.concat(o)},[]);return{score:r.reduce((e,t)=>e+t.score,0),features:r}}const mo="aggregationQuality";function yo(e,t,n){const r=function(e,t,n){const r=e.getEncodings();if(e.isAggregate()){const e=e=>hr(e)&&(e.type===Te&&!e.bin&&!e.aggregate||e.type===Ce&&!e.timeUnit);if(Qt(r,e))return{type:mo,score:.1,feature:"Aggregate with raw continuous"};if(Qt(r,e=>hr(e)&&Cr(e))){let e=Qt(r,e=>hr(e)&&"count"===e.aggregate||yr(e)),t=Qt(r,e=>hr(e)&&!!e.bin);return e?{type:mo,score:.8,feature:"Aggregate with count"}:t?{type:mo,score:.7,feature:"Aggregate with bin but without count"}:{type:mo,score:.9,feature:"Aggregate without count and without bin"}}return{type:mo,score:.3,feature:"Aggregate without dimension"}}return Qt(r,e=>hr(e)&&!Cr(e))?{type:mo,score:1,feature:"Raw with measure"}:{type:mo,score:.2,feature:"Raw without measure"}}(e);return{score:r.score,features:[r]}}var vo=Object.freeze({name:mo,score:yo});function Eo(e,t,n){const r=e.wildcardIndex.encodingIndicesByProperty.get("field");if(!r)return{score:0,features:[]};const i=e.specQuery.encodings,o=t.fieldSchemas.length,a=[];let s=0,c=1;for(let n=r.length-1;n>=0;n--){const u=r[n],l=i[u];let d;if(!hr(l))continue;d=l.field;const f=e.wildcardIndex.encodings[u].get("field"),p=t.fieldSchema(d).index,h=-p*c;s+=h,a.push({score:h,type:"fieldOrder",feature:`field ${f.name} is ${d} (#${p} in the schema)`}),c*=o}return{score:s,features:a}}var bo=Object.freeze({name:"fieldOrder",score:Eo});let To={};function So(e,t){To[e]=t}function Co(e){return To[e]}function Ao(e,t,n,r){return t.nest&&r!==t.nest.length?(e.items.forEach(e=>{Ao(e,t,n,r+1)}),t.nest[r].orderGroupBy&&e.items.sort(wo(t.nest[r].orderGroupBy,n,t.config))):(t.orderBy||t.chooseBy)&&(e.items.sort(No(t.orderBy||t.chooseBy,n,t.config)),t.chooseBy&&e.items.length>0&&e.items.splice(1)),e}function No(e,t,n){return(r,i)=>e instanceof Array?Oo(e,r,i,t,n):Oo([e],r,i,t,n)}function wo(e,t,n){return(r,i)=>{const o=Ji(r),a=Ji(i);return e instanceof Array?Oo(e,o,a,t,n):Oo([e],o,a,t,n)}}function Oo(e,t,n,r,i){for(let o of e){let e=xo(n,o,r,i).score-xo(t,o,r,i).score;if(0!==e)return e}return 0}function xo(e,t,n,r){if(void 0!==e.getRankingScore(t))return e.getRankingScore(t);const i=Co(t)(e,n,r);return e.setRankingScore(t,i),i}So("effectiveness",go),So(mo,yo),So("fieldOrder",Eo);var Io=Object.freeze({aggregation:vo,fieldOrder:bo,register:So,get:Co,rank:Ao,comparatorFactory:No,groupComparatorFactory:wo,getScore:xo,EFFECTIVENESS:"effectiveness",effectiveness:go});function Mo(e,t,n){let r={};return e=e.map(function(e){return n.smallRangeStepForHighCardinalityOrFacet&&(e=function(e,t,n,r){[N,I,w,x].forEach(t=>{n[t]=e.getEncodingQueryByChannel(t)});const i=n[I];if(void 0!==i&&hr(i)&&(n[N]||t.cardinality(i)>r.smallRangeStepForHighCardinalityOrFacet.maxCardinality)){void 0===i.scale&&(i.scale={});const e=Ar(i);i.scale&&(void 0===e||De(e))&&(i.scale.rangeStep||(i.scale.rangeStep=12))}const o=n[x];if(hr(o)&&(n[w]||t.cardinality(o)>r.smallRangeStepForHighCardinalityOrFacet.maxCardinality)){void 0===o.scale&&(o.scale={});const e=Ar(o);o.scale&&(void 0===e||De(e))&&(o.scale.rangeStep||(o.scale.rangeStep=12))}return e}(e,t,r,n)),n.nominalColorScaleForHighCardinality&&(e=function(e,t,n,r){n[P]=e.getEncodingQueryByChannel(P);const i=n[P];hr(i)&&void 0!==i&&(i.type===Ae||i.type===Rn.KEY)&&t.cardinality(i)>r.nominalColorScaleForHighCardinality.maxCardinality&&(void 0===i.scale&&(i.scale={}),i.scale&&(i.scale.range||(i.scale.scheme=r.nominalColorScaleForHighCardinality.palette)));return e}(e,t,r,n)),n.xAxisOnTopForHighYCardinalityWithoutColumn&&(e=function(e,t,n,r){if([w,x,I].forEach(t=>{n[t]=e.getEncodingQueryByChannel(t)}),void 0===n[w]){const e=n[x],i=n[I];hr(e)&&hr(i)&&void 0!==i&&i.field&&De(Ar(i))&&void 0!==e&&t.cardinality(i)>r.xAxisOnTopForHighYCardinalityWithoutColumn.maxCardinality&&(void 0===e.axis&&(e.axis={}),e.axis&&!e.axis.orient&&(e.axis.orient="top"))}return e}(e,t,r,n)),e})}function ko(e,t,n=gn){const r=zi.build(e,t,n),i=r.wildcardIndex;let o=[r];return n.propertyPrecedence.forEach(e=>{const r=at(e);if(i.hasProperty(r)){const e=xi(r)(i,t,n);o=o.reduce(e,[])}}),!n.stylize||null===n.nominalColorScaleForHighCardinality&&null===n.smallRangeStepForHighCardinalityOrFacet&&null===n.xAxisOnTopForHighYCardinalityWithoutColumn?o:Mo(o,t,n)}e.config=yn,e.constraint=wi,e.enumerate=Mi,e.generate=ko,e.model=qi,e.nest=Gi,e.property=pt,e.query=Vi,e.ranking=Io,e.recommend=function(e,t,n){return{query:e=Object.assign({},Qi(e),{config:Object.assign({},gn,n,e.config)}),result:Ao(Li(ko(e.spec,t,e.config),e.nest),e,t,0)}},e.result=Zi,e.schema=li,e.util=Kt,e.version="0.21.1",e.wildcard=hn,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/build/compassql.min.js.map b/build/compassql.min.js.map new file mode 100644 index 00000000..3f44285f --- /dev/null +++ b/build/compassql.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../node_modules/tslib/tslib.es6.js","../node_modules/clone/clone.js","../node_modules/fast-json-stable-stringify/index.js","../node_modules/vega-util/src/accessor.js","../node_modules/vega-util/src/error.js","../node_modules/vega-util/src/splitAccessPath.js","../node_modules/vega-util/src/isArray.js","../node_modules/vega-util/src/isObject.js","../node_modules/vega-util/src/isString.js","../node_modules/vega-util/src/stringValue.js","../node_modules/vega-util/src/accessors.js","../node_modules/vega-util/src/field.js","../node_modules/vega-util/src/logger.js","../node_modules/vega-util/src/isBoolean.js","../node_modules/vega-util/src/toSet.js","../node_modules/vega-lite/src/util.ts","../node_modules/vega-lite/src/channel.ts","../node_modules/vega-lite/src/axis.ts","../node_modules/vega-lite/src/legend.ts","../node_modules/vega-lite/src/log/index.ts","../node_modules/vega-lite/src/log/message.ts","../node_modules/vega-lite/src/type.ts","../node_modules/vega-lite/src/scale.ts","../src/property.ts","../node_modules/vega-lite/src/mark.ts","../node_modules/vega-lite/src/datetime.ts","../node_modules/vega-lite/src/timeunit.ts","../node_modules/datalib/src/util.js","../src/util.ts","../src/wildcard.ts","../src/config.ts","../node_modules/vega-lite/src/aggregate.ts","../node_modules/vega-lite/src/bin.ts","../node_modules/vega-lite/src/channeldef.ts","../src/query/expandedtype.ts","../node_modules/vega-lite/src/compile/scale/type.ts","../src/propindex.ts","../node_modules/vega-lite/src/encoding.ts","../node_modules/vega-lite/src/stack.ts","../src/query/spec.ts","../src/query/shorthand.ts","../src/query/encoding.ts","../node_modules/d3-time/build/d3-time.js","../node_modules/datalib/src/time.js","../node_modules/datalib/src/bins/bins.js","../node_modules/datalib/src/import/type.js","../node_modules/datalib/src/generate.js","../node_modules/datalib/src/stats.js","../src/schema.ts","../src/constraint/base.ts","../src/constraint/field.ts","../src/constraint/value.ts","../src/constraint/encoding.ts","../src/constraint/spec.ts","../src/enumerator.ts","../src/query/groupby.ts","../src/nest.ts","../src/wildcardindex.ts","../src/model.ts","../src/query/normalize.ts","../src/result.ts","../src/ranking/effectiveness/type.ts","../src/ranking/effectiveness/base.ts","../src/ranking/effectiveness/typechannel.ts","../src/ranking/effectiveness/mark.ts","../src/ranking/effectiveness/index.ts","../src/ranking/effectiveness/axis.ts","../src/ranking/effectiveness/dimension.ts","../src/ranking/effectiveness/facet.ts","../src/ranking/effectiveness/sizechannel.ts","../src/ranking/aggregation.ts","../src/ranking/fieldorder.ts","../src/ranking/ranking.ts","../src/stylize.ts","../src/generate.ts","../src/recommend.ts"],"names":["__rest","s","e","t","p","Object","prototype","hasOwnProperty","call","indexOf","getOwnPropertySymbols","i","length","clone","_instanceof","obj","type","nativeMap","nativeSet","nativePromise","Map","_","Set","Promise","parent","circular","depth","includeNonEnumerable","allParents","allChildren","useBuffer","Buffer","Infinity","_clone","child","proto","resolve","reject","then","value","err","__isArray","__isRegExp","RegExp","source","__getRegExpFlags","lastIndex","__isDate","Date","getTime","isBuffer","allocUnsafe","copy","Error","create","getPrototypeOf","index","push","forEach","key","keyChild","valueChild","set","entryChild","add","attrs","getOwnPropertyDescriptor","symbols","symbol","descriptor","enumerable","defineProperty","allPropertyNames","getOwnPropertyNames","propertyName","__objToStr","o","toString","re","flags","global","ignoreCase","multiline","clonePrototype","c","module","exports","fastJsonStableStringify","data","opts","cmp","f","cycles","node","a","b","aobj","bobj","seen","stringify","toJSON","undefined","isFinite","JSON","out","Array","isArray","TypeError","seenIndex","keys","sort","splice","accessor","fn","fields","name","fname","error","message","splitAccessPath","j","path","q","n","substring","isObject","isString","$","x","map","replace","empty","field","code","stringValue","join","Function","log","method","level","input","msg","concat","slice","console","None","Warn","Info","Debug","isBoolean","toSet","this","stableStringify","contains","array","item","flagKeys","getFirstDefined","args","arg","ROW","COLUMN","FACET","X","Y","X2","Y2","LATITUDE","LONGITUDE","LATITUDE2","LONGITUDE2","COLOR","FILL","STROKE","SHAPE","SIZE","OPACITY","FILLOPACITY","STROKEOPACITY","STROKEWIDTH","TEXT","ORDER","DETAIL","KEY","TOOLTIP","HREF","UNIT_CHANNEL_INDEX","assign","y","x2","y2","longitude","longitude2","latitude","latitude2","color","fill","stroke","opacity","fillOpacity","strokeOpacity","strokeWidth","size","shape","order","text","detail","tooltip","href","isColorChannel","channel","CHANNEL_INDEX","row","column","facet","CHANNELS","NONPOSITION_CHANNEL_INDEX","NONPOSITION_CHANNELS","POSITION_SCALE_CHANNEL_INDEX","NONPOSITION_SCALE_CHANNEL_INDEX","SCALE_CHANNEL_INDEX","isScaleChannel","supportMark","mark","point","tick","rule","circle","square","bar","rect","line","trail","area","geoshape","getSupportedMark","rangeType","COMMON_AXIS_PROPERTIES_INDEX","orient","bandPosition","domain","domainColor","domainDash","domainDashOffset","domainOpacity","domainWidth","format","formatType","grid","gridColor","gridDash","gridDashOffset","gridOpacity","gridWidth","labelAlign","labelAngle","labelBaseline","labelBound","labelColor","labelFlush","labelFlushOffset","labelFont","labelFontSize","labelFontStyle","labelFontWeight","labelLimit","labelOpacity","labelOverlap","labelPadding","labels","labelSeparation","maxExtent","minExtent","offset","position","tickColor","tickCount","tickDash","tickDashOffset","tickExtra","tickMinStep","tickOffset","tickOpacity","tickRound","ticks","tickSize","tickWidth","title","titleAlign","titleAnchor","titleAngle","titleBaseline","titleColor","titleFont","titleFontSize","titleFontStyle","titleFontWeight","titleLimit","titleOpacity","titlePadding","titleX","titleY","values","zindex","AXIS_PROPERTIES_INDEX","encoding","AXIS_PROPERTIES","gridScale","scale","encode","COMMON_LEGEND_PROPERTY_INDEX","clipHeight","columnPadding","columns","cornerRadius","direction","fillColor","gradientLength","gradientOpacity","gradientStrokeColor","gradientStrokeWidth","gradientThickness","gridAlign","labelOffset","legendX","legendY","padding","rowPadding","strokeColor","symbolDash","symbolDashOffset","symbolFillColor","symbolOffset","symbolOpacity","symbolSize","symbolStrokeColor","symbolStrokeWidth","symbolType","titleOrient","LEGEND_PROPERTIES","local","ancestor","transform","channels","opt","parentProjection","projection","scaleType","zeroFalse","aggregate","newType","fieldDef","newChannel","markOrFacet","when","hasX2","hasY2","original","actual","prop","defaultScaleType","propName","property","propertyOf","v1","v2","unitName","fullTimeUnit","d","center","extent","compositeMark","main","arguments","warn","info","debug","current","apply","TYPE_INDEX","quantitative","ordinal","temporal","nominal","geojson","QUANTITATIVE","ORDINAL","TEMPORAL","NOMINAL","GEOJSON","getFullName","toLowerCase","ScaleType","LINEAR","LOG","POW","SQRT","SYMLOG","TIME","UTC","QUANTILE","QUANTIZE","THRESHOLD","BIN_ORDINAL","POINT","BAND","SCALE_TYPES","linear","pow","sqrt","symlog","time","utc","bin-ordinal","band","quantile","quantize","threshold","CONTINUOUS_TO_CONTINUOUS_SCALES","CONTINUOUS_TO_CONTINUOUS_INDEX","CONTINUOUS_TO_DISCRETE_INDEX","CONTINUOUS_DOMAIN_INDEX","DISCRETE_DOMAIN_INDEX","hasDiscreteDomain","isContinuousToContinuous","SCALE_PROPERTY_INDEX","range","rangeStep","scheme","bins","reverse","round","clamp","nice","base","exponent","constant","interpolate","zero","paddingInner","paddingOuter","SCALE_PROPERTIES","fieldDefType","generateScaleTypeIndexKey","channelSupportScaleType","scaleTypeSupportDataType","generateScaleTypeIndex","scaleTypeSupportProperty","channelScalePropertyIncompatability","log.message","cannotUseScalePropertyWithNonColor","specifiedType","TYPE.ORDINAL","TYPE.NOMINAL","TYPE.TEMPORAL","TYPE.QUANTITATIVE","CHANNEL.X","CHANNEL.Y","CHANNEL.SIZE","CHANNEL.STROKEWIDTH","CHANNEL.OPACITY","CHANNEL.FILLOPACITY","CHANNEL.STROKEOPACITY","CHANNEL.COLOR","CHANNEL.FILL","CHANNEL.STROKE","CHANNEL.SHAPE","isEncodingNestedProp","ENCODING_TOPLEVEL_PROP_INDEX","autoCount","bin","timeUnit","hasFn","stack","axis","legend","ENCODING_TOPLEVEL_PROPS","isEncodingTopLevelProperty","ENCODING_NESTED_PROP_PARENT_INDEX","isEncodingNestedParent","BIN_CHILD_PROPS","SORT_CHILD_PROPS","BIN_PROPS","SORT_PROPS","SCALE_PROPS","AXIS_PROPS","LEGEND_PROPS","ENCODING_NESTED_PROPS","VIEW_PROPS","PROP_KEY_DELIMITER","toKey","fromKey","k","split","ENCODING_NESTED_PROP_INDEX","reduce","getEncodingNestedProp","isEncodingProperty","ALL_ENCODING_PROPS","DEFAULT_PROP_PRECEDENCE","Property","MARK","TRANSFORM","STACK","FORMAT","CHANNEL","AGGREGATE","AUTOCOUNT","BIN","HAS_FN","TIMEUNIT","FIELD","TYPE","SORT","SCALE","AXIS","LEGEND","WIDTH","HEIGHT","BACKGROUND","PADDING","TITLE","AREA","BAR","CIRCLE","SQUARE","isPathMark","m","MONTHS","DAYS","substr","TimeUnit","YEAR","MONTH","DAY","DATE","HOURS","MINUTES","SECONDS","MILLISECONDS","YEARMONTH","YEARMONTHDATE","YEARMONTHDATEHOURS","YEARMONTHDATEHOURSMINUTES","YEARMONTHDATEHOURSMINUTESSECONDS","MONTHDATE","MONTHDATEHOURS","HOURSMINUTES","HOURSMINUTESSECONDS","MINUTESSECONDS","SECONDSMILLISECONDS","QUARTER","YEARQUARTER","QUARTERMONTH","YEARQUARTERMONTH","UTCYEAR","UTCMONTH","UTCDAY","UTCDATE","UTCHOURS","UTCMINUTES","UTCSECONDS","UTCMILLISECONDS","UTCYEARMONTH","UTCYEARMONTHDATE","UTCYEARMONTHDATEHOURS","UTCYEARMONTHDATEHOURSMINUTES","UTCYEARMONTHDATEHOURSMINUTESSECONDS","UTCMONTHDATE","UTCMONTHDATEHOURS","UTCHOURSMINUTES","UTCHOURSMINUTESSECONDS","UTCMINUTESSECONDS","UTCSECONDSMILLISECONDS","UTCQUARTER","UTCYEARQUARTER","UTCQUARTERMONTH","UTCYEARQUARTERMONTH","LOCAL_SINGLE_TIMEUNIT_INDEX","year","quarter","month","day","date","hours","minutes","seconds","milliseconds","TIMEUNIT_PARTS","isLocalSingleTimeUnit","UTC_SINGLE_TIMEUNIT_INDEX","utcyear","utcquarter","utcmonth","utcday","utcdate","utchours","utcminutes","utcseconds","utcmilliseconds","isUtcSingleTimeUnit","UTC_MULTI_TIMEUNIT_INDEX","utcyearquarter","utcyearquartermonth","utcyearmonth","utcyearmonthdate","utcyearmonthdatehours","utcyearmonthdatehoursminutes","utcyearmonthdatehoursminutesseconds","utcquartermonth","utcmonthdate","utcmonthdatehours","utchoursminutes","utchoursminutesseconds","utcminutesseconds","utcsecondsmilliseconds","UTC_TIMEUNIT_INDEX","TIMEUNIT_INDEX","yearquarter","yearquartermonth","yearmonth","yearmonthdate","yearmonthdatehours","yearmonthdatehoursminutes","yearmonthdatehoursminutesseconds","quartermonth","monthdate","monthdatehours","hoursminutes","hoursminutesseconds","minutesseconds","secondsmilliseconds","SET_DATE_METHOD","convert","unit","isUTC","result","timeUnitPart","containsTimeUnit","getDateMethod","setDateMethod","dateMethods","Math","floor","singleUnit","isUtc","rawSetDateMethod","charAt","u","namedfunc","identity","true","false","duplicate","parse","equal","extend","len","vals","toMap","list","keystr","String","isFunction","isNumber","isDate","isValid","number","boolean","str","field_re","strrep","truncateOnWord","rev","cnt","tok","truncate_word_re","filter","w","trim","match","mutator","v","$func","op","$valid","$length","$in","comparator","sign","numcmp","stablesort","sortBy","keyFn","indices","idx","sa","sb","permute","swap","random","pad","pos","padchar","ceil","truncate","word","ellipsis","l","max","l1","l2","every","arr","thisArg","some","without","excludedItems","nestedMap","SHORT_WILDCARD","isWildcard","isShortWildcard","isWildcardDef","enum","initWildcard","defaultName","defaultEnumValues","initNestedPropName","fullNames","has","fullName","initialIndices","toUpperCase","shortName","shortNameWithNo","DEFAULT_NAME","binProps","maxbins","min","step","steps","minstep","divide","sortProps","scaleProps","axisProps","legendProps","getDefaultName","DEFAULT_BOOLEAN_ENUM","DEFAULT_BIN_PROPS_ENUM","binned","anchor","DEFAULT_SORT_PROPS","DEFAULT_SCALE_PROPS_ENUM","DEFAULT_AXIS_PROPS_ENUM","DEFAULT_LEGEND_PROPS_ENUM","DEFAULT_ENUM_INDEX","MARK.POINT","MARK.BAR","MARK.AREA","getDefaultEnumValues","schema","fieldNames","val","DEFAULT_QUERY_CONFIG","verbose","defaultSpecConfig","useUnaggregatedDomain","propertyPrecedence","numberNominalProportion","numberNominalLimit","constraintManuallySpecifiedValue","autoAddCount","hasAppropriateGraphicTypeForMark","omitAggregate","omitAggregatePlotWithDimensionOnlyOnFacet","omitAggregatePlotWithoutDimension","omitBarLineAreaWithOcclusion","omitBarTickWithSize","omitMultipleNonPositionalChannels","omitRaw","omitRawContinuousFieldForAggregatePlot","omitRepeatedField","omitNonPositionalOrFacetOverPositionalChannels","omitTableWithOcclusionIfAutoAddCount","omitVerticalDotPlot","omitInvalidStackSpec","omitNonSumStack","preferredBinAxis","preferredTemporalAxis","preferredOrdinalAxis","preferredNominalAxis","preferredFacet","CHANNEL.ROW","minCardinalityForBin","maxCardinalityForCategoricalColor","maxCardinalityForFacet","maxCardinalityForShape","timeUnitShouldHaveVariation","typeMatchesSchemaType","stylize","smallRangeStepForHighCardinalityOrFacet","maxCardinality","nominalColorScaleForHighCardinality","palette","xAxisOnTopForHighYCardinalityWithoutColumn","maxGoodCardinalityForFacet","maxGoodCardinalityForColor","minPercentUniqueForKey","minCardinalityForKey","extendNestedEnumIndex","enumIndex","AGGREGATE_OP_INDEX","argmax","argmin","average","count","distinct","mean","median","missing","q1","q3","ci0","ci1","stderr","stdev","stdevp","sum","valid","variance","variancep","isArgminDef","isArgmaxDef","isAggregateOp","SUM_OPS","isBinning","isBinParams","autoMaxBins","hasConditionalFieldDef","channelDef","condition","isFieldDef","isStringFieldDef","vgField","prefix","suffix","argAccessor","isCount","isInternalField","nofn","isOpFieldDef","normalizeBin","alphanumericS","varName","binToString","binSuffix","forAs","expr","datum","flatAccessWithDatum","isDiscrete","invalidFieldType","isContinuous","getTypedFieldDef","COMPATIBLE","compatible","channelCompatibility","warning","facetChannelShouldBeDiscrete","ExpandedType","specifiedScale","log.warn","discreteChannelCannotEncode","util.contains","defaultType","scaleTypeNotWorkWithFieldDef","scaleTypeNotWorkWithChannel","fieldType","PropIndex","[object Object]","channelHasField","entries","STACK_OFFSET_INDEX","normalize","STACKABLE_MARKS","STACK_BY_DEFAULT_MARKS","stackConfig","isMarkDef","fieldChannel","xDef","yDef","potentialStackedChannel","stackedFieldDef","stackedField","dimensionChannel","dimensionDef","dimensionField","stackBy","sc","cDef","disallowNonLinearStack","cannotStackNonLinearScale","cannotStackRangedMark","stackNonSummativeAggregate","groupbyChannel","impute","fromSpec","spec","width","height","background","encodings","encQ","isFieldQuery","config","isAggregate","specQ","isEnabledAutoCountQuery","getVlStack","hasRequiredStackProperties","toEncoding","wildcardMode","getStackOffset","getStackChannel","requiredEncodingProps","exclude","isDisabledAutoCountQuery","objectContainsWildcard","childProp","getReplacerIndex","replaceIndex","r","getReplacer","replacer","REPLACE_NONE","INCLUDE_ALL","pi","PROPERTY_SUPPORTED_CHANNELS","include","parts","get","encQs","viewProp","propString","fieldDefStr","isValueQuery","isAutoCountQuery","fieldQ","func","props","localeCompare","parentValue","nestedPropChildren","nestedProp","nestedPropObject","fieldDefProps","fieldAndParams","splitWithTail","delim","indexOfDelim","shorthandParser","rawFieldDef","fieldDefPart","partParams","closingBraceIndex","parsedValue","propEqualSignIndex","openingBraceIndex","getClosingIndex","openingBracketIndex","closingBracketIndex","propIndex","nextCommaIndex","closingChar","fieldDefShorthand","fnEnumIndex","encodingProperty","insideFnParts","encQMixins","vlspec","shorthand","splitShorthand","splitPart","splitPartKey","splitPartValue","DEFAULT_PROPS","params","toValueDef","toFieldDef","valueQ","ordinalDomain","fieldSchema","isMeasure","isDimension","vlChannelDef.isDiscrete","compileScaleType","vlChannelDef.isContinuous","t0","t1","newInterval","floori","offseti","interval","d0","d1","start","stop","test","setTime","end","millisecond","second","setMilliseconds","getSeconds","minute","setSeconds","getMinutes","hour","setMinutes","getHours","setHours","setDate","getDate","getTimezoneOffset","weekday","getDay","sunday","monday","tuesday","wednesday","thursday","friday","saturday","setMonth","getMonth","getFullYear","setFullYear","utcSecond","setUTCMilliseconds","getUTCSeconds","utcMinute","setUTCSeconds","getUTCMinutes","utcHour","setUTCMinutes","getUTCHours","utcDay","setUTCHours","setUTCDate","getUTCDate","utcWeekday","getUTCDay","utcSunday","utcMonday","utcTuesday","utcWednesday","utcThursday","utcFriday","utcSaturday","utcMonth","setUTCMonth","getUTCMonth","getUTCFullYear","utcYear","setUTCFullYear","days","sundays","mondays","tuesdays","wednesdays","thursdays","fridays","saturdays","weeks","months","years","utcMillisecond","utcMilliseconds","utcSeconds","utcMinutes","utcHours","utcDays","utcSundays","utcMondays","utcTuesdays","utcWednesdays","utcThursdays","utcFridays","utcSaturdays","utcWeeks","utcMonths","utcYears","version","week","utcWeek","factory","tempDate","baseDate","utcBaseDate","entry","locale","d3_time","STEPS","toUnitMap","units","find","span","minb","maxb","utc_1","EPSILON","precision","eps","logb","div","lo","hi","mid","util","bisect","date_value","date_index","dmin","dmax","minbins","raw","bins_1","TYPES","PARSERS","integer","string","TESTS","isNaN","bracket","fieldName","infer","types","annotation","all","inferAll","parsers","type_1","gen","repeat","zeros","uniform","samples","pdf","cdf","icdf","NaN","normal","next","rds","exp","PI","cd","z","Z","abs","SQRT2","bootstrap","smooth","stats","ztest1","nullH","nullh","gaussian","mu","SE","ztestP","n1","n2","diffs","ztest2","meanDiff","unique","results","quartile","H","h","geometric","harmonic","delta","M2","modeskew","avg","med","std","dot","dist","L2","cohensd","x1","s1","s2","covariance","vx","vy","xm","ym","rank","tie","cor","mua","mub","sda","sdb","ra","rb","aa","bb","ab","A","mat","B","linearRegression","res","xy","sx","sy","slope","icept","fit","intercept","R","rss","ci","N","alpha","bs","means","paired","M","entropy","counts","LN2","mutual","px","py","I","profile","sd","summary","__summary__","dlBin","dlBin_","Schema","tableSchema","_tableSchema","vlType","_fieldSchemaIndex","fieldSchemas","originalIndex","augmentTimeUnitDomain","excludeInvalid","binStats","binSummary","timeStats","timeSummary","invalidCount","dateEncQ","cardinality","singleUnitEncQ","fieldQueryParts","PrimitiveType","DATETIME","INTEGER","NUMBER","oldUnique","newUnique","bucket","Number","binUnique","timeunit","dateString","prev","cur","summaries","tableSchemaFieldIndex","fieldProfile","dataEntry","orgFieldSchema","derivedTableSchema","AbstractConstraintModel","constraint","description","properties","strict","EncodingConstraintModel","super","encWildcardIndex","allowWildcardForProperties","hasAllRequiredPropertiesSpecific","satisfy","FIELD_CONSTRAINTS","__","___","fieldQwithoutBin","timeUnitHasVariation","sType","scaleProp","sProp","primitiveType","BOOLEAN","STRING","CHANNEL.COLUMN","ec","FIELD_CONSTRAINTS_BY_PROPERTY","VALUE_CONSTRAINTS","VALUE_CONSTRAINTS_BY_PROPERTY","checkEncoding","wildcard","specM","encodingConstraints","getEncodingQueryByIndex","wildcardIndex","violatedConstraint","toShorthand","valueContraints","NONPOSITION_CHANNELS_INDEX","SpecConstraintModel","specConstraint","getMark","getEncodings","SPEC_CONSTRAINTS","usedChannel","encodingIndicesByProperty","channelUsed","CHANNEL.TEXT","MARK.CIRCLE","MARK.SQUARE","hasProperty","hasNonFacetDim","hasDim","hasEnumeratedFacetDim","specQuery","hasEncodingProperty","channelEncodingField","nonPositionChannelCount","hasEnumeratedNonPositionChannel","hasNonPositionalChannelOrFacet","hasEnumeratedNonPositionOrFacetChannel","hasX","hasY","CHANNEL.DETAIL","fieldUsed","fieldEnumerated","xEncQ","getEncodingQueryByChannel","yEncQ","xIsMeasure","yIsMeasure","xIsDimension","yIsDimension","colorEncQ","colorIsQuantitative","colorIsOrdinal","correctChannels","correctColor","stackProps","specStack","stackParentEncQ","SPEC_CONSTRAINT_INDEX","SPEC_CONSTRAINTS_BY_PROPERTY","checkSpec","specConstraints","ENUMERATOR_INDEX","getEnumerator","EncodingPropertyGeneratorFactory","answerSet","enumerate","jobIndex","propWildcard","getEncodingProperty","propVal","setEncodingProperty","resetEncodingProperty","setMark","resetMark","isExtendedGroupBy","g","parseGroupBy","groupBy","grpBy","setByKey","GROUP_BY_FIELD_TRANSFORM","GROUP_BY_ENCODING","*","valFrom","valTo","groupRegistry","registerKeyFn","nest","specModels","queryNest","rootGroup","items","groupIndex","includes","replaces","replacers","parsedGroupBy","group","orderGroupBy","specShorthand","PARSED_GROUP_BY_FIELD","getGroupByKey","PARSED_GROUP_BY_FIELD_TRANSFORM","PARSED_GROUP_BY_ENCODING","WildcardIndex","_mark","_encodings","_encodingIndicesByProperty","encodingsIndex","indicesByProp","SpecQueryModel","wildcardAssignment","_rankingScore","_spec","_channelFieldCount","_wildcardIndex","_assignedWildcardIndex","_opt","_schema","defaultWildcardName","propObj","countEncQ","specEncoding","rankingName","score","orderBy","normalizedQ","chooseBy","isResultTree","getTopResultTreeItem","topItem","ExtendedType","mapLeaves","Scorer","scoreIndex","initScore","feature","Q","BIN_Q","T","TIMEUNIT_T","TIMEUNIT_O","O","K","NONE","getExtendedType","TERRIBLE","featurize","xType","yType","hasOcclusion","SCORERS","pAxis","features","featureScore","getFeatureScore","maxFScore","MEASURES","DISCRETE_OR_NONE","SCORE","feature2","ttMark","tdMark","ddMark","init","bar_size","tick_size","featureScores","CONTINUOUS_TYPE_CHANNEL_SCORE","ORDERED_TYPE_CHANNEL_SCORE","NOMINAL_TYPE_CHANNEL_SCORE","encodingQueryByField","fieldKey","bestFieldFeature","best","effectiveness","scorer","scores","getScore","isRawContinuous","hasCount","hasBin","aggregationQualityFeature","fieldWildcardIndices","numFields","totalScore","fieldWildcard","fieldIndex","rankingRegistry","register","query","subgroup","groupComparatorFactory","comparatorFactory","m1","m2","getScoreDifference","g1","g2","scoreDifference","model","getRankingScore","setRankingScore","aggregation.name","aggregation.score","fieldOrder.score","encQIndex","yScaleType","xScaleType","generate","build","propKey","reducer","enumerator"],"mappings":"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","file":"build/compassql.min.js.map","sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","var clone = (function() {\n'use strict';\n\nfunction _instanceof(obj, type) {\n return type != null && obj instanceof type;\n}\n\nvar nativeMap;\ntry {\n nativeMap = Map;\n} catch(_) {\n // maybe a reference error because no `Map`. Give it a dummy value that no\n // value will ever be an instanceof.\n nativeMap = function() {};\n}\n\nvar nativeSet;\ntry {\n nativeSet = Set;\n} catch(_) {\n nativeSet = function() {};\n}\n\nvar nativePromise;\ntry {\n nativePromise = Promise;\n} catch(_) {\n nativePromise = function() {};\n}\n\n/**\n * Clones (copies) an Object using deep copying.\n *\n * This function supports circular references by default, but if you are certain\n * there are no circular references in your object, you can save some CPU time\n * by calling clone(obj, false).\n *\n * Caution: if `circular` is false and `parent` contains circular references,\n * your program may enter an infinite loop and crash.\n *\n * @param `parent` - the object to be cloned\n * @param `circular` - set to true if the object to be cloned may contain\n * circular references. (optional - true by default)\n * @param `depth` - set to a number if the object is only to be cloned to\n * a particular depth. (optional - defaults to Infinity)\n * @param `prototype` - sets the prototype to be used when cloning an object.\n * (optional - defaults to parent prototype).\n * @param `includeNonEnumerable` - set to true if the non-enumerable properties\n * should be cloned as well. Non-enumerable properties on the prototype\n * chain will be ignored. (optional - false by default)\n*/\nfunction clone(parent, circular, depth, prototype, includeNonEnumerable) {\n if (typeof circular === 'object') {\n depth = circular.depth;\n prototype = circular.prototype;\n includeNonEnumerable = circular.includeNonEnumerable;\n circular = circular.circular;\n }\n // maintain two arrays for circular references, where corresponding parents\n // and children have the same index\n var allParents = [];\n var allChildren = [];\n\n var useBuffer = typeof Buffer != 'undefined';\n\n if (typeof circular == 'undefined')\n circular = true;\n\n if (typeof depth == 'undefined')\n depth = Infinity;\n\n // recurse this function so we don't reset allParents and allChildren\n function _clone(parent, depth) {\n // cloning null always returns null\n if (parent === null)\n return null;\n\n if (depth === 0)\n return parent;\n\n var child;\n var proto;\n if (typeof parent != 'object') {\n return parent;\n }\n\n if (_instanceof(parent, nativeMap)) {\n child = new nativeMap();\n } else if (_instanceof(parent, nativeSet)) {\n child = new nativeSet();\n } else if (_instanceof(parent, nativePromise)) {\n child = new nativePromise(function (resolve, reject) {\n parent.then(function(value) {\n resolve(_clone(value, depth - 1));\n }, function(err) {\n reject(_clone(err, depth - 1));\n });\n });\n } else if (clone.__isArray(parent)) {\n child = [];\n } else if (clone.__isRegExp(parent)) {\n child = new RegExp(parent.source, __getRegExpFlags(parent));\n if (parent.lastIndex) child.lastIndex = parent.lastIndex;\n } else if (clone.__isDate(parent)) {\n child = new Date(parent.getTime());\n } else if (useBuffer && Buffer.isBuffer(parent)) {\n if (Buffer.allocUnsafe) {\n // Node.js >= 4.5.0\n child = Buffer.allocUnsafe(parent.length);\n } else {\n // Older Node.js versions\n child = new Buffer(parent.length);\n }\n parent.copy(child);\n return child;\n } else if (_instanceof(parent, Error)) {\n child = Object.create(parent);\n } else {\n if (typeof prototype == 'undefined') {\n proto = Object.getPrototypeOf(parent);\n child = Object.create(proto);\n }\n else {\n child = Object.create(prototype);\n proto = prototype;\n }\n }\n\n if (circular) {\n var index = allParents.indexOf(parent);\n\n if (index != -1) {\n return allChildren[index];\n }\n allParents.push(parent);\n allChildren.push(child);\n }\n\n if (_instanceof(parent, nativeMap)) {\n parent.forEach(function(value, key) {\n var keyChild = _clone(key, depth - 1);\n var valueChild = _clone(value, depth - 1);\n child.set(keyChild, valueChild);\n });\n }\n if (_instanceof(parent, nativeSet)) {\n parent.forEach(function(value) {\n var entryChild = _clone(value, depth - 1);\n child.add(entryChild);\n });\n }\n\n for (var i in parent) {\n var attrs;\n if (proto) {\n attrs = Object.getOwnPropertyDescriptor(proto, i);\n }\n\n if (attrs && attrs.set == null) {\n continue;\n }\n child[i] = _clone(parent[i], depth - 1);\n }\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(parent);\n for (var i = 0; i < symbols.length; i++) {\n // Don't need to worry about cloning a symbol because it is a primitive,\n // like a number or string.\n var symbol = symbols[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);\n if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {\n continue;\n }\n child[symbol] = _clone(parent[symbol], depth - 1);\n if (!descriptor.enumerable) {\n Object.defineProperty(child, symbol, {\n enumerable: false\n });\n }\n }\n }\n\n if (includeNonEnumerable) {\n var allPropertyNames = Object.getOwnPropertyNames(parent);\n for (var i = 0; i < allPropertyNames.length; i++) {\n var propertyName = allPropertyNames[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);\n if (descriptor && descriptor.enumerable) {\n continue;\n }\n child[propertyName] = _clone(parent[propertyName], depth - 1);\n Object.defineProperty(child, propertyName, {\n enumerable: false\n });\n }\n }\n\n return child;\n }\n\n return _clone(parent, depth);\n}\n\n/**\n * Simple flat clone using prototype, accepts only objects, usefull for property\n * override on FLAT configuration object (no nested props).\n *\n * USE WITH CAUTION! This may not behave as you wish if you do not know how this\n * works.\n */\nclone.clonePrototype = function clonePrototype(parent) {\n if (parent === null)\n return null;\n\n var c = function () {};\n c.prototype = parent;\n return new c();\n};\n\n// private utility functions\n\nfunction __objToStr(o) {\n return Object.prototype.toString.call(o);\n}\nclone.__objToStr = __objToStr;\n\nfunction __isDate(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Date]';\n}\nclone.__isDate = __isDate;\n\nfunction __isArray(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Array]';\n}\nclone.__isArray = __isArray;\n\nfunction __isRegExp(o) {\n return typeof o === 'object' && __objToStr(o) === '[object RegExp]';\n}\nclone.__isRegExp = __isRegExp;\n\nfunction __getRegExpFlags(re) {\n var flags = '';\n if (re.global) flags += 'g';\n if (re.ignoreCase) flags += 'i';\n if (re.multiline) flags += 'm';\n return flags;\n}\nclone.__getRegExpFlags = __getRegExpFlags;\n\nreturn clone;\n})();\n\nif (typeof module === 'object' && module.exports) {\n module.exports = clone;\n}\n","'use strict';\n\nmodule.exports = function (data, opts) {\n if (!opts) opts = {};\n if (typeof opts === 'function') opts = { cmp: opts };\n var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;\n\n var cmp = opts.cmp && (function (f) {\n return function (node) {\n return function (a, b) {\n var aobj = { key: a, value: node[a] };\n var bobj = { key: b, value: node[b] };\n return f(aobj, bobj);\n };\n };\n })(opts.cmp);\n\n var seen = [];\n return (function stringify (node) {\n if (node && node.toJSON && typeof node.toJSON === 'function') {\n node = node.toJSON();\n }\n\n if (node === undefined) return;\n if (typeof node == 'number') return isFinite(node) ? '' + node : 'null';\n if (typeof node !== 'object') return JSON.stringify(node);\n\n var i, out;\n if (Array.isArray(node)) {\n out = '[';\n for (i = 0; i < node.length; i++) {\n if (i) out += ',';\n out += stringify(node[i]) || 'null';\n }\n return out + ']';\n }\n\n if (node === null) return 'null';\n\n if (seen.indexOf(node) !== -1) {\n if (cycles) return JSON.stringify('__cycle__');\n throw new TypeError('Converting circular structure to JSON');\n }\n\n var seenIndex = seen.push(node) - 1;\n var keys = Object.keys(node).sort(cmp && cmp(node));\n out = '';\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = stringify(node[key]);\n\n if (!value) continue;\n if (out) out += ',';\n out += JSON.stringify(key) + ':' + value;\n }\n seen.splice(seenIndex, 1);\n return '{' + out + '}';\n })(data);\n};\n","export default function(fn, fields, name) {\n fn.fields = fields || [];\n fn.fname = name;\n return fn;\n}\n\nexport function accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nexport function accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n","export default function(message) {\n throw Error(message);\n}\n","import error from './error';\n\nexport default function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) {\n push();\n } else {\n i = j + 1;\n }\n } else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n } else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n\n if (j > i) {\n j++;\n push();\n }\n\n return path;\n}\n","export default Array.isArray;\n","export default function(_) {\n return _ === Object(_);\n}\n","export default function(_) {\n return typeof _ === 'string';\n}\n","import isArray from './isArray';\nimport isObject from './isObject';\nimport isString from './isString';\n\nexport default function $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n","import accessor from './accessor';\nimport field from './field';\n\nvar empty = [];\n\nexport var id = field('id');\n\nexport var identity = accessor(function(_) { return _; }, empty, 'identity');\n\nexport var zero = accessor(function() { return 0; }, empty, 'zero');\n\nexport var one = accessor(function() { return 1; }, empty, 'one');\n\nexport var truthy = accessor(function() { return true; }, empty, 'true');\n\nexport var falsy = accessor(function() { return false; }, empty, 'false');\n","import accessor from './accessor';\nimport splitAccessPath from './splitAccessPath';\nimport stringValue from './stringValue';\n\nexport default function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map(stringValue).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n","function log(method, level, input) {\n var msg = [level].concat([].slice.call(input));\n console[method](...msg); // eslint-disable-line no-console\n}\n\nexport var None = 0;\nexport var Error = 1;\nexport var Warn = 2;\nexport var Info = 3;\nexport var Debug = 4;\n\nexport default function(_, method) {\n var level = _ || None;\n return {\n level: function(_) {\n if (arguments.length) {\n level = +_;\n return this;\n } else {\n return level;\n }\n },\n error: function() {\n if (level >= Error) log(method || 'error', 'ERROR', arguments);\n return this;\n },\n warn: function() {\n if (level >= Warn) log(method || 'warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log(method || 'log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log(method || 'log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n","export default function(_) {\n return typeof _ === 'boolean';\n}\n","export default function(_) {\n for (var s={}, i=0, n=_.length; i(obj: T, props: K[]): Pick {\n const copy: any = {};\n for (const prop of props) {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n }\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: T, props: K[]): Omit {\n const copy = {...(obj as any)};\n for (const prop of props) {\n delete copy[prop];\n }\n return copy;\n}\n\n/**\n * Monkey patch Set so that `stringify` produces a string representation of sets.\n */\nSet.prototype['toJSON'] = function() {\n return `Set(${[...this].map(x => stableStringify(x)).join(',')})`;\n};\n\n/**\n * Converts any object to a string representation that can be consumed by humans.\n */\nexport const stringify = stableStringify;\n\n/**\n * Converts any object to a string of limited size, or a number.\n */\nexport function hash(a: any): string | number {\n if (isNumber(a)) {\n return a;\n }\n\n const str = isString(a) ? a : stableStringify(a);\n\n // short strings can be used as hash directly, longer strings are hashed to reduce memory usage\n if (str.length < 250) {\n return str;\n }\n\n // from http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n h = (h << 5) - h + char;\n h = h & h; // Convert to 32bit integer\n }\n return h;\n}\n\nexport function isNullOrFalse(x: any): x is false | null {\n return x === false || x === null;\n}\n\nexport function contains(array: T[], item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: T[], excludedItems: T[]) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: T[], other: T[]) {\n return array.concat(without(other, array));\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (const [k, a] of arr.entries()) {\n if (f(a, k, i++)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Returns true if all items return true.\n */\nexport function every(arr: T[], f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (const [k, a] of arr.entries()) {\n if (!f(a, k, i++)) {\n return false;\n }\n }\n return true;\n}\n\nexport function flatten(arrays: T[][]): T[] {\n return ([] as T[]).concat(...arrays);\n}\n\nexport function fill(val: T, len: number) {\n const arr = new Array(len);\n for (let i = 0; i < len; ++i) {\n arr[i] = val;\n }\n return arr;\n}\n\n/**\n * Like TS Partial but applies recursively to all properties.\n */\nexport type DeepPartial = {[P in keyof T]?: DeepPartial};\n\n/**\n * recursively merges src into dest\n */\nexport function mergeDeep(dest: T, ...src: DeepPartial[]): T {\n for (const s of src) {\n dest = deepMerge_(dest, s);\n }\n return dest;\n}\n\n// recursively merges src into dest\nfunction deepMerge_(dest: any, src: any) {\n if (typeof src !== 'object' || src === null) {\n return dest;\n }\n\n for (const p in src) {\n if (!src.hasOwnProperty(p)) {\n continue;\n }\n if (src[p] === undefined) {\n continue;\n }\n if (typeof src[p] !== 'object' || isArray(src[p]) || src[p] === null) {\n dest[p] = src[p];\n } else if (typeof dest[p] !== 'object' || dest[p] === null) {\n dest[p] = mergeDeep(isArray(src[p].constructor) ? [] : {}, src[p]);\n } else {\n mergeDeep(dest[p], src[p]);\n }\n }\n return dest;\n}\n\nexport function unique(values: T[], f: (item: T) => string | number): T[] {\n const results: T[] = [];\n const u = {};\n let v: string | number;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n}\n\nexport interface Dict {\n [key: string]: T;\n}\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function isEqual(dict: Dict, other: Dict) {\n const dictKeys = keys(dict);\n const otherKeys = keys(other);\n if (dictKeys.length !== otherKeys.length) {\n return false;\n }\n for (const key of dictKeys) {\n if (dict[key] !== other[key]) {\n return false;\n }\n }\n return true;\n}\n\nexport function setEqual(a: Set, b: Set) {\n if (a.size !== b.size) {\n return false;\n }\n for (const e of a) {\n if (!b.has(e)) {\n return false;\n }\n }\n return true;\n}\n\nexport function hasIntersection(a: Set, b: Set) {\n for (const key of a) {\n if (b.has(key)) {\n return true;\n }\n }\n return false;\n}\n\nexport function prefixGenerator(a: Set): Set {\n const prefixes = new Set();\n for (const x of a) {\n const splitField = splitAccessPath(x);\n // Wrap every element other than the first in `[]`\n const wrappedWithAccessors = splitField.map((y, i) => (i === 0 ? y : `[${y}]`));\n const computedPrefixes = wrappedWithAccessors.map((_, i) => wrappedWithAccessors.slice(0, i + 1).join(''));\n computedPrefixes.forEach(y => prefixes.add(y));\n }\n return prefixes;\n}\n\nexport function fieldIntersection(a: Set, b: Set): boolean {\n return hasIntersection(prefixGenerator(a), prefixGenerator(b));\n}\n\nexport function isNumeric(num: string | number) {\n return !isNaN(num as any);\n}\n\nexport function differArray(array: T[], other: T[]) {\n if (array.length !== other.length) {\n return true;\n }\n\n array.sort();\n other.sort();\n\n for (let i = 0; i < array.length; i++) {\n if (other[i] !== array[i]) {\n return true;\n }\n }\n\n return false;\n}\n\n// This is a stricter version of Object.keys but with better types. See https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\nexport const keys = Object.keys as (o: T) => (Extract)[];\n\nexport function vals(x: {[key: string]: T}): T[] {\n const _vals: T[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n}\n\nexport function entries(x: {[key: string]: T}): {key: string; value: T}[] {\n const _entries: {key: string; value: T}[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _entries.push({\n key: k,\n value: x[k]\n });\n }\n }\n return _entries;\n}\n\n// Using mapped type to declare a collect of flags for a string literal type S\n// https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types\nexport type Flag = {[K in S]: 1};\n\nexport function flagKeys(f: Flag): S[] {\n return keys(f) as S[];\n}\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n\n/**\n * Convert a string into a valid variable name\n */\nexport function varName(s: string): string {\n // Replace non-alphanumeric characters (anything besides a-zA-Z0-9_) with _\n const alphanumericS = s.replace(/\\W/g, '_');\n\n // Add _ if the string has leading numbers.\n return (s.match(/^\\d+/) ? '_' : '') + alphanumericS;\n}\n\nexport function logicalExpr(op: LogicalOperand, cb: (...args: any[]) => string): string {\n if (isLogicalNot(op)) {\n return '!(' + logicalExpr(op.not, cb) + ')';\n } else if (isLogicalAnd(op)) {\n return '(' + op.and.map((and: LogicalOperand) => logicalExpr(and, cb)).join(') && (') + ')';\n } else if (isLogicalOr(op)) {\n return '(' + op.or.map((or: LogicalOperand) => logicalExpr(or, cb)).join(') || (') + ')';\n } else {\n return cb(op);\n }\n}\n\nexport type Omit = Pick>;\n\n/**\n * Delete nested property of an object, and delete the ancestors of the property if they become empty.\n */\nexport function deleteNestedProperty(obj: any, orderedProps: string[]) {\n if (orderedProps.length === 0) {\n return true;\n }\n const prop = orderedProps.shift();\n if (deleteNestedProperty(obj[prop], orderedProps)) {\n delete obj[prop];\n }\n return keys(obj).length === 0;\n}\n\nexport function titlecase(s: string) {\n return s.charAt(0).toUpperCase() + s.substr(1);\n}\n\n/**\n * Converts a path to an access path with datum.\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function accessPathWithDatum(path: string, datum = 'datum') {\n const pieces = splitAccessPath(path);\n const prefixes = [];\n for (let i = 1; i <= pieces.length; i++) {\n const prefix = `[${pieces\n .slice(0, i)\n .map(stringValue)\n .join('][')}]`;\n prefixes.push(`${datum}${prefix}`);\n }\n return prefixes.join(' && ');\n}\n\n/**\n * Return access with datum to the flattened field.\n *\n * @param path The field name.\n * @param datum The string to use for `datum`.\n */\nexport function flatAccessWithDatum(path: string, datum: 'datum' | 'parent' | 'datum.datum' = 'datum') {\n return `${datum}[${stringValue(splitAccessPath(path).join('.'))}]`;\n}\n\n/**\n * Replaces path accesses with access to non-nested field.\n * For example, `foo[\"bar\"].baz` becomes `foo\\\\.bar\\\\.baz`.\n */\nexport function replacePathInField(path: string) {\n return `${splitAccessPath(path)\n .map(p => p.replace('.', '\\\\.'))\n .join('\\\\.')}`;\n}\n\n/**\n * Remove path accesses with access from field.\n * For example, `foo[\"bar\"].baz` becomes `foo.bar.baz`.\n */\nexport function removePathFromField(path: string) {\n return `${splitAccessPath(path).join('.')}`;\n}\n\n/**\n * Count the depth of the path. Returns 1 for fields that are not nested.\n */\nexport function accessPathDepth(path: string) {\n if (!path) {\n return 0;\n }\n return splitAccessPath(path).length;\n}\n\n/**\n * This is a replacement for chained || for numeric properties or properties that respect null so that 0 will be included.\n */\nexport function getFirstDefined(...args: T[]): T {\n for (const arg of args) {\n if (arg !== undefined) {\n return arg;\n }\n }\n return undefined;\n}\n\n// variable used to generate id\nlet idCounter = 42;\n\n/**\n * Returns a new random id every time it gets called.\n *\n * Has side effect!\n */\nexport function uniqueId(prefix?: string) {\n const id = ++idCounter;\n return prefix ? String(prefix) + id : id;\n}\n\n/**\n * Resets the id counter used in uniqueId. This can be useful for testing.\n */\nexport function resetIdCounter() {\n idCounter = 42;\n}\n\nexport function internalField(name: string) {\n return isInternalField(name) ? name : `__${name}`;\n}\n\nexport function isInternalField(name: string) {\n return name.indexOf('__') === 0;\n}\n\n/**\n * Normalize angle to be within [0,360).\n */\nexport function normalizeAngle(angle: number) {\n return ((angle % 360) + 360) % 360;\n}\n","/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {RangeType} from './compile/scale/type';\nimport {Encoding} from './encoding';\nimport {Mark} from './mark';\nimport {EncodingFacetMapping, EncodingFacetMapping as ExtendedFacetMapping} from './spec/facet';\nimport {Flag, flagKeys} from './util';\n\nexport type Channel = keyof Encoding | keyof ExtendedFacetMapping;\n\n// Facet\nexport const ROW: 'row' = 'row';\nexport const COLUMN: 'column' = 'column';\n\nexport const FACET: 'facet' = 'facet';\n\n// Position\nexport const X: 'x' = 'x';\nexport const Y: 'y' = 'y';\nexport const X2: 'x2' = 'x2';\nexport const Y2: 'y2' = 'y2';\n// Geo Position\nexport const LATITUDE: 'latitude' = 'latitude';\nexport const LONGITUDE: 'longitude' = 'longitude';\nexport const LATITUDE2: 'latitude2' = 'latitude2';\nexport const LONGITUDE2: 'longitude2' = 'longitude2';\n\n// Mark property with scale\nexport const COLOR: 'color' = 'color';\n\nexport const FILL: 'fill' = 'fill';\n\nexport const STROKE: 'stroke' = 'stroke';\n\nexport const SHAPE: 'shape' = 'shape';\nexport const SIZE: 'size' = 'size';\nexport const OPACITY: 'opacity' = 'opacity';\nexport const FILLOPACITY: 'fillOpacity' = 'fillOpacity';\n\nexport const STROKEOPACITY: 'strokeOpacity' = 'strokeOpacity';\n\nexport const STROKEWIDTH: 'strokeWidth' = 'strokeWidth';\n\n// Non-scale channel\nexport const TEXT: 'text' = 'text';\nexport const ORDER: 'order' = 'order';\nexport const DETAIL: 'detail' = 'detail';\nexport const KEY: 'key' = 'key';\n\nexport const TOOLTIP: 'tooltip' = 'tooltip';\nexport const HREF: 'href' = 'href';\n\nexport type PositionChannel = 'x' | 'y' | 'x2' | 'y2';\n\nexport type GeoPositionChannel = 'longitude' | 'latitude' | 'longitude2' | 'latitude2';\n\nexport function isGeoPositionChannel(c: Channel): c is GeoPositionChannel {\n switch (c) {\n case LATITUDE:\n case LATITUDE2:\n case LONGITUDE:\n case LONGITUDE2:\n return true;\n }\n return false;\n}\n\nexport function getPositionChannelFromLatLong(channel: GeoPositionChannel): PositionChannel {\n switch (channel) {\n case LATITUDE:\n return 'y';\n case LATITUDE2:\n return 'y2';\n case LONGITUDE:\n return 'x';\n case LONGITUDE2:\n return 'x2';\n }\n}\n\nexport const GEOPOSITION_CHANNEL_INDEX: Flag = {\n longitude: 1,\n longitude2: 1,\n latitude: 1,\n latitude2: 1\n};\n\nexport const GEOPOSITION_CHANNELS = flagKeys(GEOPOSITION_CHANNEL_INDEX);\n\nconst UNIT_CHANNEL_INDEX: Flag> = {\n // position\n x: 1,\n y: 1,\n x2: 1,\n y2: 1,\n\n ...GEOPOSITION_CHANNEL_INDEX,\n\n // color\n color: 1,\n fill: 1,\n stroke: 1,\n\n // other non-position with scale\n opacity: 1,\n fillOpacity: 1,\n strokeOpacity: 1,\n\n strokeWidth: 1,\n size: 1,\n shape: 1,\n\n // channels without scales\n order: 1,\n text: 1,\n detail: 1,\n key: 1,\n tooltip: 1,\n href: 1\n};\n\nexport type ColorChannel = 'color' | 'fill' | 'stroke';\n\nexport function isColorChannel(channel: Channel): channel is ColorChannel {\n return channel === 'color' || channel === 'fill' || channel === 'stroke';\n}\n\nexport type FacetChannel = keyof EncodingFacetMapping;\n\nconst FACET_CHANNEL_INDEX: Flag> = {\n row: 1,\n column: 1,\n facet: 1\n};\n\nexport const FACET_CHANNELS = flagKeys(FACET_CHANNEL_INDEX);\n\nconst CHANNEL_INDEX = {\n ...UNIT_CHANNEL_INDEX,\n ...FACET_CHANNEL_INDEX\n};\n\nexport const CHANNELS = flagKeys(CHANNEL_INDEX);\n\nconst {order: _o, detail: _d, ...SINGLE_DEF_CHANNEL_INDEX} = CHANNEL_INDEX;\nconst {order: _o1, detail: _d1, row: _r, column: _c, facet: _f, ...SINGLE_DEF_UNIT_CHANNEL_INDEX} = CHANNEL_INDEX;\n/**\n * Channels that cannot have an array of channelDef.\n * model.fieldDef, getFieldDef only work for these channels.\n *\n * (The only two channels that can have an array of channelDefs are \"detail\" and \"order\".\n * Since there can be multiple fieldDefs for detail and order, getFieldDef/model.fieldDef\n * are not applicable for them. Similarly, selection projection won't work with \"detail\" and \"order\".)\n */\n\nexport const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANNEL_INDEX);\n\nexport const SINGLE_DEF_UNIT_CHANNELS: SingleDefUnitChannel[] = flagKeys(SINGLE_DEF_UNIT_CHANNEL_INDEX);\n\n// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined\n// when running the schema generator\n// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0];\n\nexport type SingleDefUnitChannel =\n | 'x'\n | 'y'\n | 'x2'\n | 'y2'\n | 'longitude'\n | 'latitude'\n | 'longitude2'\n | 'latitude2'\n | 'color'\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'size'\n | 'shape'\n | 'fillOpacity'\n | 'strokeOpacity'\n | 'opacity'\n | 'text'\n | 'tooltip'\n | 'href'\n | 'key';\n\nexport type SingleDefChannel = SingleDefUnitChannel | 'row' | 'column' | 'facet';\n\nexport function isSingleDefUnitChannel(str: string): str is SingleDefUnitChannel {\n return !!SINGLE_DEF_UNIT_CHANNEL_INDEX[str];\n}\n\nexport function isChannel(str: string): str is Channel {\n return !!CHANNEL_INDEX[str];\n}\n\nexport type SecondaryRangeChannel = 'x2' | 'y2' | 'latitude2' | 'longitude2';\n\nexport const SECONDARY_RANGE_CHANNEL: SecondaryRangeChannel[] = ['x2', 'y2', 'latitude2', 'longitude2'];\n\nexport function isSecondaryRangeChannel(c: Channel): c is SecondaryRangeChannel {\n const main = getMainRangeChannel(c);\n return main !== c;\n}\n\nexport function getMainRangeChannel(channel: Channel): Channel {\n switch (channel) {\n case 'x2':\n return 'x';\n case 'y2':\n return 'y';\n case 'latitude2':\n return 'latitude';\n case 'longitude2':\n return 'longitude';\n }\n return channel;\n}\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = flagKeys(UNIT_CHANNEL_INDEX);\n\n// NONPOSITION_CHANNELS = UNIT_CHANNELS without X, Y, X2, Y2;\nconst {\n x: _x,\n y: _y,\n // x2 and y2 share the same scale as x and y\n x2: _x2,\n y2: _y2,\n latitude: _latitude,\n longitude: _longitude,\n latitude2: _latitude2,\n longitude2: _longitude2,\n // The rest of unit channels then have scale\n ...NONPOSITION_CHANNEL_INDEX\n} = UNIT_CHANNEL_INDEX;\n\nexport const NONPOSITION_CHANNELS = flagKeys(NONPOSITION_CHANNEL_INDEX);\nexport type NonPositionChannel = typeof NONPOSITION_CHANNELS[0];\n\n// POSITION_SCALE_CHANNELS = X and Y;\nconst POSITION_SCALE_CHANNEL_INDEX: {x: 1; y: 1} = {x: 1, y: 1};\nexport const POSITION_SCALE_CHANNELS = flagKeys(POSITION_SCALE_CHANNEL_INDEX);\nexport type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0];\n\n// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y\nconst {\n // x2 and y2 share the same scale as x and y\n // text and tooltip have format instead of scale,\n // href has neither format, nor scale\n text: _t,\n tooltip: _tt,\n href: _hr,\n // detail and order have no scale\n detail: _dd,\n key: _k,\n order: _oo,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n} = NONPOSITION_CHANNEL_INDEX;\nexport const NONPOSITION_SCALE_CHANNELS = flagKeys(NONPOSITION_SCALE_CHANNEL_INDEX);\nexport type NonPositionScaleChannel = typeof NONPOSITION_SCALE_CHANNELS[0];\n\nexport function isNonPositionScaleChannel(channel: Channel): channel is NonPositionScaleChannel {\n return !!NONPOSITION_CHANNEL_INDEX[channel];\n}\n\n/**\n * @returns whether Vega supports legends for a particular channel\n */\nexport function supportLegend(channel: NonPositionScaleChannel) {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n case SIZE:\n case SHAPE:\n case OPACITY:\n return true;\n\n case FILLOPACITY:\n case STROKEOPACITY:\n case STROKEWIDTH:\n return false;\n }\n}\n\n// Declare SCALE_CHANNEL_INDEX\nconst SCALE_CHANNEL_INDEX = {\n ...POSITION_SCALE_CHANNEL_INDEX,\n ...NONPOSITION_SCALE_CHANNEL_INDEX\n};\n\n/** List of channels with scales */\nexport const SCALE_CHANNELS = flagKeys(SCALE_CHANNEL_INDEX);\nexport type ScaleChannel = typeof SCALE_CHANNELS[0];\n\nexport function isScaleChannel(channel: Channel): channel is ScaleChannel {\n return !!SCALE_CHANNEL_INDEX[channel];\n}\n\nexport type SupportedMark = {[mark in Mark]?: 'always' | 'binned'};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return getSupportedMark(channel)[mark];\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to 'always', 'binned', or undefined\n */\nfunction getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case COLOR:\n case FILL:\n case STROKE:\n // falls through\n\n case DETAIL:\n case KEY:\n case TOOLTIP:\n case HREF:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n case STROKEWIDTH:\n // falls through\n\n case FACET:\n case ROW: // falls through\n case COLUMN:\n return {\n // all marks\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n rect: 'always',\n line: 'always',\n trail: 'always',\n area: 'always',\n text: 'always',\n geoshape: 'always'\n };\n case X:\n case Y:\n case LATITUDE:\n case LONGITUDE:\n return {\n // all marks except geoshape. geoshape does not use X, Y -- it uses a projection\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n rect: 'always',\n line: 'always',\n trail: 'always',\n area: 'always',\n text: 'always'\n };\n case X2:\n case Y2:\n case LATITUDE2:\n case LONGITUDE2:\n return {\n rule: 'always',\n bar: 'always',\n rect: 'always',\n area: 'always',\n circle: 'binned',\n point: 'binned',\n square: 'binned',\n tick: 'binned'\n };\n case SIZE:\n return {\n point: 'always',\n tick: 'always',\n rule: 'always',\n circle: 'always',\n square: 'always',\n bar: 'always',\n text: 'always',\n line: 'always',\n trail: 'always'\n };\n case SHAPE:\n return {point: 'always', geoshape: 'always'};\n case TEXT:\n return {text: 'always'};\n }\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case STROKEWIDTH:\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n\n // X2 and Y2 use X and Y scales, so they similarly have continuous range. [falls through]\n case X2:\n case Y2:\n return undefined;\n\n case FACET:\n case ROW:\n case COLUMN:\n case SHAPE:\n // TEXT, TOOLTIP, and HREF have no scale but have discrete output [falls through]\n case TEXT:\n case TOOLTIP:\n case HREF:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n case FILL:\n case STROKE:\n return 'flexible';\n\n // No scale, no range type.\n\n case LATITUDE:\n case LONGITUDE:\n case LATITUDE2:\n case LONGITUDE2:\n case DETAIL:\n case KEY:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('rangeType not implemented for ' + channel);\n}\n","import {\n Align,\n Axis as VgAxis,\n AxisOrient,\n BaseAxis,\n FontStyle,\n FontWeight,\n LabelOverlap,\n TextBaseline,\n TitleAnchor\n} from 'vega';\nimport {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {Color, LayoutAlign} from './vega.schema';\n\ntype BaseAxisNoSignals = AxisMixins &\n BaseAxis<\n number,\n number,\n boolean,\n number | boolean,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n number[],\n TitleAnchor\n >;\n\n// Vega axis config is the same as vega axis base. If this is not the case, add specific type.\ntype VgAxisConfigNoSignals = BaseAxisNoSignals;\n\n// Change comments to be Vega-Lite specific\ninterface AxisMixins {\n /**\n * A boolean flag indicating if grid lines should be included as part of the axis\n *\n * __Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.\n */\n grid?: boolean;\n\n /**\n * Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n *\n * __Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.\n */\n labelFlush?: boolean | number;\n\n /**\n * The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`.\n */\n labelOverlap?: LabelOverlap;\n}\n\nexport interface AxisOrientMixins {\n /**\n * The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y-axis oriented towards the right edge of the chart).\n *\n * __Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes.\n */\n orient?: AxisOrient;\n}\n\nexport type AxisConfig = VgAxisConfigNoSignals & VlOnlyGuideConfig & AxisOrientMixins;\n\nexport interface Axis extends AxisOrientMixins, BaseAxisNoSignals, Guide {\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n *\n * __Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axes with top or bottom orientation, this sets the axis group x coordinate. For y-axes with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n *\n * __Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.\n */\n tickCount?: number;\n\n /**\n * The minimum desired step between axis ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value.\n *\n * __Default value__: `undefined`\n */\n tickMinStep?: number;\n\n /**\n * Explicitly set the visible axis tick values.\n */\n values?: number[] | string[] | boolean[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use `\"zindex = 1\"`.\n *\n * __Default value:__ `1` (in front of the marks) for actual axis and `0` (behind the marks) for grids.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Mark definitions for custom axis encoding.\n *\n * @hide\n */\n encoding?: AxisEncoding;\n}\n\nexport type AxisPart = keyof AxisEncoding;\nexport const AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\n/**\n * A dictionary listing whether a certain axis property is applicable for only main axes or only grid axes.\n * (Properties not listed are applicable for both)\n */\nexport const AXIS_PROPERTY_TYPE: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in keyof VgAxis]: 'main' | 'grid' | 'both'\n} = {\n grid: 'grid',\n gridColor: 'grid',\n gridDash: 'grid',\n gridOpacity: 'grid',\n gridScale: 'grid',\n gridWidth: 'grid',\n\n orient: 'main',\n\n bandPosition: 'both', // Need to be applied to grid axis too, so the grid will align with ticks.\n domain: 'main',\n domainColor: 'main',\n domainOpacity: 'main',\n domainWidth: 'main',\n format: 'main',\n formatType: 'main',\n labelAlign: 'main',\n labelAngle: 'main',\n labelBaseline: 'main',\n labelBound: 'main',\n labelColor: 'main',\n labelFlush: 'main',\n labelFlushOffset: 'main',\n labelFont: 'main',\n labelFontSize: 'main',\n labelFontWeight: 'main',\n labelLimit: 'main',\n labelOpacity: 'main',\n labelOverlap: 'main',\n labelPadding: 'main',\n labels: 'main',\n maxExtent: 'main',\n minExtent: 'main',\n offset: 'main',\n position: 'main',\n tickColor: 'main',\n tickExtra: 'main',\n tickOffset: 'both', // Need to be applied to grid axis too, so the grid will align with ticks.\n tickOpacity: 'main',\n tickRound: 'main',\n ticks: 'main',\n tickSize: 'main',\n title: 'main',\n titleAlign: 'main',\n titleAngle: 'main',\n titleBaseline: 'main',\n titleColor: 'main',\n titleFont: 'main',\n titleFontSize: 'main',\n titleFontWeight: 'main',\n titleLimit: 'main',\n titleOpacity: 'main',\n titlePadding: 'main',\n titleX: 'main',\n titleY: 'main',\n\n tickWidth: 'both',\n tickCount: 'both',\n values: 'both',\n scale: 'both',\n zindex: 'both' // this is actually set afterward, so it doesn't matter\n};\n\nexport interface AxisEncoding {\n /**\n * Custom encoding for the axis container.\n */\n axis?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis domain rule mark.\n */\n domain?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis gridline rule marks.\n */\n grid?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for axis tick rule marks.\n */\n ticks?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the axis title text mark.\n */\n title?: GuideEncodingEntry;\n}\n\nconst COMMON_AXIS_PROPERTIES_INDEX: Flag = {\n orient: 1, // other things can depend on orient\n\n bandPosition: 1,\n domain: 1,\n domainColor: 1,\n domainDash: 1,\n domainDashOffset: 1,\n domainOpacity: 1,\n domainWidth: 1,\n format: 1,\n formatType: 1,\n grid: 1,\n gridColor: 1,\n gridDash: 1,\n gridDashOffset: 1,\n gridOpacity: 1,\n gridWidth: 1,\n labelAlign: 1,\n labelAngle: 1,\n labelBaseline: 1,\n labelBound: 1,\n labelColor: 1,\n labelFlush: 1,\n labelFlushOffset: 1,\n labelFont: 1,\n labelFontSize: 1,\n labelFontStyle: 1,\n labelFontWeight: 1,\n labelLimit: 1,\n labelOpacity: 1,\n labelOverlap: 1,\n labelPadding: 1,\n labels: 1,\n labelSeparation: 1,\n maxExtent: 1,\n minExtent: 1,\n offset: 1,\n position: 1,\n tickColor: 1,\n tickCount: 1,\n tickDash: 1,\n tickDashOffset: 1,\n tickExtra: 1,\n tickMinStep: 1,\n tickOffset: 1,\n tickOpacity: 1,\n tickRound: 1,\n ticks: 1,\n tickSize: 1,\n tickWidth: 1,\n title: 1,\n titleAlign: 1,\n titleAnchor: 1,\n titleAngle: 1,\n titleBaseline: 1,\n titleColor: 1,\n titleFont: 1,\n titleFontSize: 1,\n titleFontStyle: 1,\n titleFontWeight: 1,\n titleLimit: 1,\n titleOpacity: 1,\n titlePadding: 1,\n titleX: 1,\n titleY: 1,\n values: 1,\n zindex: 1\n};\n\nconst AXIS_PROPERTIES_INDEX: Flag = {\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encoding: 1\n};\n\nconst VG_AXIS_PROPERTIES_INDEX: Flag = {\n gridScale: 1,\n scale: 1,\n ...COMMON_AXIS_PROPERTIES_INDEX,\n encode: 1\n};\n\nexport function isAxisProperty(prop: string): prop is keyof Axis {\n return !!AXIS_PROPERTIES_INDEX[prop];\n}\n\nexport const VG_AXIS_PROPERTIES = flagKeys(VG_AXIS_PROPERTIES_INDEX);\n\n// Export for dependent projects\nexport const AXIS_PROPERTIES = flagKeys(AXIS_PROPERTIES_INDEX);\n\nexport interface AxisConfigMixins {\n /**\n * Axis configuration, which determines default properties for all `x` and `y` [axes](https://vega.github.io/vega-lite/docs/axis.html). For a full list of axis configuration options, please see the [corresponding section of the axis documentation](https://vega.github.io/vega-lite/docs/axis.html#config).\n */\n axis?: AxisConfig;\n\n /**\n * X-axis specific config.\n */\n axisX?: AxisConfig;\n\n /**\n * Y-axis specific config.\n */\n axisY?: AxisConfig;\n\n /**\n * Specific axis config for y-axis along the left edge of the chart.\n */\n axisLeft?: AxisConfig;\n\n /**\n * Specific axis config for y-axis along the right edge of the chart.\n */\n axisRight?: AxisConfig;\n\n /**\n * Specific axis config for x-axis along the top edge of the chart.\n */\n axisTop?: AxisConfig;\n\n /**\n * Specific axis config for x-axis along the bottom edge of the chart.\n */\n axisBottom?: AxisConfig;\n\n /**\n * Specific axis config for axes with \"band\" scales.\n */\n axisBand?: AxisConfig;\n}\n","import {\n Align,\n BaseLegend,\n FontStyle,\n FontWeight,\n LabelOverlap,\n Legend as VgLegend,\n LegendConfig as VgLegendConfig,\n LegendOrient,\n Orient,\n Orientation,\n SymbolShape,\n TextBaseline,\n TitleAnchor\n} from 'vega';\nimport {DateTime} from './datetime';\nimport {Guide, GuideEncodingEntry, VlOnlyGuideConfig} from './guide';\nimport {Flag, flagKeys} from './util';\nimport {Color, LayoutAlign} from './vega.schema';\n\nexport type LegendConfig = LegendMixins &\n VlOnlyGuideConfig &\n VgLegendConfig<\n number,\n number,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n SymbolShape,\n number[],\n Orient,\n TitleAnchor,\n LegendOrient\n > & {\n /**\n * Max legend length for a vertical gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `200`\n */\n gradientVerticalMaxLength?: number;\n\n /**\n * Min legend length for a vertical gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `100`\n */\n gradientVerticalMinLength?: number;\n\n /**\n * Max legend length for a horizontal gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `200`\n */\n gradientHorizontalMaxLength?: number;\n\n /**\n * Min legend length for a horizontal gradient when `config.legend.gradientLength` is undefined.\n *\n * __Default value:__ `100`\n */\n gradientHorizontalMinLength?: number;\n\n /**\n * The length in pixels of the primary axis of a color gradient. This value corresponds to the height of a vertical gradient or the width of a horizontal gradient.\n *\n * __Default value:__ `undefined`. If `undefined`, the default gradient will be determined based on the following rules:\n * - For vertical gradients, `clamp(plot_height, gradientVerticalMinLength, gradientVerticalMaxLength)`\n * - For top-`orient`ed or bottom-`orient`ed horizontal gradients, `clamp(plot_width, gradientHorizontalMinLength, gradientHorizontalMaxLength)`\n * - For other horizontal gradients, `gradientHorizontalMinLength`\n *\n * where `clamp(value, min, max)` restricts _value_ to be between the specified _min_ and _max_.\n * @minimum 0\n */\n gradientLength?: number;\n };\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend\n extends BaseLegend<\n number,\n number,\n string,\n Color,\n FontWeight,\n FontStyle,\n Align,\n TextBaseline,\n LayoutAlign,\n LabelOverlap,\n SymbolShape,\n number[],\n Orient,\n TitleAnchor,\n LegendOrient\n >,\n LegendMixins,\n Guide {\n /**\n * Mark definitions for custom legend encoding.\n *\n * @hide\n */\n encoding?: LegendEncoding;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * The minimum desired step between legend ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value.\n *\n * __Default value__: `undefined`\n */\n tickMinStep?: number;\n\n /**\n * Explicitly set the visible legend values.\n */\n values?: (number | string | boolean | DateTime)[];\n\n /**\n * The type of the legend. Use `\"symbol\"` to create a discrete legend and `\"gradient\"` for a continuous color gradient.\n *\n * __Default value:__ `\"gradient\"` for non-binned quantitative fields and temporal fields; `\"symbol\"` otherwise.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n *\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * The direction of the legend, one of `\"vertical\"` or `\"horizontal\"`.\n *\n * __Default value:__\n * - For top-/bottom-`orient`ed legends, `\"horizontal\"`\n * - For left-/right-`orient`ed legends, `\"vertical\"`\n * - For top/bottom-left/right-`orient`ed legends, `\"horizontal\"` for gradient legends and `\"vertical\"` for symbol legends.\n */\n direction?: Orientation;\n\n /**\n * The orientation of the legend, which determines how the legend is positioned within the scene. One of `\"left\"`, `\"right\"`, `\"top-left\"`, `\"top-right\"`, `\"bottom-left\"`, `\"bottom-right\"`, `\"none\"`.\n *\n * __Default value:__ `\"right\"`\n */\n orient?: LegendOrient;\n}\n\n// Change comments to be Vega-Lite specific\ninterface LegendMixins {\n /**\n * The strategy to use for resolving overlap of labels in gradient legends. If `false`, no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used. If set to `\"greedy\"`, a linear scan of the labels is performed, removing any label that overlaps with the last visible label (this often works better for log-scaled axes).\n *\n * __Default value:__ `\"greedy\"` for `log scales otherwise `true`.\n */\n labelOverlap?: LabelOverlap;\n}\n\nexport interface LegendEncoding {\n /**\n * Custom encoding for the legend container.\n * This can be useful for creating legend with custom x, y position.\n */\n legend?: GuideEncodingEntry;\n\n /**\n * Custom encoding for the legend title text mark.\n */\n title?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend label text marks.\n */\n labels?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend symbol marks.\n */\n symbols?: GuideEncodingEntry;\n\n /**\n * Custom encoding for legend gradient filled rect marks.\n */\n gradient?: GuideEncodingEntry;\n}\n\nexport const defaultLegendConfig: LegendConfig = {\n gradientHorizontalMaxLength: 200,\n gradientHorizontalMinLength: 100,\n gradientVerticalMaxLength: 200,\n gradientVerticalMinLength: 64 // This is the Vega's minimum.\n};\n\nconst COMMON_LEGEND_PROPERTY_INDEX: Flag = {\n clipHeight: 1,\n columnPadding: 1,\n columns: 1,\n cornerRadius: 1,\n direction: 1,\n fillColor: 1,\n format: 1,\n formatType: 1,\n gradientLength: 1,\n gradientOpacity: 1,\n gradientStrokeColor: 1,\n gradientStrokeWidth: 1,\n gradientThickness: 1,\n gridAlign: 1,\n labelAlign: 1,\n labelBaseline: 1,\n labelColor: 1,\n labelFont: 1,\n labelFontSize: 1,\n labelFontStyle: 1,\n labelFontWeight: 1,\n labelLimit: 1,\n labelOffset: 1,\n labelOpacity: 1,\n labelOverlap: 1,\n labelPadding: 1,\n labelSeparation: 1,\n legendX: 1,\n legendY: 1,\n offset: 1,\n orient: 1,\n padding: 1,\n rowPadding: 1,\n strokeColor: 1,\n symbolDash: 1,\n symbolDashOffset: 1,\n symbolFillColor: 1,\n symbolOffset: 1,\n symbolOpacity: 1,\n symbolSize: 1,\n symbolStrokeColor: 1,\n symbolStrokeWidth: 1,\n symbolType: 1,\n tickCount: 1,\n tickMinStep: 1,\n title: 1,\n titleAlign: 1,\n titleAnchor: 1,\n titleBaseline: 1,\n titleColor: 1,\n titleFont: 1,\n titleFontSize: 1,\n titleFontStyle: 1,\n titleFontWeight: 1,\n titleLimit: 1,\n titleOpacity: 1,\n titleOrient: 1,\n titlePadding: 1,\n type: 1,\n values: 1,\n zindex: 1\n};\n\nconst VG_LEGEND_PROPERTY_INDEX: Flag> = {\n ...COMMON_LEGEND_PROPERTY_INDEX,\n // channel scales\n opacity: 1,\n shape: 1,\n stroke: 1,\n fill: 1,\n size: 1,\n strokeWidth: 1,\n // encode\n encode: 1\n};\n\nexport const LEGEND_PROPERTIES = flagKeys(COMMON_LEGEND_PROPERTY_INDEX);\n\nexport const VG_LEGEND_PROPERTIES = flagKeys(VG_LEGEND_PROPERTY_INDEX);\n","/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\nimport * as message_ from './message';\n\nexport const message = message_;\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n\n public error(...args: any[]) {\n throw Error(...args);\n return this; // @ts-ignore\n }\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n current = new LocalLogger();\n f(current as LocalLogger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(newLogger: LoggerInterface) {\n current = newLogger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n","import {AggregateOp} from 'vega';\nimport {CompositeMark} from '../compositemark';\nimport {Aggregate} from '../aggregate';\nimport {Channel, FacetChannel, GeoPositionChannel} from '../channel';\nimport {TypedFieldDef} from '../channeldef';\nimport {ErrorBarCenter, ErrorBarExtent} from '../compositemark/errorbar';\nimport {DateTime, DateTimeExpr} from '../datetime';\nimport {Mark} from '../mark';\nimport {Projection} from '../projection';\nimport {ScaleType} from '../scale';\nimport {Type} from '../type';\nimport {stringify} from '../util';\nimport {VgSortField} from '../vega.schema';\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\n\nexport const INVALID_SPEC = 'Invalid spec';\n\n// FIT\nexport const FIT_NON_SINGLE = 'Autosize \"fit\" only works for single views and layered views.';\n\nexport const CANNOT_FIX_RANGE_STEP_WITH_FIT = 'Cannot use a fixed value of \"rangeStep\" when \"autosize\" is \"fit\".';\n\n// SELECTION\nexport function cannotProjectOnChannelWithoutField(channel: Channel) {\n return `Cannot project a selection on encoding channel \"${channel}\", which has no field.`;\n}\n\nexport function nearestNotSupportForContinuous(mark: string) {\n return `The \"nearest\" transform is not supported for ${mark} marks.`;\n}\n\nexport function selectionNotSupported(mark: CompositeMark) {\n return `Selection not supported for ${mark} yet`;\n}\n\nexport function selectionNotFound(name: string) {\n return `Cannot find a selection named \"${name}\"`;\n}\n\nexport const SCALE_BINDINGS_CONTINUOUS =\n 'Scale bindings are currently only supported for scales with unbinned, continuous domains.';\n\nexport const NO_INIT_SCALE_BINDINGS = 'Selections bound to scales cannot be separately initialized.';\n\n// REPEAT\nexport function noSuchRepeatedValue(field: string) {\n return `Unknown repeated value \"${field}\".`;\n}\n\nexport function columnsNotSupportByRowCol(type: 'facet' | 'repeat') {\n return `The \"columns\" property cannot be used when \"${type}\" has nested row/column.`;\n}\n\n// CONCAT\nexport const CONCAT_CANNOT_SHARE_AXIS =\n 'Axes cannot be shared in concatenated views yet (https://github.com/vega/vega-lite/issues/2415).';\n\n// REPEAT\nexport const REPEAT_CANNOT_SHARE_AXIS =\n 'Axes cannot be shared in repeated views yet (https://github.com/vega/vega-lite/issues/2415).';\n\n// DATA\nexport function unrecognizedParse(p: string) {\n return `Unrecognized parse \"${p}\".`;\n}\n\nexport function differentParse(field: string, local: string, ancestor: string) {\n return `An ancestor parsed field \"${field}\" as ${ancestor} but a child wants to parse the field as ${local}.`;\n}\n\n// TRANSFORMS\nexport function invalidTransformIgnored(transform: any) {\n return `Ignoring an invalid transform: ${stringify(transform)}.`;\n}\n\nexport const NO_FIELDS_NEEDS_AS =\n 'If \"from.fields\" is not specified, \"as\" has to be a string that specifies the key to be used for the data from the secondary source.';\n\n// ENCODING & FACET\n\nexport function encodingOverridden(channels: Channel[]) {\n return `Layer's shared ${channels.join(',')} channel ${channels.length === 1 ? 'is' : 'are'} overriden`;\n}\nexport function projectionOverridden(opt: {parentProjection: Projection; projection: Projection}) {\n const {parentProjection, projection} = opt;\n return `Layer's shared projection ${stringify(parentProjection)} is overridden by a child projection ${stringify(\n projection\n )}.`;\n}\n\nexport function primitiveChannelDef(\n channel: Channel,\n type: 'string' | 'number' | 'boolean',\n value: string | number | boolean\n) {\n return `Channel ${channel} is a ${type}. Converted to {value: ${stringify(value)}}.`;\n}\n\nexport function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n}\n\nexport function nonZeroScaleUsedWithLengthMark(\n mark: 'bar' | 'area',\n channel: Channel,\n opt: {scaleType?: ScaleType; zeroFalse?: boolean}\n) {\n const scaleText = opt.scaleType\n ? `${opt.scaleType} scale`\n : opt.zeroFalse\n ? 'scale with zero=false'\n : 'scale with custom domain that excludes zero';\n\n return `A ${scaleText} is used to encode ${mark}'s ${channel}. This can be misleading as the ${\n channel === 'x' ? 'width' : 'height'\n } of the ${mark} can be arbitrary based on the scale domain. You may want to use point mark instead.`;\n}\n\nexport function invalidFieldTypeForCountAggregate(type: Type, aggregate: Aggregate | string) {\n return `Invalid field type \"${type}\" for aggregate: \"${aggregate}\", using \"quantitative\" instead.`;\n}\n\nexport function invalidAggregate(aggregate: AggregateOp | string) {\n return `Invalid aggregation operator \"${aggregate}\"`;\n}\n\nexport function missingFieldType(channel: Channel, newType: Type) {\n return `Missing type for channel \"${channel}\", using \"${newType}\" instead.`;\n}\nexport function droppingColor(type: 'encoding' | 'property', opt: {fill?: boolean; stroke?: boolean}) {\n const {fill, stroke} = opt;\n return (\n `Dropping color ${type} as the plot also has ` + (fill && stroke ? 'fill and stroke' : fill ? 'fill' : 'stroke')\n );\n}\n\nexport function emptyFieldDef(fieldDef: TypedFieldDef, channel: Channel) {\n return `Dropping ${stringify(fieldDef)} from channel \"${channel}\" since it does not contain data field or value.`;\n}\nexport function latLongDeprecated(channel: Channel, type: Type, newChannel: GeoPositionChannel) {\n return `${channel}-encoding with type ${type} is deprecated. Replacing with ${newChannel}-encoding.`;\n}\n\nexport const LINE_WITH_VARYING_SIZE =\n 'Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.';\n\nexport function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet' | CompositeMark, when?: string) {\n return `${channel} dropped as it is incompatible with \"${markOrFacet}\"${when ? ` when ${when}` : ''}.`;\n}\n\nexport function invalidEncodingChannel(channel: string) {\n return `${channel}-encoding is dropped as ${channel} is not a valid encoding channel.`;\n}\n\nexport function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n}\n\nexport function facetChannelDropped(channels: FacetChannel[]) {\n return `Facet encoding dropped as ${channels.join(' and ')} ${channels.length > 1 ? 'are' : 'is'} also specified.`;\n}\n\nexport function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel \"${channel}\" to encode \"${type}\" field can be misleading as it does not encode ${\n type === 'ordinal' ? 'order' : 'magnitude'\n }.`;\n}\n\n// Mark\nexport const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL =\n 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\nexport function lineWithRange(hasX2: boolean, hasY2: boolean) {\n const channels = hasX2 && hasY2 ? 'x2 and y2' : hasX2 ? 'x2' : 'y2';\n return `Line mark is for continuous lines and thus cannot be used with ${channels}. We will use the rule mark (line segments) instead.`;\n}\n\nexport function orientOverridden(original: string, actual: string) {\n return `Specified orient \"${original}\" overridden with \"${actual}\"`;\n}\n\n// SCALE\nexport const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN =\n 'custom domain scale cannot be unioned with default field-based domain';\n\nexport function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use the scale property \"${prop}\" with non-color channel.`;\n}\n\nexport function unaggregateDomainHasNoEffectForRawField(fieldDef: TypedFieldDef) {\n return `Using unaggregated domain with raw field has no effect (${stringify(fieldDef)}).`;\n}\n\nexport function unaggregateDomainWithNonSharedDomainOp(aggregate: Aggregate | string) {\n return `Unaggregated domain not applicable for \"${aggregate}\" since it produces values outside the origin domain of the source data.`;\n}\n\nexport function unaggregatedDomainWithLogScale(fieldDef: TypedFieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${stringify(fieldDef)}).`;\n}\n\nexport function cannotApplySizeToNonOrientedMark(mark: Mark) {\n return `Cannot apply size to non-oriented mark \"${mark}\".`;\n}\n\nexport function rangeStepDropped(channel: Channel) {\n return `rangeStep for \"${channel}\" is dropped as top-level ${channel === 'x' ? 'width' : 'height'} is provided.`;\n}\n\nexport function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel \"${channel}\" does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n}\n\nexport function scaleTypeNotWorkWithFieldDef(scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `FieldDef does not work with \"${scaleType}\" scale. We are using \"${defaultScaleType}\" scale instead.`;\n}\n\nexport function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n}\n\nexport function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark \"${mark}\".`;\n}\n\nexport function mergeConflictingProperty(\n property: string | number | symbol,\n propertyOf: string | number | symbol,\n v1: T,\n v2: T\n) {\n return `Conflicting ${propertyOf.toString()} property \"${property.toString()}\" (${stringify(v1)} and ${stringify(\n v2\n )}). Using ${stringify(v1)}.`;\n}\n\nexport function independentScaleMeansIndependentGuide(channel: Channel) {\n return `Setting the scale to be independent for \"${channel}\" means we also have to set the guide (axis or legend) to be independent.`;\n}\n\nexport function domainSortDropped(sort: VgSortField) {\n return `Dropping sort property ${stringify(sort)} as unioned domains only support boolean or op 'count'.`;\n}\n\nexport const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\nexport const MORE_THAN_ONE_SORT =\n 'Domains that should be unioned has conflicting sort properties. Sort will be set to true.';\n\n// AXIS\nexport const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n// STACK\nexport function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack \"${channel}\" if there is already \"${channel}2\"`;\n}\n\nexport function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n}\n\nexport function stackNonSummativeAggregate(aggregate: Aggregate | string) {\n return `Stacking is applied even though the aggregate function is non-summative (\"${aggregate}\")`;\n}\n\n// TIMEUNIT\nexport function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${stringify(value)}`;\n}\n\nexport function dayReplacedWithDate(fullTimeUnit: string) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ${fullTimeUnit.replace(\n 'day',\n 'date'\n )}.`;\n}\n\nexport function droppedDay(d: DateTime | DateTimeExpr) {\n return `Dropping day from datetime ${stringify(d)} as day cannot be combined with other units.`;\n}\n\nexport function errorBarCenterAndExtentAreNotNeeded(center: ErrorBarCenter, extent: ErrorBarExtent) {\n return `${extent ? 'extent ' : ''}${extent && center ? 'and ' : ''}${center ? 'center ' : ''}${\n extent && center ? 'are ' : 'is '\n }not needed when data are aggregated.`;\n}\n\nexport function errorBarCenterIsUsedWithWrongExtent(\n center: ErrorBarCenter,\n extent: ErrorBarExtent,\n mark: 'errorbar' | 'errorband'\n) {\n return `${center} is not usually used with ${extent} for ${mark}.`;\n}\n\nexport function errorBarContinuousAxisHasCustomizedAggregate(\n aggregate: Aggregate | string,\n compositeMark: CompositeMark\n) {\n return `Continuous axis should not have customized aggregation function ${aggregate}; ${compositeMark} already agregates the axis.`;\n}\n\nexport function errorBarCenterIsNotNeeded(extent: ErrorBarExtent, mark: 'errorbar' | 'errorband') {\n return `Center is not needed to be specified in ${mark} when extent is ${extent}.`;\n}\n\nexport function errorBand1DNotSupport(property: 'interpolate' | 'tension') {\n return `1D error band does not support ${property}`;\n}\n\n// CHANNEL\nexport function channelRequiredForBinned(channel: Channel) {\n return `Channel ${channel} is required for \"binned\" bin`;\n}\n\nexport function domainRequiredForThresholdScale(channel: Channel) {\n return `Domain for ${channel} is required for threshold scale`;\n}\n","import {Flag} from './util';\n/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport const TYPE_INDEX: Flag = {\n quantitative: 1,\n ordinal: 1,\n temporal: 1,\n nominal: 1,\n geojson: 1\n};\n\nexport function isType(t: any): t is Type {\n return !!TYPE_INDEX[t];\n}\n\nexport const QUANTITATIVE: 'quantitative' = 'quantitative';\nexport const ORDINAL: 'ordinal' = 'ordinal';\nexport const TEMPORAL: 'temporal' = 'temporal';\nexport const NOMINAL: 'nominal' = 'nominal';\n\nexport const GEOJSON: 'geojson' = 'geojson';\n\nexport type StandardType = typeof QUANTITATIVE | typeof ORDINAL | typeof TEMPORAL | typeof NOMINAL;\n\nexport type Type = StandardType | typeof GEOJSON;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type | string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n case GEOJSON:\n return 'geojson';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","import {toSet} from 'vega-util';\nimport * as CHANNEL from './channel';\nimport {Channel, CHANNELS, isColorChannel} from './channel';\nimport {FieldName} from './channeldef';\nimport {DateTime} from './datetime';\nimport * as log from './log';\nimport * as TYPE from './type';\nimport {Type, TYPE_INDEX} from './type';\nimport {contains, Flag, flagKeys, keys} from './util';\nimport {ScaleInterpolate, ScaleInterpolateParams} from './vega.schema';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n export const SYMLOG: 'symlog' = 'symlog';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n\n // Discretizing scales\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n\n // Discrete scales\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType =\n | typeof ScaleType.LINEAR\n | typeof ScaleType.LOG\n | typeof ScaleType.POW\n | typeof ScaleType.SQRT\n | typeof ScaleType.SYMLOG\n | typeof ScaleType.TIME\n | typeof ScaleType.UTC\n | typeof ScaleType.QUANTILE\n | typeof ScaleType.QUANTIZE\n | typeof ScaleType.THRESHOLD\n | typeof ScaleType.BIN_ORDINAL\n | typeof ScaleType.ORDINAL\n | typeof ScaleType.POINT\n | typeof ScaleType.BAND;\n\n/**\n * Index for scale categories -- only scale of the same categories can be merged together.\n * Current implementation is trying to be conservative and avoid merging scale type that might not work together\n */\nconst SCALE_CATEGORY_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: ScaleType | 'numeric' | 'ordinal-position' | 'discretizing'\n} = {\n linear: 'numeric',\n log: 'numeric',\n pow: 'numeric',\n sqrt: 'numeric',\n symlog: 'numeric',\n time: 'time',\n utc: 'time',\n ordinal: 'ordinal',\n 'bin-ordinal': 'bin-ordinal', // TODO: should bin-ordinal support merging with other\n point: 'ordinal-position',\n band: 'ordinal-position',\n quantile: 'discretizing',\n quantize: 'discretizing',\n threshold: 'discretizing'\n};\n\nexport const SCALE_TYPES = keys(SCALE_CATEGORY_INDEX) as ScaleType[];\n\n/**\n * Whether the two given scale types can be merged together.\n */\nexport function scaleCompatible(scaleType1: ScaleType, scaleType2: ScaleType) {\n const scaleCategory1 = SCALE_CATEGORY_INDEX[scaleType1];\n const scaleCategory2 = SCALE_CATEGORY_INDEX[scaleType2];\n return (\n scaleCategory1 === scaleCategory2 ||\n (scaleCategory1 === 'ordinal-position' && scaleCategory2 === 'time') ||\n (scaleCategory2 === 'ordinal-position' && scaleCategory1 === 'time')\n );\n}\n\n/**\n * Index for scale precedence -- high score = higher priority for merging.\n */\nconst SCALE_PRECEDENCE_INDEX: {\n // Using Mapped Type to declare type (https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)\n [k in ScaleType]: number\n} = {\n // numeric\n linear: 0,\n log: 1,\n pow: 1,\n sqrt: 1,\n symlog: 1,\n // time\n time: 0,\n utc: 0,\n // ordinal-position -- these have higher precedence than continuous scales as they support more types of data\n point: 10,\n band: 11, // band has higher precedence as it is better for interaction\n // non grouped types\n ordinal: 0,\n 'bin-ordinal': 0,\n quantile: 0,\n quantize: 0,\n threshold: 0\n};\n\n/**\n * Return scale categories -- only scale of the same categories can be merged together.\n */\nexport function scaleTypePrecedence(scaleType: ScaleType): number {\n return SCALE_PRECEDENCE_INDEX[scaleType];\n}\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'log', 'pow', 'sqrt', 'symlog', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_TO_DISCRETE_SCALES: ScaleType[] = ['quantile', 'quantize', 'threshold'];\nconst CONTINUOUS_TO_DISCRETE_INDEX = toSet(CONTINUOUS_TO_DISCRETE_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat([\n 'quantile',\n 'quantize',\n 'threshold'\n]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function hasContinuousDomain(\n type: ScaleType\n): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'time' | 'utc' | 'quantile' | 'quantize' | 'threshold' {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(\n type: ScaleType\n): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport function isContinuousToDiscrete(type: ScaleType): type is 'quantile' | 'quantize' | 'threshold' {\n return type in CONTINUOUS_TO_DISCRETE_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, and `size` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` band and point scales of text marks.\n *\n * __Default value:__ `90`\n *\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n\n /**\n * Default range step for band and point scales of (1) the `y` channel\n * and (2) the `x` channel when the mark is not `text`.\n *\n * __Default value:__ `20`\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n *\n * __Default value:__\n * - `barBandPaddingInner` for bar marks (`0.1` by default)\n * - `rectBandPaddingInner` for rect and other marks (`0` by default)\n *\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n *\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales of `\"bar\"` marks.\n *\n * __Default value:__ `0.1`\n *\n * @minimum 0\n * @maximum 1\n */\n barBandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales of `\"bar\"` marks.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n barBandPaddingOuter?: number;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales of `\"rect\"` marks.\n *\n * __Default value:__ `0`\n *\n * @minimum 0\n * @maximum 1\n */\n rectBandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales of `\"rect\"` marks.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n rectBandPaddingOuter?: number;\n\n /**\n * Default padding for continuous scales.\n *\n * __Default:__ `5` for continuous x-scale of a vertical bar and continuous y-scale of a horizontal bar.; `0` otherwise.\n *\n * @minimum 0\n */\n continuousPadding?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n *\n * __Default value:__ `0.5`\n *\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n *\n * This is equivalent to setting `domain` to `\"unaggregate\"` for aggregated _quantitative_ fields by default.\n *\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n *\n * __Default value:__ `false`\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n *\n * If undefined (default), we will use the scale's `rangeStep` - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false.\n *\n * __Default value:__ `2`\n *\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n *\n * __Default value:__ `40`\n *\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n *\n * __Default value:__ `8`\n *\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.3`\n *\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n *\n * __Default value:__ `0.8`\n *\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n /**\n * Default minimum value for point size scale with zero=false.\n *\n * __Default value:__ `9`\n *\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks with zero=false.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for the scale of strokeWidth for rule and line marks and of size for trail marks.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n maxStrokeWidth?: number;\n\n /**\n * Default range cardinality for [`quantile`](https://vega.github.io/vega-lite/docs/scale.html#quantile) scale.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n quantileCount?: number;\n\n /**\n * Default range cardinality for [`quantize`](https://vega.github.io/vega-lite/docs/scale.html#quantize) scale.\n *\n * __Default value:__ `4`\n *\n * @minimum 0\n */\n quantizeCount?: number;\n}\n\nexport const defaultScaleConfig: ScaleConfig = {\n textXRangeStep: 90,\n rangeStep: 20,\n pointPadding: 0.5,\n\n barBandPaddingInner: 0.1,\n rectBandPaddingInner: 0,\n\n minBandSize: 2,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4,\n quantileCount: 4,\n quantizeCount: 4\n};\n\nexport interface SchemeParams {\n /**\n * A color scheme name for ordinal scales (e.g., `\"category10\"` or `\"blues\"`).\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n name: string;\n\n /**\n * The extent of the color range to use. For example `[0.2, 1]` will rescale the color scheme such that color values in the range _[0, 0.2)_ are excluded from the scheme.\n */\n extent?: number[];\n\n /**\n * The number of colors to use in the scheme. This can be useful for scale types such as `\"quantize\"`, which use the length of the scale range to determine the number of discrete bins for the scale domain.\n */\n count?: number;\n}\n\nexport type SelectionDomain =\n | {\n /**\n * The name of a selection.\n */\n selection: string;\n /**\n * The field name to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n field?: FieldName;\n }\n | {\n /**\n * The name of a selection.\n */\n selection: string;\n /**\n * The encoding channel to extract selected values for, when a selection is [projected](https://vega.github.io/vega-lite/docs/project.html)\n * over multiple fields or encodings.\n */\n encoding?: string;\n };\n\nexport type Domain = number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\nexport type Scheme = string | SchemeParams;\n\nexport function isExtendedScheme(scheme: string | SchemeParams): scheme is SchemeParams {\n return scheme && !!scheme['name'];\n}\n\nexport function isSelectionDomain(domain: Domain): domain is SelectionDomain {\n return domain && domain['selection'];\n}\n\nexport interface Scale {\n /**\n * The type of scale. Vega-Lite supports the following categories of scale types:\n *\n * 1) [**Continuous Scales**](https://vega.github.io/vega-lite/docs/scale.html#continuous) -- mapping continuous domains to continuous output ranges ([`\"linear\"`](https://vega.github.io/vega-lite/docs/scale.html#linear), [`\"pow\"`](https://vega.github.io/vega-lite/docs/scale.html#pow), [`\"sqrt\"`](https://vega.github.io/vega-lite/docs/scale.html#sqrt), [`\"symlog\"`](https://vega.github.io/vega-lite/docs/scale.html#symlog), [`\"log\"`](https://vega.github.io/vega-lite/docs/scale.html#log), [`\"time\"`](https://vega.github.io/vega-lite/docs/scale.html#time), [`\"utc\"`](https://vega.github.io/vega-lite/docs/scale.html#utc).\n *\n * 2) [**Discrete Scales**](https://vega.github.io/vega-lite/docs/scale.html#discrete) -- mapping discrete domains to discrete ([`\"ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#ordinal)) or continuous ([`\"band\"`](https://vega.github.io/vega-lite/docs/scale.html#band) and [`\"point\"`](https://vega.github.io/vega-lite/docs/scale.html#point)) output ranges.\n *\n * 3) [**Discretizing Scales**](https://vega.github.io/vega-lite/docs/scale.html#discretizing) -- mapping continuous domains to discrete output ranges [`\"bin-ordinal\"`](https://vega.github.io/vega-lite/docs/scale.html#bin-ordinal), [`\"quantile\"`](https://vega.github.io/vega-lite/docs/scale.html#quantile), [`\"quantize\"`](https://vega.github.io/vega-lite/docs/scale.html#quantize) and [`\"threshold\"`](https://vega.github.io/vega-lite/docs/scale.html#threshold).\n *\n * __Default value:__ please see the [scale type table](https://vega.github.io/vega-lite/docs/scale.html#type).\n */\n type?: ScaleType;\n\n /**\n * Customized domain values.\n *\n * For _quantitative_ fields, `domain` can take the form of a two-element array with minimum and maximum values. [Piecewise scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise) can be created by providing a `domain` with more than two entries.\n * If the input field is aggregated, `domain` can also be a string value `\"unaggregated\"`, indicating that the domain should include the raw data values prior to the aggregation.\n *\n * For _temporal_ fields, `domain` can be a two-element array minimum and maximum values, in the form of either timestamps or the [DateTime definition objects](https://vega.github.io/vega-lite/docs/types.html#datetime).\n *\n * For _ordinal_ and _nominal_ fields, `domain` can be an array that lists valid input values.\n *\n * The `selection` property can be used to [interactively determine](https://vega.github.io/vega-lite/docs/selection.html#scale-domains) the scale domain.\n */\n domain?: number[] | string[] | boolean[] | DateTime[] | 'unaggregated' | SelectionDomain;\n\n // Hide because we might not really need this.\n /**\n * If true, reverses the order of the scale range.\n * __Default value:__ `false`.\n *\n * @hide\n */\n reverse?: boolean;\n\n /**\n * The range of the scale. One of:\n *\n * - A string indicating a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config) (e.g., example, `\"symbol\"`, or `\"diverging\"`).\n *\n * - For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous), two-element array indicating minimum and maximum values, or an array with more than two entries for specifying a [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).\n *\n * - For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales, an array of desired output values.\n *\n * __Notes:__\n *\n * 1) For color scales you can also specify a color [`scheme`](https://vega.github.io/vega-lite/docs/scale.html#scheme) instead of `range`.\n *\n * 2) Any directly specified `range` for `x` and `y` channels will be ignored. Range can be customized via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` and `height`) or via [range steps and paddings properties](#range-step) for [band](#band) and [point](#point) scales.\n */\n range?: number[] | string[] | string;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in [band](https://vega.github.io/vega-lite/docs/scale.html#band) and [point](https://vega.github.io/vega-lite/docs/scale.html#point) scales.\n *\n * If `rangeStep` is `null` or if the view contains the scale's corresponding [size](https://vega.github.io/vega-lite/docs/size.html) (`width` for `x` scales and `height` for `y` scales), `rangeStep` will be automatically determined to fit the size of the view.\n *\n * __Default value:__ derived the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `textXRangeStep` (`90` by default) for x-scales of `text` marks and `rangeStep` (`21` by default) for x-scales of other marks and y-scales.\n *\n * __Warning__: If `rangeStep` is `null` and the cardinality of the scale's domain is higher than `width` or `height`, the rangeStep might become less than one pixel and the mark might not appear correctly.\n *\n * @minimum 0\n */\n rangeStep?: number | null;\n\n /**\n * A string indicating a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme) name (e.g., `\"category10\"` or `\"blues\"`) or a [scheme parameter object](https://vega.github.io/vega-lite/docs/scale.html#scheme-params).\n *\n * Discrete color schemes may be used with [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete) or [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing) scales. Continuous color schemes are intended for use with color scales.\n *\n * For the full list of supported schemes, please refer to the [Vega Scheme](https://vega.github.io/vega/docs/schemes/#reference) reference.\n */\n scheme?: string | SchemeParams;\n\n /**\n * An array of bin boundaries over the scale domain. If provided, axes and legends will use the bin boundaries to inform the choice of tick marks and text labels.\n */\n bins?: number[];\n\n /**\n * If `true`, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default value:__ `false`.\n */\n round?: boolean;\n\n /**\n * For _[continuous](https://vega.github.io/vega-lite/docs/scale.html#continuous)_ scales, expands the scale domain to accommodate the specified number of pixels on each of the scale range. The scale range must represent pixels for this parameter to function as intended. Padding adjustment is performed prior to all other adjustments, including the effects of the `zero`, `nice`, `domainMin`, and `domainMax` properties.\n *\n * For _[band](https://vega.github.io/vega-lite/docs/scale.html#band)_ scales, shortcut for setting `paddingInner` and `paddingOuter` to the same value.\n *\n * For _[point](https://vega.github.io/vega-lite/docs/scale.html#point)_ scales, alias for `paddingOuter`.\n *\n * __Default value:__ For _continuous_ scales, derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `continuousPadding`.\n * For _band and point_ scales, see `paddingInner` and `paddingOuter`.\n *\n * @minimum 0\n */\n padding?: number;\n\n /**\n * The inner padding (spacing) within each band step of band scales, as a fraction of the step size. This value must lie in the range [0,1].\n *\n * For point scale, this property is invalid as point scales do not have internal band widths (only step sizes between bands).\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingInner`.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding (spacing) at the ends of the range of band and point scales,\n * as a fraction of the step size. This value must lie in the range [0,1].\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/scale.html#config)'s `bandPaddingOuter` for band scales and `pointPadding` for point scales.\n *\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If `true`, values that exceed the data domain are clamped to either the minimum or maximum range value\n *\n * __Default value:__ derived from the [scale config](https://vega.github.io/vega-lite/docs/config.html#scale-config)'s `clamp` (`true` by default).\n */\n clamp?: boolean;\n\n /**\n * Extending the domain so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. Nicing is useful if the domain is computed from data and may be irregular. For example, for a domain of _[0.201479…, 0.996679…]_, a nice domain might be _[0.2, 1.0]_.\n *\n * For quantitative scales such as linear, `nice` can be either a boolean flag or a number. If `nice` is a number, it will represent a desired tick count. This allows greater control over the step size used to extend the bounds, guaranteeing that the returned ticks will exactly cover the domain.\n *\n * For temporal fields with time and utc scales, the `nice` value can be a string indicating the desired time interval. Legal values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, `time` and `utc` scales can accept an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}`, which includes a desired number of interval steps. Here, the domain would snap to quarter (Jan, Apr, Jul, Oct) boundaries.\n *\n * __Default value:__ `true` for unbinned _quantitative_ fields; `false` otherwise.\n *\n */\n nice?: boolean | number | NiceTime | {interval: string; step: number};\n\n /**\n * The logarithm base of the `log` scale (default `10`).\n */\n base?: number;\n\n /**\n * The exponent of the `pow` scale.\n */\n exponent?: number;\n\n /**\n * A constant determining the slope of the symlog function around zero. Only used for `symlog` scales.\n *\n * __Default value:__ `1`\n */\n constant?: number;\n\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n *\n * __Default value:__ `true` for x and y channels if the quantitative field is not binned and no custom `domain` is provided; `false` otherwise.\n *\n * __Note:__ Log, time, and utc scales do not support `zero`.\n */\n zero?: boolean;\n\n /**\n * The interpolation method for range values. By default, a general interpolator for numbers, dates, strings and colors (in HCL space) is used. For color ranges, this property allows interpolation in alternative color spaces. Legal values include `rgb`, `hsl`, `hsl-long`, `lab`, `hcl`, `hcl-long`, `cubehelix` and `cubehelix-long` ('-long' variants use longer paths in polar coordinate spaces). If object-valued, this property accepts an object with a string-valued _type_ property and an optional numeric _gamma_ property applicable to rgb and cubehelix interpolators. For more, see the [d3-interpolate documentation](https://github.com/d3/d3-interpolate).\n *\n * * __Default value:__ `hcl`\n */\n interpolate?: ScaleInterpolate | ScaleInterpolateParams;\n}\n\nconst SCALE_PROPERTY_INDEX: Flag = {\n type: 1,\n domain: 1,\n range: 1,\n rangeStep: 1,\n scheme: 1,\n bins: 1,\n // Other properties\n reverse: 1,\n round: 1,\n // quantitative / time\n clamp: 1,\n nice: 1,\n // quantitative\n base: 1,\n exponent: 1,\n constant: 1,\n interpolate: 1,\n zero: 1, // zero depends on domain\n // band/point\n padding: 1,\n paddingInner: 1,\n paddingOuter: 1\n};\n\nexport const SCALE_PROPERTIES = flagKeys(SCALE_PROPERTY_INDEX);\n\nconst {\n type,\n domain,\n range,\n rangeStep,\n scheme,\n ...NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX\n} = SCALE_PROPERTY_INDEX;\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = flagKeys(NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTY_INDEX);\n\nexport const SCALE_TYPE_INDEX = generateScaleTypeIndex();\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'reverse':\n case 'range':\n return true;\n case 'scheme':\n case 'interpolate':\n return !contains(['point', 'band', 'identity'], scaleType);\n case 'bins':\n return !contains(['point', 'band', 'identity', 'ordinal'], scaleType);\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'padding':\n return isContinuousToContinuous(scaleType) || contains(['point', 'band'], scaleType);\n case 'paddingOuter':\n case 'rangeStep':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType);\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'quantize' || scaleType === 'threshold';\n case 'exponent':\n return scaleType === 'pow';\n case 'base':\n return scaleType === 'log';\n case 'constant':\n return scaleType === 'symlog';\n case 'zero':\n return (\n hasContinuousDomain(scaleType) &&\n !contains(\n [\n 'log', // log scale cannot have zero value\n 'time',\n 'utc', // zero is not meaningful for time\n 'threshold', // threshold requires custom domain so zero does not matter\n 'quantile' // quantile depends on distribution so zero does not matter\n ],\n scaleType\n )\n );\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'interpolate':\n case 'scheme':\n if (!isColorChannel(channel)) {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'bins':\n case 'domain':\n case 'range':\n case 'base':\n case 'exponent':\n case 'constant':\n case 'nice':\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n case 'rangeStep':\n case 'reverse':\n case 'round':\n case 'clamp':\n case 'zero':\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error(`Invalid scale property \"${propName}\".`);\n}\n\nexport function scaleTypeSupportDataType(specifiedType: ScaleType, fieldDefType: Type): boolean {\n if (contains([TYPE.ORDINAL, TYPE.NOMINAL], fieldDefType)) {\n return specifiedType === undefined || hasDiscreteDomain(specifiedType);\n } else if (fieldDefType === TYPE.TEMPORAL) {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], specifiedType);\n } else if (fieldDefType === TYPE.QUANTITATIVE) {\n return contains(\n [\n ScaleType.LOG,\n ScaleType.POW,\n ScaleType.SQRT,\n ScaleType.SYMLOG,\n ScaleType.QUANTILE,\n ScaleType.QUANTIZE,\n ScaleType.THRESHOLD,\n ScaleType.LINEAR,\n undefined\n ],\n specifiedType\n );\n }\n\n return true;\n}\n\nexport function channelSupportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case CHANNEL.X:\n case CHANNEL.Y:\n return isContinuousToContinuous(scaleType) || contains(['band', 'point'], scaleType);\n case CHANNEL.SIZE: // TODO: size and opacity can support ordinal with more modification\n case CHANNEL.STROKEWIDTH:\n case CHANNEL.OPACITY:\n case CHANNEL.FILLOPACITY:\n case CHANNEL.STROKEOPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return (\n isContinuousToContinuous(scaleType) ||\n isContinuousToDiscrete(scaleType) ||\n contains(['band', 'point'], scaleType)\n );\n case CHANNEL.COLOR:\n case CHANNEL.FILL:\n case CHANNEL.STROKE:\n return scaleType !== 'band'; // band does not make sense with color\n case CHANNEL.SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function getSupportedScaleType(channel: Channel, fieldDefType: Type) {\n return SCALE_TYPE_INDEX[generateScaleTypeIndexKey(channel, fieldDefType)];\n}\n\nexport interface ScaleTypeIndex {\n [channel: string]: ScaleType[];\n}\n\n// generates ScaleTypeIndex where keys are encoding channels and values are list of valid ScaleTypes\nfunction generateScaleTypeIndex() {\n const index: ScaleTypeIndex = {};\n for (const channel of CHANNELS) {\n for (const fieldDefType of keys(TYPE_INDEX)) {\n for (const scaleType of SCALE_TYPES) {\n const key = generateScaleTypeIndexKey(channel, fieldDefType);\n if (channelSupportScaleType(channel, scaleType) && scaleTypeSupportDataType(scaleType, fieldDefType)) {\n index[key] = index[key] || [];\n index[key].push(scaleType);\n }\n }\n }\n }\n return index;\n}\n\nfunction generateScaleTypeIndexKey(channel: Channel, fieldDefType: Type) {\n return channel + '_' + fieldDefType;\n}\n","import {Axis, AXIS_PROPERTIES} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Legend, LEGEND_PROPERTIES} from 'vega-lite/build/src/legend';\nimport {Scale, SCALE_PROPERTIES} from 'vega-lite/build/src/scale';\nimport {EncodingSortField} from 'vega-lite/build/src/sort';\nimport {Flag, flagKeys} from 'vega-lite/build/src/util';\nimport {AutoCountQuery, FieldQuery, ValueQuery} from './query/encoding';\nimport {TransformQuery} from './query/transform';\nimport {Diff} from './util';\n\n/**\n * There are two types of `Property`'s.\n * One is just flat property names.\n * (Try to hover `FlatProp` to see all of them.)\n * Another is an object that describes a parent property (e.g., `scale`) and the child property (e.g., `type`)\n */\nexport type Property = FlatProp | EncodingNestedProp;\nexport type FlatProp = MarkProp | TransformProp | ViewProp | EncodingTopLevelProp;\n\nexport type MarkProp = 'mark' | 'stack'; // FIXME: determine how 'stack' works;\nexport type TransformProp = keyof TransformQuery;\nexport type ViewProp = 'width' | 'height' | 'background' | 'padding' | 'title';\nexport type EncodingTopLevelProp = Diff; // Do not include description since description is simply a metadata\n\nexport type EncodingNestedProp = BinProp | SortProp | ScaleProp | AxisProp | LegendProp;\n\nexport type EncodingNestedChildProp =\n | keyof BinParams\n | keyof EncodingSortField\n | keyof Scale\n | keyof Axis\n | keyof Legend;\n\n/**\n * An object that describes a parent property (e.g., `scale`) and the child property (e.g., `type`)\n */\nexport type BaseEncodingNestedProp = {\n parent: P;\n child: keyof T;\n};\n\nexport type BinProp = BaseEncodingNestedProp<'bin', BinParams>;\nexport type SortProp = BaseEncodingNestedProp<'sort', EncodingSortField>;\nexport type ScaleProp = BaseEncodingNestedProp<'scale', Scale>;\nexport type AxisProp = BaseEncodingNestedProp<'axis', Axis>;\nexport type LegendProp = BaseEncodingNestedProp<'legend', Legend>;\n\nexport function isEncodingNestedProp(p: Property): p is EncodingNestedProp {\n return !!p['parent'];\n}\n\nconst ENCODING_TOPLEVEL_PROP_INDEX: Flag = {\n channel: 1,\n aggregate: 1,\n autoCount: 1,\n bin: 1,\n timeUnit: 1,\n hasFn: 1,\n sort: 1,\n stack: 1,\n field: 1,\n type: 1,\n format: 1,\n scale: 1,\n axis: 1,\n legend: 1,\n value: 1\n};\n\nexport const ENCODING_TOPLEVEL_PROPS = flagKeys(ENCODING_TOPLEVEL_PROP_INDEX);\n\nexport function isEncodingTopLevelProperty(p: Property): p is EncodingTopLevelProp {\n return p in ENCODING_TOPLEVEL_PROP_INDEX;\n}\n\nexport type EncodingNestedPropParent = 'bin' | 'scale' | 'sort' | 'axis' | 'legend';\n\nconst ENCODING_NESTED_PROP_PARENT_INDEX: Flag = {\n bin: 1,\n scale: 1,\n sort: 1,\n axis: 1,\n legend: 1\n};\n\nexport function isEncodingNestedParent(prop: string): prop is EncodingNestedPropParent {\n return ENCODING_NESTED_PROP_PARENT_INDEX[prop as string];\n}\n\n// FIXME -- we should not have to manually specify these\nexport const BIN_CHILD_PROPS: (keyof BinParams)[] = ['maxbins', 'divide', 'extent', 'base', 'step', 'steps', 'minstep'];\nexport const SORT_CHILD_PROPS: (keyof EncodingSortField)[] = ['field', 'op', 'order'];\n\nconst BIN_PROPS = BIN_CHILD_PROPS.map(\n (c): BinProp => {\n return {parent: 'bin', child: c};\n }\n);\n\nexport const SORT_PROPS = SORT_CHILD_PROPS.map(\n (c): SortProp => {\n return {parent: 'sort', child: c};\n }\n);\n\nexport const SCALE_PROPS = SCALE_PROPERTIES.map(\n (c): ScaleProp => {\n return {parent: 'scale', child: c};\n }\n);\n\nconst AXIS_PROPS = AXIS_PROPERTIES.map(\n (c): AxisProp => {\n return {parent: 'axis', child: c};\n }\n);\n\nconst LEGEND_PROPS = LEGEND_PROPERTIES.map(\n (c): LegendProp => {\n return {parent: 'legend', child: c};\n }\n);\n\nexport const ENCODING_NESTED_PROPS = ([] as EncodingNestedProp[]).concat(\n BIN_PROPS,\n SORT_PROPS,\n SCALE_PROPS,\n AXIS_PROPS,\n LEGEND_PROPS\n);\n\nexport const VIEW_PROPS: Property[] = ['width', 'height', 'background', 'padding', 'title'] as Property[];\n\nconst PROP_KEY_DELIMITER = '.';\n\nexport function toKey(p: Property): string {\n if (isEncodingNestedProp(p)) {\n return p.parent + PROP_KEY_DELIMITER + p.child;\n }\n return p;\n}\n\nexport function fromKey(k: string): Property {\n const split = k.split(PROP_KEY_DELIMITER);\n /* istanbul ignore else */\n if (split.length === 1) {\n return k as Property;\n } else if (split.length === 2) {\n return {\n parent: split[0],\n child: split[1]\n } as EncodingNestedProp;\n } else {\n throw 'Invalid property key with ' + split.length + ' dots: ' + k;\n }\n}\n\nconst ENCODING_NESTED_PROP_INDEX = ENCODING_NESTED_PROPS.reduce((i, prop: EncodingNestedProp) => {\n i[prop.parent] = i[prop.parent] || [];\n i[prop.parent][prop.child] = prop;\n return i;\n}, {});\n\n// FIXME consider using a more general method\nexport function getEncodingNestedProp(parent: EncodingTopLevelProp, child: EncodingNestedChildProp) {\n return (ENCODING_NESTED_PROP_INDEX[parent] || {})[child];\n}\n\nexport function isEncodingProperty(p: Property): p is EncodingTopLevelProp | EncodingNestedProp {\n return isEncodingTopLevelProperty(p) || isEncodingNestedProp(p);\n}\n\nexport const ALL_ENCODING_PROPS = ([] as Property[]).concat(ENCODING_TOPLEVEL_PROPS, ENCODING_NESTED_PROPS);\n\nexport const DEFAULT_PROP_PRECEDENCE: Property[] = ([\n 'type', // type is a constraint for field\n 'field',\n\n // Field Transform\n 'bin',\n 'timeUnit',\n 'aggregate',\n 'autoCount',\n\n // Encoding\n 'channel',\n\n // Mark\n 'mark',\n 'stack',\n\n 'scale',\n 'sort',\n 'axis',\n 'legend'\n] as Property[]).concat(BIN_PROPS, SCALE_PROPS, AXIS_PROPS, LEGEND_PROPS, SORT_PROPS);\n\nexport namespace Property {\n export const MARK: 'mark' = 'mark';\n\n export const TRANSFORM: 'transform' = 'transform';\n // Layout\n export const STACK: 'stack' = 'stack';\n\n export const FORMAT: 'format' = 'format';\n\n // TODO: sub parts of stack\n\n // Encoding Properties\n export const CHANNEL: 'channel' = 'channel';\n export const AGGREGATE: 'aggregate' = 'aggregate';\n export const AUTOCOUNT: 'autoCount' = 'autoCount';\n export const BIN: 'bin' = 'bin';\n\n export const HAS_FN: 'hasFn' = 'hasFn';\n export const TIMEUNIT: 'timeUnit' = 'timeUnit';\n export const FIELD: 'field' = 'field';\n export const TYPE: 'type' = 'type';\n\n export const SORT: 'sort' = 'sort';\n\n export const SCALE: 'scale' = 'scale';\n export const AXIS: 'axis' = 'axis';\n\n export const LEGEND: 'legend' = 'legend';\n\n export const WIDTH: 'width' = 'width';\n export const HEIGHT: 'height' = 'height';\n export const BACKGROUND: 'background' = 'background';\n export const PADDING: 'padding' = 'padding';\n export const TITLE: 'title' = 'title';\n}\n","import {toSet} from 'vega-util';\nimport {CompositeMark, CompositeMarkDef} from './compositemark/index';\nimport {contains, flagKeys} from './util';\nimport {BaseMarkConfig} from './vega.schema';\n\nexport const AREA: 'area' = 'area';\nexport const BAR: 'bar' = 'bar';\nexport const LINE: 'line' = 'line';\nexport const POINT: 'point' = 'point';\nexport const RECT: 'rect' = 'rect';\nexport const RULE: 'rule' = 'rule';\nexport const TEXT: 'text' = 'text';\nexport const TICK: 'tick' = 'tick';\nexport const TRAIL: 'trail' = 'trail';\nexport const CIRCLE: 'circle' = 'circle';\nexport const SQUARE: 'square' = 'square';\nexport const GEOSHAPE: 'geoshape' = 'geoshape';\n\n/**\n * All types of primitive marks.\n */\nexport type Mark =\n | typeof AREA\n | typeof BAR\n | typeof LINE\n | typeof TRAIL\n | typeof POINT\n | typeof TEXT\n | typeof TICK\n | typeof RECT\n | typeof RULE\n | typeof CIRCLE\n | typeof SQUARE\n | typeof GEOSHAPE;\n\n// Using mapped type to declare index, ensuring we always have all marks when we add more.\nconst MARK_INDEX: {[M in Mark]: 1} = {\n area: 1,\n bar: 1,\n line: 1,\n point: 1,\n text: 1,\n tick: 1,\n trail: 1,\n rect: 1,\n geoshape: 1,\n rule: 1,\n circle: 1,\n square: 1\n};\n\nexport function isMark(m: string): m is Mark {\n return !!MARK_INDEX[m];\n}\n\nexport function isPathMark(m: Mark | CompositeMark): m is 'line' | 'area' | 'trail' {\n return contains(['line', 'area', 'trail'], m);\n}\n\nexport const PRIMITIVE_MARKS = flagKeys(MARK_INDEX);\n\nexport interface ColorMixins {\n /**\n * Default color. Note that `fill` and `stroke` have higher precedence than `color` and will override `color`.\n *\n * __Default value:__ `\"#4682b4\"`\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n */\n color?: string;\n}\n\nexport interface TooltipContent {\n content: 'encoding' | 'data';\n}\n\nexport interface MarkConfig extends ColorMixins, BaseMarkConfig {\n // ========== VL-Specific ==========\n\n /**\n * Whether the mark's color should be used as fill color instead of stroke color.\n *\n * __Default value:__ `false` for `point`, `line` and `rule`; otherwise, `true`.\n *\n * __Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n *\n */\n filled?: boolean;\n\n // ========== Overriding Vega ==========\n\n /**\n * The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from.\n *\n * - If `tooltip` is `{\"content\": \"encoding\"}`, then all fields from `encoding` will be used.\n * - If `tooltip` is `{\"content\": \"data\"}`, then all fields that appear in the highlighted data point will be used.\n * - If set to `null`, then no tooltip will be used.\n */\n tooltip?: string | TooltipContent | null;\n\n /**\n * Default size for marks.\n * - For `point`/`circle`/`square`, this represents the pixel area of the marks. For example: in the case of circles, the radius is determined in part by the square root of the size value.\n * - For `bar`, this represents the band size of the bar, in pixels.\n * - For `text`, this represents the font size, in pixels.\n *\n * __Default value:__ `30` for point, circle, square marks; `rangeStep` - 1 for bar marks with discrete dimensions; `5` for bar marks with continuous dimensions; `11` for text marks.\n *\n * @minimum 0\n */\n size?: number;\n\n /**\n * For line and trail marks, this `order` property can be set to `null` or `false` to make the lines use the original order in the data sources.\n */\n order?: null | boolean;\n}\n\nexport interface BarBinSpacingMixins {\n /**\n * Offset between bars for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n binSpacing?: number;\n}\n\nexport type AnyMark = CompositeMark | CompositeMarkDef | Mark | MarkDef;\n\nexport function isMarkDef(mark: string | GenericMarkDef): mark is GenericMarkDef {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: AnyMark): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = [\n 'stroke',\n 'strokeWidth',\n 'strokeDash',\n 'strokeDashOffset',\n 'strokeOpacity',\n 'strokeJoin',\n 'strokeMiterLimit'\n];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport const VL_ONLY_MARK_CONFIG_PROPERTIES: (keyof MarkConfig)[] = ['filled', 'color', 'tooltip'];\n\nexport const VL_ONLY_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX: {\n [k in typeof PRIMITIVE_MARKS[0]]?: (keyof MarkConfigMixins[k])[]\n} = {\n area: ['line', 'point'],\n bar: ['binSpacing', 'continuousBandSize', 'discreteBandSize'],\n line: ['point'],\n text: ['shortTimeLabels'],\n tick: ['bandSize', 'thickness']\n};\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n tooltip: {content: 'encoding'}\n};\n\nexport interface MarkConfigMixins {\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: AreaConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: LineConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n /** Trail-Specific Config */\n trail?: LineConfig;\n\n /** Geoshape-Specific Config */\n geoshape?: MarkConfig;\n}\n\nexport interface BarConfig extends BarBinSpacingMixins, MarkConfig {\n /**\n * The default size of the bars on continuous scales.\n *\n * __Default value:__ `5`\n *\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The default size of the bars with discrete dimensions. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport type OverlayMarkDef = MarkConfig & MarkDefMixins;\n\nexport interface PointOverlayMixins {\n /**\n * A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n *\n * - If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n *\n * - If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n *\n * - If this property is `false`, no points would be automatically added to line or area marks.\n *\n * __Default value:__ `false`.\n */\n point?: boolean | OverlayMarkDef | 'transparent';\n}\n\nexport interface LineConfig extends MarkConfig, PointOverlayMixins {}\n\nexport interface LineOverlayMixins {\n /**\n * A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n *\n * - If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n *\n * - If this value is `false`, no lines would be automatically added to area marks.\n *\n * __Default value:__ `false`.\n */\n line?: boolean | OverlayMarkDef;\n}\n\nexport interface AreaConfig extends MarkConfig, PointOverlayMixins, LineOverlayMixins {}\n\nexport interface TickThicknessMixins {\n /**\n * Thickness of the tick mark.\n *\n * __Default value:__ `1`\n *\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport interface GenericMarkDef {\n /**\n * The mark type. This could a primitive mark type\n * (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`)\n * or a composite mark type (`\"boxplot\"`, `\"errorband\"`, `\"errorbar\"`).\n */\n type: M;\n}\n\nexport interface MarkDefMixins {\n /**\n * A string or array of strings indicating the name of custom styles to apply to the mark. A style is a named collection of mark property defaults defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles. Any [mark properties](https://vega.github.io/vega-lite/docs/encoding.html#mark-prop) explicitly defined within the `encoding` will override a style default.\n *\n * __Default value:__ The mark's name. For example, a bar mark will have style `\"bar\"` by default.\n * __Note:__ Any specified style will augment the default style. For example, a bar mark with `\"style\": \"foo\"` will receive from `config.style.bar` and `config.style.foo` (the specified style `\"foo\"` has higher precedence).\n */\n style?: string | string[];\n\n /**\n * Whether a mark be clipped to the enclosing group’s width and height.\n */\n clip?: boolean;\n\n // Offset properties should not be a part of config\n\n /**\n * Offset for x-position.\n */\n xOffset?: number;\n\n /**\n * Offset for y-position.\n */\n yOffset?: number;\n\n /**\n * Offset for x2-position.\n */\n x2Offset?: number;\n\n /**\n * Offset for y2-position.\n */\n y2Offset?: number;\n}\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\n\n// Point/Line OverlayMixins are only for area, line, and trail but we don't want to declare multiple types of MarkDef\nexport interface MarkDef\n extends GenericMarkDef,\n BarBinSpacingMixins,\n MarkConfig,\n PointOverlayMixins,\n LineOverlayMixins,\n TickThicknessMixins,\n MarkDefMixins {}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 5\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport interface TickConfig extends MarkConfig, TickThicknessMixins {\n /**\n * The width of the ticks.\n *\n * __Default value:__ 3/4 of rangeStep.\n * @minimum 0\n */\n bandSize?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n\nexport function getMarkType(m: string | GenericMarkDef) {\n return isMarkDef(m) ? m.type : m;\n}\n","// DateTime definition object\n\nimport {isNumber} from 'vega-util';\nimport * as log from './log';\nimport {duplicate, keys} from './util';\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of a week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of a day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing the minute segment of time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing the second segment (0-59) of a time value\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing the millisecond segment of time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n\n /**\n * A boolean flag indicating if date time is in utc time. If false, the date time is in local time\n */\n utc?: boolean;\n}\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n utc?: boolean;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return (\n !!o &&\n (!!o.year ||\n !!o.quarter ||\n !!o.month ||\n !!o.date ||\n !!o.day ||\n !!o.hours ||\n !!o.minutes ||\n !!o.seconds ||\n !!o.milliseconds)\n );\n}\n\nexport const MONTHS = [\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december'\n];\nexport const SHORT_MONTHS = MONTHS.map(m => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map(d => d.substr(0, 3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1).toString();\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1).toString();\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (const timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n if (d.utc) {\n return `utc(${units.join(', ')})`;\n } else {\n return `datetime(${units.join(', ')})`;\n }\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport * as log from './log';\nimport {accessPathWithDatum, Flag, flagKeys} from './util';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' =\n 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE and MONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const MONTHDATEHOURS: 'monthdatehours' = 'monthdatehours';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n export const UTCYEAR: 'utcyear' = 'utcyear';\n export const UTCMONTH: 'utcmonth' = 'utcmonth';\n export const UTCDAY: 'utcday' = 'utcday';\n export const UTCDATE: 'utcdate' = 'utcdate';\n export const UTCHOURS: 'utchours' = 'utchours';\n export const UTCMINUTES: 'utcminutes' = 'utcminutes';\n export const UTCSECONDS: 'utcseconds' = 'utcseconds';\n export const UTCMILLISECONDS: 'utcmilliseconds' = 'utcmilliseconds';\n export const UTCYEARMONTH: 'utcyearmonth' = 'utcyearmonth';\n export const UTCYEARMONTHDATE: 'utcyearmonthdate' = 'utcyearmonthdate';\n export const UTCYEARMONTHDATEHOURS: 'utcyearmonthdatehours' = 'utcyearmonthdatehours';\n export const UTCYEARMONTHDATEHOURSMINUTES: 'utcyearmonthdatehoursminutes' = 'utcyearmonthdatehoursminutes';\n export const UTCYEARMONTHDATEHOURSMINUTESSECONDS: 'utcyearmonthdatehoursminutesseconds' =\n 'utcyearmonthdatehoursminutesseconds';\n\n // UTCMONTHDATE and UTCMONTHDATEHOURS always include 29 February since we use year 0th (which is a leap year);\n export const UTCMONTHDATE: 'utcmonthdate' = 'utcmonthdate';\n export const UTCMONTHDATEHOURS: 'utcmonthdatehours' = 'utcmonthdatehours';\n export const UTCHOURSMINUTES: 'utchoursminutes' = 'utchoursminutes';\n export const UTCHOURSMINUTESSECONDS: 'utchoursminutesseconds' = 'utchoursminutesseconds';\n export const UTCMINUTESSECONDS: 'utcminutesseconds' = 'utcminutesseconds';\n export const UTCSECONDSMILLISECONDS: 'utcsecondsmilliseconds' = 'utcsecondsmilliseconds';\n export const UTCQUARTER: 'utcquarter' = 'utcquarter';\n export const UTCYEARQUARTER: 'utcyearquarter' = 'utcyearquarter';\n export const UTCQUARTERMONTH: 'utcquartermonth' = 'utcquartermonth';\n export const UTCYEARQUARTERMONTH: 'utcyearquartermonth' = 'utcyearquartermonth';\n}\n\nexport type LocalSingleTimeUnit =\n | typeof TimeUnit.YEAR\n | typeof TimeUnit.QUARTER\n | typeof TimeUnit.MONTH\n | typeof TimeUnit.DAY\n | typeof TimeUnit.DATE\n | typeof TimeUnit.HOURS\n | typeof TimeUnit.MINUTES\n | typeof TimeUnit.SECONDS\n | typeof TimeUnit.MILLISECONDS;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nconst LOCAL_SINGLE_TIMEUNIT_INDEX: Flag = {\n year: 1,\n quarter: 1,\n month: 1,\n day: 1,\n date: 1,\n hours: 1,\n minutes: 1,\n seconds: 1,\n milliseconds: 1\n};\n\nexport const TIMEUNIT_PARTS = flagKeys(LOCAL_SINGLE_TIMEUNIT_INDEX);\n\nexport function isLocalSingleTimeUnit(timeUnit: string): timeUnit is LocalSingleTimeUnit {\n return !!LOCAL_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type UtcSingleTimeUnit =\n | typeof TimeUnit.UTCYEAR\n | typeof TimeUnit.UTCQUARTER\n | typeof TimeUnit.UTCMONTH\n | typeof TimeUnit.UTCDAY\n | typeof TimeUnit.UTCDATE\n | typeof TimeUnit.UTCHOURS\n | typeof TimeUnit.UTCMINUTES\n | typeof TimeUnit.UTCSECONDS\n | typeof TimeUnit.UTCMILLISECONDS;\n\nconst UTC_SINGLE_TIMEUNIT_INDEX: Flag = {\n utcyear: 1,\n utcquarter: 1,\n utcmonth: 1,\n utcday: 1,\n utcdate: 1,\n utchours: 1,\n utcminutes: 1,\n utcseconds: 1,\n utcmilliseconds: 1\n};\n\nexport function isUtcSingleTimeUnit(timeUnit: string): timeUnit is UtcSingleTimeUnit {\n return !!UTC_SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport type SingleTimeUnit = LocalSingleTimeUnit | UtcSingleTimeUnit;\n\nexport type LocalMultiTimeUnit =\n // Local Time\n | typeof TimeUnit.YEARQUARTER\n | typeof TimeUnit.YEARQUARTERMONTH\n | typeof TimeUnit.YEARMONTH\n | typeof TimeUnit.YEARMONTHDATE\n | typeof TimeUnit.YEARMONTHDATEHOURS\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS\n | typeof TimeUnit.QUARTERMONTH\n | typeof TimeUnit.MONTHDATE\n | typeof TimeUnit.MONTHDATEHOURS\n | typeof TimeUnit.HOURSMINUTES\n | typeof TimeUnit.HOURSMINUTESSECONDS\n | typeof TimeUnit.MINUTESSECONDS\n | typeof TimeUnit.SECONDSMILLISECONDS;\n\nconst LOCAL_MULTI_TIMEUNIT_INDEX: Flag = {\n yearquarter: 1,\n yearquartermonth: 1,\n\n yearmonth: 1,\n yearmonthdate: 1,\n yearmonthdatehours: 1,\n yearmonthdatehoursminutes: 1,\n yearmonthdatehoursminutesseconds: 1,\n\n quartermonth: 1,\n\n monthdate: 1,\n monthdatehours: 1,\n\n hoursminutes: 1,\n hoursminutesseconds: 1,\n\n minutesseconds: 1,\n\n secondsmilliseconds: 1\n};\n\nexport type UtcMultiTimeUnit =\n | typeof TimeUnit.UTCYEARQUARTER\n | typeof TimeUnit.UTCYEARQUARTERMONTH\n | typeof TimeUnit.UTCYEARMONTH\n | typeof TimeUnit.UTCYEARMONTHDATE\n | typeof TimeUnit.UTCYEARMONTHDATEHOURS\n | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.UTCYEARMONTHDATEHOURSMINUTESSECONDS\n | typeof TimeUnit.UTCQUARTERMONTH\n | typeof TimeUnit.UTCMONTHDATE\n | typeof TimeUnit.UTCMONTHDATEHOURS\n | typeof TimeUnit.UTCHOURSMINUTES\n | typeof TimeUnit.UTCHOURSMINUTESSECONDS\n | typeof TimeUnit.UTCMINUTESSECONDS\n | typeof TimeUnit.UTCSECONDSMILLISECONDS;\n\nconst UTC_MULTI_TIMEUNIT_INDEX: Flag = {\n utcyearquarter: 1,\n utcyearquartermonth: 1,\n\n utcyearmonth: 1,\n utcyearmonthdate: 1,\n utcyearmonthdatehours: 1,\n utcyearmonthdatehoursminutes: 1,\n utcyearmonthdatehoursminutesseconds: 1,\n\n utcquartermonth: 1,\n\n utcmonthdate: 1,\n utcmonthdatehours: 1,\n\n utchoursminutes: 1,\n utchoursminutesseconds: 1,\n\n utcminutesseconds: 1,\n\n utcsecondsmilliseconds: 1\n};\n\nexport type MultiTimeUnit = LocalMultiTimeUnit | UtcMultiTimeUnit;\n\nexport type LocalTimeUnit = LocalSingleTimeUnit | LocalMultiTimeUnit;\nexport type UtcTimeUnit = UtcSingleTimeUnit | UtcMultiTimeUnit;\n\nconst UTC_TIMEUNIT_INDEX: Flag = {\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport function isUTCTimeUnit(t: string): t is UtcTimeUnit {\n return !!UTC_TIMEUNIT_INDEX[t];\n}\n\nexport function getLocalTimeUnit(t: UtcTimeUnit): LocalTimeUnit {\n return t.substr(3) as LocalTimeUnit;\n}\n\nexport type TimeUnit = SingleTimeUnit | MultiTimeUnit;\n\nconst TIMEUNIT_INDEX: Flag = {\n ...LOCAL_SINGLE_TIMEUNIT_INDEX,\n ...UTC_SINGLE_TIMEUNIT_INDEX,\n ...LOCAL_MULTI_TIMEUNIT_INDEX,\n ...UTC_MULTI_TIMEUNIT_INDEX\n};\n\nexport const TIMEUNITS = flagKeys(TIMEUNIT_INDEX);\n\nexport function isTimeUnit(t: string): t is TimeUnit {\n return !!TIMEUNIT_INDEX[t];\n}\n\ntype DateMethodName = keyof Date;\n\nconst SET_DATE_METHOD: Record = {\n year: 'setFullYear',\n month: 'setMonth',\n date: 'setDate',\n hours: 'setHours',\n minutes: 'setMinutes',\n seconds: 'setSeconds',\n milliseconds: 'setMilliseconds',\n // Day and quarter have their own special cases\n quarter: null,\n day: null\n};\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const isUTC = isUTCTimeUnit(unit);\n const result: Date = isUTC\n ? // start with uniform date\n new Date(Date.UTC(1972, 0, 1, 0, 0, 0, 0)) // 1972 is the first leap year after 1970, the start of unix time\n : new Date(1972, 0, 1, 0, 0, 0, 0);\n for (const timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(unit, timeUnitPart)) {\n switch (timeUnitPart) {\n case TimeUnit.DAY:\n throw new Error(\"Cannot convert to TimeUnits containing 'day'\");\n case TimeUnit.QUARTER: {\n const {getDateMethod, setDateMethod} = dateMethods('month', isUTC);\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result[setDateMethod](Math.floor(date[getDateMethod]() / 3) * 3);\n break;\n }\n default: {\n const {getDateMethod, setDateMethod} = dateMethods(timeUnitPart, isUTC);\n result[setDateMethod](date[getDateMethod]());\n }\n }\n }\n }\n return result;\n}\n\nfunction dateMethods(singleUnit: SingleTimeUnit, isUtc: boolean) {\n const rawSetDateMethod = SET_DATE_METHOD[singleUnit];\n const setDateMethod = isUtc ? 'setUTC' + rawSetDateMethod.substr(3) : rawSetDateMethod;\n const getDateMethod = 'get' + (isUtc ? 'UTC' : '') + rawSetDateMethod.substr(3);\n return {setDateMethod, getDateMethod};\n}\n\nexport function getTimeUnitParts(timeUnit: TimeUnit) {\n return TIMEUNIT_PARTS.reduce((parts, part) => {\n if (containsTimeUnit(timeUnit, part)) {\n return [...parts, part];\n }\n return parts;\n }, []);\n}\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n const index = fullTimeUnit.indexOf(timeUnit);\n return (\n index > -1 && (timeUnit !== TimeUnit.SECONDS || index === 0 || fullTimeUnit.charAt(index - 1) !== 'i') // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = accessPathWithDatum(field);\n\n const utc = isUTCTimeUnit(fullTimeUnit) ? 'utc' : '';\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(${utc}quarter(${fieldRef})-1)`;\n } else {\n return `${utc}${timeUnit}(${fieldRef})`;\n }\n }\n\n const d = TIMEUNIT_PARTS.reduce(\n (dateExpr: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n dateExpr[tu] = func(tu);\n }\n return dateExpr;\n },\n {} as {[key in SingleTimeUnit]: string}\n );\n\n return dateTimeExpr(d);\n}\n\nexport function getDateTimeComponents(timeUnit: TimeUnit, shortTimeLabels: boolean) {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateComponents: string[] = [];\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n const timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n const dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n return dateTimeComponents;\n}\n\n/**\n * returns the signal expression used for axis labels for a time unit\n */\nexport function formatExpression(\n timeUnit: TimeUnit,\n field: string,\n shortTimeLabels: boolean,\n isUTCScale: boolean\n): string {\n if (!timeUnit) {\n return undefined;\n }\n\n const dateTimeComponents: string[] = getDateTimeComponents(timeUnit, shortTimeLabels);\n let expression = '';\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n\n // We only use utcFormat for utc scale\n // For utc time units, the data is already converted as a part of timeUnit transform.\n // Thus, utc time units should use timeFormat to avoid shifting the time twice.\n if (isUTCScale) {\n expression += `utcFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n } else {\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function normalizeTimeUnit(timeUnit: TimeUnit): TimeUnit {\n if (timeUnit !== 'day' && timeUnit.indexOf('day') >= 0) {\n log.warn(log.message.dayReplacedWithDate(timeUnit));\n return timeUnit.replace('day', 'date') as TimeUnit;\n }\n return timeUnit;\n}\n","var u = module.exports;\n\n// utility functions\n\nvar FNAME = '__name__';\n\nu.namedfunc = function(name, f) { return (f[FNAME] = name, f); };\n\nu.name = function(f) { return f==null ? null : f[FNAME]; };\n\nu.identity = function(x) { return x; };\n\nu.true = u.namedfunc('true', function() { return true; });\n\nu.false = u.namedfunc('false', function() { return false; });\n\nu.duplicate = function(obj) {\n return JSON.parse(JSON.stringify(obj));\n};\n\nu.equal = function(a, b) {\n return JSON.stringify(a) === JSON.stringify(b);\n};\n\nu.extend = function(obj) {\n for (var x, name, i=1, len=arguments.length; i 1 ?\n function(x, v) {\n for (var i=0; i b || b == null) && a != null ? 1 :\n ((b = b instanceof Date ? +b : b),\n (a = a instanceof Date ? +a : a)) !== a && b === b ? -1 :\n b !== b && a === a ? 1 : 0;\n};\n\nu.numcmp = function(a, b) { return a - b; };\n\nu.stablesort = function(array, sortBy, keyFn) {\n var indices = array.reduce(function(idx, v, i) {\n return (idx[keyFn(v)] = i, idx);\n }, {});\n\n array.sort(function(a, b) {\n var sa = sortBy(a),\n sb = sortBy(b);\n return sa < sb ? -1 : sa > sb ? 1\n : (indices[keyFn(a)] - indices[keyFn(b)]);\n });\n\n return array;\n};\n\n// permutes an array using a Knuth shuffle\nu.permute = function(a) {\n var m = a.length,\n swap,\n i;\n\n while (m) {\n i = Math.floor(Math.random() * m--);\n swap = a[m];\n a[m] = a[i];\n a[i] = swap;\n }\n};\n\n// string functions\n\nu.pad = function(s, length, pos, padchar) {\n padchar = padchar || \" \";\n var d = length - s.length;\n if (d <= 0) return s;\n switch (pos) {\n case 'left':\n return strrep(d, padchar) + s;\n case 'middle':\n case 'center':\n return strrep(Math.floor(d/2), padchar) +\n s + strrep(Math.ceil(d/2), padchar);\n default:\n return s + strrep(d, padchar);\n }\n};\n\nfunction strrep(n, str) {\n var s = \"\", i;\n for (i=0; i {\n [key: string]: T;\n}\n\nexport function contains(array: any[], item: any) {\n return array.indexOf(item) !== -1;\n};\n\nexport function every(arr: T[], f: (item: T, key: number) => boolean) {\n for (let i = 0; i < arr.length; i++) {\n if (!f(arr[i], i)) {\n return false;\n }\n }\n return true;\n};\n\nexport function forEach(obj: any, f: (item: any, key: number|string, i: number)=>void, thisArg?: any) {\n if (obj.forEach) {\n obj.forEach.call(thisArg, f);\n } else {\n for (let k in obj) {\n f.call(thisArg, obj[k], k, obj);\n }\n }\n};\n\nexport function some(arr: T[], f: (item: T, key: number|string, i: number)=>boolean) {\n let i = 0, k;\n for (k in arr) {\n if (f(arr[k], k, i++)) {\n return true;\n }\n }\n return false;\n};\n\nexport function nestedMap(array: any[], f: (item: any)=>any): any[] {\n return array.map((a) => {\n if (isArray(a)) {\n return nestedMap(a, f);\n }\n return f(a);\n });\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: Array, excludedItems: Array) {\n return array.filter(function(item) {\n return !contains(excludedItems, item);\n });\n}\n\nexport type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];\n","import {Axis, AXIS_PROPERTIES} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Channel, COLOR, COLUMN, ROW, SIZE, X, Y} from 'vega-lite/build/src/channel';\nimport {TypedFieldDef} from 'vega-lite/build/src/channeldef';\nimport {Legend, LEGEND_PROPERTIES} from 'vega-lite/build/src/legend';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {Scale, ScaleType, SCALE_PROPERTIES} from 'vega-lite/build/src/scale';\nimport {EncodingSortField, SortOrder} from 'vega-lite/build/src/sort';\nimport {StackOffset} from 'vega-lite/build/src/stack';\nimport {TimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {isEncodingNestedProp, Property} from './property';\nimport {Schema} from './schema';\nimport {extend, isArray} from './util';\n\nexport const SHORT_WILDCARD: SHORT_WILDCARD = '?';\nexport type SHORT_WILDCARD = '?';\n\nexport interface Wildcard {\n name?: string;\n\n /**\n * List of values to enumerate\n */\n enum?: T[];\n}\n\nexport type WildcardProperty = T | Wildcard | SHORT_WILDCARD;\n\nexport interface ExtendedWildcard extends Wildcard {\n [prop: string]: any;\n}\n\nexport function isWildcard(prop: any): prop is Wildcard | SHORT_WILDCARD {\n return isShortWildcard(prop) || isWildcardDef(prop);\n}\n\nexport function isShortWildcard(prop: any): prop is SHORT_WILDCARD {\n return prop === SHORT_WILDCARD;\n}\n\nexport function isWildcardDef(prop: any): prop is Wildcard {\n return prop !== undefined && prop != null && (!!prop.enum || !!prop.name) && !isArray(prop);\n}\n\nexport function initWildcard(\n prop: SHORT_WILDCARD | ExtendedWildcard,\n defaultName: string,\n defaultEnumValues: any[]\n): ExtendedWildcard {\n return extend(\n {},\n {\n name: defaultName,\n enum: defaultEnumValues\n },\n prop === SHORT_WILDCARD ? {} : prop\n );\n}\n\n/**\n * Initial short names from list of full camelCaseNames.\n * For each camelCaseNames, return unique short names based on initial (e.g., `ccn`)\n */\nfunction initNestedPropName(fullNames: string[]) {\n let index = {};\n let has = {};\n for (const fullName of fullNames) {\n const initialIndices = [0];\n for (let i = 0; i < fullName.length; i++) {\n if (fullName.charAt(i).toUpperCase() === fullName.charAt(i)) {\n initialIndices.push(i);\n }\n }\n let shortName = initialIndices\n .map(i => fullName.charAt(i))\n .join('')\n .toLowerCase();\n if (!has[shortName]) {\n index[fullName] = shortName;\n has[shortName] = true;\n continue;\n }\n // If duplicate, add last character and try again!\n if (initialIndices[initialIndices.length - 1] !== fullName.length - 1) {\n shortName = initialIndices\n .concat([fullName.length - 1])\n .map(i => fullName.charAt(i))\n .join('')\n .toLowerCase();\n if (!has[shortName]) {\n index[fullName] = shortName;\n has[shortName] = true;\n continue;\n }\n }\n for (let i = 1; !index[fullName]; i++) {\n let shortNameWithNo = shortName + '_' + i;\n if (!has[shortNameWithNo]) {\n index[fullName] = shortNameWithNo;\n has[shortNameWithNo] = true;\n break;\n }\n }\n }\n return index;\n}\n\nexport const DEFAULT_NAME = {\n mark: 'm',\n channel: 'c',\n aggregate: 'a',\n autoCount: '#',\n hasFn: 'h',\n bin: 'b',\n sort: 'so',\n stack: 'st',\n scale: 's',\n format: 'f',\n axis: 'ax',\n legend: 'l',\n value: 'v',\n\n timeUnit: 'tu',\n field: 'f',\n type: 't',\n\n binProps: {\n maxbins: 'mb',\n min: 'mi',\n max: 'ma',\n base: 'b',\n step: 's',\n steps: 'ss',\n minstep: 'ms',\n divide: 'd'\n },\n sortProps: {\n field: 'f',\n op: 'o',\n order: 'or'\n },\n scaleProps: initNestedPropName(SCALE_PROPERTIES),\n axisProps: initNestedPropName(AXIS_PROPERTIES),\n legendProps: initNestedPropName(LEGEND_PROPERTIES)\n};\n\nexport function getDefaultName(prop: Property) {\n if (isEncodingNestedProp(prop)) {\n return DEFAULT_NAME[prop.parent] + '-' + DEFAULT_NAME[prop.parent + 'Props'][prop.child];\n }\n if (DEFAULT_NAME[prop]) {\n return DEFAULT_NAME[prop];\n }\n /* istanbul ignore next */\n throw new Error('Default name undefined for ' + prop);\n}\n\n/**\n * Generic index for default enum (values to enumerate) of a particular definition type.\n */\nexport type DefEnumIndex = {[P in keyof T]-?: T[P][]};\n\nconst DEFAULT_BOOLEAN_ENUM = [false, true];\n\nexport type EnumIndex = {\n mark: Mark[];\n channel: Channel[];\n autoCount: boolean[];\n hasFn: boolean[];\n} & DefEnumIndex> & {\n sort: (EncodingSortField | SortOrder)[];\n stack: StackOffset[];\n format: string[];\n scale: boolean[];\n axis: boolean[];\n legend: boolean[];\n value: any[];\n\n binProps: Partial>;\n sortProps: Partial>>;\n scaleProps: Partial>;\n axisProps: Partial>;\n legendProps: Partial>;\n };\n\nconst DEFAULT_BIN_PROPS_ENUM: DefEnumIndex = {\n maxbins: [5, 10, 20],\n extent: [undefined],\n base: [10],\n step: [undefined],\n steps: [undefined],\n minstep: [undefined],\n divide: [[5, 2]],\n binned: [false],\n anchor: [undefined],\n nice: [true]\n};\n\nconst DEFAULT_SORT_PROPS: DefEnumIndex> = {\n field: [undefined], // This should be never call and instead read from the schema\n op: ['min', 'mean'],\n order: ['ascending', 'descending']\n};\n\nconst DEFAULT_SCALE_PROPS_ENUM: DefEnumIndex = {\n type: [undefined, ScaleType.LOG],\n domain: [undefined],\n base: [undefined],\n exponent: [1, 2],\n constant: [undefined],\n\n bins: [undefined],\n\n clamp: DEFAULT_BOOLEAN_ENUM,\n nice: DEFAULT_BOOLEAN_ENUM,\n reverse: DEFAULT_BOOLEAN_ENUM,\n round: DEFAULT_BOOLEAN_ENUM,\n zero: DEFAULT_BOOLEAN_ENUM,\n\n padding: [undefined],\n paddingInner: [undefined],\n paddingOuter: [undefined],\n\n interpolate: [undefined],\n\n range: [undefined],\n rangeStep: [17, 21],\n scheme: [undefined]\n};\n\nconst DEFAULT_AXIS_PROPS_ENUM: DefEnumIndex = {\n zindex: [1, 0],\n offset: [undefined],\n orient: [undefined],\n values: [undefined],\n\n bandPosition: [undefined],\n encoding: [undefined],\n\n domain: DEFAULT_BOOLEAN_ENUM,\n domainColor: [undefined],\n domainDash: [undefined],\n domainDashOffset: [undefined],\n domainOpacity: [undefined],\n domainWidth: [undefined],\n\n formatType: [undefined],\n\n grid: DEFAULT_BOOLEAN_ENUM,\n gridColor: [undefined],\n gridDash: [undefined],\n gridDashOffset: [undefined],\n gridOpacity: [undefined],\n gridWidth: [undefined],\n\n format: [undefined],\n labels: DEFAULT_BOOLEAN_ENUM,\n labelAlign: [undefined],\n labelAngle: [undefined],\n labelBaseline: [undefined],\n labelColor: [undefined],\n labelFlushOffset: [undefined],\n labelFont: [undefined],\n labelFontSize: [undefined],\n labelFontStyle: [undefined],\n labelFontWeight: [undefined],\n labelLimit: [undefined],\n labelOpacity: [undefined],\n labelSeparation: [undefined],\n labelOverlap: [undefined],\n labelPadding: [undefined],\n labelBound: [undefined],\n labelFlush: [undefined],\n\n maxExtent: [undefined],\n minExtent: [undefined],\n position: [undefined],\n\n ticks: DEFAULT_BOOLEAN_ENUM,\n tickColor: [undefined],\n tickCount: [undefined],\n tickDash: [undefined],\n tickExtra: [undefined],\n tickDashOffset: [undefined],\n tickMinStep: [undefined],\n tickOffset: [undefined],\n tickOpacity: [undefined],\n tickRound: [undefined],\n tickSize: [undefined],\n tickWidth: [undefined],\n\n title: [undefined],\n titleAlign: [undefined],\n titleAnchor: [undefined],\n titleAngle: [undefined],\n titleBaseline: [undefined],\n titleColor: [undefined],\n titleFont: [undefined],\n titleFontSize: [undefined],\n titleFontStyle: [undefined],\n titleFontWeight: [undefined],\n titleLimit: [undefined],\n titleOpacity: [undefined],\n titlePadding: [undefined],\n titleX: [undefined],\n titleY: [undefined]\n};\n\nconst DEFAULT_LEGEND_PROPS_ENUM: DefEnumIndex = {\n orient: ['left', 'right'],\n format: [undefined],\n type: [undefined],\n values: [undefined],\n zindex: [undefined],\n\n clipHeight: [undefined],\n columnPadding: [undefined],\n columns: [undefined],\n cornerRadius: [undefined],\n direction: [undefined],\n encoding: [undefined],\n fillColor: [undefined],\n formatType: [undefined],\n gridAlign: [undefined],\n offset: [undefined],\n padding: [undefined],\n rowPadding: [undefined],\n strokeColor: [undefined],\n\n labelAlign: [undefined],\n labelBaseline: [undefined],\n labelColor: [undefined],\n labelFont: [undefined],\n labelFontSize: [undefined],\n labelFontStyle: [undefined],\n labelFontWeight: [undefined],\n labelLimit: [undefined],\n labelOffset: [undefined],\n labelOpacity: [undefined],\n labelOverlap: [undefined],\n labelPadding: [undefined],\n labelSeparation: [undefined],\n\n legendX: [undefined],\n legendY: [undefined],\n\n gradientLength: [undefined],\n gradientOpacity: [undefined],\n gradientStrokeColor: [undefined],\n gradientStrokeWidth: [undefined],\n gradientThickness: [undefined],\n\n symbolDash: [undefined],\n symbolDashOffset: [undefined],\n symbolFillColor: [undefined],\n symbolOffset: [undefined],\n symbolOpacity: [undefined],\n symbolSize: [undefined],\n symbolStrokeColor: [undefined],\n symbolStrokeWidth: [undefined],\n symbolType: [undefined],\n\n tickCount: [undefined],\n tickMinStep: [undefined],\n\n title: [undefined],\n titleAnchor: [undefined],\n titleAlign: [undefined],\n titleBaseline: [undefined],\n titleColor: [undefined],\n titleFont: [undefined],\n titleFontSize: [undefined],\n titleFontStyle: [undefined],\n titleFontWeight: [undefined],\n titleLimit: [undefined],\n titleOpacity: [undefined],\n titleOrient: [undefined],\n titlePadding: [undefined]\n};\n\n// Use FullEnumIndex to make sure we have all properties specified here!\nexport const DEFAULT_ENUM_INDEX: EnumIndex = {\n mark: [MARK.POINT, MARK.BAR, MARK.LINE, MARK.AREA, MARK.RECT, MARK.TICK, MARK.TEXT],\n channel: [X, Y, ROW, COLUMN, SIZE, COLOR], // TODO: TEXT\n\n aggregate: [undefined, 'mean'],\n autoCount: DEFAULT_BOOLEAN_ENUM,\n bin: DEFAULT_BOOLEAN_ENUM,\n hasFn: DEFAULT_BOOLEAN_ENUM,\n timeUnit: [undefined, TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.MINUTES, TimeUnit.SECONDS],\n\n field: [undefined], // This is not used as field should be read from schema\n type: [TYPE.NOMINAL, TYPE.ORDINAL, TYPE.QUANTITATIVE, TYPE.TEMPORAL],\n\n sort: ['ascending', 'descending'],\n stack: ['zero', 'normalize', 'center', null],\n value: [undefined],\n\n format: [undefined],\n title: [undefined],\n scale: [true],\n axis: DEFAULT_BOOLEAN_ENUM,\n legend: DEFAULT_BOOLEAN_ENUM,\n\n binProps: DEFAULT_BIN_PROPS_ENUM,\n sortProps: DEFAULT_SORT_PROPS,\n scaleProps: DEFAULT_SCALE_PROPS_ENUM,\n axisProps: DEFAULT_AXIS_PROPS_ENUM,\n legendProps: DEFAULT_LEGEND_PROPS_ENUM\n};\n\n// TODO: rename this to getDefaultEnum\nexport function getDefaultEnumValues(prop: Property, schema: Schema, opt: QueryConfig): any[] {\n if (prop === 'field' || (isEncodingNestedProp(prop) && prop.parent === 'sort' && prop.child === 'field')) {\n // For field, by default enumerate all fields\n return schema.fieldNames();\n }\n\n let val;\n if (isEncodingNestedProp(prop)) {\n val = opt.enum[prop.parent + 'Props'][prop.child];\n } else {\n val = opt.enum[prop];\n }\n\n if (val !== undefined) {\n return val;\n }\n\n /* istanbul ignore next */\n throw new Error('No default enumValues for ' + JSON.stringify(prop));\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Config} from 'vega-lite/build/src/config';\nimport {DEFAULT_PROP_PRECEDENCE, toKey} from './property';\nimport {DEFAULT_ENUM_INDEX, EnumIndex} from './wildcard';\n\n// We name this QueryConfig to avoid confusion with Vega-Lite's Config\nexport interface QueryConfig {\n verbose?: boolean;\n\n defaultSpecConfig?: Config;\n\n propertyPrecedence?: string[];\n\n enum?: Partial;\n\n /** Default ratio for number fields to be considered ordinal */\n numberNominalProportion?: number;\n\n /** Default cutoff for not applying the numberOrdinalProportion inference */\n numberNominalLimit?: number;\n\n // SPECIAL MODE\n /**\n * Allow automatically adding a special count (autoCount) field for plots\n * that contain only discrete fields. In such cases, adding count make the\n * output plots way more meaningful.\n */\n autoAddCount?: boolean;\n\n // CONSTRAINTS\n constraintManuallySpecifiedValue?: boolean;\n // Spec Constraints\n\n hasAppropriateGraphicTypeForMark?: boolean;\n omitAggregate?: boolean;\n omitAggregatePlotWithDimensionOnlyOnFacet?: boolean;\n omitAggregatePlotWithoutDimension?: boolean;\n omitBarLineAreaWithOcclusion?: boolean;\n omitBarTickWithSize?: boolean;\n omitMultipleNonPositionalChannels?: boolean;\n omitRaw?: boolean;\n omitRawContinuousFieldForAggregatePlot?: boolean;\n omitRawWithXYBothOrdinalScaleOrBin?: boolean;\n omitRepeatedField?: boolean;\n omitNonPositionalOrFacetOverPositionalChannels?: boolean;\n omitTableWithOcclusionIfAutoAddCount?: boolean;\n omitVerticalDotPlot?: boolean;\n omitInvalidStackSpec?: boolean;\n omitNonSumStack?: boolean;\n\n preferredBinAxis?: Channel;\n preferredTemporalAxis?: Channel;\n preferredOrdinalAxis?: Channel;\n preferredNominalAxis?: Channel;\n preferredFacet?: Channel;\n\n // Field Encoding Constraints\n minCardinalityForBin?: number;\n maxCardinalityForCategoricalColor?: number;\n maxCardinalityForFacet?: number;\n maxCardinalityForShape?: number;\n timeUnitShouldHaveVariation?: boolean;\n typeMatchesSchemaType?: boolean;\n\n // STYLIZE\n stylize?: boolean;\n smallRangeStepForHighCardinalityOrFacet?: {maxCardinality: number; rangeStep: number};\n nominalColorScaleForHighCardinality?: {maxCardinality: number; palette: string};\n xAxisOnTopForHighYCardinalityWithoutColumn?: {maxCardinality: number};\n\n // EFFECTIVENESS PREFERENCE\n maxGoodCardinalityForColor?: number; // FIXME: revise\n maxGoodCardinalityForFacet?: number; // FIXME: revise\n // HIGH CARDINALITY STRINGS\n minPercentUniqueForKey?: number;\n minCardinalityForKey?: number;\n}\n\nexport const DEFAULT_QUERY_CONFIG: QueryConfig = {\n verbose: false,\n defaultSpecConfig: {\n line: {point: true},\n scale: {useUnaggregatedDomain: true}\n },\n propertyPrecedence: DEFAULT_PROP_PRECEDENCE.map(toKey),\n enum: DEFAULT_ENUM_INDEX,\n\n numberNominalProportion: 0.05,\n numberNominalLimit: 40,\n\n // CONSTRAINTS\n constraintManuallySpecifiedValue: false,\n // Spec Constraints -- See description inside src/constraints/spec.ts\n autoAddCount: false,\n\n hasAppropriateGraphicTypeForMark: true,\n omitAggregate: false,\n omitAggregatePlotWithDimensionOnlyOnFacet: true,\n omitAggregatePlotWithoutDimension: false,\n omitBarLineAreaWithOcclusion: true,\n omitBarTickWithSize: true,\n omitMultipleNonPositionalChannels: true,\n omitRaw: false,\n omitRawContinuousFieldForAggregatePlot: true,\n omitRepeatedField: true,\n omitNonPositionalOrFacetOverPositionalChannels: true,\n omitTableWithOcclusionIfAutoAddCount: true,\n omitVerticalDotPlot: false,\n omitInvalidStackSpec: true,\n omitNonSumStack: true,\n\n preferredBinAxis: CHANNEL.X,\n preferredTemporalAxis: CHANNEL.X,\n preferredOrdinalAxis: CHANNEL.Y, // ordinal on y makes it easier to read.\n preferredNominalAxis: CHANNEL.Y, // nominal on y makes it easier to read.\n preferredFacet: CHANNEL.ROW, // row make it easier to scroll than column\n\n // Field Encoding Constraints -- See description inside src/constraint/field.ts\n minCardinalityForBin: 15,\n maxCardinalityForCategoricalColor: 20,\n maxCardinalityForFacet: 20,\n maxCardinalityForShape: 6,\n timeUnitShouldHaveVariation: true,\n typeMatchesSchemaType: true,\n\n // STYLIZE\n stylize: true,\n smallRangeStepForHighCardinalityOrFacet: {maxCardinality: 10, rangeStep: 12},\n nominalColorScaleForHighCardinality: {maxCardinality: 10, palette: 'category20'},\n xAxisOnTopForHighYCardinalityWithoutColumn: {maxCardinality: 30},\n\n // RANKING PREFERENCE\n maxGoodCardinalityForFacet: 5, // FIXME: revise\n maxGoodCardinalityForColor: 7, // FIXME: revise\n\n // HIGH CARDINALITY STRINGS\n minPercentUniqueForKey: 0.8,\n minCardinalityForKey: 50\n};\n\nexport function extendConfig(opt: QueryConfig) {\n return {\n ...DEFAULT_QUERY_CONFIG,\n ...opt,\n enum: extendEnumIndex(opt.enum)\n };\n}\n\nfunction extendEnumIndex(enumIndex: Partial) {\n const enumOpt: EnumIndex = {\n ...DEFAULT_ENUM_INDEX,\n ...enumIndex,\n binProps: extendNestedEnumIndex(enumIndex, 'bin'),\n scaleProps: extendNestedEnumIndex(enumIndex, 'scale'),\n axisProps: extendNestedEnumIndex(enumIndex, 'axis'),\n legendProps: extendNestedEnumIndex(enumIndex, 'legend')\n };\n return enumOpt;\n}\n\nfunction extendNestedEnumIndex(enumIndex: Partial, prop: 'bin' | 'scale' | 'axis' | 'legend') {\n return {\n ...DEFAULT_ENUM_INDEX[prop + 'Props'],\n ...enumIndex[prop + 'Props']\n };\n}\n","import {AggregateOp} from 'vega';\nimport {isString, toSet} from 'vega-util';\nimport {contains, Flag, flagKeys} from './util';\n\nconst AGGREGATE_OP_INDEX: Flag = {\n argmax: 1,\n argmin: 1,\n average: 1,\n count: 1,\n distinct: 1,\n max: 1,\n mean: 1,\n median: 1,\n min: 1,\n missing: 1,\n q1: 1,\n q3: 1,\n ci0: 1,\n ci1: 1,\n stderr: 1,\n stdev: 1,\n stdevp: 1,\n sum: 1,\n valid: 1,\n values: 1,\n variance: 1,\n variancep: 1\n};\n\nexport interface ArgminDef {\n argmin: string;\n}\n\nexport interface ArgmaxDef {\n argmax: string;\n}\n\nexport type Aggregate = AggregateOp | ArgmaxDef | ArgminDef;\n\nexport function isArgminDef(a: Aggregate | string): a is ArgminDef {\n return !!a && !!a['argmin'];\n}\n\nexport function isArgmaxDef(a: Aggregate | string): a is ArgmaxDef {\n return !!a && !!a['argmax'];\n}\n\nexport const AGGREGATE_OPS = flagKeys(AGGREGATE_OP_INDEX);\n\nexport function isAggregateOp(a: string | ArgminDef | ArgmaxDef): a is AggregateOp {\n return isString(a) && !!AGGREGATE_OP_INDEX[a];\n}\n\nexport const COUNTING_OPS: AggregateOp[] = ['count', 'valid', 'missing', 'distinct'];\n\nexport function isCountingAggregateOp(aggregate: string | Aggregate): boolean {\n return aggregate && isString(aggregate) && contains(COUNTING_OPS, aggregate);\n}\n\nexport function isMinMaxOp(aggregate: Aggregate | string): boolean {\n return aggregate && isString(aggregate) && contains(['min', 'max'], aggregate);\n}\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = ['count', 'sum', 'distinct', 'valid', 'missing'];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = ['mean', 'average', 'median', 'q1', 'q3', 'min', 'max'];\n\nexport const SHARED_DOMAIN_OP_INDEX = toSet(SHARED_DOMAIN_OPS);\n","import {isBoolean, isObject} from 'vega-util';\nimport {BinParams} from './bin';\nimport {\n Channel,\n COLOR,\n COLUMN,\n FILL,\n FILLOPACITY,\n OPACITY,\n ROW,\n SHAPE,\n SIZE,\n STROKE,\n STROKEOPACITY,\n STROKEWIDTH\n} from './channel';\nimport {normalizeBin} from './channeldef';\nimport {keys, varName} from './util';\n\nexport interface BaseBin {\n /**\n * The number base to use for automatic bin determination (default is base 10).\n *\n * __Default value:__ `10`\n *\n */\n base?: number;\n /**\n * An exact step size to use between bins.\n *\n * __Note:__ If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n *\n * __Default value:__ `[5, 2]`\n *\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n *\n * __Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels\n *\n * @minimum 2\n */\n maxbins?: number;\n /**\n * A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n *\n * __Default Value:__ the minimum bin extent value\n */\n anchor?: number;\n /**\n * If true (the default), attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n */\n nice?: boolean;\n}\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface BinParams extends BaseBin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[]; // VgBinTransform uses a different extent so we need to pull this out.\n\n /**\n * When set to true, Vega-Lite treats the input data as already binned.\n */\n binned?: boolean;\n}\n\nexport type Bin = boolean | BinParams | 'binned' | null;\n\n/**\n * Create a key for the bin configuration. Not for prebinned bin.\n */\nexport function binToString(bin: BinParams | true) {\n if (isBoolean(bin)) {\n bin = normalizeBin(bin, undefined);\n }\n return (\n 'bin' +\n keys(bin)\n .map(p => varName(`_${p}_${bin[p]}`))\n .join('')\n );\n}\n\n/**\n * Vega-Lite should bin the data.\n */\nexport function isBinning(bin: BinParams | boolean | 'binned'): bin is BinParams | true {\n return bin === true || (isBinParams(bin) && !bin.binned);\n}\n\n/**\n * The data is already binned and so Vega-Lite should not bin it again.\n */\nexport function isBinned(bin: BinParams | boolean | 'binned'): bin is 'binned' {\n return bin === 'binned' || (isBinParams(bin) && bin.binned);\n}\n\nexport function isBinParams(bin: BinParams | boolean | 'binned'): bin is BinParams {\n return isObject(bin);\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n case COLOR:\n case FILL:\n case STROKE:\n case STROKEWIDTH:\n case OPACITY:\n case FILLOPACITY:\n case STROKEOPACITY:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule [falls through]\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n","// Declaration and utility for variants of a field definition object\nimport {isArray, isBoolean, isNumber, isString} from 'vega-util';\nimport {Aggregate, isAggregateOp, isArgmaxDef, isArgminDef, isCountingAggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {autoMaxBins, Bin, BinParams, binToString, isBinned, isBinning} from './bin';\nimport {Channel, isScaleChannel, isSecondaryRangeChannel, POSITION_SCALE_CHANNELS, rangeType} from './channel';\nimport {CompositeAggregate} from './compositemark';\nimport {Config} from './config';\nimport {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {FormatMixins, Guide, TitleMixins} from './guide';\nimport {ImputeParams} from './impute';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {LogicalOperand} from './logical';\nimport {Predicate} from './predicate';\nimport {Scale} from './scale';\nimport {Sort, SortOrder} from './sort';\nimport {isFacetFieldDef} from './spec/facet';\nimport {StackOffset} from './stack';\nimport {\n getLocalTimeUnit,\n getTimeUnitParts,\n isLocalSingleTimeUnit,\n isUtcSingleTimeUnit,\n normalizeTimeUnit,\n TimeUnit\n} from './timeunit';\nimport {AggregatedFieldDef, WindowFieldDef} from './transform';\nimport {getFullName, QUANTITATIVE, StandardType, Type} from './type';\nimport {contains, flatAccessWithDatum, getFirstDefined, internalField, replacePathInField, titlecase} from './util';\n\nexport type Value = number | string | boolean | null;\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between `0` to `1` for opacity).\n */\n value: V;\n}\n\n/**\n * Generic type for conditional channelDef.\n * F defines the underlying FieldDef type.\n */\n\nexport type ChannelDefWithCondition, V extends Value> =\n | FieldDefWithCondition\n | ValueDefWithCondition;\n\n/**\n * A ValueDef with Condition where either the conition or the value are optional.\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\n\nexport type ValueDefWithCondition, V extends Value = Value> =\n | ValueDefWithOptionalCondition\n | ConditionOnlyDef;\n\nexport type StringValueDefWithCondition = ValueDefWithCondition<\n MarkPropFieldDef,\n string | null\n>;\n\nexport type NumericValueDefWithCondition = ValueDefWithCondition<\n MarkPropFieldDef,\n number\n>;\n\nexport type TypeForShape = 'nominal' | 'ordinal' | 'geojson';\n\nexport type ShapeValueDefWithCondition = StringValueDefWithCondition;\n\nexport type TextValueDefWithCondition = ValueDefWithCondition, Value>;\n\nexport type Conditional | ValueDef> = ConditionalPredicate | ConditionalSelection;\n\nexport type ConditionalPredicate | ValueDef> = {\n /**\n * Predicate for triggering the condition\n */\n test: LogicalOperand;\n} & CD;\n\nexport type ConditionalSelection | ValueDef> = {\n /**\n * A [selection name](https://vega.github.io/vega-lite/docs/selection.html), or a series of [composed selections](https://vega.github.io/vega-lite/docs/selection.html#compose).\n */\n selection: LogicalOperand;\n} & CD;\n\nexport function isConditionalSelection(c: Conditional): c is ConditionalSelection {\n return c['selection'];\n}\n\nexport interface ConditionValueDefMixins {\n /**\n * One or more value definition(s) with [a selection or a test predicate](https://vega.github.io/vega-lite/docs/condition.html).\n *\n * __Note:__ A field definition's `condition` property can only contain [conditional value definitions](https://vega.github.io/vega-lite/docs/condition.html#value)\n * since Vega-Lite only allows at most one encoded field per encoding channel.\n */\n condition?: Conditional> | Conditional>[];\n}\n\n/**\n * A FieldDef with Condition\n * {\n * condition: {value: ...},\n * field: ...,\n * ...\n * }\n */\n\nexport type FieldDefWithCondition, V extends Value = Value> = F & ConditionValueDefMixins;\n\nexport type StringFieldDefWithCondition = FieldDefWithCondition<\n MarkPropFieldDef,\n string | null\n>;\n\nexport type NumericFieldDefWithCondition = FieldDefWithCondition<\n MarkPropFieldDef,\n number\n>;\n\nexport type ShapeFieldDefWithCondition = StringFieldDefWithCondition;\n\nexport type TextFieldDefWithCondition = FieldDefWithCondition, Value>;\n\n/**\n * A ValueDef with optional Condition\n * {\n * condition: {field: ...} | {value: ...},\n * value: ...,\n * }\n */\n\nexport interface ValueDefWithOptionalCondition, V extends Value> extends ValueDef {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition?: Conditional | Conditional> | Conditional>[];\n}\n\n/**\n * A Condition only definition.\n * {\n * condition: {field: ...} | {value: ...}\n * }\n */\nexport interface ConditionOnlyDef, V extends Value = Value> {\n /**\n * A field definition or one or more value definition(s) with a selection predicate.\n */\n condition: Conditional | Conditional> | Conditional>[];\n}\n\n/**\n * Reference to a repeated value.\n */\nexport interface RepeatRef {\n repeat: 'row' | 'column' | 'repeat';\n}\n\nexport type FieldName = string;\nexport type Field = FieldName | RepeatRef;\n\nexport function isRepeatRef(field: Field): field is RepeatRef {\n return field && !isString(field) && 'repeat' in field;\n}\n\n/** @hide */\nexport type HiddenCompositeAggregate = CompositeAggregate;\n\nexport interface FieldDefBase {\n /**\n * __Required.__ A string defining the name of the field from which to pull a data value\n * or an object defining iterated values from the [`repeat`](https://vega.github.io/vega-lite/docs/repeat.html) operator.\n *\n * __Note:__ Dots (`.`) and brackets (`[` and `]`) can be used to access nested objects (e.g., `\"field\": \"foo.bar\"` and `\"field\": \"foo['bar']\"`).\n * If field names contain dots or brackets but are not nested, you can use `\\\\` to escape dots and brackets (e.g., `\"a\\\\.b\"` and `\"a\\\\[0\\\\]\"`).\n * See more details about escaping in the [field documentation](https://vega.github.io/vega-lite/docs/field.html).\n *\n * __Note:__ `field` is not required if `aggregate` is `count`.\n */\n field?: F;\n\n // function\n\n /**\n * Time unit (e.g., `year`, `yearmonth`, `month`, `hours`) for a temporal field.\n * or [a temporal field that gets casted as ordinal](https://vega.github.io/vega-lite/docs/type.html#cast).\n *\n * __Default value:__ `undefined` (None)\n */\n timeUnit?: TimeUnit;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n *\n * __Default value:__ `undefined` (None)\n */\n aggregate?: Aggregate | HiddenCompositeAggregate;\n\n /**\n * A flag for binning a `quantitative` field, [an object defining binning parameters](https://vega.github.io/vega-lite/docs/bin.html#params), or indicating that the data for `x` or `y` channel are binned before they are imported into Vega-Lite (`\"binned\"`).\n *\n * - If `true`, default [binning parameters](https://vega.github.io/vega-lite/docs/bin.html) will be applied.\n *\n * - If `\"binned\"`, this indicates that the data for the `x` (or `y`) channel are already binned. You can map the bin-start field to `x` (or `y`) and the bin-end field to `x2` (or `y2`). The scale and axis will be formatted similar to binning in Vega-lite. To adjust the axis ticks based on the bin step, you can also set the axis's [`tickMinStep`](https://vega.github.io/vega-lite/docs/axis.html#ticks) property.\n *\n * __Default value:__ `false`\n */\n bin?: B;\n}\n\nexport function toFieldDefBase(fieldDef: TypedFieldDef): FieldDefBase {\n const {field, timeUnit, bin, aggregate} = fieldDef;\n return {\n ...(timeUnit ? {timeUnit} : {}),\n ...(bin ? {bin} : {}),\n ...(aggregate ? {aggregate} : {}),\n field\n };\n}\n\nexport interface TypeMixins {\n /**\n * The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or `\"nominal\"`).\n * It can also be a `\"geojson\"` type for encoding ['geoshape'](https://vega.github.io/vega-lite/docs/geoshape.html).\n *\n *\n * __Note:__\n *\n * - Data values for a temporal field can be either a date-time string (e.g., `\"2015-03-07 12:32:17\"`, `\"17:01\"`, `\"2015-03-16\"`. `\"2015\"`) or a timestamp number (e.g., `1552199579097`).\n * - Data `type` describes the semantics of the data rather than the primitive data types (`number`, `string`, etc.). The same primitive data type can have different types of measurement. For example, numeric data can represent quantitative, ordinal, or nominal data.\n * - When using with [`bin`](https://vega.github.io/vega-lite/docs/bin.html), the `type` property can be either `\"quantitative\"` (for using a linear bin scale) or [`\"ordinal\"` (for using an ordinal bin scale)](https://vega.github.io/vega-lite/docs/type.html#cast-bin).\n * - When using with [`timeUnit`](https://vega.github.io/vega-lite/docs/timeunit.html), the `type` property can be either `\"temporal\"` (for using a temporal scale) or [`\"ordinal\"` (for using an ordinal scale)](https://vega.github.io/vega-lite/docs/type.html#cast-bin).\n * - When using with [`aggregate`](https://vega.github.io/vega-lite/docs/aggregate.html), the `type` property refers to the post-aggregation data type. For example, we can calculate count `distinct` of a categorical field `\"cat\"` using `{\"aggregate\": \"distinct\", \"field\": \"cat\", \"type\": \"quantitative\"}`. The `\"type\"` of the aggregate output is `\"quantitative\"`.\n * - Secondary channels (e.g., `x2`, `y2`, `xError`, `yError`) do not have `type` as they have exactly the same type as their primary channels (e.g., `x`, `y`).\n */\n type: T;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport type TypedFieldDef<\n F extends Field,\n T extends Type = Type,\n B extends Bin = boolean | BinParams | 'binned' | null // This is equivalent to Bin but we use the full form so the docs has detailed types\n> = FieldDefBase & TitleMixins & TypeMixins;\n\nexport interface SortableFieldDef<\n F extends Field,\n T extends Type = StandardType,\n B extends Bin = boolean | BinParams | null\n> extends TypedFieldDef {\n /**\n * Sort order for the encoded field.\n *\n * For continuous fields (quantitative or temporal), `sort` can be either `\"ascending\"` or `\"descending\"`.\n *\n * For discrete fields, `sort` can be one of the following:\n * - `\"ascending\"` or `\"descending\"` -- for sorting by the values' natural order in Javascript.\n * - [A sort-by-encoding definition](https://vega.github.io/vega-lite/docs/sort.html#sort-by-encoding) for sorting by another encoding channel. (This type of sort definition is not available for `row` and `column` channels.)\n * - [A sort field definition](https://vega.github.io/vega-lite/docs/sort.html#sort-field) for sorting by another field.\n * - [An array specifying the field values in preferred order](https://vega.github.io/vega-lite/docs/sort.html#sort-array). In this case, the sort order will obey the values in the array, followed by any unspecified values in their original order. For discrete time field, values in the sort array can be [date-time definition objects](types#datetime). In addition, for time units `\"month\"` and `\"day\"`, the values can be the month or day names (case insensitive) or their 3-letter initials (e.g., `\"Mon\"`, `\"Tue\"`).\n * - `null` indicating no sort.\n *\n * __Default value:__ `\"ascending\"`\n *\n * __Note:__ `null` is not supported for `row` and `column`.\n */\n sort?: Sort;\n}\n\nexport function isSortableFieldDef(fieldDef: FieldDef): fieldDef is SortableFieldDef {\n return isTypedFieldDef(fieldDef) && !!fieldDef['sort'];\n}\n\nexport interface ScaleFieldDef<\n F extends Field,\n T extends Type = StandardType,\n B extends Bin = boolean | BinParams | null\n> extends SortableFieldDef {\n /**\n * An object defining properties of the channel's scale, which is the function that transforms values in the data domain (numbers, dates, strings, etc) to visual values (pixels, colors, sizes) of the encoding channels.\n *\n * If `null`, the scale will be [disabled and the data value will be directly encoded](https://vega.github.io/vega-lite/docs/scale.html#disable).\n *\n * __Default value:__ If undefined, default [scale properties](https://vega.github.io/vega-lite/docs/scale.html) are applied.\n */\n scale?: Scale | null;\n}\n\n/**\n * A field definition of a secondary channel that shares a scale with another primary channel. For example, `x2`, `xError` and `xError2` share the same scale with `x`.\n */\nexport type SecondaryFieldDef = FieldDefBase & TitleMixins; // x2/y2 shouldn't have bin, but we keep bin property for simplicity of the codebase.\n\n/**\n * Field Def without scale (and without bin: \"binned\" support).\n */\nexport type FieldDefWithoutScale = TypedFieldDef;\n\nexport type LatLongFieldDef = FieldDefBase &\n TitleMixins &\n Partial>; // Lat long shouldn't have bin, but we keep bin property for simplicity of the codebase.\n\nexport interface PositionFieldDef\n extends ScaleFieldDef<\n F,\n StandardType,\n boolean | BinParams | 'binned' | null // This is equivalent to Bin but we use the full form so the docs has detailed types\n > {\n /**\n * An object defining properties of axis's gridlines, ticks and labels.\n * If `null`, the axis for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [axis properties](https://vega.github.io/vega-lite/docs/axis.html) are applied.\n */\n axis?: Axis | null;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * `stack` is only applicable for `x` and `y` channels with continuous domains.\n * For example, `stack` of `y` can be used to customize stacking for a vertical bar chart.\n *\n * `stack` can be one of the following values:\n * - `\"zero\"` or `true`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).\n * - `\"normalize\"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized).
\n * -`\"center\"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).\n * - `null` or `false` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions are true:\n * (1) the mark is `bar` or `area`;\n * (2) the stacked measure channel (x or y) has a linear scale;\n * (3) At least one of non-position channels mapped to an unaggregated field that is different from x and y. Otherwise, `null` by default.\n */\n stack?: StackOffset | null | boolean;\n\n /**\n * An object defining the properties of the Impute Operation to be applied.\n * The field value of the other positional channel is taken as `key` of the `Impute` Operation.\n * The field of the `color` channel if specified is used as `groupby` of the `Impute` Operation.\n */\n impute?: ImputeParams;\n}\n\n/**\n * Field definition of a mark property, which can contain a legend.\n */\nexport type MarkPropFieldDef = ScaleFieldDef<\n F,\n T,\n boolean | BinParams | null\n> & {\n /**\n * An object defining properties of the legend.\n * If `null`, the legend for the encoding channel will be removed.\n *\n * __Default value:__ If undefined, default [legend properties](https://vega.github.io/vega-lite/docs/legend.html) are applied.\n */\n legend?: Legend | null;\n};\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDefWithoutScale {\n /**\n * The sort order. One of `\"ascending\"` (default) or `\"descending\"`.\n */\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDefWithoutScale, FormatMixins {}\n\nexport type FieldDef = SecondaryFieldDef | TypedFieldDef;\nexport type ChannelDef = FieldDef, V extends Value = Value> = ChannelDefWithCondition<\n FD,\n V\n>;\n\nexport function isConditionalDef(\n channelDef: ChannelDef, V>\n): channelDef is ChannelDefWithCondition, V> {\n return !!channelDef && !!channelDef.condition;\n}\n\n/**\n * Return if a channelDef is a ConditionalValueDef with ConditionFieldDef\n */\n\nexport function hasConditionalFieldDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef & {condition: Conditional>} {\n return !!channelDef && !!channelDef.condition && !isArray(channelDef.condition) && isFieldDef(channelDef.condition);\n}\n\nexport function hasConditionalValueDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef & {condition: Conditional> | Conditional>[]} {\n return !!channelDef && !!channelDef.condition && (isArray(channelDef.condition) || isValueDef(channelDef.condition));\n}\n\nexport function isFieldDef(\n channelDef: ChannelDef>\n): channelDef is\n | TypedFieldDef\n | SecondaryFieldDef\n | PositionFieldDef\n | ScaleFieldDef\n | MarkPropFieldDef\n | OrderFieldDef\n | TextFieldDef {\n return !!channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isTypedFieldDef(channelDef: ChannelDef>): channelDef is TypedFieldDef {\n return !!channelDef && ((!!channelDef['field'] && !!channelDef['type']) || channelDef['aggregate'] === 'count');\n}\n\nexport function isStringFieldDef(channelDef: ChannelDef>): channelDef is TypedFieldDef {\n return isFieldDef(channelDef) && isString(channelDef.field);\n}\n\nexport function isValueDef(\n channelDef: ChannelDef, V>\n): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\nexport function isScaleFieldDef(channelDef: ChannelDef>): channelDef is ScaleFieldDef {\n return !!channelDef && (!!channelDef['scale'] || !!channelDef['sort']);\n}\n\nexport function isPositionFieldDef(\n channelDef: ChannelDef>\n): channelDef is PositionFieldDef {\n return !!channelDef && (!!channelDef['axis'] || !!channelDef['stack'] || !!channelDef['impute']);\n}\n\nexport function isMarkPropFieldDef(\n channelDef: ChannelDef>\n): channelDef is MarkPropFieldDef {\n return !!channelDef && !!channelDef['legend'];\n}\n\nexport function isTextFieldDef(channelDef: ChannelDef>): channelDef is TextFieldDef {\n return !!channelDef && !!channelDef['format'];\n}\n\nexport interface FieldRefOption {\n /** Exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field with datum, parent, or datum.datum (e.g., datum['...'] for Vega Expression */\n expr?: 'datum' | 'parent' | 'datum.datum';\n /** Prepend fn with custom function prefix */\n prefix?: string;\n /** Append suffix to the field ref for bin (default='start') */\n binSuffix?: 'end' | 'range' | 'mid';\n /** Append suffix to the field ref (general) */\n suffix?: string;\n /**\n * Use the field name for `as` in a transform.\n * We will not escape nested accesses because Vega transform outputs cannot be nested.\n */\n forAs?: boolean;\n}\n\nfunction isOpFieldDef(\n fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef\n): fieldDef is WindowFieldDef | AggregatedFieldDef {\n return !!fieldDef['op'];\n}\n\n/**\n * Get a Vega field reference from a Vega-Lite field def.\n */\nexport function vgField(\n fieldDef: FieldDefBase | WindowFieldDef | AggregatedFieldDef,\n opt: FieldRefOption = {}\n): string {\n let field = fieldDef.field;\n const prefix = opt.prefix;\n let suffix = opt.suffix;\n\n let argAccessor = ''; // for accessing argmin/argmax field at the end without getting escaped\n\n if (isCount(fieldDef)) {\n field = internalField('count');\n } else {\n let fn: string;\n\n if (!opt.nofn) {\n if (isOpFieldDef(fieldDef)) {\n fn = fieldDef.op;\n } else {\n const {bin, aggregate, timeUnit} = fieldDef;\n if (isBinning(bin)) {\n fn = binToString(bin);\n suffix = (opt.binSuffix || '') + (opt.suffix || '');\n } else if (aggregate) {\n if (isArgmaxDef(aggregate)) {\n argAccessor = `.${field}`;\n field = `argmax_${aggregate.argmax}`;\n } else if (isArgminDef(aggregate)) {\n argAccessor = `.${field}`;\n field = `argmin_${aggregate.argmin}`;\n } else {\n fn = String(aggregate);\n }\n } else if (timeUnit) {\n fn = String(timeUnit);\n }\n }\n }\n\n if (fn) {\n field = field ? `${fn}_${field}` : fn;\n }\n }\n\n if (suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.forAs) {\n return field;\n } else if (opt.expr) {\n // Expression to access flattened field. No need to escape dots.\n return flatAccessWithDatum(field, opt.expr) + argAccessor;\n } else {\n // We flattened all fields so paths should have become dot.\n return replacePathInField(field) + argAccessor;\n }\n}\n\nexport function isDiscrete(fieldDef: TypedFieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n case 'geojson':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'temporal':\n return false;\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: TypedFieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDefBase) {\n return fieldDef.aggregate === 'count';\n}\n\nexport type FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => string;\n\nexport function verbalTitleFormatter(fieldDef: FieldDefBase, config: Config) {\n const {field, bin, timeUnit, aggregate} = fieldDef;\n if (aggregate === 'count') {\n return config.countTitle;\n } else if (isBinning(bin)) {\n return `${field} (binned)`;\n } else if (timeUnit) {\n const units = getTimeUnitParts(timeUnit).join('-');\n return `${field} (${units})`;\n } else if (aggregate) {\n if (isArgmaxDef(aggregate)) {\n return `${field} for max ${aggregate.argmax}`;\n } else if (isArgminDef(aggregate)) {\n return `${field} for min ${aggregate.argmin}`;\n } else {\n return `${titlecase(aggregate)} of ${field}`;\n }\n }\n return field;\n}\n\nexport function functionalTitleFormatter(fieldDef: FieldDefBase) {\n const {aggregate, bin, timeUnit, field} = fieldDef;\n if (isArgmaxDef(aggregate)) {\n return `${field} for argmax(${aggregate.argmax})`;\n } else if (isArgminDef(aggregate)) {\n return `${field} for argmin(${aggregate.argmin})`;\n }\n\n const fn = aggregate || timeUnit || (isBinning(bin) && 'bin');\n if (fn) {\n return fn.toUpperCase() + '(' + field + ')';\n } else {\n return field;\n }\n}\n\nexport const defaultTitleFormatter: FieldTitleFormatter = (fieldDef: FieldDefBase, config: Config) => {\n switch (config.fieldTitle) {\n case 'plain':\n return fieldDef.field;\n case 'functional':\n return functionalTitleFormatter(fieldDef);\n default:\n return verbalTitleFormatter(fieldDef, config);\n }\n};\n\nlet titleFormatter = defaultTitleFormatter;\n\nexport function setTitleFormatter(formatter: FieldTitleFormatter) {\n titleFormatter = formatter;\n}\n\nexport function resetTitleFormatter() {\n setTitleFormatter(defaultTitleFormatter);\n}\n\nexport function title(\n fieldDef: TypedFieldDef | SecondaryFieldDef,\n config: Config,\n {allowDisabling, includeDefault = true}: {allowDisabling: boolean; includeDefault?: boolean}\n) {\n const guide = getGuide(fieldDef) || {};\n const guideTitle = guide.title;\n const def = includeDefault ? defaultTitle(fieldDef, config) : undefined;\n\n if (allowDisabling) {\n return getFirstDefined(guideTitle, fieldDef.title, def);\n } else {\n return guideTitle || fieldDef.title || def;\n }\n}\n\nexport function getGuide(fieldDef: TypedFieldDef | SecondaryFieldDef): Guide {\n if (isPositionFieldDef(fieldDef) && fieldDef.axis) {\n return fieldDef.axis;\n } else if (isMarkPropFieldDef(fieldDef) && fieldDef.legend) {\n return fieldDef.legend;\n } else if (isFacetFieldDef(fieldDef) && fieldDef.header) {\n return fieldDef.header;\n }\n return undefined;\n}\n\nexport function defaultTitle(fieldDef: FieldDefBase, config: Config) {\n return titleFormatter(fieldDef, config);\n}\n\nexport function format(fieldDef: TypedFieldDef) {\n if (isTextFieldDef(fieldDef) && fieldDef.format) {\n return fieldDef.format;\n } else {\n const guide = getGuide(fieldDef) || {};\n return guide.format;\n }\n}\n\nexport function defaultType(fieldDef: TypedFieldDef, channel: Channel): Type {\n if (fieldDef.timeUnit) {\n return 'temporal';\n }\n if (isBinning(fieldDef.bin)) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Returns the fieldDef -- either from the outer channelDef or from the condition of channelDef.\n * @param channelDef\n */\n\nexport function getFieldDef(channelDef: ChannelDef>): FieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\nexport function getTypedFieldDef(channelDef: ChannelDef>): TypedFieldDef {\n if (isFieldDef(channelDef)) {\n return channelDef;\n } else if (hasConditionalFieldDef(channelDef)) {\n return channelDef.condition;\n }\n return undefined;\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(channelDef: ChannelDef, channel: Channel): ChannelDef {\n if (isString(channelDef) || isNumber(channelDef) || isBoolean(channelDef)) {\n const primitiveType = isString(channelDef) ? 'string' : isNumber(channelDef) ? 'number' : 'boolean';\n log.warn(log.message.primitiveChannelDef(channel, primitiveType, channelDef));\n return {value: channelDef};\n }\n\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(channelDef)) {\n return normalizeFieldDef(channelDef, channel);\n } else if (hasConditionalFieldDef(channelDef)) {\n return {\n ...channelDef,\n // Need to cast as normalizeFieldDef normally return FieldDef, but here we know that it is definitely Condition\n condition: normalizeFieldDef(channelDef.condition, channel) as Conditional>\n };\n }\n return channelDef;\n}\nexport function normalizeFieldDef(fieldDef: FieldDef, channel: Channel) {\n const {aggregate, timeUnit, bin} = fieldDef;\n // Drop invalid aggregate\n if (aggregate && !isAggregateOp(aggregate) && !isArgmaxDef(aggregate) && !isArgminDef(aggregate)) {\n const {aggregate: _, ...fieldDefWithoutAggregate} = fieldDef;\n log.warn(log.message.invalidAggregate(aggregate));\n fieldDef = fieldDefWithoutAggregate;\n }\n\n // Normalize Time Unit\n if (timeUnit) {\n fieldDef = {\n ...fieldDef,\n timeUnit: normalizeTimeUnit(timeUnit)\n };\n }\n\n // Normalize bin\n if (isBinning(bin)) {\n fieldDef = {\n ...fieldDef,\n bin: normalizeBin(bin, channel)\n } as FieldDef;\n }\n\n if (isBinned(bin) && !contains(POSITION_SCALE_CHANNELS, channel)) {\n log.warn(`Channel ${channel} should not be used with \"binned\" bin`);\n }\n\n // Normalize Type\n if (isTypedFieldDef(fieldDef)) {\n const {type} = fieldDef;\n const fullType = getFullName(type);\n if (type !== fullType) {\n // convert short type to full type\n fieldDef = {\n ...fieldDef,\n type: fullType\n };\n }\n if (type !== 'quantitative') {\n if (isCountingAggregateOp(aggregate)) {\n log.warn(log.message.invalidFieldTypeForCountAggregate(type, aggregate));\n fieldDef = {\n ...fieldDef,\n type: 'quantitative'\n };\n }\n }\n } else if (!isSecondaryRangeChannel(channel)) {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef as TypedFieldDef, channel);\n log.warn(log.message.missingFieldType(channel, newType));\n\n fieldDef = {\n ...fieldDef,\n type: newType\n };\n }\n\n if (isTypedFieldDef(fieldDef)) {\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n }\n return fieldDef;\n}\n\nexport function normalizeBin(bin: BinParams | boolean | 'binned', channel: Channel) {\n if (isBoolean(bin)) {\n return {maxbins: autoMaxBins(channel)};\n } else if (bin === 'binned') {\n return {\n binned: true\n };\n } else if (!bin.maxbins && !bin.step) {\n return {...bin, maxbins: autoMaxBins(channel)};\n } else {\n return bin;\n }\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(\n fieldDef: TypedFieldDef,\n channel: Channel\n): {compatible: boolean; warning?: string} {\n const type = fieldDef.type;\n\n if (type === 'geojson' && channel !== 'shape') {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with a geojson data.`\n };\n }\n\n switch (channel) {\n case 'row':\n case 'column':\n case 'facet':\n if (isContinuous(fieldDef)) {\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'fill':\n case 'stroke':\n case 'text':\n case 'detail':\n case 'key':\n case 'tooltip':\n case 'href':\n return COMPATIBLE;\n\n case 'longitude':\n case 'longitude2':\n case 'latitude':\n case 'latitude2':\n if (type !== QUANTITATIVE) {\n return {\n compatible: false,\n warning: `Channel ${channel} should be used with a quantitative field only, not ${fieldDef.type} field.`\n };\n }\n return COMPATIBLE;\n\n case 'opacity':\n case 'fillOpacity':\n case 'strokeOpacity':\n case 'strokeWidth':\n case 'size':\n case 'x2':\n case 'y2':\n if (type === 'nominal' && !fieldDef['sort']) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with an unsorted discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (!contains(['ordinal', 'nominal', 'geojson'], fieldDef.type)) {\n return {\n compatible: false,\n warning: 'Shape channel should be used with only either discrete or geojson data.'\n };\n }\n return COMPATIBLE;\n\n case 'order':\n if (fieldDef.type === 'nominal' && !('sort' in fieldDef)) {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n\nexport function isNumberFieldDef(fieldDef: TypedFieldDef) {\n return fieldDef.type === 'quantitative' || isBinning(fieldDef.bin);\n}\n\n/**\n * Check if the field def uses a time format or does not use any format but is temporal (this does not cover field defs that are temporal but use a number format).\n */\nexport function isTimeFormatFieldDef(fieldDef: TypedFieldDef): boolean {\n const formatType =\n (isPositionFieldDef(fieldDef) && fieldDef.axis && fieldDef.axis.formatType) ||\n (isMarkPropFieldDef(fieldDef) && fieldDef.legend && fieldDef.legend.formatType) ||\n (isTextFieldDef(fieldDef) && fieldDef.formatType);\n return formatType === 'time' || (!formatType && isTimeFieldDef(fieldDef));\n}\n\n/**\n * Check if field def has tye `temporal`. If you want to also cover field defs that use a time format, use `isTimeFormatFieldDef`.\n */\nexport function isTimeFieldDef(fieldDef: TypedFieldDef) {\n return fieldDef.type === 'temporal' || !!fieldDef.timeUnit;\n}\n\n/**\n * Getting a value associated with a fielddef.\n * Convert the value to Vega expression if applicable (for datetime object, or string if the field def is temporal or has timeUnit)\n */\nexport function valueExpr(\n v: number | string | boolean | DateTime,\n {\n timeUnit,\n type,\n time,\n undefinedIfExprNotRequired\n }: {\n timeUnit: TimeUnit;\n type?: Type;\n time?: boolean;\n undefinedIfExprNotRequired?: boolean;\n }\n): string {\n let expr;\n if (isDateTime(v)) {\n expr = dateTimeExpr(v, true);\n } else if (isString(v) || isNumber(v)) {\n if (timeUnit || type === 'temporal') {\n if (isLocalSingleTimeUnit(timeUnit)) {\n expr = dateTimeExpr({[timeUnit]: v}, true);\n } else if (isUtcSingleTimeUnit(timeUnit)) {\n // FIXME is this really correct?\n expr = valueExpr(v, {timeUnit: getLocalTimeUnit(timeUnit)});\n } else {\n // just pass the string to date function (which will call JS Date.parse())\n expr = `datetime(${JSON.stringify(v)})`;\n }\n }\n }\n if (expr) {\n return time ? `time(${expr})` : expr;\n }\n // number or boolean or normal string\n return undefinedIfExprNotRequired ? undefined : JSON.stringify(v);\n}\n\n/**\n * Standardize value array -- convert each value to Vega expression if applicable\n */\nexport function valueArray(fieldDef: TypedFieldDef, values: (number | string | boolean | DateTime)[]) {\n const {timeUnit, type} = fieldDef;\n return values.map(v => {\n const expr = valueExpr(v, {timeUnit, type, undefinedIfExprNotRequired: true});\n // return signal for the expression if we need an expression\n if (expr !== undefined) {\n return {signal: expr};\n }\n // otherwise just return the original value\n return v;\n });\n}\n\n/**\n * Checks whether a fieldDef for a particular channel requires a computed bin range.\n */\nexport function binRequiresRange(fieldDef: TypedFieldDef, channel: Channel) {\n if (!isBinning(fieldDef.bin)) {\n console.warn('Only use this method with binned field defs');\n return false;\n }\n\n // We need the range only when the user explicitly forces a binned field to be use discrete scale. In this case, bin range is used in axis and legend labels.\n // We could check whether the axis or legend exists (not disabled) but that seems overkill.\n return isScaleChannel(channel) && contains(['ordinal', 'nominal'], fieldDef.type);\n}\n","import * as TYPE from 'vega-lite/build/src/type';\nimport {Type} from 'vega-lite/build/src/type';\n\nexport namespace ExpandedType {\n export const QUANTITATIVE = TYPE.QUANTITATIVE;\n export const ORDINAL = TYPE.ORDINAL;\n export const TEMPORAL = TYPE.TEMPORAL;\n export const NOMINAL = TYPE.NOMINAL;\n export const KEY: 'key' = 'key';\n}\n\nexport type ExpandedType = Type | typeof ExpandedType.KEY;\n\nexport function isDiscrete(fieldType: any) {\n return fieldType === TYPE.ORDINAL || fieldType === TYPE.NOMINAL || fieldType === ExpandedType.KEY;\n}\n","import {isBinning} from '../../bin';\nimport {Channel, isColorChannel, isScaleChannel, rangeType} from '../../channel';\nimport {TypedFieldDef} from '../../channeldef';\nimport * as log from '../../log';\nimport {Mark} from '../../mark';\nimport {channelSupportScaleType, Scale, ScaleType, scaleTypeSupportDataType} from '../../scale';\nimport * as util from '../../util';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport function scaleType(\n specifiedScale: Scale,\n channel: Channel,\n fieldDef: TypedFieldDef,\n mark: Mark\n): ScaleType {\n const defaultScaleType = defaultType(channel, fieldDef, mark);\n const {type} = specifiedScale;\n\n if (!isScaleChannel(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (type !== undefined) {\n // Check if explicitly specified scale type is supported by the channel\n if (!channelSupportScaleType(channel, type)) {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, type, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the data type\n if (!scaleTypeSupportDataType(type, fieldDef.type)) {\n log.warn(log.message.scaleTypeNotWorkWithFieldDef(type, defaultScaleType));\n return defaultScaleType;\n }\n\n return type;\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\n// NOTE: Voyager uses this method.\nfunction defaultType(channel: Channel, fieldDef: TypedFieldDef, mark: Mark): ScaleType {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n if (isColorChannel(channel) || rangeType(channel) === 'discrete') {\n if (channel === 'shape' && fieldDef.type === 'ordinal') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n }\n return 'ordinal';\n }\n\n if (util.contains(['x', 'y'], channel)) {\n if (util.contains(['rect', 'bar', 'rule'], mark)) {\n // The rect/bar mark should fit into a band.\n // For rule, using band scale to make rule align with axis ticks better https://github.com/vega/vega-lite/issues/3429\n return 'band';\n }\n if (mark === 'bar') {\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n\n case 'temporal':\n if (isColorChannel(channel)) {\n return 'time';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n return 'time';\n\n case 'quantitative':\n if (isColorChannel(channel)) {\n if (isBinning(fieldDef.bin)) {\n return 'bin-ordinal';\n }\n\n return 'linear';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n return 'linear';\n\n case 'geojson':\n return undefined;\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n","import { Dict, keys } from './util';\nimport {\n Property, toKey,\n} from './property';\n\nexport interface PropIndexReader {\n has(p: Property): boolean;\n get(p: Property): T;\n}\n\n/**\n * Dictionary that takes property as a key.\n */\nexport class PropIndex implements PropIndexReader {\n private index: Dict;\n\n constructor(i: Dict = null) {\n this.index = i ? { ...i } : {};\n }\n\n public has(p: Property) {\n return toKey(p) in this.index;\n }\n\n public get(p: Property) {\n return this.index[toKey(p)];\n }\n\n public set(p: Property, value: T) {\n this.index[toKey(p)] = value;\n return this;\n }\n\n public setByKey(key: string, value: T) {\n this.index[key] = value;\n }\n\n public map(f: (t: T) => U): PropIndex {\n const i = new PropIndex();\n for (const k in this.index) {\n i.index[k] = f(this.index[k]);\n }\n return i;\n }\n\n public size() {\n return keys(this.index).length;\n }\n\n public duplicate(): PropIndex {\n return new PropIndex(this.index);\n }\n}\n","import {AggregateOp} from 'vega';\nimport {isArray} from 'vega-util';\nimport {isArgmaxDef, isArgminDef} from './aggregate';\nimport {isBinning} from './bin';\nimport {Channel, CHANNELS, isChannel, isNonPositionScaleChannel, isSecondaryRangeChannel, supportMark} from './channel';\nimport {\n binRequiresRange,\n ChannelDef,\n Field,\n FieldDef,\n FieldDefWithoutScale,\n getFieldDef,\n getGuide,\n getTypedFieldDef,\n hasConditionalFieldDef,\n isConditionalDef,\n isFieldDef,\n isTypedFieldDef,\n isValueDef,\n LatLongFieldDef,\n normalize,\n normalizeFieldDef,\n NumericFieldDefWithCondition,\n NumericValueDefWithCondition,\n OrderFieldDef,\n PositionFieldDef,\n SecondaryFieldDef,\n ShapeFieldDefWithCondition,\n ShapeValueDefWithCondition,\n StringFieldDefWithCondition,\n StringValueDefWithCondition,\n TextFieldDef,\n TextFieldDefWithCondition,\n TextValueDefWithCondition,\n title,\n TypedFieldDef,\n ValueDef,\n vgField\n} from './channeldef';\nimport {Config} from './config';\nimport * as log from './log';\nimport {Mark} from './mark';\nimport {EncodingFacetMapping} from './spec/facet';\nimport {getDateTimeComponents} from './timeunit';\nimport {AggregatedFieldDef, BinTransform, TimeUnitTransform} from './transform';\nimport {TEMPORAL} from './type';\nimport {keys, some} from './util';\n\nexport interface Encoding {\n /**\n * X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"` without `x2`.\n *\n * The `value` of this channel can be a number or a string `\"width\"`.\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"` without `y2`\n *\n * The `value` of this channel can be a number or a string `\"height\"`.\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n *\n * The `value` of this channel can be a number or a string `\"width\"`.\n */\n // TODO: Ham need to add default behavior\n // `x2` cannot have type as it should have the same type as `x`\n x2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n *\n * The `value` of this channel can be a number or a string `\"height\"`.\n */\n // TODO: Ham need to add default behavior\n // `y2` cannot have type as it should have the same type as `y`\n y2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Longitude position of geographically projected marks.\n */\n longitude?: LatLongFieldDef | ValueDef;\n\n /**\n * Latitude position of geographically projected marks.\n */\n latitude?: LatLongFieldDef | ValueDef;\n\n /**\n * Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // `longitude2` cannot have type as it should have the same type as `longitude`\n longitude2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n */\n // `latitude2` cannot have type as it should have the same type as `latitude`\n latitude2?: SecondaryFieldDef | ValueDef;\n\n /**\n * Color of the marks – either fill or stroke color based on the `filled` property of mark definition.\n * By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n * `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n *\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_\n * 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. If either `fill` or `stroke` channel is specified, `color` channel will be ignored.\n * 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme).\n */\n color?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Fill color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `fill` channel, `color ` channel will be ignored. To customize both fill and stroke, please use `fill` and `stroke` channels (not `fill` and `color`).\n */\n fill?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Stroke color of the marks.\n * __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `color` property.\n *\n * _Note:_ When using `stroke` channel, `color ` channel will be ignored. To customize both stroke and fill, please use `stroke` and `fill` channels (not `stroke` and `color`).\n */\n\n stroke?: StringFieldDefWithCondition | StringValueDefWithCondition;\n\n /**\n * Opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `opacity` property.\n */\n opacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Fill opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `fillOpacity` property.\n */\n fillOpacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Stroke opacity of the marks.\n *\n * __Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `strokeOpacity` property.\n */\n strokeOpacity?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Stroke width of the marks.\n *\n * __Default value:__ If undefined, the default stroke width depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark)'s `strokeWidth` property.\n */\n strokeWidth?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Size of the mark.\n * - For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n * - For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n * - For `\"text\"` – the text's font size.\n * - Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)\n */\n size?: NumericFieldDefWithCondition | NumericValueDefWithCondition;\n\n /**\n * Shape of the mark.\n *\n * 1. For `point` marks the supported values include:\n * - plotting shapes: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, `\"triangle-down\"`, `\"triangle-right\"`, or `\"triangle-left\"`.\n * - the line symbol `\"stroke\"`\n * - centered directional shapes `\"arrow\"`, `\"wedge\"`, or `\"triangle\"`\n * - a custom [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.)\n *\n * 2. For `geoshape` marks it should be a field definition of the geojson data\n *\n * __Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property. (`\"circle\"` if unset.)\n */\n shape?: ShapeFieldDefWithCondition | ShapeValueDefWithCondition;\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line, trail, and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDefWithoutScale | FieldDefWithoutScale[];\n\n /**\n * A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data.\n */\n key?: FieldDefWithoutScale;\n\n /**\n * Text of the `text` mark.\n */\n text?: TextFieldDefWithCondition | TextValueDefWithCondition;\n\n /**\n * The tooltip text to show upon mouse hover.\n */\n tooltip?: TextFieldDefWithCondition | TextValueDefWithCondition | TextFieldDef[] | null;\n\n /**\n * A URL to load upon mouse click.\n */\n href?: TextFieldDefWithCondition | TextValueDefWithCondition;\n\n /**\n * Order of the marks.\n * - For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n * - For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n * - Otherwise, this `order` channel encodes layer order of the marks.\n *\n * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.\n */\n order?: OrderFieldDef | OrderFieldDef[] | ValueDef;\n}\n\nexport interface EncodingWithFacet extends Encoding, EncodingFacetMapping {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, fieldDef => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef) || hasConditionalFieldDef(channelDef);\n }\n }\n return false;\n}\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, channel => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, fieldDef => !!fieldDef.aggregate);\n } else {\n const fieldDef = getFieldDef(channelDef);\n return fieldDef && !!fieldDef.aggregate;\n }\n }\n return false;\n });\n}\nexport function extractTransformsFromEncoding(oldEncoding: Encoding, config: Config) {\n const groupby: string[] = [];\n const bins: BinTransform[] = [];\n const timeUnits: TimeUnitTransform[] = [];\n const aggregate: AggregatedFieldDef[] = [];\n const encoding: Encoding = {};\n\n forEach(oldEncoding, (channelDef, channel) => {\n // Extract potential embedded transformations along with remaining properties\n if (isFieldDef(channelDef)) {\n const {field, aggregate: aggOp, timeUnit, bin, ...remaining} = channelDef;\n if (aggOp || timeUnit || bin) {\n const guide = getGuide(channelDef);\n const isTitleDefined = guide && guide.title;\n let newField = vgField(channelDef, {forAs: true});\n const newFieldDef: FieldDef = {\n // Only add title if it doesn't exist\n ...(isTitleDefined ? [] : {title: title(channelDef, config, {allowDisabling: true})}),\n ...remaining,\n // Always overwrite field\n field: newField\n };\n const isPositionChannel: boolean = channel === 'x' || channel === 'y';\n\n if (aggOp) {\n let op: AggregateOp;\n\n if (isArgmaxDef(aggOp)) {\n op = 'argmax';\n newField = vgField({aggregate: 'argmax', field: aggOp.argmax}, {forAs: true});\n newFieldDef.field = `${newField}.${field}`;\n } else if (isArgminDef(aggOp)) {\n op = 'argmin';\n newField = vgField({aggregate: 'argmin', field: aggOp.argmin}, {forAs: true});\n newFieldDef.field = `${newField}.${field}`;\n } else if (aggOp !== 'boxplot' && aggOp !== 'errorbar' && aggOp !== 'errorband') {\n op = aggOp;\n }\n\n if (op) {\n const aggregateEntry: AggregatedFieldDef = {\n op,\n as: newField\n };\n if (field) {\n aggregateEntry.field = field;\n }\n aggregate.push(aggregateEntry);\n }\n } else if (isTypedFieldDef(channelDef) && isBinning(bin)) {\n bins.push({bin, field, as: newField});\n // Add additional groupbys for range and end of bins\n groupby.push(vgField(channelDef, {binSuffix: 'end'}));\n if (binRequiresRange(channelDef, channel)) {\n groupby.push(vgField(channelDef, {binSuffix: 'range'}));\n }\n // Create accompanying 'x2' or 'y2' field if channel is 'x' or 'y' respectively\n if (isPositionChannel) {\n const secondaryChannel: SecondaryFieldDef = {\n field: newField + '_end'\n };\n encoding[channel + '2'] = secondaryChannel;\n }\n newFieldDef.bin = 'binned';\n if (!isSecondaryRangeChannel(channel)) {\n newFieldDef['type'] = 'quantitative';\n }\n } else if (timeUnit) {\n timeUnits.push({timeUnit, field, as: newField});\n\n // Add formatting to appropriate property based on the type of channel we're processing\n const format = getDateTimeComponents(timeUnit, config.axis.shortTimeLabels).join(' ');\n const formatType = isTypedFieldDef(channelDef) && channelDef.type !== TEMPORAL && 'time';\n if (channel === 'text' || channel === 'tooltip') {\n newFieldDef['format'] = newFieldDef['format'] || format;\n if (formatType) {\n newFieldDef['formatType'] = formatType;\n }\n } else if (isNonPositionScaleChannel(channel)) {\n newFieldDef['legend'] = {format, ...(formatType ? {formatType} : {}), ...newFieldDef['legend']};\n } else if (isPositionChannel) {\n newFieldDef['axis'] = {format, ...(formatType ? {formatType} : {}), ...newFieldDef['axis']};\n }\n }\n if (!aggOp) {\n groupby.push(newField);\n }\n // now the field should refer to post-transformed field instead\n encoding[channel] = newFieldDef;\n } else {\n groupby.push(field);\n encoding[channel] = oldEncoding[channel];\n }\n } else {\n // For value def, just copy\n encoding[channel] = oldEncoding[channel];\n }\n });\n\n return {\n bins,\n timeUnits,\n aggregate,\n groupby,\n encoding\n };\n}\n\nexport function markChannelCompatible(encoding: Encoding, channel: Channel, mark: Mark) {\n const markSupported = supportMark(channel, mark);\n if (!markSupported) {\n return false;\n } else if (markSupported === 'binned') {\n const primaryFieldDef = encoding[channel === 'x2' ? 'x' : 'y'];\n\n // circle, point, square and tick only support x2/y2 when their corresponding x/y fieldDef\n // has \"binned\" data and thus need x2/y2 to specify the bin-end field.\n if (isFieldDef(primaryFieldDef) && isFieldDef(encoding[channel]) && primaryFieldDef.bin === 'binned') {\n return true;\n } else {\n return false;\n }\n }\n return true;\n}\n\nexport function normalizeEncoding(encoding: Encoding, mark: Mark): Encoding {\n return keys(encoding).reduce((normalizedEncoding: Encoding, channel: Channel | string) => {\n if (!isChannel(channel)) {\n // Drop invalid channel\n log.warn(log.message.invalidEncodingChannel(channel));\n return normalizedEncoding;\n }\n\n if (!markChannelCompatible(encoding, channel, mark)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, mark));\n return normalizedEncoding;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const fieldDef = getTypedFieldDef(encoding[channel]);\n if (fieldDef && fieldDef.aggregate) {\n log.warn(log.message.LINE_WITH_VARYING_SIZE);\n return normalizedEncoding;\n }\n }\n\n // Drop color if either fill or stroke is specified\n if (channel === 'color' && ('fill' in encoding || 'stroke' in encoding)) {\n log.warn(log.message.droppingColor('encoding', {fill: 'fill' in encoding, stroke: 'stroke' in encoding}));\n return normalizedEncoding;\n }\n\n const channelDef = encoding[channel];\n if (\n channel === 'detail' ||\n (channel === 'order' && !isArray(channelDef) && !isValueDef(channelDef)) ||\n (channel === 'tooltip' && isArray(channelDef))\n ) {\n if (channelDef) {\n // Array of fieldDefs for detail channel (or production rule)\n normalizedEncoding[channel] = (isArray(channelDef) ? channelDef : [channelDef]).reduce(\n (defs: FieldDef[], fieldDef: FieldDef) => {\n if (!isFieldDef(fieldDef)) {\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n } else {\n defs.push(normalizeFieldDef(fieldDef, channel));\n }\n return defs;\n },\n []\n );\n }\n } else {\n if (channel === 'tooltip' && channelDef === null) {\n // Preserve null so we can use it to disable tooltip\n normalizedEncoding[channel] = null;\n } else if (!isFieldDef(channelDef) && !isValueDef(channelDef) && !isConditionalDef(channelDef)) {\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n return normalizedEncoding;\n }\n normalizedEncoding[channel] = normalize(channelDef as ChannelDef, channel);\n }\n return normalizedEncoding;\n }, {});\n}\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n const arr: FieldDef[] = [];\n for (const channel of keys(encoding)) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach(def => {\n if (isFieldDef(def)) {\n arr.push(def);\n } else if (hasConditionalFieldDef(def)) {\n arr.push(def.condition);\n }\n });\n }\n }\n return arr;\n}\n\nexport function forEach(\n mapping: U,\n f: (cd: ChannelDef, c: Channel) => void,\n thisArg?: any\n) {\n if (!mapping) {\n return;\n }\n\n for (const channel of keys(mapping)) {\n const el = mapping[channel];\n if (isArray(el)) {\n el.forEach((channelDef: ChannelDef) => {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, el, channel);\n }\n }\n}\n\nexport function reduce(\n mapping: U,\n f: (acc: any, fd: TypedFieldDef, c: Channel) => U,\n init: T,\n thisArg?: any\n) {\n if (!mapping) {\n return init;\n }\n\n return keys(mapping).reduce((r, channel) => {\n const map = mapping[channel];\n if (isArray(map)) {\n return map.reduce((r1: T, channelDef: ChannelDef) => {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, map, channel);\n }\n }, init);\n}\n","import {isArray, isBoolean} from 'vega-util';\nimport {SUM_OPS} from './aggregate';\nimport {NonPositionChannel, NONPOSITION_CHANNELS, X, X2, Y2} from './channel';\nimport {\n Field,\n getTypedFieldDef,\n isFieldDef,\n isStringFieldDef,\n PositionFieldDef,\n TypedFieldDef,\n vgField\n} from './channeldef';\nimport {channelHasField, Encoding} from './encoding';\nimport * as log from './log';\nimport {AREA, BAR, CIRCLE, isMarkDef, isPathMark, LINE, Mark, MarkDef, POINT, RULE, SQUARE, TEXT, TICK} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, Flag, getFirstDefined} from './util';\n\nexport type StackOffset = 'zero' | 'center' | 'normalize';\n\nconst STACK_OFFSET_INDEX: Flag = {\n zero: 1,\n center: 1,\n normalize: 1\n};\n\nexport function isStackOffset(s: string): s is StackOffset {\n return !!STACK_OFFSET_INDEX[s];\n}\n\nexport interface StackProperties {\n /** Dimension axis of the stack. */\n groupbyChannel: 'x' | 'y';\n\n /** Measure axis of the stack. */\n fieldChannel: 'x' | 'y';\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: TypedFieldDef;\n channel: NonPositionChannel;\n }[];\n\n /**\n * See `\"stack\"` property of Position Field Def.\n */\n offset: StackOffset;\n\n /**\n * Whether this stack will produce impute transform\n */\n impute: boolean;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\nfunction potentialStackedChannel(encoding: Encoding): 'x' | 'y' | undefined {\n const xDef = encoding.x;\n const yDef = encoding.y;\n\n if (isFieldDef(xDef) && isFieldDef(yDef)) {\n if (xDef.type === 'quantitative' && yDef.type === 'quantitative') {\n if (xDef.stack) {\n return 'x';\n } else if (yDef.stack) {\n return 'y';\n }\n // if there is no explicit stacking, only apply stack if there is only one aggregate for x or y\n if (!!xDef.aggregate !== !!yDef.aggregate) {\n return xDef.aggregate ? 'x' : 'y';\n }\n } else if (xDef.type === 'quantitative') {\n return 'x';\n } else if (yDef.type === 'quantitative') {\n return 'y';\n }\n } else if (isFieldDef(xDef) && xDef.type === 'quantitative') {\n return 'x';\n } else if (isFieldDef(yDef) && yDef.type === 'quantitative') {\n return 'y';\n }\n return undefined;\n}\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\nexport function stack(\n m: Mark | MarkDef,\n encoding: Encoding,\n stackConfig: StackOffset,\n opt: {\n disallowNonLinearStack?: boolean; // This option is for CompassQL\n } = {}\n): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n const fieldChannel = potentialStackedChannel(encoding);\n if (!fieldChannel) {\n return null;\n }\n\n const stackedFieldDef = encoding[fieldChannel] as PositionFieldDef;\n const stackedField = isStringFieldDef(stackedFieldDef) ? vgField(stackedFieldDef, {}) : undefined;\n\n const dimensionChannel = fieldChannel === 'x' ? 'y' : 'x';\n const dimensionDef = encoding[dimensionChannel];\n const dimensionField = isStringFieldDef(dimensionDef) ? vgField(dimensionDef, {}) : undefined;\n\n // Should have grouping level of detail that is different from the dimension field\n const stackBy = NONPOSITION_CHANNELS.reduce((sc, channel) => {\n // Ignore tooltip in stackBy (https://github.com/vega/vega-lite/issues/4001)\n if (channel !== 'tooltip' && channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach(cDef => {\n const fieldDef = getTypedFieldDef(cDef);\n if (fieldDef.aggregate) {\n return;\n }\n\n // Check whether the channel's field is identical to x/y's field or if the channel is a repeat\n const f = isStringFieldDef(fieldDef) ? vgField(fieldDef, {}) : undefined;\n if (\n // if fielddef is a repeat, just include it in the stack by\n !f ||\n // otherwise, the field must be different from x and y fields.\n (f !== dimensionField && f !== stackedField)\n ) {\n sc.push({channel, fieldDef});\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Automatically determine offset\n let offset: StackOffset;\n if (stackedFieldDef.stack !== undefined) {\n if (isBoolean(stackedFieldDef.stack)) {\n offset = stackedFieldDef.stack ? 'zero' : null;\n } else {\n offset = stackedFieldDef.stack;\n }\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n offset = getFirstDefined(stackConfig, 'zero');\n } else {\n offset = stackConfig;\n }\n\n if (!offset || !isStackOffset(offset)) {\n return null;\n }\n\n // warn when stacking non-linear\n if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {\n if (opt.disallowNonLinearStack) {\n return null;\n } else {\n log.warn(log.message.cannotStackNonLinearScale(stackedFieldDef.scale.type));\n }\n }\n\n // Check if it is a ranged mark\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n if (stackedFieldDef.stack !== undefined) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n }\n return null;\n }\n\n // Warn if stacking summative aggregate\n if (stackedFieldDef.aggregate && !contains(SUM_OPS, stackedFieldDef.aggregate)) {\n log.warn(log.message.stackNonSummativeAggregate(stackedFieldDef.aggregate));\n }\n\n return {\n groupbyChannel: dimensionDef ? dimensionChannel : undefined,\n fieldChannel,\n impute: isPathMark(mark),\n stackBy,\n offset\n };\n}\n","import {toMap} from 'datalib/src/util';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Config} from 'vega-lite/build/src/config';\nimport {Data} from 'vega-lite/build/src/data';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec, TopLevel} from 'vega-lite/build/src/spec';\nimport {stack, StackOffset, StackProperties} from 'vega-lite/build/src/stack';\nimport {TitleParams} from 'vega-lite/build/src/title';\nimport {ALL_ENCODING_PROPS, getEncodingNestedProp, isEncodingTopLevelProperty, Property, toKey} from '../property';\nimport {contains, extend, isObject, keys, some, without} from '../util';\nimport {isWildcard, WildcardProperty} from '../wildcard';\nimport {EncodingQuery, isDisabledAutoCountQuery, isEnabledAutoCountQuery, isFieldQuery, toEncoding} from './encoding';\nimport {TransformQuery} from './transform';\n\n/**\n * A \"query\" version of a [Vega-Lite](https://github.com/vega/vega-lite)'s `UnitSpec` (single view specification).\n * This interface and most of its children have `Query` suffixes to hint that their instanced are queries that\n * can contain wildcards to describe a collection of specifications.\n */\nexport interface SpecQuery {\n data?: Data;\n\n // TODO: support mark definition object\n mark: WildcardProperty;\n transform?: TransformQuery[];\n\n /**\n * Array of encoding query mappings.\n * Note: Vega-Lite's `encoding` is an object whose keys are unique encoding channels.\n * However, for CompassQL, the `channel` property of encoding query mappings can be wildcards.\n * Thus the `encoding` object in Vega-Lite is flatten as the `encodings` array in CompassQL.\n */\n encodings: EncodingQuery[];\n\n /**\n * The width of the resulting encodings.\n * __NOTE:__ Does not support wildcards.\n */\n width?: number;\n\n /**\n * The height of the resulting encodings.\n * __NOTE:__ Does not support wildcards.\n */\n height?: number;\n\n /**\n * CSS color property to use as the background of visualization.\n * __NOTE:__ Does not support wildcards.\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the\n * visualization canvas to the data rectangle. If a number, specifies\n * padding for all sides. If an object, the value should have the\n * format {\"left\": 5, \"top\": 5, \"right\": 5, \"bottom\": 5}\n * to specify padding for each side of the visualization.\n *\n * __NOTE:__ Does not support wildcards.\n */\n padding?: number | Object;\n\n /**\n * Title for the plot.\n * __NOTE:__ Does not support wildcards.\n */\n title?: string | TitleParams;\n\n // TODO: make config query (not important at all, only for the sake of completeness.)\n /**\n * Vega-Lite Configuration\n */\n config?: Config;\n}\n\n/**\n * Convert a Vega-Lite's ExtendedUnitSpec into a CompassQL's SpecQuery\n * @param {ExtendedUnitSpec} spec\n * @returns\n */\nexport function fromSpec(spec: TopLevel): SpecQuery {\n return extend(\n spec.data ? {data: spec.data} : {},\n spec.transform ? {transform: spec.transform} : {},\n spec.width ? {width: spec.width} : {},\n spec.height ? {height: spec.height} : {},\n spec.background ? {background: spec.background} : {},\n spec.padding ? {padding: spec.padding} : {},\n spec.title ? {title: spec.title} : {},\n {\n mark: spec.mark,\n encodings: keys(spec.encoding).map((channel: Channel) => {\n let encQ: EncodingQuery = {channel: channel};\n let channelDef = spec.encoding[channel];\n\n for (const prop in channelDef) {\n if (isEncodingTopLevelProperty(prop as Property) && channelDef[prop] !== undefined) {\n // Currently bin, scale, axis, legend only support boolean, but not null.\n // Therefore convert null to false.\n if (contains(['bin', 'scale', 'axis', 'legend'], prop) && channelDef[prop] === null) {\n encQ[prop] = false;\n } else {\n encQ[prop] = channelDef[prop];\n }\n }\n }\n\n if (isFieldQuery(encQ) && encQ.aggregate === 'count' && !encQ.field) {\n encQ.field = '*';\n }\n\n return encQ;\n })\n },\n spec.config ? {config: spec.config} : {}\n );\n}\n\nexport function isAggregate(specQ: SpecQuery) {\n return some(specQ.encodings, (encQ: EncodingQuery) => {\n return (isFieldQuery(encQ) && !isWildcard(encQ.aggregate) && !!encQ.aggregate) || isEnabledAutoCountQuery(encQ);\n });\n}\n\n/**\n * @return The Vega-Lite `StackProperties` object that describes the stack\n * configuration of `specQ`. Returns `null` if this is not stackable.\n */\nexport function getVlStack(specQ: SpecQuery): StackProperties {\n if (!hasRequiredStackProperties(specQ)) {\n return null;\n }\n\n const encoding = toEncoding(specQ.encodings, {schema: null, wildcardMode: 'null'});\n const mark = specQ.mark as Mark;\n\n return stack(mark, encoding, undefined, {disallowNonLinearStack: true});\n}\n\n/**\n * @return The `StackOffset` specified in `specQ`, `undefined` if none\n * is specified.\n */\nexport function getStackOffset(specQ: SpecQuery): StackOffset {\n for (const encQ of specQ.encodings) {\n if (encQ[Property.STACK] !== undefined && !isWildcard(encQ[Property.STACK])) {\n return encQ[Property.STACK];\n }\n }\n return undefined;\n}\n\n/**\n * @return The `Channel` in which `stack` is specified in `specQ`, or\n * `null` if none is specified.\n */\nexport function getStackChannel(specQ: SpecQuery): Channel {\n for (const encQ of specQ.encodings) {\n if (encQ[Property.STACK] !== undefined && !isWildcard(encQ.channel)) {\n return encQ.channel;\n }\n }\n return null;\n}\n\n/**\n * Returns true iff the given SpecQuery has the properties defined\n * to be a potential Stack spec.\n * @param specQ The SpecQuery in question.\n */\nexport function hasRequiredStackProperties(specQ: SpecQuery) {\n // TODO(haldenl): make this leaner, a lot of encQ properties aren't required for stack.\n // TODO(haldenl): check mark, then encodings\n if (isWildcard(specQ.mark)) {\n return false;\n }\n\n const requiredEncodingProps = [\n Property.STACK,\n Property.CHANNEL,\n Property.MARK,\n Property.FIELD,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ];\n const exclude = toMap(without(ALL_ENCODING_PROPS, requiredEncodingProps));\n\n const encodings = specQ.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ));\n for (const encQ of encodings) {\n if (objectContainsWildcard(encQ, {exclude: exclude})) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Returns true iff the given object does not contain a nested wildcard.\n * @param obj The object in question.\n * @param opt With optional `exclude` property, which defines properties to\n * ignore when testing for wildcards.\n */\n// TODO(haldenl): rename to objectHasWildcard, rename prop to obj\nfunction objectContainsWildcard(obj: any, opt: {exclude?: {[key: string]: 1}} = {}) {\n if (!isObject(obj)) {\n return false;\n }\n\n for (const childProp in obj) {\n if (obj.hasOwnProperty(childProp)) {\n const wildcard = isWildcard(obj[childProp]);\n if ((wildcard && (!opt.exclude || !opt.exclude[childProp])) || objectContainsWildcard(obj[childProp], opt)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Returns true iff the given `specQ` contains a wildcard.\n * @param specQ The `SpecQuery` in question.\n * @param opt With optional `exclude` property, which defines properties to\n * ignore when testing for wildcards.\n */\nexport function hasWildcard(specQ: SpecQuery, opt: {exclude?: Property[]} = {}) {\n const exclude = opt.exclude ? toMap(opt.exclude.map(toKey)) : {};\n if (isWildcard(specQ.mark) && !exclude['mark']) {\n return true;\n }\n\n for (const encQ of specQ.encodings) {\n if (objectContainsWildcard(encQ, exclude)) {\n return true;\n }\n }\n return false;\n}\n","import {isString} from 'datalib/src/util';\nimport {isAggregateOp} from 'vega-lite/build/src/aggregate';\nimport {Channel, isChannel} from 'vega-lite/build/src/channel';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec} from 'vega-lite/build/src/spec';\nimport {StackProperties} from 'vega-lite/build/src/stack';\nimport {isTimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {getFullName} from 'vega-lite/build/src/type';\nimport {\n DEFAULT_PROP_PRECEDENCE,\n EncodingNestedChildProp,\n getEncodingNestedProp,\n isEncodingNestedParent,\n Property,\n SORT_PROPS,\n VIEW_PROPS\n} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Dict, isArray, isBoolean, keys} from '../util';\nimport {isShortWildcard, isWildcard, SHORT_WILDCARD} from '../wildcard';\nimport {\n EncodingQuery,\n FieldQuery,\n FieldQueryBase,\n isAutoCountQuery,\n isDisabledAutoCountQuery,\n isEnabledAutoCountQuery,\n isFieldQuery,\n isValueQuery\n} from './encoding';\nimport {fromSpec, getVlStack, SpecQuery} from './spec';\n\nexport type Replacer = (s: string) => string;\n\nexport function getReplacerIndex(replaceIndex: PropIndex>): PropIndex {\n return replaceIndex.map(r => getReplacer(r));\n}\n\nexport function getReplacer(replace: Dict): Replacer {\n return (s: string) => {\n if (replace[s] !== undefined) {\n return replace[s];\n }\n return s;\n };\n}\n\nexport function value(v: any, replacer: Replacer): any {\n if (isWildcard(v)) {\n // Return the enum array if it's a full wildcard, or just return SHORT_WILDCARD for short ones.\n if (!isShortWildcard(v) && v.enum) {\n return SHORT_WILDCARD + JSON.stringify(v.enum);\n } else {\n return SHORT_WILDCARD;\n }\n }\n if (replacer) {\n return replacer(v);\n }\n return v;\n}\n\nexport function replace(v: any, replacer: Replacer): any {\n if (replacer) {\n return replacer(v);\n }\n return v;\n}\n\nexport const REPLACE_NONE = new PropIndex();\n\nexport const INCLUDE_ALL: PropIndex =\n // FIXME: remove manual TRANSFORM concat once we really support enumerating transform.\n []\n .concat(DEFAULT_PROP_PRECEDENCE, SORT_PROPS, [Property.TRANSFORM, Property.STACK], VIEW_PROPS)\n .reduce((pi, prop: Property) => pi.set(prop, true), new PropIndex());\n\nexport function vlSpec(\n vlspec: FacetedUnitSpec,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n) {\n const specQ = fromSpec(vlspec);\n return spec(specQ, include, replace);\n}\n\nexport const PROPERTY_SUPPORTED_CHANNELS = {\n axis: {x: true, y: true, row: true, column: true},\n legend: {color: true, opacity: true, size: true, shape: true},\n scale: {x: true, y: true, color: true, opacity: true, row: true, column: true, size: true, shape: true},\n sort: {x: true, y: true, path: true, order: true},\n stack: {x: true, y: true}\n};\n\n/**\n * Returns a shorthand for a spec query\n * @param specQ a spec query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function spec(\n specQ: SpecQuery,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n): string {\n const parts: string[] = [];\n\n if (include.get(Property.MARK)) {\n parts.push(value(specQ.mark, replace.get(Property.MARK)));\n }\n\n if (specQ.transform && specQ.transform.length > 0) {\n parts.push('transform:' + JSON.stringify(specQ.transform));\n }\n\n let stack: StackProperties;\n if (include.get(Property.STACK)) {\n stack = getVlStack(specQ);\n }\n\n if (specQ.encodings) {\n const encodings = specQ.encodings\n .reduce((encQs, encQ) => {\n // Exclude encoding mapping with autoCount=false as they are basically disabled.\n if (!isDisabledAutoCountQuery(encQ)) {\n let str;\n if (!!stack && encQ.channel === stack.fieldChannel) {\n str = encoding({...encQ, stack: stack.offset}, include, replace);\n } else {\n str = encoding(encQ, include, replace);\n }\n if (str) {\n // only add if the shorthand isn't an empty string.\n encQs.push(str);\n }\n }\n return encQs;\n }, [])\n .sort() // sort at the end to ignore order\n .join('|');\n\n if (encodings) {\n parts.push(encodings);\n }\n }\n\n for (let viewProp of VIEW_PROPS) {\n const propString = viewProp.toString();\n if (include.get(viewProp) && !!specQ[propString]) {\n const value = specQ[propString];\n parts.push(`${propString}=${JSON.stringify(value)}`);\n }\n }\n\n return parts.join('|');\n}\n\n/**\n * Returns a shorthand for an encoding query\n * @param encQ an encoding query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function encoding(\n encQ: EncodingQuery,\n include: PropIndex = INCLUDE_ALL,\n replace: PropIndex = REPLACE_NONE\n): string {\n const parts = [];\n if (include.get(Property.CHANNEL)) {\n parts.push(value(encQ.channel, replace.get(Property.CHANNEL)));\n }\n\n if (isFieldQuery(encQ)) {\n const fieldDefStr = fieldDef(encQ, include, replace);\n\n if (fieldDefStr) {\n parts.push(fieldDefStr);\n }\n } else if (isValueQuery(encQ)) {\n parts.push(encQ.value);\n } else if (isAutoCountQuery(encQ)) {\n parts.push('autocount()');\n }\n\n return parts.join(':');\n}\n\n/**\n * Returns a field definition shorthand for an encoding query\n * @param encQ an encoding query\n * @param include Dict Set listing property types (key) to be included in the shorthand\n * @param replace Dictionary of replace function for values of a particular property type (key)\n */\nexport function fieldDef(\n encQ: EncodingQuery,\n include: PropIndex = INCLUDE_ALL,\n replacer: PropIndex = REPLACE_NONE\n): string {\n if (include.get(Property.AGGREGATE) && isDisabledAutoCountQuery(encQ)) {\n return '-';\n }\n\n const fn = func(encQ, include, replacer);\n const props = fieldDefProps(encQ, include, replacer);\n\n let fieldAndParams;\n if (isFieldQuery(encQ)) {\n // field\n fieldAndParams = include.get('field') ? value(encQ.field, replacer.get('field')) : '...';\n // type\n if (include.get(Property.TYPE)) {\n if (isWildcard(encQ.type)) {\n fieldAndParams += ',' + value(encQ.type, replacer.get(Property.TYPE));\n } else {\n const typeShort = ((encQ.type || TYPE.QUANTITATIVE) + '').substr(0, 1);\n fieldAndParams += ',' + value(typeShort, replacer.get(Property.TYPE));\n }\n }\n // encoding properties\n fieldAndParams += props\n .map(p => {\n let val = p.value instanceof Array ? '[' + p.value + ']' : p.value;\n return ',' + p.key + '=' + val;\n })\n .join('');\n } else if (isAutoCountQuery(encQ)) {\n fieldAndParams = '*,q';\n }\n\n if (!fieldAndParams) {\n return null;\n }\n if (fn) {\n let fnPrefix = isString(fn) ? fn : SHORT_WILDCARD + (keys(fn).length > 0 ? JSON.stringify(fn) : '');\n\n return fnPrefix + '(' + fieldAndParams + ')';\n }\n return fieldAndParams;\n}\n\n/**\n * Return function part of\n */\nfunction func(fieldQ: FieldQuery, include: PropIndex, replacer: PropIndex): string | Object {\n if (include.get(Property.AGGREGATE) && fieldQ.aggregate && !isWildcard(fieldQ.aggregate)) {\n return replace(fieldQ.aggregate, replacer.get(Property.AGGREGATE));\n } else if (include.get(Property.AGGREGATE) && isEnabledAutoCountQuery(fieldQ)) {\n // autoCount is considered a part of aggregate\n return replace('count', replacer.get(Property.AGGREGATE));\n } else if (include.get(Property.TIMEUNIT) && fieldQ.timeUnit && !isWildcard(fieldQ.timeUnit)) {\n return replace(fieldQ.timeUnit, replacer.get(Property.TIMEUNIT));\n } else if (include.get(Property.BIN) && fieldQ.bin && !isWildcard(fieldQ.bin)) {\n return 'bin';\n } else {\n let fn: any = null;\n for (const prop of [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN]) {\n const val = fieldQ[prop];\n if (include.get(prop) && fieldQ[prop] && isWildcard(val)) {\n // assign fnEnumIndex[prop] = array of enum values or just \"?\" if it is SHORT_WILDCARD\n fn = fn || {};\n fn[prop] = isShortWildcard(val) ? val : val.enum;\n }\n }\n if (fn && fieldQ.hasFn) {\n fn.hasFn = true;\n }\n return fn;\n }\n}\n\n/**\n * Return key-value of parameters of field defs\n */\nfunction fieldDefProps(fieldQ: FieldQuery, include: PropIndex, replacer: PropIndex) {\n /** Encoding properties e.g., Scale, Axis, Legend */\n const props: {key: string; value: boolean | Object}[] = [];\n\n // Parameters of function such as bin will be just top-level properties\n if (!isBoolean(fieldQ.bin) && !isShortWildcard(fieldQ.bin)) {\n const bin = fieldQ.bin;\n for (const child in bin) {\n const prop = getEncodingNestedProp('bin', child as EncodingNestedChildProp);\n if (prop && include.get(prop) && bin[child] !== undefined) {\n props.push({\n key: child,\n value: value(bin[child], replacer.get(prop))\n });\n }\n }\n // Sort to make sure that parameter are ordered consistently\n props.sort((a, b) => a.key.localeCompare(b.key));\n }\n\n for (const parent of [Property.SCALE, Property.SORT, Property.STACK, Property.AXIS, Property.LEGEND]) {\n if (!isWildcard(fieldQ.channel) && !PROPERTY_SUPPORTED_CHANNELS[parent][fieldQ.channel as Channel]) {\n continue;\n }\n\n if (include.get(parent) && fieldQ[parent] !== undefined) {\n const parentValue = fieldQ[parent];\n if (isBoolean(parentValue) || parentValue === null) {\n // `scale`, `axis`, `legend` can be false/null.\n props.push({\n key: parent + '',\n value: parentValue || false // return true or false (false if null)\n });\n } else if (isString(parentValue)) {\n // `sort` can be a string (ascending/descending).\n props.push({\n key: parent + '',\n value: replace(JSON.stringify(parentValue), replacer.get(parent))\n });\n } else {\n let nestedPropChildren = [];\n for (const child in parentValue) {\n const nestedProp = getEncodingNestedProp(parent, child as EncodingNestedChildProp);\n if (nestedProp && include.get(nestedProp) && parentValue[child] !== undefined) {\n nestedPropChildren.push({\n key: child,\n value: value(parentValue[child], replacer.get(nestedProp))\n });\n }\n }\n\n if (nestedPropChildren.length > 0) {\n const nestedPropObject = nestedPropChildren\n .sort((a, b) => a.key.localeCompare(b.key))\n .reduce((o, item) => {\n o[item.key] = item.value;\n return o;\n }, {});\n\n // Sort to make sure that parameter are ordered consistently\n props.push({\n key: parent + '',\n value: JSON.stringify(nestedPropObject)\n });\n }\n }\n }\n }\n return props;\n}\n\nexport function parse(shorthand: string): SpecQuery {\n // TODO(https://github.com/uwdata/compassql/issues/259):\n // Do not split directly, but use an upgraded version of `getClosingBraceIndex()`\n let splitShorthand = shorthand.split('|');\n\n let specQ: SpecQuery = {\n mark: splitShorthand[0] as Mark,\n encodings: [] as EncodingQuery[]\n };\n\n for (let i = 1; i < splitShorthand.length; i++) {\n let part = splitShorthand[i];\n const splitPart = splitWithTail(part, ':', 1);\n const splitPartKey = splitPart[0];\n const splitPartValue = splitPart[1];\n\n if (isChannel(splitPartKey) || splitPartKey === '?') {\n const encQ = shorthandParser.encoding(splitPartKey, splitPartValue);\n specQ.encodings.push(encQ);\n continue;\n }\n\n if (splitPartKey === 'transform') {\n specQ.transform = JSON.parse(splitPartValue);\n continue;\n }\n }\n\n return specQ;\n}\n\n/**\n * Split a string n times into substrings with the specified delimiter and return them as an array.\n * @param str The string to be split\n * @param delim The delimiter string used to separate the string\n * @param number The value used to determine how many times the string is split\n */\nexport function splitWithTail(str: string, delim: string, count: number): string[] {\n let result = [];\n let lastIndex = 0;\n\n for (let i = 0; i < count; i++) {\n let indexOfDelim = str.indexOf(delim, lastIndex);\n\n if (indexOfDelim !== -1) {\n result.push(str.substring(lastIndex, indexOfDelim));\n lastIndex = indexOfDelim + 1;\n } else {\n break;\n }\n }\n\n result.push(str.substr(lastIndex));\n\n // If the specified count is greater than the number of delimiters that exist in the string,\n // an empty string will be pushed count minus number of delimiter occurence times.\n if (result.length !== count + 1) {\n while (result.length !== count + 1) {\n result.push('');\n }\n }\n\n return result;\n}\n\nexport namespace shorthandParser {\n export function encoding(channel: Channel | SHORT_WILDCARD, fieldDefShorthand: string): EncodingQuery {\n let encQMixins =\n fieldDefShorthand.indexOf('(') !== -1\n ? fn(fieldDefShorthand)\n : rawFieldDef(splitWithTail(fieldDefShorthand, ',', 2));\n return {\n channel,\n ...encQMixins\n };\n }\n\n export function rawFieldDef(fieldDefPart: string[]): FieldQueryBase {\n const fieldQ: FieldQueryBase = {};\n fieldQ.field = fieldDefPart[0];\n fieldQ.type = getFullName(fieldDefPart[1].toUpperCase()) || '?';\n\n let partParams = fieldDefPart[2];\n let closingBraceIndex = 0;\n let i = 0;\n\n while (i < partParams.length) {\n let propEqualSignIndex = partParams.indexOf('=', i);\n let parsedValue;\n if (propEqualSignIndex !== -1) {\n let prop = partParams.substring(i, propEqualSignIndex);\n if (partParams[i + prop.length + 1] === '{') {\n let openingBraceIndex = i + prop.length + 1;\n closingBraceIndex = getClosingIndex(openingBraceIndex, partParams, '}');\n const value = partParams.substring(openingBraceIndex, closingBraceIndex + 1);\n parsedValue = JSON.parse(value);\n\n // index after next comma\n i = closingBraceIndex + 2;\n } else if (partParams[i + prop.length + 1] === '[') {\n // find closing square bracket\n let openingBracketIndex = i + prop.length + 1;\n let closingBracketIndex = getClosingIndex(openingBracketIndex, partParams, ']');\n const value = partParams.substring(openingBracketIndex, closingBracketIndex + 1);\n parsedValue = JSON.parse(value);\n\n // index after next comma\n i = closingBracketIndex + 2;\n } else {\n let propIndex = i;\n // Substring until the next comma (or end of the string)\n let nextCommaIndex = partParams.indexOf(',', i + prop.length);\n if (nextCommaIndex === -1) {\n nextCommaIndex = partParams.length;\n }\n // index after next comma\n i = nextCommaIndex + 1;\n\n parsedValue = JSON.parse(partParams.substring(propIndex + prop.length + 1, nextCommaIndex));\n }\n\n if (isEncodingNestedParent(prop)) {\n fieldQ[prop] = parsedValue;\n } else {\n // prop is a property of the aggregation function such as bin\n fieldQ.bin = fieldQ.bin || {};\n fieldQ.bin[prop] = parsedValue;\n }\n } else {\n // something is wrong with the format of the partParams\n // exits loop if don't have then infintie loop\n break;\n }\n }\n return fieldQ;\n }\n\n export function getClosingIndex(openingBraceIndex: number, str: string, closingChar: string): number {\n for (let i = openingBraceIndex; i < str.length; i++) {\n if (str[i] === closingChar) {\n return i;\n }\n }\n }\n\n export function fn(fieldDefShorthand: string): FieldQueryBase {\n const fieldQ: FieldQueryBase = {};\n // Aggregate, Bin, TimeUnit as wildcard case\n if (fieldDefShorthand[0] === '?') {\n let closingBraceIndex = getClosingIndex(1, fieldDefShorthand, '}');\n\n let fnEnumIndex = JSON.parse(fieldDefShorthand.substring(1, closingBraceIndex + 1));\n\n for (let encodingProperty in fnEnumIndex) {\n if (isArray(fnEnumIndex[encodingProperty])) {\n fieldQ[encodingProperty] = {enum: fnEnumIndex[encodingProperty]};\n } else {\n // Definitely a `SHORT_WILDCARD`\n fieldQ[encodingProperty] = fnEnumIndex[encodingProperty];\n }\n }\n\n return {\n ...fieldQ,\n ...rawFieldDef(\n splitWithTail(fieldDefShorthand.substring(closingBraceIndex + 2, fieldDefShorthand.length - 1), ',', 2)\n )\n };\n } else {\n let func = fieldDefShorthand.substring(0, fieldDefShorthand.indexOf('('));\n let insideFn = fieldDefShorthand.substring(func.length + 1, fieldDefShorthand.length - 1);\n let insideFnParts = splitWithTail(insideFn, ',', 2);\n\n if (isAggregateOp(func)) {\n return {\n aggregate: func,\n ...rawFieldDef(insideFnParts)\n };\n } else if (isTimeUnit(func)) {\n return {\n timeUnit: func,\n ...rawFieldDef(insideFnParts)\n };\n } else if (func === 'bin') {\n return {\n bin: {},\n ...rawFieldDef(insideFnParts)\n };\n }\n }\n }\n}\n","import {isObject} from 'datalib/src/util';\nimport {AggregateOp} from 'vega';\nimport {Axis} from 'vega-lite/build/src/axis';\nimport {BinParams} from 'vega-lite/build/src/bin';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport * as vlChannelDef from 'vega-lite/build/src/channeldef';\nimport {ValueDef} from 'vega-lite/build/src/channeldef';\nimport {scaleType as compileScaleType} from 'vega-lite/build/src/compile/scale/type';\nimport {Encoding} from 'vega-lite/build/src/encoding';\nimport {Legend} from 'vega-lite/build/src/legend';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {Scale} from 'vega-lite/build/src/scale';\nimport {EncodingSortField, SortOrder} from 'vega-lite/build/src/sort';\nimport {StackOffset} from 'vega-lite/build/src/stack';\nimport {TimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {Type as VLType} from 'vega-lite/build/src/type';\nimport {FlatProp, isEncodingNestedParent, Property} from '../property';\nimport {Schema} from '../schema';\nimport {isWildcard, SHORT_WILDCARD, Wildcard, WildcardProperty} from '../wildcard';\nimport {ExpandedType} from './expandedtype';\nimport {PROPERTY_SUPPORTED_CHANNELS} from './shorthand';\n\nexport type EncodingQuery = FieldQuery | ValueQuery | AutoCountQuery;\n\nexport interface EncodingQueryBase {\n channel: WildcardProperty;\n\n description?: string;\n}\n\nexport interface ValueQuery extends EncodingQueryBase {\n value: WildcardProperty;\n}\n\nexport function isValueQuery(encQ: EncodingQuery): encQ is ValueQuery {\n return encQ !== null && encQ !== undefined && encQ['value'] !== undefined;\n}\n\nexport function isFieldQuery(encQ: EncodingQuery): encQ is FieldQuery {\n return encQ !== null && encQ !== undefined && (encQ['field'] || encQ['aggregate'] === 'count');\n}\n\nexport function isAutoCountQuery(encQ: EncodingQuery): encQ is AutoCountQuery {\n return encQ !== null && encQ !== undefined && 'autoCount' in encQ;\n}\n\nexport function isDisabledAutoCountQuery(encQ: EncodingQuery) {\n return isAutoCountQuery(encQ) && encQ.autoCount === false;\n}\n\nexport function isEnabledAutoCountQuery(encQ: EncodingQuery) {\n return isAutoCountQuery(encQ) && encQ.autoCount === true;\n}\n\n/**\n * A special encoding query that gets added internally if the `config.autoCount` flag is on. See SpecQueryModel.build for its generation.\n *\n * __Note:__ this type of query should not be specified by users.\n */\nexport interface AutoCountQuery extends EncodingQueryBase {\n /**\n * A count function that gets added internally if the config.autoCount flag in on.\n * This allows us to add one extra encoding mapping if needed when the query produces\n * plot that only have discrete fields.\n * In such cases, adding count make the output plots way more meaningful.\n */\n autoCount: WildcardProperty;\n type: 'quantitative';\n}\n\nexport interface FieldQueryBase {\n // FieldDef\n aggregate?: WildcardProperty;\n timeUnit?: WildcardProperty;\n\n /**\n * Special flag for enforcing that the field should have a fuction (one of timeUnit, bin, or aggregate).\n *\n * For example, if you enumerate both bin and aggregate then you need `undefined` for both.\n *\n * ```\n * {aggregate: {enum: [undefined, 'mean', 'sum']}, bin: {enum: [false, true]}}\n * ```\n *\n * This would enumerate a fieldDef with \"mean\", \"sum\", bin:true, and no function at all.\n * If you want only \"mean\", \"sum\", bin:true, then use `hasFn: true`\n *\n * ```\n * {aggregate: {enum: [undefined, 'mean', 'sum']}, bin: {enum: [false, true]}, hasFn: true}\n * ```\n */\n hasFn?: boolean;\n\n bin?: boolean | BinQuery | SHORT_WILDCARD;\n scale?: boolean | ScaleQuery | SHORT_WILDCARD;\n\n sort?: SortOrder | EncodingSortField;\n stack?: StackOffset | SHORT_WILDCARD;\n\n field?: WildcardProperty;\n type?: WildcardProperty;\n\n axis?: boolean | AxisQuery | SHORT_WILDCARD;\n legend?: boolean | LegendQuery | SHORT_WILDCARD;\n\n format?: string;\n}\n\nexport type FieldQuery = EncodingQueryBase & FieldQueryBase;\n\n// Using Mapped Type from TS2.1 to declare query for an object without nested property\n// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#mapped-types\nexport type FlatQuery = {[P in keyof T]: WildcardProperty};\n\nexport type FlatQueryWithEnableFlag = (Wildcard | {}) & FlatQuery;\n\nexport type BinQuery = FlatQueryWithEnableFlag;\nexport type ScaleQuery = FlatQueryWithEnableFlag;\nexport type AxisQuery = FlatQueryWithEnableFlag;\nexport type LegendQuery = FlatQueryWithEnableFlag;\n\nconst DEFAULT_PROPS = [\n Property.AGGREGATE,\n Property.BIN,\n Property.TIMEUNIT,\n Property.FIELD,\n Property.TYPE,\n Property.SCALE,\n Property.SORT,\n Property.AXIS,\n Property.LEGEND,\n Property.STACK,\n Property.FORMAT\n];\n\nexport interface ConversionParams {\n schema?: Schema;\n props?: FlatProp[];\n wildcardMode?: 'skip' | 'null';\n}\n\nexport function toEncoding(encQs: EncodingQuery[], params: ConversionParams): Encoding {\n const {wildcardMode = 'skip'} = params;\n let encoding: Encoding = {};\n\n for (const encQ of encQs) {\n if (isDisabledAutoCountQuery(encQ)) {\n continue; // Do not include this in the output.\n }\n\n const {channel} = encQ;\n\n // if channel is a wildcard, return null\n if (isWildcard(channel)) {\n throw new Error('Cannot convert wildcard channel to a fixed channel');\n }\n const channelDef = isValueQuery(encQ) ? toValueDef(encQ) : toFieldDef(encQ, params);\n\n if (channelDef === null) {\n if (params.wildcardMode === 'null') {\n // contains invalid property (e.g., wildcard, thus cannot return a proper spec.)\n return null;\n }\n continue;\n }\n // Otherwise, we can set the channelDef\n encoding[channel] = channelDef;\n }\n return encoding;\n}\n\nexport function toValueDef(valueQ: ValueQuery): ValueDef {\n const {value} = valueQ;\n if (isWildcard(value)) {\n return null;\n }\n return {value};\n}\n\nexport function toFieldDef(\n encQ: FieldQuery | AutoCountQuery,\n params: ConversionParams = {}\n): vlChannelDef.TypedFieldDef {\n const {props = DEFAULT_PROPS, schema, wildcardMode = 'skip'} = params;\n\n if (isFieldQuery(encQ)) {\n const fieldDef = {} as vlChannelDef.TypedFieldDef;\n for (const prop of props) {\n let encodingProperty = encQ[prop];\n if (isWildcard(encodingProperty)) {\n if (wildcardMode === 'skip') continue;\n return null;\n }\n\n if (encodingProperty !== undefined) {\n // if the channel supports this prop\n const isSupportedByChannel =\n !PROPERTY_SUPPORTED_CHANNELS[prop] || PROPERTY_SUPPORTED_CHANNELS[prop][encQ.channel as Channel];\n if (!isSupportedByChannel) {\n continue;\n }\n\n if (isEncodingNestedParent(prop) && isObject(encodingProperty)) {\n encodingProperty = {...encodingProperty}; // Make a shallow copy first\n for (const childProp in encodingProperty) {\n // ensure nested properties are not wildcard before assigning to field def\n if (isWildcard(encodingProperty[childProp])) {\n if (wildcardMode === 'null') {\n return null;\n }\n delete encodingProperty[childProp]; // skip\n }\n }\n }\n\n if (prop === 'bin' && encodingProperty === false) {\n continue;\n } else if (prop === 'type' && encodingProperty === 'key') {\n fieldDef.type = 'nominal';\n } else {\n fieldDef[prop] = encodingProperty;\n }\n }\n\n if (prop === Property.SCALE && schema && encQ.type === TYPE.ORDINAL) {\n const scale = encQ.scale;\n const {ordinalDomain} = schema.fieldSchema(encQ.field as string);\n\n if (scale !== null && ordinalDomain) {\n fieldDef[Property.SCALE] = {\n domain: ordinalDomain,\n // explicitly specfied domain property should override ordinalDomain\n ...(isObject(scale) ? scale : {})\n };\n }\n }\n }\n return fieldDef;\n } else {\n if (encQ.autoCount === false) {\n throw new Error(`Cannot convert {autoCount: false} into a field def`);\n } else {\n return {\n aggregate: 'count',\n field: '*',\n type: 'quantitative'\n };\n }\n }\n}\n\n/**\n * Is a field query continuous field?\n * This method is applicable only for fieldQuery without wildcard\n */\nexport function isContinuous(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n return vlChannelDef.isContinuous(toFieldDef(encQ, {props: ['bin', 'timeUnit', 'field', 'type']}));\n }\n return isAutoCountQuery(encQ);\n}\n\nexport function isMeasure(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n return !isDimension(encQ) && encQ.type !== 'temporal';\n }\n return isAutoCountQuery(encQ);\n}\n\n/**\n * Is a field query discrete field?\n * This method is applicable only for fieldQuery without wildcard\n */\nexport function isDimension(encQ: EncodingQuery) {\n if (isFieldQuery(encQ)) {\n const fieldDef = toFieldDef(encQ, {props: ['bin', 'timeUnit', 'type']});\n return vlChannelDef.isDiscrete(fieldDef) || !!fieldDef.timeUnit;\n }\n return false;\n}\n\n/**\n * Returns the true scale type of an encoding.\n * @returns {ScaleType} If the scale type was not specified, it is inferred from the encoding's TYPE.\n * @returns {undefined} If the scale type was not specified and Type (or TimeUnit if applicable) is a Wildcard, there is no clear scale type\n */\n\nexport function scaleType(fieldQ: FieldQuery) {\n const scale: ScaleQuery = fieldQ.scale === true || fieldQ.scale === SHORT_WILDCARD ? {} : fieldQ.scale || {};\n\n const {type, channel, timeUnit, bin} = fieldQ;\n\n // HACK: All of markType, and scaleConfig only affect\n // sub-type of ordinal to quantitative scales (point or band)\n // Currently, most of scaleType usage in CompassQL doesn't care about this subtle difference.\n // Thus, instead of making this method requiring the global mark,\n // we will just call it with mark = undefined .\n // Thus, currently, we will always get a point scale unless a CompassQuery specifies band.\n const markType: Mark = undefined;\n\n if (isWildcard(scale.type) || isWildcard(type) || isWildcard(channel) || isWildcard(bin)) {\n return undefined;\n }\n\n // If scale type is specified, then use scale.type\n if (scale.type) {\n return scale.type;\n }\n\n // if type is fixed and it's not temporal, we can ignore time unit.\n if (type === 'temporal' && isWildcard(timeUnit)) {\n return undefined;\n }\n\n // if type is fixed and it's not quantitative, we can ignore bin\n if (type === 'quantitative' && isWildcard(bin)) {\n return undefined;\n }\n\n let vegaLiteType: VLType = type === ExpandedType.KEY ? 'nominal' : type;\n\n const fieldDef = {\n type: vegaLiteType,\n timeUnit: timeUnit as TimeUnit,\n bin: bin as BinParams\n };\n return compileScaleType({type: scale.type}, channel, fieldDef, markType);\n}\n","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) :\n factory((global.d3_time = {}));\n}(this, function (exports) { 'use strict';\n\n var t0 = new Date;\n var t1 = new Date;\n function newInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = new Date(+date)), date;\n }\n\n interval.floor = interval;\n\n interval.round = function(date) {\n var d0 = new Date(+date),\n d1 = new Date(date - 1);\n floori(d0), floori(d1), offseti(d1, 1);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.ceil = function(date) {\n return floori(date = new Date(date - 1)), offseti(date, 1), date;\n };\n\n interval.offset = function(date, step) {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = function(start, stop, step) {\n var range = [];\n start = new Date(start - 1);\n stop = new Date(+stop);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n offseti(start, 1), floori(start);\n if (start < stop) range.push(new Date(+start));\n while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start));\n return range;\n };\n\n interval.filter = function(test) {\n return newInterval(function(date) {\n while (floori(date), !test(date)) date.setTime(date - 1);\n }, function(date, step) {\n while (--step >= 0) while (offseti(date, 1), !test(date));\n });\n };\n\n if (count) {\n interval.count = function(start, end) {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = function(step) {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? function(d) { return field(d) % step === 0; }\n : function(d) { return interval.count(0, d) % step === 0; });\n };\n }\n\n return interval;\n };\n\n var millisecond = newInterval(function() {\n // noop\n }, function(date, step) {\n date.setTime(+date + step);\n }, function(start, end) {\n return end - start;\n });\n\n // An optimized implementation for this simple case.\n millisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return newInterval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n };\n\n var second = newInterval(function(date) {\n date.setMilliseconds(0);\n }, function(date, step) {\n date.setTime(+date + step * 1e3);\n }, function(start, end) {\n return (end - start) / 1e3;\n }, function(date) {\n return date.getSeconds();\n });\n\n var minute = newInterval(function(date) {\n date.setSeconds(0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 6e4);\n }, function(start, end) {\n return (end - start) / 6e4;\n }, function(date) {\n return date.getMinutes();\n });\n\n var hour = newInterval(function(date) {\n date.setMinutes(0, 0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 36e5);\n }, function(start, end) {\n return (end - start) / 36e5;\n }, function(date) {\n return date.getHours();\n });\n\n var day = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5;\n }, function(date) {\n return date.getDate() - 1;\n });\n\n function weekday(i) {\n return newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5;\n });\n }\n\n var sunday = weekday(0);\n var monday = weekday(1);\n var tuesday = weekday(2);\n var wednesday = weekday(3);\n var thursday = weekday(4);\n var friday = weekday(5);\n var saturday = weekday(6);\n\n var month = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setDate(1);\n }, function(date, step) {\n date.setMonth(date.getMonth() + step);\n }, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n }, function(date) {\n return date.getMonth();\n });\n\n var year = newInterval(function(date) {\n date.setHours(0, 0, 0, 0);\n date.setMonth(0, 1);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n }, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n }, function(date) {\n return date.getFullYear();\n });\n\n var utcSecond = newInterval(function(date) {\n date.setUTCMilliseconds(0);\n }, function(date, step) {\n date.setTime(+date + step * 1e3);\n }, function(start, end) {\n return (end - start) / 1e3;\n }, function(date) {\n return date.getUTCSeconds();\n });\n\n var utcMinute = newInterval(function(date) {\n date.setUTCSeconds(0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 6e4);\n }, function(start, end) {\n return (end - start) / 6e4;\n }, function(date) {\n return date.getUTCMinutes();\n });\n\n var utcHour = newInterval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n }, function(date, step) {\n date.setTime(+date + step * 36e5);\n }, function(start, end) {\n return (end - start) / 36e5;\n }, function(date) {\n return date.getUTCHours();\n });\n\n var utcDay = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n }, function(start, end) {\n return (end - start) / 864e5;\n }, function(date) {\n return date.getUTCDate() - 1;\n });\n\n function utcWeekday(i) {\n return newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / 6048e5;\n });\n }\n\n var utcSunday = utcWeekday(0);\n var utcMonday = utcWeekday(1);\n var utcTuesday = utcWeekday(2);\n var utcWednesday = utcWeekday(3);\n var utcThursday = utcWeekday(4);\n var utcFriday = utcWeekday(5);\n var utcSaturday = utcWeekday(6);\n\n var utcMonth = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCDate(1);\n }, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n }, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n }, function(date) {\n return date.getUTCMonth();\n });\n\n var utcYear = newInterval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCMonth(0, 1);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n }, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n }, function(date) {\n return date.getUTCFullYear();\n });\n\n var milliseconds = millisecond.range;\n var seconds = second.range;\n var minutes = minute.range;\n var hours = hour.range;\n var days = day.range;\n var sundays = sunday.range;\n var mondays = monday.range;\n var tuesdays = tuesday.range;\n var wednesdays = wednesday.range;\n var thursdays = thursday.range;\n var fridays = friday.range;\n var saturdays = saturday.range;\n var weeks = sunday.range;\n var months = month.range;\n var years = year.range;\n\n var utcMillisecond = millisecond;\n var utcMilliseconds = milliseconds;\n var utcSeconds = utcSecond.range;\n var utcMinutes = utcMinute.range;\n var utcHours = utcHour.range;\n var utcDays = utcDay.range;\n var utcSundays = utcSunday.range;\n var utcMondays = utcMonday.range;\n var utcTuesdays = utcTuesday.range;\n var utcWednesdays = utcWednesday.range;\n var utcThursdays = utcThursday.range;\n var utcFridays = utcFriday.range;\n var utcSaturdays = utcSaturday.range;\n var utcWeeks = utcSunday.range;\n var utcMonths = utcMonth.range;\n var utcYears = utcYear.range;\n\n var version = \"0.1.1\";\n\n exports.version = version;\n exports.milliseconds = milliseconds;\n exports.seconds = seconds;\n exports.minutes = minutes;\n exports.hours = hours;\n exports.days = days;\n exports.sundays = sundays;\n exports.mondays = mondays;\n exports.tuesdays = tuesdays;\n exports.wednesdays = wednesdays;\n exports.thursdays = thursdays;\n exports.fridays = fridays;\n exports.saturdays = saturdays;\n exports.weeks = weeks;\n exports.months = months;\n exports.years = years;\n exports.utcMillisecond = utcMillisecond;\n exports.utcMilliseconds = utcMilliseconds;\n exports.utcSeconds = utcSeconds;\n exports.utcMinutes = utcMinutes;\n exports.utcHours = utcHours;\n exports.utcDays = utcDays;\n exports.utcSundays = utcSundays;\n exports.utcMondays = utcMondays;\n exports.utcTuesdays = utcTuesdays;\n exports.utcWednesdays = utcWednesdays;\n exports.utcThursdays = utcThursdays;\n exports.utcFridays = utcFridays;\n exports.utcSaturdays = utcSaturdays;\n exports.utcWeeks = utcWeeks;\n exports.utcMonths = utcMonths;\n exports.utcYears = utcYears;\n exports.millisecond = millisecond;\n exports.second = second;\n exports.minute = minute;\n exports.hour = hour;\n exports.day = day;\n exports.sunday = sunday;\n exports.monday = monday;\n exports.tuesday = tuesday;\n exports.wednesday = wednesday;\n exports.thursday = thursday;\n exports.friday = friday;\n exports.saturday = saturday;\n exports.week = sunday;\n exports.month = month;\n exports.year = year;\n exports.utcSecond = utcSecond;\n exports.utcMinute = utcMinute;\n exports.utcHour = utcHour;\n exports.utcDay = utcDay;\n exports.utcSunday = utcSunday;\n exports.utcMonday = utcMonday;\n exports.utcTuesday = utcTuesday;\n exports.utcWednesday = utcWednesday;\n exports.utcThursday = utcThursday;\n exports.utcFriday = utcFriday;\n exports.utcSaturday = utcSaturday;\n exports.utcWeek = utcSunday;\n exports.utcMonth = utcMonth;\n exports.utcYear = utcYear;\n exports.interval = newInterval;\n\n}));","var d3_time = require('d3-time');\n\nvar tempDate = new Date(),\n baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD\n utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0);\n\nfunction date(d) {\n return (tempDate.setTime(+d), tempDate);\n}\n\n// create a time unit entry\nfunction entry(type, date, unit, step, min, max) {\n var e = {\n type: type,\n date: date,\n unit: unit\n };\n if (step) {\n e.step = step;\n } else {\n e.minstep = 1;\n }\n if (min != null) e.min = min;\n if (max != null) e.max = max;\n return e;\n}\n\nfunction create(type, unit, base, step, min, max) {\n return entry(type,\n function(d) { return unit.offset(base, d); },\n function(d) { return unit.count(base, d); },\n step, min, max);\n}\n\nvar locale = [\n create('second', d3_time.second, baseDate),\n create('minute', d3_time.minute, baseDate),\n create('hour', d3_time.hour, baseDate),\n create('day', d3_time.day, baseDate, [1, 7]),\n create('month', d3_time.month, baseDate, [1, 3, 6]),\n create('year', d3_time.year, baseDate),\n\n // periodic units\n entry('seconds',\n function(d) { return new Date(1970, 0, 1, 0, 0, d); },\n function(d) { return date(d).getSeconds(); },\n null, 0, 59\n ),\n entry('minutes',\n function(d) { return new Date(1970, 0, 1, 0, d); },\n function(d) { return date(d).getMinutes(); },\n null, 0, 59\n ),\n entry('hours',\n function(d) { return new Date(1970, 0, 1, d); },\n function(d) { return date(d).getHours(); },\n null, 0, 23\n ),\n entry('weekdays',\n function(d) { return new Date(1970, 0, 4+d); },\n function(d) { return date(d).getDay(); },\n [1], 0, 6\n ),\n entry('dates',\n function(d) { return new Date(1970, 0, d); },\n function(d) { return date(d).getDate(); },\n [1], 1, 31\n ),\n entry('months',\n function(d) { return new Date(1970, d % 12, 1); },\n function(d) { return date(d).getMonth(); },\n [1], 0, 11\n )\n];\n\nvar utc = [\n create('second', d3_time.utcSecond, utcBaseDate),\n create('minute', d3_time.utcMinute, utcBaseDate),\n create('hour', d3_time.utcHour, utcBaseDate),\n create('day', d3_time.utcDay, utcBaseDate, [1, 7]),\n create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]),\n create('year', d3_time.utcYear, utcBaseDate),\n\n // periodic units\n entry('seconds',\n function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); },\n function(d) { return date(d).getUTCSeconds(); },\n null, 0, 59\n ),\n entry('minutes',\n function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); },\n function(d) { return date(d).getUTCMinutes(); },\n null, 0, 59\n ),\n entry('hours',\n function(d) { return new Date(Date.UTC(1970, 0, 1, d)); },\n function(d) { return date(d).getUTCHours(); },\n null, 0, 23\n ),\n entry('weekdays',\n function(d) { return new Date(Date.UTC(1970, 0, 4+d)); },\n function(d) { return date(d).getUTCDay(); },\n [1], 0, 6\n ),\n entry('dates',\n function(d) { return new Date(Date.UTC(1970, 0, d)); },\n function(d) { return date(d).getUTCDate(); },\n [1], 1, 31\n ),\n entry('months',\n function(d) { return new Date(Date.UTC(1970, d % 12, 1)); },\n function(d) { return date(d).getUTCMonth(); },\n [1], 0, 11\n )\n];\n\nvar STEPS = [\n [31536e6, 5], // 1-year\n [7776e6, 4], // 3-month\n [2592e6, 4], // 1-month\n [12096e5, 3], // 2-week\n [6048e5, 3], // 1-week\n [1728e5, 3], // 2-day\n [864e5, 3], // 1-day\n [432e5, 2], // 12-hour\n [216e5, 2], // 6-hour\n [108e5, 2], // 3-hour\n [36e5, 2], // 1-hour\n [18e5, 1], // 30-minute\n [9e5, 1], // 15-minute\n [3e5, 1], // 5-minute\n [6e4, 1], // 1-minute\n [3e4, 0], // 30-second\n [15e3, 0], // 15-second\n [5e3, 0], // 5-second\n [1e3, 0] // 1-second\n];\n\nfunction find(units, span, minb, maxb) {\n var step = STEPS[0], i, n, bins;\n\n for (i=1, n=STEPS.length; i step[0]) {\n bins = span / step[0];\n if (bins > maxb) {\n return units[STEPS[i-1][1]];\n }\n if (bins >= minb) {\n return units[step[1]];\n }\n }\n }\n return units[STEPS[n-1][1]];\n}\n\nfunction toUnitMap(units) {\n var map = {}, i, n;\n for (i=0, n=units.length; i maxb) { step *= base; }\n\n // decrease step size if allowed\n for (i=0; i= minstep && span / v <= maxb) step = v;\n }\n }\n\n // update precision, min and max\n v = Math.log(step);\n precision = v >= 0 ? 0 : ~~(-v / logb) + 1;\n eps = Math.pow(base, -precision - 1);\n min = Math.min(min, Math.floor(min / step + eps) * step);\n max = Math.ceil(max / step) * step;\n\n return {\n start: min,\n stop: max,\n step: step,\n unit: {precision: precision},\n value: value,\n index: index\n };\n}\n\nfunction bisect(a, x, lo, hi) {\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (util.cmp(a[mid], x) < 0) { lo = mid + 1; }\n else { hi = mid; }\n }\n return lo;\n}\n\nfunction value(v) {\n return this.step * Math.floor(v / this.step + EPSILON);\n}\n\nfunction index(v) {\n return Math.floor((v - this.start) / this.step + EPSILON);\n}\n\nfunction date_value(v) {\n return this.unit.date(value.call(this, v));\n}\n\nfunction date_index(v) {\n return index.call(this, this.unit.unit(v));\n}\n\nbins.date = function(opt) {\n if (!opt) { throw Error(\"Missing date binning options.\"); }\n\n // find time step, then bin\n var units = opt.utc ? time.utc : time,\n dmin = opt.min,\n dmax = opt.max,\n maxb = opt.maxbins || 20,\n minb = opt.minbins || 4,\n span = (+dmax) - (+dmin),\n unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb),\n spec = bins({\n min: unit.min != null ? unit.min : unit.unit(dmin),\n max: unit.max != null ? unit.max : unit.unit(dmax),\n maxbins: maxb,\n minstep: unit.minstep,\n steps: unit.step\n });\n\n spec.unit = unit;\n spec.index = date_index;\n if (!opt.raw) spec.value = date_value;\n return spec;\n};\n\nmodule.exports = bins;\n","var util = require('../util');\n\nvar TYPES = '__types__';\n\nvar PARSERS = {\n boolean: util.boolean,\n integer: util.number,\n number: util.number,\n date: util.date,\n string: function(x) { return x == null || x === '' ? null : x + ''; }\n};\n\nvar TESTS = {\n boolean: function(x) { return x==='true' || x==='false' || util.isBoolean(x); },\n integer: function(x) { return TESTS.number(x) && (x=+x) === ~~x; },\n number: function(x) { return !isNaN(+x) && !util.isDate(x); },\n date: function(x) { return !isNaN(Date.parse(x)); }\n};\n\nfunction annotation(data, types) {\n if (!types) return data && data[TYPES] || null;\n data[TYPES] = types;\n}\n\nfunction fieldNames(datum) {\n return util.keys(datum);\n}\n\nfunction bracket(fieldName) {\n return '[' + fieldName + ']';\n}\n\nfunction type(values, f) {\n values = util.array(values);\n f = util.$(f);\n var v, i, n;\n\n // if data array has type annotations, use them\n if (values[TYPES]) {\n v = f(values[TYPES]);\n if (util.isString(v)) return v;\n }\n\n for (i=0, n=values.length; !util.isValid(v) && i stop) range.push(j);\n else while ((j = start + step * ++i) < stop) range.push(j);\n return range;\n};\n\ngen.random = {};\n\ngen.random.uniform = function(min, max) {\n if (max === undefined) {\n max = min === undefined ? 1 : min;\n min = 0;\n }\n var d = max - min;\n var f = function() {\n return min + d * Math.random();\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n return (x >= min && x <= max) ? 1/d : 0;\n };\n f.cdf = function(x) {\n return x < min ? 0 : x > max ? 1 : (x - min) / d;\n };\n f.icdf = function(p) {\n return (p >= 0 && p <= 1) ? min + p*d : NaN;\n };\n return f;\n};\n\ngen.random.integer = function(a, b) {\n if (b === undefined) {\n b = a;\n a = 0;\n }\n var d = b - a;\n var f = function() {\n return a + Math.floor(d * Math.random());\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n return (x === Math.floor(x) && x >= a && x < b) ? 1/d : 0;\n };\n f.cdf = function(x) {\n var v = Math.floor(x);\n return v < a ? 0 : v >= b ? 1 : (v - a + 1) / d;\n };\n f.icdf = function(p) {\n return (p >= 0 && p <= 1) ? a - 1 + Math.floor(p*d) : NaN;\n };\n return f;\n};\n\ngen.random.normal = function(mean, stdev) {\n mean = mean || 0;\n stdev = stdev || 1;\n var next;\n var f = function() {\n var x = 0, y = 0, rds, c;\n if (next !== undefined) {\n x = next;\n next = undefined;\n return x;\n }\n do {\n x = Math.random()*2-1;\n y = Math.random()*2-1;\n rds = x*x + y*y;\n } while (rds === 0 || rds > 1);\n c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform\n next = mean + y*c*stdev;\n return mean + x*c*stdev;\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n f.pdf = function(x) {\n var exp = Math.exp(Math.pow(x-mean, 2) / (-2 * Math.pow(stdev, 2)));\n return (1 / (stdev * Math.sqrt(2*Math.PI))) * exp;\n };\n f.cdf = function(x) {\n // Approximation from West (2009)\n // Better Approximations to Cumulative Normal Functions\n var cd,\n z = (x - mean) / stdev,\n Z = Math.abs(z);\n if (Z > 37) {\n cd = 0;\n } else {\n var sum, exp = Math.exp(-Z*Z/2);\n if (Z < 7.07106781186547) {\n sum = 3.52624965998911e-02 * Z + 0.700383064443688;\n sum = sum * Z + 6.37396220353165;\n sum = sum * Z + 33.912866078383;\n sum = sum * Z + 112.079291497871;\n sum = sum * Z + 221.213596169931;\n sum = sum * Z + 220.206867912376;\n cd = exp * sum;\n sum = 8.83883476483184e-02 * Z + 1.75566716318264;\n sum = sum * Z + 16.064177579207;\n sum = sum * Z + 86.7807322029461;\n sum = sum * Z + 296.564248779674;\n sum = sum * Z + 637.333633378831;\n sum = sum * Z + 793.826512519948;\n sum = sum * Z + 440.413735824752;\n cd = cd / sum;\n } else {\n sum = Z + 0.65;\n sum = Z + 4 / sum;\n sum = Z + 3 / sum;\n sum = Z + 2 / sum;\n sum = Z + 1 / sum;\n cd = exp / sum / 2.506628274631;\n }\n }\n return z > 0 ? 1 - cd : cd;\n };\n f.icdf = function(p) {\n // Approximation of Probit function using inverse error function.\n if (p <= 0 || p >= 1) return NaN;\n var x = 2*p - 1,\n v = (8 * (Math.PI - 3)) / (3 * Math.PI * (4-Math.PI)),\n a = (2 / (Math.PI*v)) + (Math.log(1 - Math.pow(x,2)) / 2),\n b = Math.log(1 - (x*x)) / v,\n s = (x > 0 ? 1 : -1) * Math.sqrt(Math.sqrt((a*a) - b) - a);\n return mean + stdev * Math.SQRT2 * s;\n };\n return f;\n};\n\ngen.random.bootstrap = function(domain, smooth) {\n // Generates a bootstrap sample from a set of observations.\n // Smooth bootstrapping adds random zero-centered noise to the samples.\n var val = domain.filter(util.isValid),\n len = val.length,\n err = smooth ? gen.random.normal(0, smooth) : null;\n var f = function() {\n return val[~~(Math.random()*len)] + (err ? err() : 0);\n };\n f.samples = function(n) {\n return gen.zeros(n).map(f);\n };\n return f;\n};","var util = require('./util');\nvar type = require('./import/type');\nvar gen = require('./generate');\n\nvar stats = module.exports;\n\n// Collect unique values.\n// Output: an array of unique values, in first-observed order\nstats.unique = function(values, f, results) {\n f = util.$(f);\n results = results || [];\n var u = {}, v, i, n;\n for (i=0, n=values.length; i 0 ? Math.pow(mean, 1/c) : 0;\n return mean;\n};\n\n// Compute the harmonic mean of an array of numbers.\nstats.mean.harmonic = function(values, f) {\n f = util.$(f);\n var mean = 0, c, n, v, i;\n for (i=0, c=0, n=values.length; i b) b = v;\n }\n }\n return [a, b];\n};\n\n// Find the integer indices of the minimum and maximum values.\nstats.extent.index = function(values, f) {\n f = util.$(f);\n var x = -1, y = -1, a, b, v, i, n = values.length;\n for (i=0; i b) { b = v; y = i; }\n }\n }\n return [x, y];\n};\n\n// Compute the dot product of two arrays of numbers.\nstats.dot = function(values, a, b) {\n var sum = 0, i, v;\n if (!b) {\n if (values.length !== a.length) {\n throw Error('Array lengths must match.');\n }\n for (i=0; i -1 && p !== v) {\n mu = 1 + (i-1 + tie) / 2;\n for (; tie -1) {\n mu = 1 + (n-1 + tie) / 2;\n for (; tie max) max = x;\n delta = x - mean;\n mean = mean + delta / (++valid);\n M2 = M2 + delta * (x - mean);\n vals.push(x);\n }\n }\n M2 = M2 / (valid - 1);\n sd = Math.sqrt(M2);\n\n // sort values for median and iqr\n vals.sort(util.cmp);\n\n return {\n type: type(values, f),\n unique: u,\n count: values.length,\n valid: valid,\n missing: missing,\n distinct: distinct,\n min: min,\n max: max,\n mean: mean,\n stdev: sd,\n median: (v = stats.quantile(vals, 0.5)),\n q1: stats.quantile(vals, 0.25),\n q3: stats.quantile(vals, 0.75),\n modeskew: sd === 0 ? 0 : (mean - v) / sd\n };\n};\n\n// Compute profiles for all variables in a data set.\nstats.summary = function(data, fields) {\n fields = fields || util.keys(data[0]);\n var s = fields.map(function(f) {\n var p = stats.profile(data, util.$(f));\n return (p.field = f, p);\n });\n return (s.__summary__ = true, s);\n};\n","import dlBin_ from 'datalib/src/bins/bins';\nimport {inferAll} from 'datalib/src/import/type';\nimport {summary} from 'datalib/src/stats';\nimport {autoMaxBins} from 'vega-lite/build/src/bin';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {containsTimeUnit, convert, TimeUnit, TIMEUNIT_PARTS} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from './config';\nimport {BinQuery, EncodingQuery, FieldQuery, isAutoCountQuery} from './query/encoding';\nimport {ExpandedType} from './query/expandedtype';\nimport {cmp, duplicate, extend, keys} from './util';\n\nconst dlBin = dlBin_;\n\n/**\n * Table Schema Field Descriptor interface\n * see: https://specs.frictionlessdata.io/table-schema/\n */\nexport interface TableSchemaFieldDescriptor {\n /* name of field **/\n name: string;\n\n /* A nicer human readable label or title for the field **/\n title?: string;\n\n /* number, integer, string, datetime */\n type: PrimitiveType;\n\n /* A string specifying a format */\n format?: string;\n\n /* A description for the field */\n description?: string;\n}\n\n/**\n * Field Schema\n */\nexport interface FieldSchema extends TableSchemaFieldDescriptor {\n vlType?: ExpandedType;\n\n index?: number;\n // Need to keep original index for re-exporting TableSchema\n originalIndex?: number;\n\n stats: DLFieldProfile;\n binStats?: {[maxbins: string]: DLFieldProfile};\n timeStats?: {[timeUnit: string]: DLFieldProfile};\n\n // array of valid input values (fields)\n ordinalDomain?: string[];\n}\n\n/**\n * Table Schema\n * see: https://specs.frictionlessdata.io/table-schema/\n */\nexport interface TableSchema {\n fields: F[];\n missingValues?: string[];\n primaryKey?: string | string[];\n foreignKeys?: object[];\n}\n\n/**\n * Build a Schema object.\n *\n * @param data - a set of raw data in the same format that Vega-Lite / Vega takes\n * Basically, it's an array in the form of:\n *\n * [\n * {a: 1, b:2},\n * {a: 2, b:3},\n * ...\n * ]\n *\n * @return a Schema object\n */\nexport function build(\n data: any,\n opt: QueryConfig = {},\n tableSchema: TableSchema = {fields: []}\n): Schema {\n opt = extend({}, DEFAULT_QUERY_CONFIG, opt);\n\n // create profiles for each variable\n let summaries: DLFieldProfile[] = summary(data);\n let types = inferAll(data); // inferAll does stronger type inference than summary\n\n let tableSchemaFieldIndex = tableSchema.fields.reduce((m, field: TableSchemaFieldDescriptor) => {\n m[field.name] = field;\n return m;\n }, {});\n\n let fieldSchemas: FieldSchema[] = summaries.map(function(fieldProfile, index) {\n const name: string = fieldProfile.field;\n // In Table schema, 'date' doesn't include time so use 'datetime'\n const type: PrimitiveType = types[name] === 'date' ? PrimitiveType.DATETIME : (types[name] as any);\n let distinct: number = fieldProfile.distinct;\n let vlType: ExpandedType;\n\n if (type === PrimitiveType.NUMBER) {\n vlType = TYPE.QUANTITATIVE;\n } else if (type === PrimitiveType.INTEGER) {\n // use ordinal or nominal when cardinality of integer type is relatively low and the distinct values are less than an amount specified in options\n if (distinct < opt.numberNominalLimit && distinct / fieldProfile.count < opt.numberNominalProportion) {\n vlType = TYPE.NOMINAL;\n } else {\n vlType = TYPE.QUANTITATIVE;\n }\n } else if (type === PrimitiveType.DATETIME) {\n vlType = TYPE.TEMPORAL;\n // need to get correct min/max of date data because datalib's summary method does not\n // calculate this correctly for date types.\n fieldProfile.min = new Date(data[0][name]);\n fieldProfile.max = new Date(data[0][name]);\n for (const dataEntry of data) {\n const time = new Date(dataEntry[name]).getTime();\n if (time < (fieldProfile.min as Date).getTime()) {\n fieldProfile.min = new Date(time);\n }\n if (time > (fieldProfile.max as Date).getTime()) {\n fieldProfile.max = new Date(time);\n }\n }\n } else {\n vlType = TYPE.NOMINAL;\n }\n\n if (\n vlType === TYPE.NOMINAL &&\n distinct / fieldProfile.count > opt.minPercentUniqueForKey &&\n fieldProfile.count > opt.minCardinalityForKey\n ) {\n vlType = ExpandedType.KEY;\n }\n\n let fieldSchema = {\n name: name,\n // Need to keep original index for re-exporting TableSchema\n originalIndex: index,\n vlType: vlType,\n type: type,\n stats: fieldProfile,\n timeStats: {} as {[timeUnit: string]: DLFieldProfile},\n binStats: {} as {[key: string]: DLFieldProfile}\n };\n\n // extend field schema with table schema field - if present\n const orgFieldSchema = tableSchemaFieldIndex[fieldSchema.name];\n fieldSchema = extend(fieldSchema, orgFieldSchema);\n\n return fieldSchema;\n });\n\n // calculate preset bins for quantitative and temporal data\n for (let fieldSchema of fieldSchemas) {\n if (fieldSchema.vlType === TYPE.QUANTITATIVE) {\n for (let maxbins of opt.enum.binProps.maxbins) {\n fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats);\n }\n } else if (fieldSchema.vlType === TYPE.TEMPORAL) {\n for (let unit of opt.enum.timeUnit) {\n if (unit !== undefined) {\n fieldSchema.timeStats[unit] = timeSummary(unit, fieldSchema.stats);\n }\n }\n }\n }\n\n const derivedTableSchema: TableSchema = {\n ...tableSchema,\n fields: fieldSchemas\n };\n\n return new Schema(derivedTableSchema);\n}\n\n// order the field schema when we construct a new Schema\n// this orders the fields in the UI\nconst order = {\n nominal: 0,\n key: 1,\n ordinal: 2,\n temporal: 3,\n quantitative: 4\n};\n\nexport class Schema {\n private _tableSchema: TableSchema;\n private _fieldSchemaIndex: {[field: string]: FieldSchema};\n\n constructor(tableSchema: TableSchema) {\n this._tableSchema = tableSchema;\n\n tableSchema.fields.sort(function(a: FieldSchema, b: FieldSchema) {\n // first order by vlType: nominal < temporal < quantitative < ordinal\n if (order[a.vlType] < order[b.vlType]) {\n return -1;\n } else if (order[a.vlType] > order[b.vlType]) {\n return 1;\n } else {\n // then order by field (alphabetically)\n return a.name.localeCompare(b.name);\n }\n });\n\n // Add index for sorting\n tableSchema.fields.forEach((fieldSchema, index) => (fieldSchema.index = index));\n\n this._fieldSchemaIndex = tableSchema.fields.reduce((m, fieldSchema: FieldSchema) => {\n m[fieldSchema.name] = fieldSchema;\n return m;\n }, {});\n }\n\n /** @return a list of the field names (for enumerating). */\n public fieldNames() {\n return this._tableSchema.fields.map(fieldSchema => fieldSchema.name);\n }\n\n /** @return a list of FieldSchemas */\n public get fieldSchemas() {\n return this._tableSchema.fields;\n }\n\n public fieldSchema(fieldName: string) {\n return this._fieldSchemaIndex[fieldName];\n }\n\n public tableSchema() {\n // the fieldschemas are re-arranged\n // but this is not allowed in table schema.\n // so we will re-order based on original index.\n const tableSchema = duplicate(this._tableSchema);\n tableSchema.fields.sort((a, b) => a.originalIndex - b.originalIndex);\n return tableSchema;\n }\n\n /**\n * @return primitive type of the field if exist, otherwise return null\n */\n public primitiveType(fieldName: string) {\n return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].type : null;\n }\n\n /**\n * @return vlType of measturement of the field if exist, otherwise return null\n */\n public vlType(fieldName: string) {\n return this._fieldSchemaIndex[fieldName] ? this._fieldSchemaIndex[fieldName].vlType : null;\n }\n\n /** @return cardinality of the field associated with encQ, null if it doesn't exist.\n * @param augmentTimeUnitDomain - TimeUnit field domains will not be augmented if explicitly set to false.\n */\n public cardinality(fieldQ: FieldQuery, augmentTimeUnitDomain: boolean = true, excludeInvalid: boolean = false) {\n const fieldSchema = this._fieldSchemaIndex[fieldQ.field as string];\n if (fieldQ.aggregate || (isAutoCountQuery(fieldQ) && fieldQ.autoCount)) {\n return 1;\n } else if (fieldQ.bin) {\n // encQ.bin will either be a boolean or a BinQuery\n let bin: BinQuery;\n if (typeof fieldQ.bin === 'boolean') {\n // autoMaxBins defaults to 10 if channel is Wildcard\n bin = {\n maxbins: autoMaxBins(fieldQ.channel as Channel)\n };\n } else if (fieldQ.bin === '?') {\n bin = {\n enum: [true, false]\n };\n } else {\n bin = fieldQ.bin;\n }\n const maxbins: any = bin.maxbins;\n if (!fieldSchema.binStats[maxbins]) {\n // need to calculate\n fieldSchema.binStats[maxbins] = binSummary(maxbins, fieldSchema.stats);\n }\n // don't need to worry about excludeInvalid here because invalid values don't affect linearly binned field's cardinality\n return fieldSchema.binStats[maxbins].distinct;\n } else if (fieldQ.timeUnit) {\n if (augmentTimeUnitDomain) {\n switch (fieldQ.timeUnit) {\n // TODO: this should not always be the case once Vega-Lite supports turning off domain augmenting (VL issue #1385)\n case TimeUnit.SECONDS:\n return 60;\n case TimeUnit.MINUTES:\n return 60;\n case TimeUnit.HOURS:\n return 24;\n case TimeUnit.DAY:\n return 7;\n case TimeUnit.DATE:\n return 31;\n case TimeUnit.MONTH:\n return 12;\n case TimeUnit.QUARTER:\n return 4;\n case TimeUnit.MILLISECONDS:\n return 1000;\n }\n }\n let unit = fieldQ.timeUnit as string;\n let timeStats = fieldSchema.timeStats;\n // if the cardinality for the timeUnit is not cached, calculate it\n if (!timeStats || !timeStats[unit]) {\n timeStats = {\n ...timeStats,\n [unit]: timeSummary(fieldQ.timeUnit as TimeUnit, fieldSchema.stats)\n };\n }\n\n if (excludeInvalid) {\n return timeStats[unit].distinct - invalidCount(timeStats[unit].unique, ['Invalid Date', null]);\n } else {\n return timeStats[unit].distinct;\n }\n } else {\n if (fieldSchema) {\n if (excludeInvalid) {\n return fieldSchema.stats.distinct - invalidCount(fieldSchema.stats.unique, [NaN, null]);\n } else {\n return fieldSchema.stats.distinct;\n }\n } else {\n return null;\n }\n }\n }\n\n /**\n * Given an EncodingQuery with a timeUnit, returns true if the date field\n * has multiple distinct values for all parts of the timeUnit. Returns undefined\n * if the timeUnit is undefined.\n * i.e.\n * ('yearmonth', [Jan 1 2000, Feb 2 2000] returns false)\n * ('yearmonth', [Jan 1 2000, Feb 2 2001] returns true)\n */\n public timeUnitHasVariation(fieldQ: FieldQuery): boolean {\n if (!fieldQ.timeUnit) {\n return;\n }\n\n // if there is no variation in `date`, there should not be variation in `day`\n if (fieldQ.timeUnit === TimeUnit.DAY) {\n const dateEncQ: EncodingQuery = extend({}, fieldQ, {timeUnit: TimeUnit.DATE});\n if (this.cardinality(dateEncQ, false, true) <= 1) {\n return false;\n }\n }\n\n let fullTimeUnit = fieldQ.timeUnit;\n for (let timeUnitPart of TIMEUNIT_PARTS) {\n if (containsTimeUnit(fullTimeUnit as TimeUnit, timeUnitPart)) {\n // Create a clone of encQ, but with singleTimeUnit\n const singleUnitEncQ = extend({}, fieldQ, {timeUnit: timeUnitPart});\n if (this.cardinality(singleUnitEncQ, false, true) <= 1) {\n return false;\n }\n }\n }\n return true;\n }\n\n public domain(fieldQueryParts: {field: string}): any[] {\n // TODO: differentiate for field with bin / timeUnit\n const fieldSchema = this._fieldSchemaIndex[fieldQueryParts.field as string];\n let domain: any[] = keys(fieldSchema.stats.unique);\n if (fieldSchema.vlType === TYPE.QUANTITATIVE) {\n // return [min, max], coerced into number types\n return [+fieldSchema.stats.min, +fieldSchema.stats.max];\n } else if (fieldSchema.type === PrimitiveType.DATETIME) {\n // return [min, max] dates\n return [fieldSchema.stats.min, fieldSchema.stats.max];\n } else if (fieldSchema.type === PrimitiveType.INTEGER || fieldSchema.type === PrimitiveType.NUMBER) {\n // coerce non-quantitative numerical data into number type\n domain = domain.map(x => +x);\n return domain.sort(cmp);\n } else if (fieldSchema.vlType === TYPE.ORDINAL && fieldSchema.ordinalDomain) {\n return fieldSchema.ordinalDomain;\n }\n\n return domain\n .map(x => {\n // Convert 'null' to null as it is encoded similarly in datalib.\n // This is wrong when it is a string 'null' but that rarely happens.\n return x === 'null' ? null : x;\n })\n .sort(cmp);\n }\n\n /**\n * @return a Summary corresponding to the field of the given EncodingQuery\n */\n public stats(fieldQ: FieldQuery) {\n // TODO: differentiate for field with bin / timeUnit vs without\n const fieldSchema = this._fieldSchemaIndex[fieldQ.field as string];\n return fieldSchema ? fieldSchema.stats : null;\n }\n}\n\n/**\n * @return a summary of the binning scheme determined from the given max number of bins\n */\nfunction binSummary(maxbins: number, summary: DLFieldProfile): DLFieldProfile {\n const bin = dlBin({\n min: summary.min,\n max: summary.max,\n maxbins: maxbins\n });\n\n // start with summary, pre-binning\n const result = extend({}, summary);\n result.unique = binUnique(bin, summary.unique);\n result.distinct = (bin.stop - bin.start) / bin.step;\n result.min = bin.start;\n result.max = bin.stop;\n\n return result;\n}\n\n/** @return a modified version of the passed summary with unique and distinct set according to the timeunit.\n * Maps 'null' (string) keys to the null value and invalid dates to 'Invalid Date' in the unique dictionary.\n */\nfunction timeSummary(timeunit: TimeUnit, summary: DLFieldProfile): DLFieldProfile {\n const result = extend({}, summary);\n\n let unique: {[value: string]: number} = {};\n keys(summary.unique).forEach(function(dateString) {\n // don't convert null value because the Date constructor will actually convert it to a date\n let date: Date = dateString === 'null' ? null : new Date(dateString);\n // at this point, `date` is either the null value, a valid Date object, or \"Invalid Date\" which is a Date\n let key: string;\n if (date === null) {\n key = null;\n } else if (isNaN(date.getTime())) {\n key = 'Invalid Date';\n } else {\n key = (timeunit === TimeUnit.DAY ? date.getDay() : convert(timeunit, date)).toString();\n }\n unique[key] = (unique[key] || 0) + summary.unique[dateString];\n });\n\n result.unique = unique;\n result.distinct = keys(unique).length;\n\n return result;\n}\n\n/**\n * @return a new unique object based off of the old unique count and a binning scheme\n */\nfunction binUnique(bin: any, oldUnique: any) {\n const newUnique = {};\n for (let value in oldUnique) {\n let bucket: number;\n if (value === null) {\n bucket = null;\n } else if (isNaN(Number(value))) {\n bucket = NaN;\n } else {\n bucket = bin.value(Number(value)) as number;\n }\n newUnique[bucket] = (newUnique[bucket] || 0) + oldUnique[value];\n }\n return newUnique;\n}\n\n/** @return the number of items in list that occur as keys of unique */\nfunction invalidCount(unique: {}, list: any[]) {\n return list.reduce(function(prev, cur) {\n return unique[cur] ? prev + 1 : prev;\n }, 0);\n}\n\nexport enum PrimitiveType {\n STRING = 'string' as any,\n NUMBER = 'number' as any,\n INTEGER = 'integer' as any,\n BOOLEAN = 'boolean' as any,\n DATETIME = 'datetime' as any\n}\n","import {QueryConfig} from '../config';\nimport {isEncodingNestedProp, Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\nimport { every} from '../util';\n\nimport {EncodingQueryBase} from '../query/encoding';\n\n/**\n * Abstract interface for a constraint.\n */\nexport interface AbstractConstraint {\n name: string;\n description: string;\n properties: Property[];\n\n /**\n * Whether this constraint requires all specified properties types to be specific\n * in order to call satisfy function.\n */\n allowWildcardForProperties: boolean;\n\n /**\n * Whether this constraint is strict (not optional).\n */\n strict: boolean;\n}\n\n/**\n * Abstract model for a constraint.\n */\nexport class AbstractConstraintModel {\n protected constraint: AbstractConstraint;\n\n constructor(constraint: AbstractConstraint) {\n this.constraint = constraint;\n }\n\n public name(): string {\n return this.constraint.name;\n }\n\n public description(): string {\n return this.constraint.description;\n }\n\n public properties(): Property[] {\n return this.constraint.properties;\n }\n\n public strict(): boolean {\n return this.constraint.strict;\n }\n}\n\n/**\n * Collection of constraints for a single encoding mapping.\n */\n\n/** A method for satisfying whether the provided encoding query satisfy the constraint. */\nexport interface EncodingConstraintChecker {\n (encQ: E, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig): boolean;\n}\n\nexport class EncodingConstraintModel extends AbstractConstraintModel {\n constructor(constraint: EncodingConstraint) {\n super(constraint);\n }\n\n public hasAllRequiredPropertiesSpecific(encQ: E): boolean {\n return every(this.constraint.properties, (prop: Property) => {\n\n if (isEncodingNestedProp(prop)) {\n let parent = prop.parent;\n let child = prop.child;\n\n if (!encQ[parent]) {\n return true;\n }\n\n return !isWildcard(encQ[parent][child]);\n }\n\n if (!encQ[prop]) {\n return true;\n }\n\n return !isWildcard(encQ[prop]);\n });\n }\n\n public satisfy(encQ: E, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig): boolean {\n // TODO: Re-order logic to optimize the \"allowWildcardForProperties\" check\n if (!this.constraint.allowWildcardForProperties) {\n // TODO: extract as a method and do unit test\n\n if (!this.hasAllRequiredPropertiesSpecific(encQ)) {\n return true;\n }\n }\n return (this.constraint as EncodingConstraint).satisfy(encQ, schema, encWildcardIndex, opt);\n }\n}\n\n/** Constraint for a single encoding mapping */\nexport interface EncodingConstraint extends AbstractConstraint {\n /** Method for checking if the encoding query satisfies this constraint. */\n satisfy: EncodingConstraintChecker;\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {channelCompatibility, TypedFieldDef} from 'vega-lite/build/src/channeldef';\nimport {\n channelScalePropertyIncompatability,\n hasDiscreteDomain,\n Scale,\n ScaleType,\n scaleTypeSupportProperty\n} from 'vega-lite/build/src/scale';\nimport {isLocalSingleTimeUnit, isUtcSingleTimeUnit} from 'vega-lite/build/src/timeunit';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {getEncodingNestedProp, Property, SCALE_PROPS} from '../property';\nimport {PropIndex} from '../propindex';\nimport {AutoCountQuery, FieldQuery, isFieldQuery, ScaleQuery, scaleType, toFieldDef} from '../query/encoding';\nimport {ExpandedType, isDiscrete} from '../query/expandedtype';\nimport {PrimitiveType, Schema} from '../schema';\nimport {contains} from '../util';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {EncodingConstraint, EncodingConstraintModel} from './base';\n\nexport const FIELD_CONSTRAINTS: EncodingConstraintModel[] = [\n {\n name: 'aggregateOpSupportedByType',\n description: 'Aggregate function should be supported by data type.',\n properties: [Property.TYPE, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.aggregate) {\n return !isDiscrete(fieldQ.type);\n }\n // TODO: some aggregate function are actually supported by ordinal\n return true; // no aggregate is okay with any type.\n }\n },\n {\n name: 'asteriskFieldWithCountOnly',\n description: 'Field=\"*\" should be disallowed except aggregate=\"count\"',\n properties: [Property.FIELD, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n return (fieldQ.field === '*') === (fieldQ.aggregate === 'count');\n }\n },\n {\n name: 'minCardinalityForBin',\n description: 'binned quantitative field should not have too low cardinality',\n properties: [Property.BIN, Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.bin && fieldQ.type === TYPE.QUANTITATIVE) {\n // We remove bin so schema can infer the raw unbinned cardinality.\n let fieldQwithoutBin: FieldQuery = {\n channel: fieldQ.channel,\n field: fieldQ.field,\n type: fieldQ.type\n };\n return schema.cardinality(fieldQwithoutBin) >= opt.minCardinalityForBin;\n }\n return true;\n }\n },\n {\n name: 'binAppliedForQuantitative',\n description: 'bin should be applied to quantitative field only.',\n properties: [Property.TYPE, Property.BIN],\n allowWildcardForProperties: false,\n strict: true, // FIXME VL2.0 actually support ordinal type for bin\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.bin) {\n // If binned, the type must be quantitative\n return fieldQ.type === TYPE.QUANTITATIVE;\n }\n return true;\n }\n },\n {\n name: 'channelFieldCompatible',\n description: `encoding channel's range type be compatible with channel type.`,\n properties: [Property.CHANNEL, Property.TYPE, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n const fieldDef: TypedFieldDef = {\n field: 'f', // actual field doesn't really matter here\n ...toFieldDef(fieldQ, {schema, props: ['bin', 'timeUnit', 'type']})\n };\n\n const {compatible} = channelCompatibility(fieldDef, fieldQ.channel as Channel);\n\n if (compatible) {\n return true;\n } else {\n // In VL, facet's field def must be discrete (O/N), but in CompassQL we can relax this a bit.\n const isFacet = fieldQ.channel === 'row' || fieldQ.channel === 'column';\n\n if (isFacet && (isLocalSingleTimeUnit(fieldDef.timeUnit) || isUtcSingleTimeUnit(fieldDef.timeUnit))) {\n return true;\n }\n return false;\n }\n }\n },\n {\n name: 'hasFn',\n description: 'A field with as hasFn flag should have one of aggregate, timeUnit, or bin.',\n properties: [Property.AGGREGATE, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.hasFn) {\n return !!fieldQ.aggregate || !!fieldQ.bin || !!fieldQ.timeUnit;\n }\n return true;\n }\n },\n {\n name: 'omitScaleZeroWithBinnedField',\n description: 'Do not use scale zero with binned field',\n properties: [Property.SCALE, getEncodingNestedProp('scale', 'zero'), Property.BIN],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.bin && fieldQ.scale) {\n if ((fieldQ.scale as ScaleQuery).zero === true) {\n return false;\n }\n }\n return true;\n }\n },\n {\n name: 'onlyOneTypeOfFunction',\n description: 'Only of of aggregate, autoCount, timeUnit, or bin should be applied at the same time.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery | AutoCountQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (isFieldQuery(fieldQ)) {\n const numFn =\n (!isWildcard(fieldQ.aggregate) && !!fieldQ.aggregate ? 1 : 0) +\n (!isWildcard(fieldQ.bin) && !!fieldQ.bin ? 1 : 0) +\n (!isWildcard(fieldQ.timeUnit) && !!fieldQ.timeUnit ? 1 : 0);\n return numFn <= 1;\n }\n // For autoCount there is always only one type of function\n return true;\n }\n },\n {\n name: 'timeUnitAppliedForTemporal',\n description: 'Time unit should be applied to temporal field only.',\n properties: [Property.TYPE, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.timeUnit && fieldQ.type !== TYPE.TEMPORAL) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'timeUnitShouldHaveVariation',\n description: 'A particular time unit should be applied only if they produce unique values.',\n properties: [Property.TIMEUNIT, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.timeUnit && fieldQ.type === TYPE.TEMPORAL) {\n if (!encWildcardIndex.has('timeUnit') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n return schema.timeUnitHasVariation(fieldQ);\n }\n return true;\n }\n },\n {\n name: 'scalePropertiesSupportedByScaleType',\n description: 'Scale properties must be supported by correct scale type',\n properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.TYPE]),\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.scale) {\n const scale: ScaleQuery = fieldQ.scale as ScaleQuery;\n\n // If fieldQ.type is an Wildcard and scale.type is undefined, it is equivalent\n // to scale type is Wildcard. If scale type is an Wildcard, we do not yet know\n // what the scale type is, and thus can ignore the constraint.\n\n const sType = scaleType(fieldQ);\n\n if (sType === undefined || sType === null) {\n // If still ambiguous, doesn't check the constraint\n return true;\n }\n\n for (let scaleProp in scale) {\n if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') {\n // ignore type and properties of wildcards\n continue;\n }\n const sProp = scaleProp as keyof Scale;\n if (sType === 'point') {\n // HACK: our current implementation of scaleType() can return point\n // when the scaleType is a band since we didn't pass all parameter to Vega-Lite's scale type method.\n if (!scaleTypeSupportProperty('point', sProp) && !scaleTypeSupportProperty('band', sProp)) {\n return false;\n }\n } else if (!scaleTypeSupportProperty(sType, sProp)) {\n return false;\n }\n }\n }\n return true;\n }\n },\n {\n name: 'scalePropertiesSupportedByChannel',\n description: 'Not all scale properties are supported by all encoding channels',\n properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.CHANNEL]),\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ) {\n let channel: Channel = fieldQ.channel as Channel;\n let scale: ScaleQuery = fieldQ.scale as ScaleQuery;\n if (channel && !isWildcard(channel) && scale) {\n if (channel === 'row' || channel === 'column') {\n // row / column do not have scale\n return false;\n }\n for (let scaleProp in scale) {\n if (!scale.hasOwnProperty(scaleProp)) continue;\n if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') {\n // ignore type and properties of wildcards\n continue;\n }\n let isSupported = channelScalePropertyIncompatability(channel, scaleProp as keyof Scale) === undefined;\n if (!isSupported) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'typeMatchesPrimitiveType',\n description: \"Data type should be supported by field's primitive type.\",\n properties: [Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.field === '*') {\n return true;\n }\n\n const primitiveType = schema.primitiveType(fieldQ.field as string);\n const type = fieldQ.type;\n\n if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n\n switch (primitiveType) {\n case PrimitiveType.BOOLEAN:\n case PrimitiveType.STRING:\n return type !== TYPE.QUANTITATIVE && type !== TYPE.TEMPORAL;\n case PrimitiveType.NUMBER:\n case PrimitiveType.INTEGER:\n return type !== TYPE.TEMPORAL;\n case PrimitiveType.DATETIME:\n // TODO: add NOMINAL, ORDINAL support after we support this in Vega-Lite\n return type === TYPE.TEMPORAL;\n case null:\n // field does not exist in the schema\n return false;\n }\n throw new Error('Not implemented');\n }\n },\n {\n name: 'typeMatchesSchemaType',\n description: \"Enumerated data type of a field should match the field's type in the schema.\",\n properties: [Property.FIELD, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, encWildcardIndex: PropIndex>, opt: QueryConfig) => {\n if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) {\n // Do not have to check this as this is manually specified by users.\n return true;\n }\n\n if (fieldQ.field === '*') {\n return fieldQ.type === TYPE.QUANTITATIVE;\n }\n\n return schema.vlType(fieldQ.field as string) === fieldQ.type;\n }\n },\n {\n name: 'maxCardinalityForCategoricalColor',\n description: 'Categorical channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n // TODO: missing case where ordinal / temporal use categorical color\n // (once we do so, need to add Property.BIN, Property.TIMEUNIT)\n if (fieldQ.channel === CHANNEL.COLOR && (fieldQ.type === TYPE.NOMINAL || fieldQ.type === ExpandedType.KEY)) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForCategoricalColor;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'maxCardinalityForFacet',\n description: 'Row/column channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.channel === CHANNEL.ROW || fieldQ.channel === CHANNEL.COLUMN) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForFacet;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'maxCardinalityForShape',\n description: 'Shape channel should not have too high cardinality',\n properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (fieldQ: FieldQuery, schema: Schema, _: PropIndex>, opt: QueryConfig) => {\n if (fieldQ.channel === CHANNEL.SHAPE) {\n return schema.cardinality(fieldQ) <= opt.maxCardinalityForShape;\n }\n return true; // other channel is irrelevant to this constraint\n }\n },\n {\n name: 'dataTypeAndFunctionMatchScaleType',\n description: 'Scale type must match data type',\n properties: [\n Property.TYPE,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TIMEUNIT,\n Property.BIN\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (fieldQ.scale) {\n const type = fieldQ.type;\n const sType = scaleType(fieldQ);\n\n if (isDiscrete(type)) {\n return sType === undefined || hasDiscreteDomain(sType);\n } else if (type === TYPE.TEMPORAL) {\n if (!fieldQ.timeUnit) {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType);\n } else {\n return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType) || hasDiscreteDomain(sType);\n }\n } else if (type === TYPE.QUANTITATIVE) {\n if (fieldQ.bin) {\n return contains([ScaleType.LINEAR, undefined], sType);\n } else {\n return contains(\n [\n ScaleType.LOG,\n ScaleType.POW,\n ScaleType.SQRT,\n ScaleType.QUANTILE,\n ScaleType.QUANTIZE,\n ScaleType.LINEAR,\n undefined\n ],\n sType\n );\n }\n }\n }\n return true;\n }\n },\n {\n name: 'stackIsOnlyUsedWithXY',\n description: 'stack should only be allowed for x and y channels',\n properties: [Property.STACK, Property.CHANNEL],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (fieldQ: FieldQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n if (!!fieldQ.stack) {\n return fieldQ.channel === CHANNEL.X || fieldQ.channel === CHANNEL.Y;\n }\n return true;\n }\n }\n].map((ec: EncodingConstraint) => new EncodingConstraintModel(ec));\n\nexport const FIELD_CONSTRAINT_INDEX: {\n [name: string]: EncodingConstraintModel;\n} = FIELD_CONSTRAINTS.reduce((m, ec: EncodingConstraintModel) => {\n m[ec.name()] = ec;\n return m;\n}, {});\n\nexport const FIELD_CONSTRAINTS_BY_PROPERTY = FIELD_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n // Initialize array and use it\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n return index;\n}, new PropIndex[]>());\n","import {QueryConfig} from '../config';\nimport {Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\nimport {contains} from '../util';\n\nimport {ValueQuery} from '../query/encoding';\nimport {EncodingConstraintModel, EncodingConstraint} from './base';\n\nexport const VALUE_CONSTRAINTS: EncodingConstraintModel[] = [\n {\n name: 'doesNotSupportConstantValue',\n description: 'row, column, x, y, order, and detail should not work with constant values.',\n properties: [Property.TYPE, Property.AGGREGATE],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (valueQ: ValueQuery, _: Schema, __: PropIndex>, ___: QueryConfig) => {\n\n return !(contains(['row', 'column', 'x', 'y', 'detail', 'order'], valueQ.channel));\n }\n }\n].map((ec: EncodingConstraint) => new EncodingConstraintModel(ec));\n\nexport const VALUE_CONSTRAINT_INDEX: {[name: string]: EncodingConstraintModel} =\n VALUE_CONSTRAINTS.reduce((m, ec: EncodingConstraintModel) => {\n m[ec.name()] = ec;\n return m;\n }, {});\n\nexport const VALUE_CONSTRAINTS_BY_PROPERTY =\n VALUE_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n\n return index;\n }, new PropIndex[]>());\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {Property} from '../property';\nimport {Wildcard} from '../wildcard';\nimport {Schema} from '../schema';\n\nimport {isValueQuery} from '../query/encoding';\nimport {FIELD_CONSTRAINTS_BY_PROPERTY} from './field';\nimport {VALUE_CONSTRAINTS_BY_PROPERTY} from './value';\n\n/**\n * Check all encoding constraints for a particular property and index tuple\n */\nexport function checkEncoding(prop: Property, wildcard: Wildcard, index: number,\n specM: SpecQueryModel, schema: Schema, opt: QueryConfig): string {\n\n // Check encoding constraint\n const encodingConstraints = FIELD_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n const encQ = specM.getEncodingQueryByIndex(index);\n\n for (const c of encodingConstraints) {\n // Check if the constraint is enabled\n if (c.strict() || !!opt[c.name()]) {\n // For strict constraint, or enabled non-strict, check the constraints\n\n const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt);\n if (!satisfy) {\n let violatedConstraint = '(enc) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n\n const valueContraints = VALUE_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n\n for (const c of valueContraints) {\n // Check if the constraint is enabled\n if ((c.strict() || !!opt[c.name()]) && isValueQuery(encQ)) {\n // For strict constraint, or enabled non-strict, check the constraints\n const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt);\n if (!satisfy) {\n let violatedConstraint = '(enc) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n return null;\n}\n","import {SUM_OPS} from 'vega-lite/build/src/aggregate';\nimport * as CHANNEL from 'vega-lite/build/src/channel';\nimport {NONPOSITION_CHANNELS, supportMark} from 'vega-lite/build/src/channel';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {ScaleType} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {getEncodingNestedProp, isEncodingNestedProp, isEncodingProperty, Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {\n EncodingQuery,\n FieldQuery,\n isAutoCountQuery,\n isDimension,\n isDisabledAutoCountQuery,\n isEnabledAutoCountQuery,\n isFieldQuery,\n isMeasure,\n isValueQuery,\n ScaleQuery,\n scaleType\n} from '../query/encoding';\nimport {ExpandedType} from '../query/expandedtype';\nimport {Schema} from '../schema';\nimport {contains, every, some} from '../util';\nimport {isWildcard, Wildcard} from '../wildcard';\nimport {AbstractConstraint, AbstractConstraintModel} from './base';\n\nconst NONPOSITION_CHANNELS_INDEX = NONPOSITION_CHANNELS.reduce((m, channel) => {\n m[channel] = true;\n return m;\n}, {});\n\nexport interface SpecConstraintChecker {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): boolean;\n}\n\nexport class SpecConstraintModel extends AbstractConstraintModel {\n constructor(specConstraint: SpecConstraint) {\n super(specConstraint);\n }\n\n public hasAllRequiredPropertiesSpecific(specM: SpecQueryModel): boolean {\n return every(this.constraint.properties, prop => {\n if (prop === Property.MARK) {\n return !isWildcard(specM.getMark());\n }\n\n // TODO: transform\n\n if (isEncodingNestedProp(prop)) {\n let parent = prop.parent;\n let child = prop.child;\n\n return every(specM.getEncodings(), encQ => {\n if (!encQ[parent]) {\n return true;\n }\n\n return !isWildcard(encQ[parent][child]);\n });\n }\n\n if (!isEncodingProperty(prop)) {\n throw new Error('UNIMPLEMENTED');\n }\n\n return every(specM.getEncodings(), encQ => {\n if (!encQ[prop]) {\n return true;\n }\n return !isWildcard(encQ[prop]);\n });\n });\n }\n\n public satisfy(specM: SpecQueryModel, schema: Schema, opt: QueryConfig) {\n // TODO: Re-order logic to optimize the \"allowWildcardForProperties\" check\n if (!this.constraint.allowWildcardForProperties) {\n if (!this.hasAllRequiredPropertiesSpecific(specM)) {\n return true;\n }\n }\n\n return (this.constraint as SpecConstraint).satisfy(specM, schema, opt);\n }\n}\n\nexport interface SpecConstraint extends AbstractConstraint {\n /** Method for checking if the spec query satisfies this constraint. */\n satisfy: SpecConstraintChecker;\n}\n\nexport const SPEC_CONSTRAINTS: SpecConstraintModel[] = [\n {\n name: 'noRepeatedChannel',\n description: 'Each encoding channel should only be used once.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n let usedChannel = {};\n\n // channel for all encodings should be valid\n return every(specM.getEncodings(), encQ => {\n if (!isWildcard(encQ.channel)) {\n // If channel is specified, it should no be used already\n if (usedChannel[encQ.channel]) {\n return false;\n }\n usedChannel[encQ.channel] = true;\n return true;\n }\n return true; // unspecified channel is valid\n });\n }\n },\n {\n name: 'alwaysIncludeZeroInScaleWithBarMark',\n description: 'Do not recommend bar mark if scale does not start at zero',\n properties: [\n Property.MARK,\n Property.SCALE,\n getEncodingNestedProp('scale', 'zero'),\n Property.CHANNEL,\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n const encodings = specM.getEncodings();\n\n if (mark === MARK.BAR) {\n for (let encQ of encodings) {\n if (\n isFieldQuery(encQ) &&\n (encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) &&\n encQ.type === TYPE.QUANTITATIVE &&\n (encQ.scale && (encQ.scale as ScaleQuery).zero === false)\n ) {\n // TODO: zero shouldn't be manually specified\n return false;\n }\n }\n }\n\n return true;\n }\n },\n {\n name: 'autoAddCount',\n description:\n 'Automatically adding count only for plots with only ordinal, binned quantitative, or temporal with timeunit fields.',\n properties: [Property.BIN, Property.TIMEUNIT, Property.TYPE, Property.AUTOCOUNT],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const hasAutoCount = some(specM.getEncodings(), (encQ: EncodingQuery) => isEnabledAutoCountQuery(encQ));\n\n if (hasAutoCount) {\n // Auto count should only be applied if all fields are nominal, ordinal, temporal with timeUnit, binned quantitative, or autoCount\n return every(specM.getEncodings(), (encQ: EncodingQuery) => {\n if (isValueQuery(encQ)) {\n return true;\n }\n\n if (isAutoCountQuery(encQ)) {\n return true;\n }\n\n switch (encQ.type) {\n case TYPE.QUANTITATIVE:\n return !!encQ.bin;\n case TYPE.TEMPORAL:\n return !!encQ.timeUnit;\n case TYPE.ORDINAL:\n case ExpandedType.KEY:\n case TYPE.NOMINAL:\n return true;\n }\n /* istanbul ignore next */\n throw new Error('Unsupported Type');\n });\n } else {\n const autoCountEncIndex = specM.wildcardIndex.encodingIndicesByProperty.get('autoCount') || [];\n const neverHaveAutoCount = every(autoCountEncIndex, (index: number) => {\n let encQ = specM.getEncodingQueryByIndex(index);\n return isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount);\n });\n if (neverHaveAutoCount) {\n // If the query surely does not have autoCount\n // then one of the field should be\n // (1) unbinned quantitative\n // (2) temporal without time unit\n // (3) nominal or ordinal field\n // or at least have potential to be (still ambiguous).\n return some(specM.getEncodings(), (encQ: EncodingQuery) => {\n if ((isFieldQuery(encQ) || isAutoCountQuery(encQ)) && encQ.type === TYPE.QUANTITATIVE) {\n if (isDisabledAutoCountQuery(encQ)) {\n return false;\n } else {\n return isFieldQuery(encQ) && (!encQ.bin || isWildcard(encQ.bin));\n }\n } else if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) {\n return !encQ.timeUnit || isWildcard(encQ.timeUnit);\n }\n return false; // nominal or ordinal\n });\n }\n }\n\n return true; // no auto count, no constraint\n }\n },\n {\n name: 'channelPermittedByMarkType',\n description: 'Each encoding channel should be supported by the mark type',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: true, // only require mark\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n // if mark is unspecified, no need to check\n if (isWildcard(mark)) return true;\n\n // TODO: can optimize this to detect only what's the changed property if needed.\n return every(specM.getEncodings(), encQ => {\n // channel unspecified, no need to check\n if (isWildcard(encQ.channel)) return true;\n\n return !!supportMark(encQ.channel, mark as Mark);\n });\n }\n },\n {\n name: 'hasAllRequiredChannelsForMark',\n description: 'All required channels for the specified mark should be specified',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n switch (mark) {\n case MARK.AREA:\n case MARK.LINE:\n return specM.channelUsed(CHANNEL.X) && specM.channelUsed(CHANNEL.Y);\n case MARK.TEXT:\n return specM.channelUsed(CHANNEL.TEXT);\n case MARK.BAR:\n case MARK.CIRCLE:\n case MARK.SQUARE:\n case MARK.TICK:\n case MARK.RULE:\n case MARK.RECT:\n return specM.channelUsed(CHANNEL.X) || specM.channelUsed(CHANNEL.Y);\n case MARK.POINT:\n // This allows generating a point plot if channel was not a wildcard.\n return (\n !specM.wildcardIndex.hasProperty(Property.CHANNEL) ||\n specM.channelUsed(CHANNEL.X) ||\n specM.channelUsed(CHANNEL.Y)\n );\n }\n /* istanbul ignore next */\n throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + JSON.stringify(mark));\n }\n },\n {\n name: 'omitAggregate',\n description: 'Omit aggregate plots.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (specM.isAggregate()) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'omitAggregatePlotWithDimensionOnlyOnFacet',\n description: 'Omit aggregate plots with dimensions only on facets as that leads to inefficient use of space.',\n properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n let hasNonFacetDim = false,\n hasDim = false,\n hasEnumeratedFacetDim = false;\n specM.specQuery.encodings.forEach((encQ, index) => {\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) return; // skip unused field\n\n // FieldQuery & !encQ.aggregate\n if (isFieldQuery(encQ) && !encQ.aggregate) {\n // isDimension\n hasDim = true;\n if (contains([CHANNEL.ROW, CHANNEL.COLUMN], encQ.channel)) {\n if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL)) {\n hasEnumeratedFacetDim = true;\n }\n } else {\n hasNonFacetDim = true;\n }\n }\n });\n if (hasDim && !hasNonFacetDim) {\n if (hasEnumeratedFacetDim || opt.constraintManuallySpecifiedValue) {\n return false;\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitAggregatePlotWithoutDimension',\n description: 'Aggregate plots without dimension should be omitted',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.BIN, Property.TIMEUNIT, Property.TYPE],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (specM.isAggregate()) {\n // TODO relax\n return some(specM.getEncodings(), (encQ: EncodingQuery) => {\n if (isDimension(encQ) || (isFieldQuery(encQ) && encQ.type === 'temporal')) {\n return true;\n }\n return false;\n });\n }\n return true;\n }\n },\n {\n // TODO: we can be smarter and check if bar has occlusion based on profiling statistics\n name: 'omitBarLineAreaWithOcclusion',\n description: \"Don't use bar, line or area to visualize raw plot as they often lead to occlusion.\",\n properties: [Property.MARK, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (contains([MARK.BAR, MARK.LINE, MARK.AREA], specM.getMark())) {\n return specM.isAggregate();\n }\n return true;\n }\n },\n {\n name: 'omitBarTickWithSize',\n description: 'Do not map field to size channel with bar and tick mark',\n properties: [Property.CHANNEL, Property.MARK],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n const mark = specM.getMark();\n if (contains([MARK.TICK, MARK.BAR], mark)) {\n if (specM.channelEncodingField(CHANNEL.SIZE)) {\n if (opt.constraintManuallySpecifiedValue) {\n // If size is used and we constraintManuallySpecifiedValue,\n // then the spec violates this constraint.\n return false;\n } else {\n // Otherwise have to search for the size channel and check if it is enumerated\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (encQ.channel === CHANNEL.SIZE) {\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n // If enumerated, then this is bad\n return false;\n } else {\n // If it's manually specified, no need to continue searching, just return.\n return true;\n }\n }\n }\n }\n }\n }\n return true; // skip\n }\n },\n {\n name: 'omitBarAreaForLogScale',\n description: \"Do not use bar and area mark for x and y's log scale\",\n properties: [\n Property.MARK,\n Property.CHANNEL,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n const encodings = specM.getEncodings();\n\n // TODO: mark or scale type should be enumerated\n if (mark === MARK.AREA || mark === MARK.BAR) {\n for (let encQ of encodings) {\n if (isFieldQuery(encQ) && ((encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) && encQ.scale)) {\n let sType = scaleType(encQ);\n\n if (sType === ScaleType.LOG) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitMultipleNonPositionalChannels',\n description:\n 'Unless manually specified, do not use multiple non-positional encoding channel to avoid over-encoding.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n // have to use specM.specQuery.encodings insetad of specM.getEncodings()\n // since specM.getEncodings() remove encQ with autoCount===false from the array\n // and thus might shift the index\n const encodings = specM.specQuery.encodings;\n let nonPositionChannelCount = 0;\n let hasEnumeratedNonPositionChannel = false;\n\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) {\n continue; // ignore skipped encoding\n }\n\n const channel = encQ.channel;\n if (!isWildcard(channel)) {\n if (NONPOSITION_CHANNELS_INDEX[channel + '']) {\n nonPositionChannelCount += 1;\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n hasEnumeratedNonPositionChannel = true;\n }\n if (\n nonPositionChannelCount > 1 &&\n (hasEnumeratedNonPositionChannel || opt.constraintManuallySpecifiedValue)\n ) {\n return false;\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitNonPositionalOrFacetOverPositionalChannels',\n description: 'Do not use non-positional channels unless all positional channels are used',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n const encodings = specM.specQuery.encodings;\n let hasNonPositionalChannelOrFacet = false;\n let hasEnumeratedNonPositionOrFacetChannel = false;\n let hasX = false,\n hasY = false;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) {\n continue; // ignore skipped encoding\n }\n\n const channel = encQ.channel;\n if (channel === CHANNEL.X) {\n hasX = true;\n } else if (channel === CHANNEL.Y) {\n hasY = true;\n } else if (!isWildcard(channel)) {\n // All non positional channel / Facet\n hasNonPositionalChannelOrFacet = true;\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) {\n hasEnumeratedNonPositionOrFacetChannel = true;\n }\n }\n }\n\n if (\n hasEnumeratedNonPositionOrFacetChannel ||\n (opt.constraintManuallySpecifiedValue && hasNonPositionalChannelOrFacet)\n ) {\n return hasX && hasY;\n }\n return true;\n }\n },\n {\n name: 'omitRaw',\n description: 'Omit raw plots.',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (!specM.isAggregate()) {\n return false;\n }\n return true;\n }\n },\n {\n name: 'omitRawContinuousFieldForAggregatePlot',\n description:\n 'Aggregate plot should not use raw continuous field as group by values. ' +\n '(Quantitative should be binned. Temporal should have time unit.)',\n properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN, Property.TYPE],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) continue; // skip unused encoding\n\n // TODO: aggregate for ordinal and temporal\n\n if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) {\n // Temporal fields should have timeUnit or is still a wildcard\n if (\n !encQ.timeUnit &&\n (specM.wildcardIndex.hasEncodingProperty(i, Property.TIMEUNIT) || opt.constraintManuallySpecifiedValue)\n ) {\n return false;\n }\n }\n if (encQ.type === TYPE.QUANTITATIVE) {\n if (isFieldQuery(encQ) && !encQ.bin && !encQ.aggregate) {\n // If Raw Q\n if (\n specM.wildcardIndex.hasEncodingProperty(i, Property.BIN) ||\n specM.wildcardIndex.hasEncodingProperty(i, Property.AGGREGATE) ||\n specM.wildcardIndex.hasEncodingProperty(i, Property.AUTOCOUNT)\n ) {\n // and it's raw from enumeration\n return false;\n }\n if (opt.constraintManuallySpecifiedValue) {\n // or if we constraintManuallySpecifiedValue\n return false;\n }\n }\n }\n }\n }\n return true;\n }\n },\n {\n name: 'omitRawDetail',\n description: 'Do not use detail channel with raw plot.',\n properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (specM.isAggregate()) {\n return true;\n }\n return every(specM.specQuery.encodings, (encQ, index) => {\n if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) return true; // ignore autoCount field\n\n if (encQ.channel === CHANNEL.DETAIL) {\n // Detail channel for raw plot is not good, except when its enumerated\n // or when it's manually specified but we constraintManuallySpecifiedValue.\n if (\n specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL) ||\n opt.constraintManuallySpecifiedValue\n ) {\n return false;\n }\n }\n return true;\n });\n }\n },\n {\n name: 'omitRepeatedField',\n description: 'Each field should be mapped to only one channel',\n properties: [Property.FIELD],\n allowWildcardForProperties: true,\n strict: false, // over-encoding is sometimes good, but let's turn it off by default\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n let fieldUsed = {};\n let fieldEnumerated = {};\n\n const encodings = specM.specQuery.encodings;\n for (let i = 0; i < encodings.length; i++) {\n const encQ = encodings[i];\n\n if (isValueQuery(encQ) || isAutoCountQuery(encQ)) continue;\n\n let field;\n if (encQ.field && !isWildcard(encQ.field)) {\n field = encQ.field as string;\n }\n if (isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount)) {\n field = 'count_*';\n }\n\n if (field) {\n if (specM.wildcardIndex.hasEncodingProperty(i, Property.FIELD)) {\n fieldEnumerated[field] = true;\n }\n // When the field is specified previously,\n // if it is enumerated (either previously or in this encQ)\n // or if the opt.constraintManuallySpecifiedValue is true,\n // then it violates the constraint.\n\n if (fieldUsed[field]) {\n if (fieldEnumerated[field] || opt.constraintManuallySpecifiedValue) {\n return false;\n }\n }\n\n fieldUsed[field] = true;\n }\n }\n return true;\n }\n },\n // TODO: omitShapeWithBin\n {\n name: 'omitVerticalDotPlot',\n description: 'Do not output vertical dot plot.',\n properties: [Property.CHANNEL],\n allowWildcardForProperties: true,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const encodings = specM.getEncodings();\n if (encodings.length === 1 && encodings[0].channel === CHANNEL.Y) {\n return false;\n }\n return true;\n }\n },\n // EXPENSIVE CONSTRAINTS -- check them later!\n {\n name: 'hasAppropriateGraphicTypeForMark',\n description: 'Has appropriate graphic type for mark',\n properties: [\n Property.CHANNEL,\n Property.MARK,\n Property.TYPE,\n Property.TIMEUNIT,\n Property.BIN,\n Property.AGGREGATE,\n Property.AUTOCOUNT\n ],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const mark = specM.getMark();\n\n switch (mark) {\n case MARK.AREA:\n case MARK.LINE:\n if (specM.isAggregate()) {\n // TODO: refactor based on profiling statistics\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsMeasure = isMeasure(xEncQ);\n const yIsMeasure = isMeasure(yEncQ);\n\n // for aggregate line / area, we need at least one group-by axis and one measure axis.\n return (\n xEncQ &&\n yEncQ &&\n xIsMeasure !== yIsMeasure &&\n // and the dimension axis should not be nominal\n // TODO: make this clause optional\n\n !(isFieldQuery(xEncQ) && !xIsMeasure && contains(['nominal', 'key'], xEncQ.type)) &&\n !(isFieldQuery(yEncQ) && !yIsMeasure && contains(['nominal', 'key'], yEncQ.type))\n );\n // TODO: allow connected scatterplot\n }\n return true;\n case MARK.TEXT:\n // FIXME correctly when we add text\n return true;\n case MARK.BAR:\n case MARK.TICK:\n // Bar and tick should not use size.\n if (specM.channelEncodingField(CHANNEL.SIZE)) {\n return false;\n } else {\n // Tick and Bar should have one and only one measure\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsMeasure = isMeasure(xEncQ);\n const yIsMeasure = isMeasure(yEncQ);\n if (xIsMeasure !== yIsMeasure) {\n return true;\n }\n return false;\n }\n case MARK.RECT:\n // Until CompassQL supports layering, it only makes sense for\n // rect to encode DxD or 1xD (otherwise just use bar).\n // Furthermore, color should only be used in a 'heatmap' fashion\n // (with a measure field).\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const xIsDimension = isDimension(xEncQ);\n const yIsDimension = isDimension(yEncQ);\n\n const colorEncQ = specM.getEncodingQueryByChannel(CHANNEL.COLOR);\n const colorIsQuantitative = isMeasure(colorEncQ);\n const colorIsOrdinal = isFieldQuery(colorEncQ) ? colorEncQ.type === TYPE.ORDINAL : false;\n\n const correctChannels =\n (xIsDimension && yIsDimension) ||\n (xIsDimension && !specM.channelUsed(CHANNEL.Y)) ||\n (yIsDimension && !specM.channelUsed(CHANNEL.X));\n\n const correctColor = !colorEncQ || (colorEncQ && (colorIsQuantitative || colorIsOrdinal));\n\n return correctChannels && correctColor;\n case MARK.CIRCLE:\n case MARK.POINT:\n case MARK.SQUARE:\n case MARK.RULE:\n return true;\n }\n /* istanbul ignore next */\n throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + mark);\n }\n },\n {\n name: 'omitInvalidStackSpec',\n description: 'If stack is specified, must follow Vega-Lite stack rules',\n properties: [\n Property.STACK,\n Property.FIELD,\n Property.CHANNEL,\n Property.MARK,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n if (!specM.wildcardIndex.hasProperty(Property.STACK)) {\n return true;\n }\n\n const stackProps = specM.getVlStack();\n if (stackProps === null && specM.getStackOffset() !== null) {\n return false;\n }\n\n if (stackProps.fieldChannel !== specM.getStackChannel()) {\n return false;\n }\n\n return true;\n }\n },\n {\n name: 'omitNonSumStack',\n description: 'Stack specifications that use non-summative aggregates should be omitted (even implicit ones)',\n properties: [\n Property.CHANNEL,\n Property.MARK,\n Property.AGGREGATE,\n Property.AUTOCOUNT,\n Property.SCALE,\n getEncodingNestedProp('scale', 'type'),\n Property.TYPE\n ],\n allowWildcardForProperties: false,\n strict: true,\n satisfy: (specM: SpecQueryModel, _: Schema, __: QueryConfig) => {\n const specStack = specM.getVlStack();\n if (specStack != null) {\n const stackParentEncQ = specM.getEncodingQueryByChannel(specStack.fieldChannel) as FieldQuery;\n if (!contains(SUM_OPS, stackParentEncQ.aggregate)) {\n return false;\n }\n }\n return true;\n }\n },\n {\n name: 'omitTableWithOcclusionIfAutoAddCount',\n description:\n 'Plots without aggregation or autocount where x and y are both discrete should be omitted if autoAddCount is enabled as they often lead to occlusion',\n properties: [\n Property.CHANNEL,\n Property.TYPE,\n Property.TIMEUNIT,\n Property.BIN,\n Property.AGGREGATE,\n Property.AUTOCOUNT\n ],\n allowWildcardForProperties: false,\n strict: false,\n satisfy: (specM: SpecQueryModel, _: Schema, opt: QueryConfig) => {\n if (opt.autoAddCount) {\n const xEncQ = specM.getEncodingQueryByChannel('x');\n const yEncQ = specM.getEncodingQueryByChannel('y');\n\n if ((!isFieldQuery(xEncQ) || isDimension(xEncQ)) && (!isFieldQuery(yEncQ) || isDimension(yEncQ))) {\n if (!specM.isAggregate()) {\n return false;\n } else {\n return every(specM.getEncodings(), encQ => {\n let channel = encQ.channel;\n\n if (\n channel !== CHANNEL.X &&\n channel !== CHANNEL.Y &&\n channel !== CHANNEL.ROW &&\n channel !== CHANNEL.COLUMN\n ) {\n // Non-position fields should not be unaggreated fields\n if (isFieldQuery(encQ) && !encQ.aggregate) {\n return false;\n }\n }\n return true;\n });\n }\n }\n }\n return true;\n }\n }\n].map(sc => new SpecConstraintModel(sc));\n\n// For testing\nexport const SPEC_CONSTRAINT_INDEX: {[name: string]: SpecConstraintModel} = SPEC_CONSTRAINTS.reduce(\n (m: any, c: SpecConstraintModel) => {\n m[c.name()] = c;\n return m;\n },\n {}\n);\n\nconst SPEC_CONSTRAINTS_BY_PROPERTY = SPEC_CONSTRAINTS.reduce((index, c) => {\n for (const prop of c.properties()) {\n // Initialize array and use it\n index.set(prop, index.get(prop) || []);\n index.get(prop).push(c);\n }\n return index;\n}, new PropIndex());\n\n/**\n * Check all encoding constraints for a particular property and index tuple\n */\nexport function checkSpec(\n prop: Property,\n wildcard: Wildcard,\n specM: SpecQueryModel,\n schema: Schema,\n opt: QueryConfig\n): string {\n // Check encoding constraint\n const specConstraints = SPEC_CONSTRAINTS_BY_PROPERTY.get(prop) || [];\n\n for (const c of specConstraints) {\n // Check if the constraint is enabled\n if (c.strict() || !!opt[c.name()]) {\n // For strict constraint, or enabled non-strict, check the constraints\n\n const satisfy = c.satisfy(specM, schema, opt);\n if (!satisfy) {\n let violatedConstraint = '(spec) ' + c.name();\n /* istanbul ignore if */\n if (opt.verbose) {\n console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name);\n }\n return violatedConstraint;\n }\n }\n }\n return null;\n}\n","import {Mark} from 'vega-lite/build/src/mark';\n\nimport {QueryConfig} from './config';\nimport {checkEncoding} from './constraint/encoding';\nimport {checkSpec} from './constraint/spec';\nimport {WildcardIndex} from './wildcardindex';\nimport {SpecQueryModel} from './model';\nimport {Property, ENCODING_TOPLEVEL_PROPS, ENCODING_NESTED_PROPS} from './property';\nimport {PropIndex} from './propindex';\nimport {Wildcard} from './wildcard';\nimport {Schema} from './schema';\nimport {isValueQuery, isDisabledAutoCountQuery} from './query/encoding';\n\nconst ENUMERATOR_INDEX = new PropIndex();\n\nexport interface Enumerator {\n (answerSets: SpecQueryModel[], specM: SpecQueryModel): SpecQueryModel[];\n}\n\nexport function getEnumerator(prop: Property) {\n return ENUMERATOR_INDEX.get(prop);\n}\n\nexport interface EnumeratorFactory {\n (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator;\n}\n\nENUMERATOR_INDEX.set('mark', (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator => {\n return (answerSet, specM: SpecQueryModel) => {\n const markWildcard = specM.getMark() as Wildcard;\n\n // enumerate the value\n markWildcard.enum.forEach((mark) => {\n specM.setMark(mark);\n // Check spec constraint\n const violatedSpecConstraint = checkSpec('mark', wildcardIndex.mark, specM, schema, opt);\n if (!violatedSpecConstraint) {\n // emit\n answerSet.push(specM.duplicate());\n }\n });\n\n // Reset to avoid side effect\n specM.resetMark();\n\n return answerSet;\n };\n});\n\nENCODING_TOPLEVEL_PROPS.forEach((prop) => {\n ENUMERATOR_INDEX.set(prop, EncodingPropertyGeneratorFactory(prop));\n});\n\nENCODING_NESTED_PROPS.forEach((nestedProp) => {\n ENUMERATOR_INDEX.set(nestedProp, EncodingPropertyGeneratorFactory(nestedProp));\n});\n\n/**\n * @param prop property type.\n * @return an answer set reducer factory for the given prop.\n */\nexport function EncodingPropertyGeneratorFactory(prop: Property): EnumeratorFactory {\n /**\n * @return as reducer that takes a specQueryModel as input and output an answer set array.\n */\n return (wildcardIndex: WildcardIndex, schema: Schema, opt: QueryConfig): Enumerator => {\n\n return (answerSet: SpecQueryModel[], specM: SpecQueryModel) => {\n // index of encoding mappings that require enumeration\n const indices = wildcardIndex.encodingIndicesByProperty.get(prop);\n\n function enumerate(jobIndex: number) {\n if (jobIndex === indices.length) {\n // emit and terminate\n answerSet.push(specM.duplicate());\n return;\n }\n const index = indices[jobIndex];\n const wildcard: Wildcard = wildcardIndex.encodings[index].get(prop);\n const encQ = specM.getEncodingQueryByIndex(index);\n const propWildcard = specM.getEncodingProperty(index, prop);\n\n if (isValueQuery(encQ) || (\n // TODO: encQ.exclude\n // If this encoding query is an excluded autoCount, there is no point enumerating other properties\n // for this encoding query because they will be excluded anyway.\n // Thus, we can just move on to the next encoding to enumerate.\n (isDisabledAutoCountQuery(encQ)) ||\n // nested encoding property might have its parent set to false\n // therefore, we no longer have to enumerate them\n !propWildcard\n )\n ) { // TODO: encQ.excluded\n enumerate(jobIndex + 1);\n } else {\n wildcard.enum.forEach((propVal) => {\n if (propVal === null) {\n // our duplicate() method use JSON.stringify, parse and thus can accidentally\n // convert undefined in an array into null\n propVal = undefined;\n }\n specM.setEncodingProperty(index, prop, propVal, wildcard);\n\n // Check encoding constraint\n const violatedEncodingConstraint = checkEncoding(prop, wildcard, index, specM, schema, opt);\n if (violatedEncodingConstraint) {\n return; // do not keep searching\n }\n // Check spec constraint\n const violatedSpecConstraint = checkSpec(prop, wildcard, specM, schema, opt);\n if (violatedSpecConstraint) {\n return; // do not keep searching\n }\n // If qualify all of the constraints, keep enumerating\n enumerate(jobIndex + 1);\n });\n\n // Reset to avoid side effect\n specM.resetEncodingProperty(index, prop, wildcard);\n }\n }\n\n // start enumerating from 0\n enumerate(0);\n\n return answerSet;\n };\n };\n}\n","import {isArray, isObject} from 'datalib/src/util';\n\nimport {getReplacerIndex} from './shorthand';\nimport {Property} from '../property';\nimport {PropIndex} from '../propindex';\nimport {Dict,keys} from '../util';\n\n\nexport interface ExtendedGroupBy {\n property: string;\n replace?: Dict;\n}\n\nexport const REPLACE_BLANK_FIELDS: Dict = {'*': ''};\nexport const REPLACE_XY_CHANNELS: Dict = {x: 'xy', y: 'xy'};\nexport const REPLACE_FACET_CHANNELS: Dict = {row: 'facet', column: 'facet'};\nexport const REPLACE_MARK_STYLE_CHANNELS: Dict = {color: 'style', opacity: 'style', shape: 'style', size: 'style'};\n\nexport function isExtendedGroupBy(g: string | ExtendedGroupBy): g is ExtendedGroupBy {\n return isObject(g) && !!g['property'];\n}\n\nexport type GroupBy = string | Array;\n\nexport interface Nest {\n groupBy: GroupBy;\n orderGroupBy?: string | string[];\n}\n\n\nexport function parseGroupBy(groupBy: Array,\n include?: PropIndex,\n replaceIndex?: PropIndex>\n ) {\n\n include = include || new PropIndex();\n replaceIndex = replaceIndex || new PropIndex>();\n\n groupBy.forEach((grpBy: string | ExtendedGroupBy) => {\n if (isExtendedGroupBy(grpBy)) {\n include.setByKey(grpBy.property, true);\n replaceIndex.setByKey(grpBy.property, grpBy.replace);\n } else {\n include.setByKey(grpBy, true);\n }\n });\n\n return {\n include: include,\n replaceIndex: replaceIndex,\n replacer: getReplacerIndex(replaceIndex)\n };\n}\n\nexport function toString(groupBy: GroupBy): string {\n if (isArray(groupBy)) {\n return groupBy.map((g: string | ExtendedGroupBy) => {\n if (isExtendedGroupBy(g)) {\n if (g.replace) {\n let replaceIndex = keys(g.replace).reduce((index, valFrom) => {\n const valTo = g.replace[valFrom];\n (index[valTo] = index[valTo] || []).push(valFrom);\n return index;\n }, {});\n\n return g.property + '[' + keys(replaceIndex).map((valTo) => {\n const valsFrom = replaceIndex[valTo].sort();\n return valsFrom.join(',') + '=>' + valTo;\n }).join(';') + ']';\n }\n return g.property;\n }\n return g;\n }).join(',');\n } else {\n return groupBy;\n }\n}\n\nexport const GROUP_BY_FIELD_TRANSFORM = [\n Property.FIELD, Property.TYPE,\n Property.AGGREGATE, Property.BIN, Property.TIMEUNIT, Property.STACK\n];\n\nexport const GROUP_BY_ENCODING = (GROUP_BY_FIELD_TRANSFORM as Array).concat([\n {\n property: Property.CHANNEL,\n replace: {\n 'x': 'xy', 'y': 'xy',\n 'color': 'style', 'size': 'style', 'shape': 'style', 'opacity': 'style',\n 'row': 'facet', 'column': 'facet'\n }\n }\n]);\n\n","import {isArray} from 'datalib/src/util';\nimport {SpecQueryModel, SpecQueryModelGroup} from './model';\nimport {Property} from './property';\nimport {PropIndex} from './propindex';\nimport {GROUP_BY_ENCODING, GROUP_BY_FIELD_TRANSFORM, Nest, parseGroupBy} from './query/groupby';\nimport {Replacer, spec as specShorthand} from './query/shorthand';\nimport {SpecQuery} from './query/spec';\nimport {Dict} from './util';\n\n/**\n * Registry for all possible grouping key functions.\n */\nlet groupRegistry: Dict<(specM: SpecQuery) => string> = {};\n\n/**\n * Add a grouping function to the registry.\n */\nexport function registerKeyFn(name: string, keyFn: (specM: SpecQuery) => string) {\n groupRegistry[name] = keyFn;\n}\n\nexport const FIELD = 'field';\nexport const FIELD_TRANSFORM = 'fieldTransform';\nexport const ENCODING = 'encoding';\nexport const SPEC = 'spec';\n\n/**\n * Group the input spec query model by a key function registered in the group registry\n * @return\n */\nexport function nest(specModels: SpecQueryModel[], queryNest: Nest[]): SpecQueryModelGroup {\n if (queryNest) {\n const rootGroup: SpecQueryModelGroup = {\n name: '',\n path: '',\n items: []\n };\n let groupIndex: Dict = {};\n\n // global `includes` and `replaces` will get augmented by each level's groupBy.\n // Upper level's `groupBy` will get cascaded to lower-level groupBy.\n // `replace` can be overriden in a lower-level to support different grouping.\n let includes: Array> = [];\n let replaces: Array>> = [];\n let replacers: Array> = [];\n\n for (let l = 0; l < queryNest.length; l++) {\n includes.push(l > 0 ? includes[l - 1].duplicate() : new PropIndex());\n replaces.push(l > 0 ? replaces[l - 1].duplicate() : new PropIndex>());\n\n const groupBy = queryNest[l].groupBy;\n if (isArray(groupBy)) {\n // If group is array, it's an array of extended group by that need to be parsed\n let parsedGroupBy = parseGroupBy(groupBy, includes[l], replaces[l]);\n replacers.push(parsedGroupBy.replacer);\n }\n }\n\n // With includes and replacers, now we can construct the nesting tree\n\n specModels.forEach(specM => {\n let path = '';\n let group: SpecQueryModelGroup = rootGroup;\n for (let l = 0; l < queryNest.length; l++) {\n const groupBy = (group.groupBy = queryNest[l].groupBy);\n group.orderGroupBy = queryNest[l].orderGroupBy;\n\n const key = isArray(groupBy)\n ? specShorthand(specM.specQuery, includes[l], replacers[l])\n : groupRegistry[groupBy](specM.specQuery);\n\n path += '/' + key;\n if (!groupIndex[path]) {\n // this item already exists on the path\n groupIndex[path] = {\n name: key,\n path: path,\n items: []\n };\n\n group.items.push(groupIndex[path]);\n }\n group = groupIndex[path];\n }\n group.items.push(specM);\n });\n return rootGroup;\n } else {\n // no nesting, just return a flat group\n return {\n name: '',\n path: '',\n items: specModels\n };\n }\n}\n\n// TODO: move this to groupBy, rename properly, and export\nconst GROUP_BY_FIELD = [Property.FIELD];\nconst PARSED_GROUP_BY_FIELD = parseGroupBy(GROUP_BY_FIELD);\n\nexport function getGroupByKey(specM: SpecQuery, groupBy: string) {\n return groupRegistry[groupBy](specM);\n}\n\nregisterKeyFn(FIELD, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_FIELD.include, PARSED_GROUP_BY_FIELD.replacer);\n});\n\nexport const PARSED_GROUP_BY_FIELD_TRANSFORM = parseGroupBy(GROUP_BY_FIELD_TRANSFORM);\n\nregisterKeyFn(FIELD_TRANSFORM, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_FIELD_TRANSFORM.include, PARSED_GROUP_BY_FIELD_TRANSFORM.replacer);\n});\n\nexport const PARSED_GROUP_BY_ENCODING = parseGroupBy(GROUP_BY_ENCODING);\n\nregisterKeyFn(ENCODING, (specQ: SpecQuery) => {\n return specShorthand(specQ, PARSED_GROUP_BY_ENCODING.include, PARSED_GROUP_BY_ENCODING.replacer);\n});\n\nregisterKeyFn(SPEC, (specQ: SpecQuery) => JSON.stringify(specQ));\n","import {Mark} from 'vega-lite/build/src/mark';\n\nimport {Wildcard} from './wildcard';\nimport {Property, isEncodingProperty} from './property';\nimport {PropIndex} from './propindex';\n\n\nexport interface EncodingsWildcardIndex {\n [index: number]: PropIndex>;\n}\n\nexport class WildcardIndex {\n private _mark: Wildcard;\n // TODO: transform\n\n /**\n * Dictionary mapping encoding index to an encoding wildcard index.\n */\n\n private _encodings: EncodingsWildcardIndex;\n private _encodingIndicesByProperty: PropIndex;\n\n constructor() {\n this._mark = undefined;\n this._encodings = {};\n this._encodingIndicesByProperty = new PropIndex();\n }\n\n public setEncodingProperty(index: number, prop: Property, wildcard: Wildcard) {\n const encodingsIndex = this._encodings;\n\n // Init encoding index and set prop\n const encIndex = encodingsIndex[index] = encodingsIndex[index] || new PropIndex>();\n encIndex.set(prop, wildcard);\n\n // Initialize indicesByProperty[prop] and add index\n const indicesByProp = this._encodingIndicesByProperty;\n indicesByProp.set(prop, (indicesByProp.get(prop) || []));\n indicesByProp.get(prop).push(index);\n\n return this;\n }\n\n public hasEncodingProperty(index: number, prop: Property) {\n return !!this._encodings[index] && this._encodings[index].has(prop);\n }\n\n public hasProperty(prop: Property) {\n if (isEncodingProperty(prop)) {\n return this.encodingIndicesByProperty.has(prop);\n } else if (prop === 'mark') {\n return !!this.mark;\n }\n /* istanbul ignore next */\n throw new Error('Unimplemented for property ' + prop);\n }\n\n public isEmpty() {\n return !this.mark && this.encodingIndicesByProperty.size() === 0;\n }\n\n public setMark(mark: Wildcard) {\n this._mark = mark;\n return this;\n }\n\n public get mark() {\n return this._mark;\n }\n\n public get encodings() {\n return this._encodings;\n }\n\n public get encodingIndicesByProperty() {\n return this._encodingIndicesByProperty;\n }\n}\n","import {isString} from 'datalib/src/util';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {Data} from 'vega-lite/build/src/data';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {FacetedUnitSpec, TopLevel} from 'vega-lite/build/src/spec';\nimport {StackOffset, StackProperties} from 'vega-lite/build/src/stack';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {getGroupByKey} from './nest';\nimport {\n ENCODING_NESTED_PROPS,\n ENCODING_TOPLEVEL_PROPS,\n isEncodingNestedParent,\n isEncodingNestedProp,\n Property\n} from './property';\nimport {\n AutoCountQuery,\n EncodingQuery,\n isAutoCountQuery,\n isDisabledAutoCountQuery,\n isFieldQuery,\n toEncoding\n} from './query/encoding';\nimport {ExtendedGroupBy, parseGroupBy} from './query/groupby';\nimport {spec as specShorthand} from './query/shorthand';\nimport {getStackChannel, getStackOffset, getVlStack, isAggregate, SpecQuery} from './query/spec';\nimport {RankingScore} from './ranking/ranking';\nimport {ResultTree} from './result';\nimport {Schema} from './schema';\nimport {Dict, duplicate, extend} from './util';\nimport {getDefaultEnumValues, getDefaultName, initWildcard, isWildcard, SHORT_WILDCARD, Wildcard} from './wildcard';\nimport {WildcardIndex} from './wildcardindex';\n\n/**\n * Internal class for specQuery that provides helper for the enumeration process.\n */\nexport class SpecQueryModel {\n private _spec: SpecQuery;\n\n /** channel => EncodingQuery */\n private _channelFieldCount: Dict;\n private _wildcardIndex: WildcardIndex;\n private _assignedWildcardIndex: Dict;\n private _schema: Schema;\n private _opt: QueryConfig;\n\n private _rankingScore: Dict = {};\n\n /**\n * Build a WildcardIndex by detecting wildcards\n * in the input specQuery and replacing short wildcards (\"?\")\n * with full ones (objects with `name` and `enum` values).\n *\n * @return a SpecQueryModel that wraps the specQuery and the WildcardIndex.\n */\n public static build(specQ: SpecQuery, schema: Schema, opt: QueryConfig): SpecQueryModel {\n let wildcardIndex: WildcardIndex = new WildcardIndex();\n // mark\n if (isWildcard(specQ.mark)) {\n const name = getDefaultName(Property.MARK);\n specQ.mark = initWildcard(specQ.mark, name, opt.enum.mark);\n wildcardIndex.setMark(specQ.mark);\n }\n\n // TODO: transform\n\n // encodings\n specQ.encodings.forEach((encQ, index) => {\n if (isAutoCountQuery(encQ)) {\n // This is only for testing purpose\n console.warn('A field with autoCount should not be included as autoCount meant to be an internal object.');\n\n encQ.type = TYPE.QUANTITATIVE; // autoCount is always quantitative\n }\n\n if (isFieldQuery(encQ) && encQ.type === undefined) {\n // type is optional -- we automatically augment wildcard if not specified\n encQ.type = SHORT_WILDCARD;\n }\n\n // For each property of the encodingQuery, enumerate\n ENCODING_TOPLEVEL_PROPS.forEach(prop => {\n if (isWildcard(encQ[prop])) {\n // Assign default wildcard name and enum values.\n const defaultWildcardName = getDefaultName(prop) + index;\n const defaultEnumValues = getDefaultEnumValues(prop, schema, opt);\n const wildcard = (encQ[prop] = initWildcard(encQ[prop], defaultWildcardName, defaultEnumValues));\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, prop, wildcard);\n }\n });\n\n // For each nested property of the encoding query (e.g., encQ.bin.maxbins)\n ENCODING_NESTED_PROPS.forEach(prop => {\n const propObj = encQ[prop.parent]; // the property object e.g., encQ.bin\n if (propObj) {\n const child = prop.child;\n if (isWildcard(propObj[child])) {\n // Assign default wildcard name and enum values.\n const defaultWildcardName = getDefaultName(prop) + index;\n const defaultEnumValues = getDefaultEnumValues(prop, schema, opt);\n const wildcard = (propObj[child] = initWildcard(propObj[child], defaultWildcardName, defaultEnumValues));\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, prop, wildcard);\n }\n }\n });\n });\n\n // AUTO COUNT\n // Add Auto Count Field\n if (opt.autoAddCount) {\n const channel: Wildcard = {\n name: getDefaultName(Property.CHANNEL) + specQ.encodings.length,\n enum: getDefaultEnumValues(Property.CHANNEL, schema, opt)\n };\n const autoCount: Wildcard = {\n name: getDefaultName(Property.AUTOCOUNT) + specQ.encodings.length,\n enum: [false, true]\n };\n const countEncQ: AutoCountQuery = {\n channel,\n autoCount,\n type: TYPE.QUANTITATIVE\n };\n specQ.encodings.push(countEncQ);\n\n const index = specQ.encodings.length - 1;\n\n // Add index of the encoding mapping to the property's wildcard index.\n wildcardIndex.setEncodingProperty(index, Property.CHANNEL, channel);\n wildcardIndex.setEncodingProperty(index, Property.AUTOCOUNT, autoCount);\n }\n\n return new SpecQueryModel(specQ, wildcardIndex, schema, opt, {});\n }\n\n constructor(\n spec: SpecQuery,\n wildcardIndex: WildcardIndex,\n schema: Schema,\n opt: QueryConfig,\n wildcardAssignment: Dict\n ) {\n this._spec = spec;\n this._channelFieldCount = spec.encodings.reduce(\n (m, encQ) => {\n if (!isWildcard(encQ.channel) && (!isAutoCountQuery(encQ) || encQ.autoCount !== false)) {\n m[encQ.channel + ''] = 1;\n }\n return m;\n },\n {} as Dict\n );\n\n this._wildcardIndex = wildcardIndex;\n this._assignedWildcardIndex = wildcardAssignment;\n this._opt = opt;\n this._schema = schema;\n }\n\n public get wildcardIndex() {\n return this._wildcardIndex;\n }\n\n public get schema() {\n return this._schema;\n }\n\n public get specQuery() {\n return this._spec;\n }\n\n public duplicate(): SpecQueryModel {\n return new SpecQueryModel(\n duplicate(this._spec),\n this._wildcardIndex,\n this._schema,\n this._opt,\n duplicate(this._assignedWildcardIndex)\n );\n }\n\n public setMark(mark: Mark) {\n const name = this._wildcardIndex.mark.name;\n this._assignedWildcardIndex[name] = this._spec.mark = mark;\n }\n\n public resetMark() {\n const wildcard = (this._spec.mark = this._wildcardIndex.mark);\n delete this._assignedWildcardIndex[wildcard.name];\n }\n\n public getMark() {\n return this._spec.mark;\n }\n\n public getEncodingProperty(index: number, prop: Property) {\n const encQ = this._spec.encodings[index];\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n return encQ[prop.parent][prop.child];\n }\n return encQ[prop]; // encoding property (non-nested)\n }\n\n public setEncodingProperty(index: number, prop: Property, value: any, wildcard: Wildcard) {\n const encQ = this._spec.encodings[index];\n\n if (prop === Property.CHANNEL && encQ.channel && !isWildcard(encQ.channel)) {\n // If there is an old channel\n this._channelFieldCount[encQ.channel as Channel]--;\n }\n\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n encQ[prop.parent][prop.child] = value;\n } else if (isEncodingNestedParent(prop) && value === true) {\n encQ[prop] = extend(\n {},\n encQ[prop], // copy all existing properties\n {enum: undefined, name: undefined} // except name and values to it no longer an wildcard\n );\n } else {\n // encoding property (non-nested)\n encQ[prop] = value;\n }\n\n this._assignedWildcardIndex[wildcard.name] = value;\n\n if (prop === Property.CHANNEL) {\n // If there is a new channel, make sure it exists and add it to the count.\n this._channelFieldCount[value] = (this._channelFieldCount[value] || 0) + 1;\n }\n }\n\n public resetEncodingProperty(index: number, prop: Property, wildcard: Wildcard) {\n const encQ = this._spec.encodings[index];\n if (prop === Property.CHANNEL) {\n this._channelFieldCount[encQ.channel as Channel]--;\n }\n\n // reset it to wildcard\n if (isEncodingNestedProp(prop)) {\n // nested encoding property\n encQ[prop.parent][prop.child] = wildcard;\n } else {\n // encoding property (non-nested)\n encQ[prop] = wildcard;\n }\n\n // add remove value that is reset from the assignment map\n delete this._assignedWildcardIndex[wildcard.name];\n }\n\n public channelUsed(channel: Channel) {\n // do not include encoding that has autoCount = false because it is not a part of the output spec.\n return this._channelFieldCount[channel] > 0;\n }\n\n public channelEncodingField(channel: Channel) {\n const encodingQuery = this.getEncodingQueryByChannel(channel);\n return isFieldQuery(encodingQuery);\n }\n\n public getEncodings(): EncodingQuery[] {\n // do not include encoding that has autoCount = false because it is not a part of the output spec.\n return this._spec.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ));\n }\n\n public getEncodingQueryByChannel(channel: Channel) {\n for (let specEncoding of this._spec.encodings) {\n if (specEncoding.channel === channel) {\n return specEncoding;\n }\n }\n return undefined;\n }\n\n public getEncodingQueryByIndex(i: number) {\n return this._spec.encodings[i];\n }\n\n public isAggregate() {\n return isAggregate(this._spec);\n }\n\n /**\n * @return The Vega-Lite `StackProperties` object that describes the stack\n * configuration of `this`. Returns `null` if this is not stackable.\n */\n public getVlStack(): StackProperties {\n return getVlStack(this._spec);\n }\n\n /**\n * @return The `StackOffset` specified in `this`, `undefined` if none\n * is specified.\n */\n public getStackOffset(): StackOffset {\n return getStackOffset(this._spec);\n }\n\n /**\n * @return The `Channel` in which `stack` is specified in `this`, or\n * `null` if none is specified.\n */\n public getStackChannel(): Channel {\n return getStackChannel(this._spec);\n }\n\n public toShorthand(groupBy?: string | (string | ExtendedGroupBy)[]): string {\n if (groupBy) {\n if (isString(groupBy)) {\n return getGroupByKey(this.specQuery, groupBy);\n }\n const parsedGroupBy = parseGroupBy(groupBy);\n return specShorthand(this._spec, parsedGroupBy.include, parsedGroupBy.replacer);\n }\n return specShorthand(this._spec);\n }\n\n /**\n * Convert a query to a Vega-Lite spec if it is completed.\n * @return a Vega-Lite spec if completed, null otherwise.\n */\n public toSpec(data?: Data): TopLevel {\n if (isWildcard(this._spec.mark)) return null;\n\n let spec: any = {};\n data = data || this._spec.data;\n if (data) {\n spec.data = data;\n }\n\n if (this._spec.transform) {\n spec.transform = this._spec.transform;\n }\n\n spec.mark = this._spec.mark as Mark;\n spec.encoding = toEncoding(this.specQuery.encodings, {schema: this._schema, wildcardMode: 'null'});\n\n if (this._spec.width) {\n spec.width = this._spec.width;\n }\n if (this._spec.height) {\n spec.height = this._spec.height;\n }\n if (this._spec.background) {\n spec.background = this._spec.background;\n }\n if (this._spec.padding) {\n spec.padding = this._spec.padding;\n }\n if (this._spec.title) {\n spec.title = this._spec.title;\n }\n\n if (spec.encoding === null) {\n return null;\n }\n if (this._spec.config || this._opt.defaultSpecConfig)\n spec.config = extend({}, this._opt.defaultSpecConfig, this._spec.config);\n\n return spec;\n }\n\n public getRankingScore(rankingName: string) {\n return this._rankingScore[rankingName];\n }\n\n public setRankingScore(rankingName: string, score: RankingScore) {\n this._rankingScore[rankingName] = score;\n }\n}\nexport type SpecQueryModelGroup = ResultTree;\n","import {Query} from './query';\nimport {Nest} from './groupby';\nimport {duplicate} from '../util';\n\n/**\n * Normalize the non-nested version of the query\n * (basically when you have a `groupBy`)\n * to a standardize nested.\n */\nexport function normalize(q: Query): Query {\n if (q.groupBy) {\n let nest: Nest = {\n groupBy: q.groupBy\n };\n\n if (q.orderBy) {\n nest.orderGroupBy = q.orderBy;\n }\n\n let normalizedQ: Query = {\n spec: duplicate(q.spec), // We will cause side effect to q.spec in SpecQueryModel.build\n nest: [nest],\n };\n\n if (q.chooseBy) {\n normalizedQ.chooseBy = q.chooseBy;\n }\n\n if (q.config) {\n normalizedQ.config = q.config;\n }\n\n return normalizedQ;\n }\n return duplicate(q); // We will cause side effect to q.spec in SpecQueryModel.build\n}\n","import {GroupBy} from './query/groupby';\n\n/**\n * An ordered tree structure for storing query results.\n */\nexport interface ResultTree {\n name: string;\n path: string;\n items: (ResultTree | T)[];\n groupBy?: GroupBy;\n orderGroupBy?: string | string[];\n}\n\nexport function isResultTree(item: ResultTree | T): item is ResultTree {\n return (>item).items !== undefined;\n}\n\nexport function getTopResultTreeItem(specQuery: ResultTree): T {\n let topItem = specQuery.items[0];\n while (topItem && isResultTree(topItem)) {\n topItem = topItem.items[0];\n }\n return topItem;\n}\n\nexport function mapLeaves(group: ResultTree, f: (item: T) => U): ResultTree {\n return {\n ...group,\n items: group.items.map(item => (isResultTree(item) ? mapLeaves(item, f) : f(item)))\n };\n}\n","import {hasDiscreteDomain} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {FieldQuery, scaleType} from '../../query/encoding';\nimport {ExpandedType} from '../../query/expandedtype';\n\n/**\n * Finer grained data types that takes binning and timeUnit into account.\n */\nexport enum ExtendedType {\n Q = TYPE.QUANTITATIVE as any,\n BIN_Q = ('bin_' + TYPE.QUANTITATIVE) as any,\n T = TYPE.TEMPORAL as any,\n\n /**\n * Time Unit Temporal Field with time scale.\n */\n TIMEUNIT_T = 'timeUnit_time' as any,\n /**\n * Time Unit Temporal Field with ordinal scale.\n */\n TIMEUNIT_O = ('timeUnit_' + TYPE.ORDINAL) as any,\n O = TYPE.ORDINAL as any,\n N = TYPE.NOMINAL as any,\n K = ExpandedType.KEY as any,\n NONE = '-' as any\n}\n\nexport const Q = ExtendedType.Q;\nexport const BIN_Q = ExtendedType.BIN_Q;\nexport const T = ExtendedType.T;\nexport const TIMEUNIT_T = ExtendedType.TIMEUNIT_T;\nexport const TIMEUNIT_O = ExtendedType.TIMEUNIT_O;\nexport const O = ExtendedType.O;\nexport const N = ExtendedType.N;\nexport const K = ExtendedType.K;\nexport const NONE = ExtendedType.NONE;\n\nexport function getExtendedType(fieldQ: FieldQuery): ExtendedType {\n if (fieldQ.bin) {\n return ExtendedType.BIN_Q;\n } else if (fieldQ.timeUnit) {\n const sType = scaleType(fieldQ);\n return hasDiscreteDomain(sType) ? ExtendedType.TIMEUNIT_O : ExtendedType.TIMEUNIT_T;\n }\n return fieldQ.type as ExtendedType;\n}\n","import {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {Dict} from '../../util';\n\n\nexport abstract class Scorer {\n public readonly type: string;\n public readonly scoreIndex: Dict;\n constructor(type: string) {\n this.type = type;\n this.scoreIndex = this.initScore();\n }\n\n protected abstract initScore(): Dict;\n\n protected getFeatureScore(feature: string): FeatureScore {\n const type = this.type;\n const score = this.scoreIndex[feature];\n if (score !== undefined) {\n return {type, feature, score};\n }\n return undefined;\n }\n\n public abstract getScore(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[];\n}\n","\n\n\nimport {QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {fieldDef as fieldDefShorthand} from '../../query/shorthand';\nimport {EncodingQuery, isFieldQuery, isAutoCountQuery} from '../../query/encoding';\nimport {Dict, extend, forEach, keys, contains} from '../../util';\n\nimport {Schema} from '../../schema';\nimport {FeatureScore} from '../ranking';\nimport {BIN_Q, TIMEUNIT_T, TIMEUNIT_O, Q, N, O, T, ExtendedType, getExtendedType, K} from './type';\n\n\nimport {Scorer} from './base';\nimport {Channel} from 'vega-lite/build/src/channel';\n\n\n\nexport const TERRIBLE = -10;\n\n/**\n * Effectiveness score for relationship between\n * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based)\n */\nexport class TypeChannelScorer extends Scorer {\n constructor() {\n super('TypeChannel');\n }\n protected initScore() {\n let SCORE = {} as Dict;\n\n // Continuous Quantitative / Temporal Fields\n const CONTINUOUS_TYPE_CHANNEL_SCORE = {\n x: 0,\n y: 0,\n size: -0.575,\n color: -0.725, // Middle between -0.7 and -0.75\n text: -2,\n opacity: -3,\n\n shape: TERRIBLE,\n row: TERRIBLE,\n column: TERRIBLE,\n detail: 2 * TERRIBLE\n };\n\n [Q, T, TIMEUNIT_T].forEach((type) => {\n keys(CONTINUOUS_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(type, channel)] = CONTINUOUS_TYPE_CHANNEL_SCORE[channel];\n });\n });\n\n // Discretized Quantitative / Temporal Fields / Ordinal\n\n const ORDERED_TYPE_CHANNEL_SCORE = extend({}, CONTINUOUS_TYPE_CHANNEL_SCORE, {\n row: -0.75,\n column: -0.75,\n\n shape: -3.1,\n text: -3.2,\n detail: -4\n });\n\n [BIN_Q, TIMEUNIT_O, O].forEach((type) => {\n keys(ORDERED_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(type, channel)] = ORDERED_TYPE_CHANNEL_SCORE[channel];\n });\n });\n\n const NOMINAL_TYPE_CHANNEL_SCORE = {\n x: 0,\n y: 0,\n color: -0.6, // TODO: make it adjustable based on preference (shape is better for black and white)\n shape: -0.65,\n row: -0.7,\n column: -0.7,\n text: -0.8,\n\n detail: -2,\n size: -3,\n opacity: -3.1,\n };\n\n keys(NOMINAL_TYPE_CHANNEL_SCORE).forEach((channel: Channel) => {\n SCORE[this.featurize(N, channel)] = NOMINAL_TYPE_CHANNEL_SCORE[channel];\n SCORE[this.featurize(K, channel)] =\n // Putting key on position or detail isn't terrible\n contains(['x', 'y', 'detail'], channel) ? -1 :\n NOMINAL_TYPE_CHANNEL_SCORE[channel] - 2;\n });\n\n return SCORE;\n }\n\n public featurize(type: ExtendedType, channel: Channel) {\n return type + '_' + channel;\n }\n\n public getScore(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[] {\n const encodingQueryByField = specM.getEncodings().reduce((m, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const fieldKey = fieldDefShorthand(encQ);\n (m[fieldKey] = m[fieldKey] || []).push(encQ);\n }\n return m;\n }, {});\n\n const features: FeatureScore[] = [];\n\n forEach(encodingQueryByField, (encQs: EncodingQuery[]) => {\n const bestFieldFeature = encQs.reduce((best: FeatureScore, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const type = getExtendedType(encQ);\n const feature = this.featurize(type, encQ.channel as Channel);\n const featureScore = this.getFeatureScore(feature);\n\n if (best === null || featureScore.score > best.score) {\n return featureScore;\n }\n }\n return best;\n }, null);\n\n features.push(bestFieldFeature);\n\n // TODO: add plus for over-encoding of one field\n });\n return features;\n }\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport * as MARK from 'vega-lite/build/src/mark';\nimport {Mark} from 'vega-lite/build/src/mark';\nimport {QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {Dict, forEach} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\nimport {BIN_Q, ExtendedType, getExtendedType, K, N, NONE, O, Q, T, TIMEUNIT_O, TIMEUNIT_T} from './type';\n\nexport class MarkScorer extends Scorer {\n constructor() {\n super('Mark');\n }\n\n protected initScore() {\n return init();\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n let mark = specM.getMark() as Mark;\n if (mark === MARK.CIRCLE || mark === MARK.SQUARE) {\n mark = MARK.POINT;\n }\n const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X);\n const xType = xEncQ ? getExtendedType(xEncQ) : NONE;\n\n const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y);\n const yType = yEncQ ? getExtendedType(yEncQ) : NONE;\n\n const isOccluded = !specM.isAggregate(); // FIXME\n\n const feature = xType + '_' + yType + '_' + isOccluded + '_' + mark;\n const featureScore = this.getFeatureScore(feature);\n\n if (featureScore) {\n return [featureScore];\n }\n console.error('feature score missing for', feature);\n return [];\n }\n}\n\nexport function featurize(xType: ExtendedType, yType: ExtendedType, hasOcclusion: boolean, mark: Mark) {\n return xType + '_' + yType + '_' + hasOcclusion + '_' + mark;\n}\n\nfunction init() {\n const MEASURES = [Q, T];\n const DISCRETE = [BIN_Q, TIMEUNIT_O, O, N, K];\n const DISCRETE_OR_NONE = DISCRETE.concat([NONE]);\n\n let SCORE = {} as Dict;\n // QxQ\n MEASURES.forEach(xType => {\n MEASURES.forEach(yType => {\n // has occlusion\n const occludedQQMark = {\n point: 0,\n text: -0.2,\n tick: -0.5,\n rect: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedQQMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n\n // no occlusion\n // TODO: possible to use connected scatter plot\n const noOccludedQQMark = {\n point: 0,\n text: -0.2,\n tick: -0.5,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(noOccludedQQMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n });\n });\n\n // DxQ, QxD\n MEASURES.forEach(xType => {\n // HAS OCCLUSION\n DISCRETE_OR_NONE.forEach(yType => {\n const occludedDimensionMeasureMark = {\n tick: 0,\n point: -0.2,\n text: -0.5,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedDimensionMeasureMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n // also do the inverse\n const feature2 = featurize(yType, xType, true, mark);\n SCORE[feature2] = score;\n });\n });\n\n [TIMEUNIT_T].forEach(yType => {\n const occludedDimensionMeasureMark = {\n // For Time Dimension with time scale, tick is not good\n point: 0,\n text: -0.5,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n forEach(occludedDimensionMeasureMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n // also do the inverse\n const feature2 = featurize(yType, xType, true, mark);\n SCORE[feature2] = score;\n });\n });\n\n // NO OCCLUSION\n [NONE, N, O, K].forEach(yType => {\n const noOccludedQxN = {\n bar: 0,\n point: -0.2,\n tick: -0.25,\n text: -0.3,\n // Line / Area can mislead trend for N\n line: -2, // FIXME line vs area?\n area: -2,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxN, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n\n [BIN_Q].forEach(yType => {\n const noOccludedQxBinQ = {\n bar: 0,\n point: -0.2,\n tick: -0.25,\n text: -0.3,\n // Line / Area isn't the best fit for bin\n line: -0.5, // FIXME line vs area?\n area: -0.5,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxBinQ, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n\n [TIMEUNIT_T, TIMEUNIT_O].forEach(yType => {\n // For aggregate / surely no occlusion plot, Temporal with time or ordinal\n // are not that different.\n const noOccludedQxBinQ = {\n line: 0,\n area: -0.1,\n bar: -0.2,\n point: -0.3,\n tick: -0.35,\n text: -0.4,\n // Non-sense to use rule here\n rule: -2.5\n };\n forEach(noOccludedQxBinQ, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n\n // also do the inverse\n const feature2 = featurize(yType, xType, false, mark);\n SCORE[feature2] = score;\n });\n });\n });\n\n [TIMEUNIT_T].forEach(xType => {\n [TIMEUNIT_T].forEach(yType => {\n // has occlusion\n const ttMark = {\n point: 0,\n rect: -0.1, // assuming rect will be small\n text: -0.5,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n // No difference between has occlusion and no occlusion\n // as most of the time, it will be the occluded case.\n forEach(ttMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n forEach(ttMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n });\n\n DISCRETE_OR_NONE.forEach(yType => {\n // has occlusion\n const tdMark = {\n tick: 0,\n point: -0.2,\n text: -0.5,\n rect: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n // No difference between has occlusion and no occlusion\n // as most of the time, it will be the occluded case.\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(yType, xType, true, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n forEach(tdMark, (score, mark: Mark) => {\n const feature = featurize(yType, xType, false, mark);\n SCORE[feature] = score;\n });\n });\n });\n\n // DxD\n // Note: We use for loop here because using forEach sometimes leads to a mysterious bug\n for (const xType of DISCRETE_OR_NONE) {\n for (const yType of DISCRETE_OR_NONE) {\n // has occlusion\n const ddMark = {\n point: 0,\n rect: 0,\n text: -0.1,\n tick: -1,\n bar: -2,\n line: -2,\n area: -2,\n rule: -2.5\n };\n\n forEach(ddMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, true, mark);\n SCORE[feature] = score;\n });\n\n // same for no occlusion.\n forEach(ddMark, (score, mark: Mark) => {\n const feature = featurize(xType, yType, false, mark);\n SCORE[feature] = score;\n });\n }\n }\n\n return SCORE;\n}\n","import {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {RankingScore, FeatureScore} from '../ranking';\nimport {AxisScorer} from './axis';\nimport {DimensionScorer} from './dimension';\nimport {FacetScorer} from './facet';\nimport {SizeChannelScorer} from './sizechannel';\nimport {TypeChannelScorer} from './typechannel';\nimport {MarkScorer} from './mark';\n\nconst SCORERS = [\n new AxisScorer(),\n new DimensionScorer(),\n new FacetScorer(),\n new MarkScorer(),\n new SizeChannelScorer(),\n new TypeChannelScorer()\n];\n\n// TODO: x/y, row/column preference\n// TODO: stacking\n// TODO: Channel, Cardinality\n// TODO: Penalize over encoding\nexport function effectiveness(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore {\n const features = SCORERS.reduce((f, scorer) => {\n const scores = scorer.getScore(specM, schema, opt);\n return f.concat(scores);\n }, [] as FeatureScore[]);\n\n return {\n score: features.reduce((s, f) => {\n return s + f.score;\n }, 0),\n features: features\n };\n}\n","/**\n * Field Type (with Bin and TimeUnit) and Channel Score (Cleveland / Mackinlay based)\n */\n\nimport * as CHANNEL from 'vega-lite/build/src/channel';\nimport {Channel} from 'vega-lite/build/src/channel';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {EncodingQuery, isAutoCountQuery, isFieldQuery} from '../../query/encoding';\nimport {Schema} from '../../schema';\nimport {Dict} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\nimport {BIN_Q, ExtendedType, getExtendedType, N, O, T, TIMEUNIT_O, TIMEUNIT_T} from './type';\n\n/**\n * Effectiveness Score for preferred axis.\n */\nexport class AxisScorer extends Scorer {\n constructor() {\n super('Axis');\n }\n protected initScore(opt: QueryConfig = {}) {\n opt = {...DEFAULT_QUERY_CONFIG, ...opt};\n let score: Dict = {};\n\n const preferredAxes = [\n {\n feature: BIN_Q,\n opt: 'preferredBinAxis'\n },\n {\n feature: T,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: TIMEUNIT_T,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: TIMEUNIT_O,\n opt: 'preferredTemporalAxis'\n },\n {\n feature: O,\n opt: 'preferredOrdinalAxis'\n },\n {\n feature: N,\n opt: 'preferredNominalAxis'\n }\n ];\n\n preferredAxes.forEach(pAxis => {\n if (opt[pAxis.opt] === CHANNEL.X) {\n // penalize the other axis\n score[pAxis.feature + '_' + CHANNEL.Y] = -0.01;\n } else if (opt[pAxis.opt] === CHANNEL.Y) {\n // penalize the other axis\n score[pAxis.feature + '_' + CHANNEL.X] = -0.01;\n }\n });\n\n return score;\n }\n\n public featurize(type: ExtendedType, channel: Channel) {\n return type + '_' + channel;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n return specM.getEncodings().reduce((features, encQ: EncodingQuery) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const type = getExtendedType(encQ);\n const feature = this.featurize(type, encQ.channel as Channel);\n const featureScore = this.getFeatureScore(feature);\n\n if (featureScore) {\n features.push(featureScore);\n }\n }\n return features;\n }, []);\n }\n}\n","import {Dict} from '../../util';\nimport {Scorer} from './base';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {EncodingQuery, isFieldQuery, isAutoCountQuery} from '../../query/encoding';\n\n/**\n * Penalize if facet channels are the only dimensions\n */\nexport class DimensionScorer extends Scorer {\n constructor() {\n super('Dimension');\n }\n\n protected initScore() {\n return {\n row: -2,\n column: -2,\n color: 0,\n opacity: 0,\n size: 0,\n shape: 0\n } as Dict;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n if (specM.isAggregate()) {\n specM.getEncodings().reduce((maxFScore, encQ: EncodingQuery) => {\n if (isAutoCountQuery(encQ) || (isFieldQuery(encQ) && !encQ.aggregate)) { // isDimension\n const featureScore = this.getFeatureScore(encQ.channel + '');\n if (featureScore && featureScore.score > maxFScore.score) {\n return featureScore;\n }\n }\n return maxFScore;\n }, {type: 'Dimension', feature: 'No Dimension', score: -5});\n }\n return [];\n }\n}\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {DEFAULT_QUERY_CONFIG, QueryConfig} from '../../config';\nimport {SpecQueryModel} from '../../model';\nimport {EncodingQuery, isAutoCountQuery, isFieldQuery} from '../../query/encoding';\nimport {Schema} from '../../schema';\nimport {Dict} from '../../util';\nimport {FeatureScore} from '../ranking';\nimport {Scorer} from './base';\n\n/**\n * Effective Score for preferred facet\n */\nexport class FacetScorer extends Scorer {\n constructor() {\n super('Facet');\n }\n protected initScore(opt?: QueryConfig) {\n opt = {...DEFAULT_QUERY_CONFIG, ...opt};\n let score: Dict = {};\n\n if (opt.preferredFacet === CHANNEL.ROW) {\n // penalize the other axis\n score[CHANNEL.COLUMN] = -0.01;\n } else if (opt.preferredFacet === CHANNEL.COLUMN) {\n // penalize the other axis\n score[CHANNEL.ROW] = -0.01;\n }\n\n return score;\n }\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n return specM.getEncodings().reduce((features, encQ: EncodingQuery) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const featureScore = this.getFeatureScore(encQ.channel as string);\n if (featureScore) {\n features.push(featureScore);\n }\n }\n return features;\n }, []);\n }\n}\n","import {Dict} from '../../util';\nimport {Scorer} from './base';\nimport {SpecQueryModel} from '../../model';\nimport {Schema} from '../../schema';\nimport {QueryConfig} from '../../config';\nimport {FeatureScore} from '../ranking';\nimport {isFieldQuery, isAutoCountQuery} from '../../query/encoding';\n\n/**\n * Effectivenss score that penalize size for bar and tick\n */\nexport class SizeChannelScorer extends Scorer {\n constructor() {\n super('SizeChannel');\n }\n\n protected initScore() {\n return {\n bar_size: -2,\n tick_size: -2\n } as Dict;\n }\n\n public getScore(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore[] {\n const mark = specM.getMark();\n return specM.getEncodings().reduce((featureScores, encQ) => {\n if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) {\n const feature = mark + '_' + encQ.channel;\n const featureScore = this.getFeatureScore(feature);\n if (featureScore) {\n featureScores.push(featureScore);\n }\n }\n return featureScores;\n }, []);\n }\n}\n","import * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {EncodingQuery, isDimension, isEnabledAutoCountQuery, isFieldQuery} from '../query/encoding';\nimport {Schema} from '../schema';\nimport {some} from '../util';\nimport {FeatureScore, RankingScore} from './ranking';\n\nexport const name = 'aggregationQuality';\n\nexport function score(specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore {\n const feature = aggregationQualityFeature(specM, schema, opt);\n return {\n score: feature.score,\n features: [feature]\n };\n}\n\nfunction aggregationQualityFeature(specM: SpecQueryModel, _: Schema, __: QueryConfig): FeatureScore {\n const encodings = specM.getEncodings();\n if (specM.isAggregate()) {\n const isRawContinuous = (encQ: EncodingQuery) => {\n return (\n isFieldQuery(encQ) &&\n ((encQ.type === TYPE.QUANTITATIVE && !encQ.bin && !encQ.aggregate) ||\n (encQ.type === TYPE.TEMPORAL && !encQ.timeUnit))\n );\n };\n\n if (some(encodings, isRawContinuous)) {\n // These are plots that pollute continuous fields as dimension.\n // They are often intermediate visualizations rather than what users actually want.\n return {\n type: name,\n score: 0.1,\n feature: 'Aggregate with raw continuous'\n };\n }\n\n if (some(encodings, encQ => isFieldQuery(encQ) && isDimension(encQ))) {\n let hasCount = some(encodings, (encQ: EncodingQuery) => {\n return (isFieldQuery(encQ) && encQ.aggregate === 'count') || isEnabledAutoCountQuery(encQ);\n });\n let hasBin = some(encodings, (encQ: EncodingQuery) => {\n return isFieldQuery(encQ) && !!encQ.bin;\n });\n\n if (hasCount) {\n // If there is count, we might add additional count field, making it a little less simple\n // then when we just apply aggregate to Q field\n return {\n type: name,\n score: 0.8,\n feature: 'Aggregate with count'\n };\n } else if (hasBin) {\n // This is not as good as binning all the Q and show heatmap\n return {\n type: name,\n score: 0.7,\n feature: 'Aggregate with bin but without count'\n };\n } else {\n return {\n type: name,\n score: 0.9,\n feature: 'Aggregate without count and without bin'\n };\n }\n }\n // no dimension -- often not very useful\n return {\n type: name,\n score: 0.3,\n feature: 'Aggregate without dimension'\n };\n } else {\n if (some(encodings, encQ => isFieldQuery(encQ) && !isDimension(encQ))) {\n // raw plots with measure -- simplest of all!\n return {\n type: name,\n score: 1,\n feature: 'Raw with measure'\n };\n }\n // raw plots with no measure -- often a lot of occlusion\n return {\n type: name,\n score: 0.2,\n feature: 'Raw without measure'\n };\n }\n}\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel} from '../model';\nimport {Schema} from '../schema';\nimport {isFieldQuery} from '../query/encoding';\n\nimport {RankingScore, FeatureScore} from './ranking';\n\nexport const name = 'fieldOrder';\n\n/**\n * Return ranking score based on indices of encoded fields in the schema.\n * If there are multiple fields, prioritize field on the lower indices of encodings.\n *\n * For example, to compare two specs with two encodings each,\n * first we compare the field on the 0-th index\n * and only compare the field on the 1-th index only if the fields on the 0-th index are the same.\n */\nexport function score(specM: SpecQueryModel, schema: Schema, _: QueryConfig): RankingScore {\n const fieldWildcardIndices = specM.wildcardIndex.encodingIndicesByProperty.get('field');\n if (!fieldWildcardIndices) {\n return {\n score: 0,\n features: []\n };\n }\n\n const encodings = specM.specQuery.encodings;\n const numFields = schema.fieldSchemas.length;\n\n const features: FeatureScore[] = [];\n let totalScore = 0, base = 1;\n\n for (let i = fieldWildcardIndices.length - 1; i >= 0; i--) {\n const index = fieldWildcardIndices[i];\n const encoding = encodings[index];\n\n // Skip ValueQuery as we only care about order of fields.\n let field;\n\n if (isFieldQuery(encoding)) {\n field = encoding.field as string;\n } else { // ignore ValueQuery / AutoCountQuery\n continue;\n }\n\n const fieldWildcard = specM.wildcardIndex.encodings[index].get('field');\n const fieldIndex = schema.fieldSchema(field).index;\n // reverse order field with lower index should get higher score and come first\n const score = - fieldIndex * base;\n totalScore += score;\n\n features.push({\n score: score,\n type: 'fieldOrder',\n feature: `field ${fieldWildcard.name} is ${field} (#${fieldIndex} in the schema)`\n });\n\n base *= numFields;\n }\n\n return {\n score: totalScore,\n features: features\n };\n}\n","import {QueryConfig} from '../config';\nimport {SpecQueryModel, SpecQueryModelGroup} from '../model';\nimport {getTopResultTreeItem} from '../result';\nimport {Query} from '../query/query';\nimport {Dict} from '../util';\nimport {Schema} from '../schema';\nimport {effectiveness} from './effectiveness';\n\nexport * from './effectiveness';\nimport * as aggregation from './aggregation';\nimport * as fieldOrder from './fieldorder';\n\nexport {aggregation, fieldOrder};\n\nexport interface RankingScore {\n score: number;\n features: FeatureScore[];\n}\n\nexport interface FeatureScore {\n score: number;\n type: string;\n feature: string;\n}\n\nexport interface FeatureInitializer {\n (): Dict;\n}\n\nexport interface Featurizer {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): FeatureScore[];\n}\n\nexport interface FeatureFactory {\n type: string;\n init: FeatureInitializer;\n getScore: Featurizer;\n}\n\nexport interface RankingFunction {\n (specM: SpecQueryModel, schema: Schema, opt: QueryConfig): RankingScore;\n}\n\n/**\n * Registry for all encoding ranking functions\n */\nlet rankingRegistry: Dict = {};\n\n/**\n * Add an ordering function to the registry.\n */\nexport function register(name: string, keyFn: RankingFunction) {\n rankingRegistry[name] = keyFn;\n}\n\nexport function get(name: string) {\n return rankingRegistry[name];\n}\n\nexport function rank(group: SpecQueryModelGroup, query: Query, schema: Schema, level: number): SpecQueryModelGroup {\n if (!query.nest || level === query.nest.length) {\n if (query.orderBy || query.chooseBy) {\n group.items.sort(comparatorFactory(query.orderBy || query.chooseBy, schema, query.config));\n if (query.chooseBy) {\n if (group.items.length > 0) {\n // for chooseBy -- only keep the top-item\n group.items.splice(1);\n }\n }\n }\n } else {\n // sort lower-level nodes first because our ranking takes top-item in the subgroup\n group.items.forEach((subgroup) => {\n rank(subgroup as SpecQueryModelGroup, query, schema, level + 1);\n });\n if (query.nest[level].orderGroupBy) {\n group.items.sort(groupComparatorFactory(query.nest[level].orderGroupBy, schema, query.config));\n }\n }\n return group;\n}\n\nexport function comparatorFactory(name: string | string[], schema: Schema, opt: QueryConfig) {\n return (m1: SpecQueryModel, m2: SpecQueryModel) => {\n if (name instanceof Array) {\n return getScoreDifference(name, m1, m2, schema, opt);\n } else {\n return getScoreDifference([name], m1, m2, schema, opt);\n }\n };\n}\n\nexport function groupComparatorFactory(name: string | string[], schema: Schema, opt: QueryConfig): (g1: SpecQueryModelGroup, g2: SpecQueryModelGroup) => number {\n return (g1: SpecQueryModelGroup, g2: SpecQueryModelGroup): number => {\n const m1 = getTopResultTreeItem(g1);\n const m2 = getTopResultTreeItem(g2);\n if (name instanceof Array) {\n return getScoreDifference(name, m1, m2, schema, opt);\n } else {\n return getScoreDifference([name], m1, m2, schema, opt);\n }\n };\n}\n\nfunction getScoreDifference(name: string[], m1: SpecQueryModel, m2: SpecQueryModel, schema: Schema, opt: QueryConfig): number {\n for (let rankingName of name) {\n let scoreDifference = getScore(m2, rankingName, schema, opt).score - getScore(m1, rankingName, schema, opt).score;\n if (scoreDifference !== 0) {\n return scoreDifference;\n }\n }\n return 0;\n}\n\nexport function getScore(model: SpecQueryModel, rankingName: string, schema: Schema, opt: QueryConfig) {\n if (model.getRankingScore(rankingName) !== undefined) {\n return model.getRankingScore(rankingName);\n }\n const fn = get(rankingName);\n const score = fn(model, schema, opt);\n model.setRankingScore(rankingName, score);\n return score;\n}\n\nexport const EFFECTIVENESS = 'effectiveness';\nregister(EFFECTIVENESS, effectiveness);\n\nregister(aggregation.name, aggregation.score);\nregister(fieldOrder.name, fieldOrder.score);\n","import * as CHANNEL from 'vega-lite/build/src/channel';\nimport {hasDiscreteDomain} from 'vega-lite/build/src/scale';\nimport * as TYPE from 'vega-lite/build/src/type';\nimport {QueryConfig} from './config';\nimport {SpecQueryModel} from './model';\nimport {AxisQuery, EncodingQuery, isFieldQuery, ScaleQuery, scaleType} from './query/encoding';\nimport {ExpandedType} from './query/expandedtype';\nimport {Schema} from './schema';\nimport {Dict} from './util';\n\nexport function stylize(answerSet: SpecQueryModel[], schema: Schema, opt: QueryConfig): SpecQueryModel[] {\n let encQIndex: Dict = {};\n answerSet = answerSet.map(function(specM) {\n if (opt.smallRangeStepForHighCardinalityOrFacet) {\n specM = smallRangeStepForHighCardinalityOrFacet(specM, schema, encQIndex, opt);\n }\n\n if (opt.nominalColorScaleForHighCardinality) {\n specM = nominalColorScaleForHighCardinality(specM, schema, encQIndex, opt);\n }\n\n if (opt.xAxisOnTopForHighYCardinalityWithoutColumn) {\n specM = xAxisOnTopForHighYCardinalityWithoutColumn(specM, schema, encQIndex, opt);\n }\n return specM;\n });\n\n return answerSet;\n}\n\nexport function smallRangeStepForHighCardinalityOrFacet(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n [CHANNEL.ROW, CHANNEL.Y, CHANNEL.COLUMN, CHANNEL.X].forEach(channel => {\n encQIndex[channel] = specM.getEncodingQueryByChannel(channel);\n });\n\n const yEncQ = encQIndex[CHANNEL.Y];\n if (yEncQ !== undefined && isFieldQuery(yEncQ)) {\n if (\n encQIndex[CHANNEL.ROW] ||\n schema.cardinality(yEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality\n ) {\n // We check for undefined rather than\n // yEncQ.scale = yEncQ.scale || {} to cover the case where\n // yEncQ.scale has been set to false/null.\n // This prevents us from incorrectly overriding scale and\n // assigning a rangeStep when scale is set to false.\n if (yEncQ.scale === undefined) {\n yEncQ.scale = {};\n }\n\n // We do not want to assign a rangeStep if scale is set to false\n // and we only apply this if the scale is (or can be) an ordinal scale.\n const yScaleType = scaleType(yEncQ);\n if (yEncQ.scale && (yScaleType === undefined || hasDiscreteDomain(yScaleType))) {\n if (!(yEncQ.scale as ScaleQuery).rangeStep) {\n (yEncQ.scale as ScaleQuery).rangeStep = 12;\n }\n }\n }\n }\n\n const xEncQ = encQIndex[CHANNEL.X];\n if (isFieldQuery(xEncQ)) {\n if (\n encQIndex[CHANNEL.COLUMN] ||\n schema.cardinality(xEncQ) > opt.smallRangeStepForHighCardinalityOrFacet.maxCardinality\n ) {\n // Just like y, we don't want to do this if scale is null/false\n if (xEncQ.scale === undefined) {\n xEncQ.scale = {};\n }\n\n // We do not want to assign a rangeStep if scale is set to false\n // and we only apply this if the scale is (or can be) an ordinal scale.\n const xScaleType = scaleType(xEncQ);\n if (xEncQ.scale && (xScaleType === undefined || hasDiscreteDomain(xScaleType))) {\n if (!(xEncQ.scale as ScaleQuery).rangeStep) {\n (xEncQ.scale as ScaleQuery).rangeStep = 12;\n }\n }\n }\n }\n\n return specM;\n}\n\nexport function nominalColorScaleForHighCardinality(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n encQIndex[CHANNEL.COLOR] = specM.getEncodingQueryByChannel(CHANNEL.COLOR);\n\n const colorEncQ = encQIndex[CHANNEL.COLOR];\n if (\n isFieldQuery(colorEncQ) &&\n colorEncQ !== undefined &&\n (colorEncQ.type === TYPE.NOMINAL || colorEncQ.type === ExpandedType.KEY) &&\n schema.cardinality(colorEncQ) > opt.nominalColorScaleForHighCardinality.maxCardinality\n ) {\n if (colorEncQ.scale === undefined) {\n colorEncQ.scale = {};\n }\n\n if (colorEncQ.scale) {\n if (!(colorEncQ.scale as ScaleQuery).range) {\n (colorEncQ.scale as ScaleQuery).scheme = opt.nominalColorScaleForHighCardinality.palette;\n }\n }\n }\n\n return specM;\n}\n\nexport function xAxisOnTopForHighYCardinalityWithoutColumn(\n specM: SpecQueryModel,\n schema: Schema,\n encQIndex: Dict,\n opt: QueryConfig\n): SpecQueryModel {\n [CHANNEL.COLUMN, CHANNEL.X, CHANNEL.Y].forEach(channel => {\n encQIndex[channel] = specM.getEncodingQueryByChannel(channel);\n });\n\n if (encQIndex[CHANNEL.COLUMN] === undefined) {\n const xEncQ = encQIndex[CHANNEL.X];\n const yEncQ = encQIndex[CHANNEL.Y];\n if (\n isFieldQuery(xEncQ) &&\n isFieldQuery(yEncQ) &&\n yEncQ !== undefined &&\n yEncQ.field &&\n hasDiscreteDomain(scaleType(yEncQ))\n ) {\n if (xEncQ !== undefined) {\n if (schema.cardinality(yEncQ) > opt.xAxisOnTopForHighYCardinalityWithoutColumn.maxCardinality) {\n if (xEncQ.axis === undefined) {\n xEncQ.axis = {};\n }\n\n if (xEncQ.axis && !(xEncQ.axis as AxisQuery).orient) {\n (xEncQ.axis as AxisQuery).orient = 'top';\n }\n }\n }\n }\n }\n\n return specM;\n}\n","\nimport {QueryConfig, DEFAULT_QUERY_CONFIG} from './config';\nimport {getEnumerator} from './enumerator';\nimport {SpecQueryModel} from './model';\nimport {fromKey} from'./property';\nimport {SpecQuery} from './query/spec';\nimport {Schema} from './schema';\nimport {stylize} from './stylize';\n\nexport function generate(specQ: SpecQuery, schema: Schema, opt: QueryConfig = DEFAULT_QUERY_CONFIG) {\n // 1. Build a SpecQueryModel, which also contains wildcardIndex\n const specM = SpecQueryModel.build(specQ, schema, opt);\n const wildcardIndex = specM.wildcardIndex;\n\n // 2. Enumerate each of the properties based on propPrecedence.\n\n let answerSet = [specM]; // Initialize Answer Set with only the input spec query.\n opt.propertyPrecedence.forEach((propKey) => {\n const prop = fromKey(propKey);\n // If the original specQuery contains wildcard for this prop\n if (wildcardIndex.hasProperty(prop)) {\n // update answerset\n const enumerator = getEnumerator(prop);\n const reducer = enumerator(wildcardIndex, schema, opt);\n answerSet = answerSet.reduce(reducer, []);\n }\n });\n\n if (opt.stylize) {\n if ((opt.nominalColorScaleForHighCardinality !== null) ||\n (opt.smallRangeStepForHighCardinalityOrFacet !== null) ||\n (opt.xAxisOnTopForHighYCardinalityWithoutColumn !== null)) {\n return stylize(answerSet, schema, opt);\n }\n }\n\n return answerSet;\n}\n","import {DEFAULT_QUERY_CONFIG, QueryConfig} from './config';\nimport {generate} from './generate';\nimport {SpecQueryModelGroup} from './model';\nimport {nest} from './nest';\nimport {normalize} from './query/normalize';\nimport {Query} from './query/query';\nimport {rank} from './ranking/ranking';\nimport {Schema} from './schema';\n\nexport function recommend(q: Query, schema: Schema, config?: QueryConfig): {query: Query, result: SpecQueryModelGroup} {\n // 1. Normalize non-nested `groupBy` to always have `groupBy` inside `nest`\n // and merge config with the following precedence\n // query.config > config > DEFAULT_QUERY_CONFIG\n q = {\n ...normalize(q),\n config: {\n ...DEFAULT_QUERY_CONFIG,\n ...config,\n ...q.config\n }\n };\n // 2. Generate\n const answerSet = generate(q.spec, schema, q.config);\n const nestedAnswerSet = nest(answerSet, q.nest);\n const result = rank(nestedAnswerSet, q, schema, 0);\n\n return {\n query: q,\n result: result\n };\n}\n"]} \ No newline at end of file diff --git a/build/src/constraint/base.js b/build/src/constraint/base.js new file mode 100644 index 00000000..8a10f378 --- /dev/null +++ b/build/src/constraint/base.js @@ -0,0 +1,55 @@ +import { isEncodingNestedProp } from '../property'; +import { isWildcard } from '../wildcard'; +import { every } from '../util'; +/** + * Abstract model for a constraint. + */ +export class AbstractConstraintModel { + constructor(constraint) { + this.constraint = constraint; + } + name() { + return this.constraint.name; + } + description() { + return this.constraint.description; + } + properties() { + return this.constraint.properties; + } + strict() { + return this.constraint.strict; + } +} +export class EncodingConstraintModel extends AbstractConstraintModel { + constructor(constraint) { + super(constraint); + } + hasAllRequiredPropertiesSpecific(encQ) { + return every(this.constraint.properties, (prop) => { + if (isEncodingNestedProp(prop)) { + let parent = prop.parent; + let child = prop.child; + if (!encQ[parent]) { + return true; + } + return !isWildcard(encQ[parent][child]); + } + if (!encQ[prop]) { + return true; + } + return !isWildcard(encQ[prop]); + }); + } + satisfy(encQ, schema, encWildcardIndex, opt) { + // TODO: Re-order logic to optimize the "allowWildcardForProperties" check + if (!this.constraint.allowWildcardForProperties) { + // TODO: extract as a method and do unit test + if (!this.hasAllRequiredPropertiesSpecific(encQ)) { + return true; + } + } + return this.constraint.satisfy(encQ, schema, encWildcardIndex, opt); + } +} +//# sourceMappingURL=base.js.map \ No newline at end of file diff --git a/build/src/constraint/encoding.js b/build/src/constraint/encoding.js new file mode 100644 index 00000000..16e8f421 --- /dev/null +++ b/build/src/constraint/encoding.js @@ -0,0 +1,44 @@ +import { isValueQuery } from '../query/encoding'; +import { FIELD_CONSTRAINTS_BY_PROPERTY } from './field'; +import { VALUE_CONSTRAINTS_BY_PROPERTY } from './value'; +/** + * Check all encoding constraints for a particular property and index tuple + */ +export function checkEncoding(prop, wildcard, index, specM, schema, opt) { + // Check encoding constraint + const encodingConstraints = FIELD_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + const encQ = specM.getEncodingQueryByIndex(index); + for (const c of encodingConstraints) { + // Check if the constraint is enabled + if (c.strict() || !!opt[c.name()]) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt); + if (!satisfy) { + let violatedConstraint = '(enc) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + const valueContraints = VALUE_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + for (const c of valueContraints) { + // Check if the constraint is enabled + if ((c.strict() || !!opt[c.name()]) && isValueQuery(encQ)) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(encQ, schema, specM.wildcardIndex.encodings[index], opt); + if (!satisfy) { + let violatedConstraint = '(enc) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + return null; +} +//# sourceMappingURL=encoding.js.map \ No newline at end of file diff --git a/build/src/constraint/field.js b/build/src/constraint/field.js new file mode 100644 index 00000000..a3949df0 --- /dev/null +++ b/build/src/constraint/field.js @@ -0,0 +1,403 @@ +import * as CHANNEL from 'vega-lite/build/src/channel'; +import { channelCompatibility } from 'vega-lite/build/src/channeldef'; +import { channelScalePropertyIncompatability, hasDiscreteDomain, ScaleType, scaleTypeSupportProperty } from 'vega-lite/build/src/scale'; +import { isLocalSingleTimeUnit, isUtcSingleTimeUnit } from 'vega-lite/build/src/timeunit'; +import * as TYPE from 'vega-lite/build/src/type'; +import { getEncodingNestedProp, Property, SCALE_PROPS } from '../property'; +import { PropIndex } from '../propindex'; +import { isFieldQuery, scaleType, toFieldDef } from '../query/encoding'; +import { ExpandedType, isDiscrete } from '../query/expandedtype'; +import { PrimitiveType } from '../schema'; +import { contains } from '../util'; +import { isWildcard } from '../wildcard'; +import { EncodingConstraintModel } from './base'; +export const FIELD_CONSTRAINTS = [ + { + name: 'aggregateOpSupportedByType', + description: 'Aggregate function should be supported by data type.', + properties: [Property.TYPE, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.aggregate) { + return !isDiscrete(fieldQ.type); + } + // TODO: some aggregate function are actually supported by ordinal + return true; // no aggregate is okay with any type. + } + }, + { + name: 'asteriskFieldWithCountOnly', + description: 'Field="*" should be disallowed except aggregate="count"', + properties: [Property.FIELD, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + return (fieldQ.field === '*') === (fieldQ.aggregate === 'count'); + } + }, + { + name: 'minCardinalityForBin', + description: 'binned quantitative field should not have too low cardinality', + properties: [Property.BIN, Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.bin && fieldQ.type === TYPE.QUANTITATIVE) { + // We remove bin so schema can infer the raw unbinned cardinality. + let fieldQwithoutBin = { + channel: fieldQ.channel, + field: fieldQ.field, + type: fieldQ.type + }; + return schema.cardinality(fieldQwithoutBin) >= opt.minCardinalityForBin; + } + return true; + } + }, + { + name: 'binAppliedForQuantitative', + description: 'bin should be applied to quantitative field only.', + properties: [Property.TYPE, Property.BIN], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.bin) { + // If binned, the type must be quantitative + return fieldQ.type === TYPE.QUANTITATIVE; + } + return true; + } + }, + { + name: 'channelFieldCompatible', + description: `encoding channel's range type be compatible with channel type.`, + properties: [Property.CHANNEL, Property.TYPE, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + const fieldDef = Object.assign({ field: 'f' }, toFieldDef(fieldQ, { schema, props: ['bin', 'timeUnit', 'type'] })); + const { compatible } = channelCompatibility(fieldDef, fieldQ.channel); + if (compatible) { + return true; + } + else { + // In VL, facet's field def must be discrete (O/N), but in CompassQL we can relax this a bit. + const isFacet = fieldQ.channel === 'row' || fieldQ.channel === 'column'; + if (isFacet && (isLocalSingleTimeUnit(fieldDef.timeUnit) || isUtcSingleTimeUnit(fieldDef.timeUnit))) { + return true; + } + return false; + } + } + }, + { + name: 'hasFn', + description: 'A field with as hasFn flag should have one of aggregate, timeUnit, or bin.', + properties: [Property.AGGREGATE, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.hasFn) { + return !!fieldQ.aggregate || !!fieldQ.bin || !!fieldQ.timeUnit; + } + return true; + } + }, + { + name: 'omitScaleZeroWithBinnedField', + description: 'Do not use scale zero with binned field', + properties: [Property.SCALE, getEncodingNestedProp('scale', 'zero'), Property.BIN], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.bin && fieldQ.scale) { + if (fieldQ.scale.zero === true) { + return false; + } + } + return true; + } + }, + { + name: 'onlyOneTypeOfFunction', + description: 'Only of of aggregate, autoCount, timeUnit, or bin should be applied at the same time.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN], + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (isFieldQuery(fieldQ)) { + const numFn = (!isWildcard(fieldQ.aggregate) && !!fieldQ.aggregate ? 1 : 0) + + (!isWildcard(fieldQ.bin) && !!fieldQ.bin ? 1 : 0) + + (!isWildcard(fieldQ.timeUnit) && !!fieldQ.timeUnit ? 1 : 0); + return numFn <= 1; + } + // For autoCount there is always only one type of function + return true; + } + }, + { + name: 'timeUnitAppliedForTemporal', + description: 'Time unit should be applied to temporal field only.', + properties: [Property.TYPE, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.timeUnit && fieldQ.type !== TYPE.TEMPORAL) { + return false; + } + return true; + } + }, + { + name: 'timeUnitShouldHaveVariation', + description: 'A particular time unit should be applied only if they produce unique values.', + properties: [Property.TIMEUNIT, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (fieldQ.timeUnit && fieldQ.type === TYPE.TEMPORAL) { + if (!encWildcardIndex.has('timeUnit') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + return schema.timeUnitHasVariation(fieldQ); + } + return true; + } + }, + { + name: 'scalePropertiesSupportedByScaleType', + description: 'Scale properties must be supported by correct scale type', + properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.TYPE]), + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.scale) { + const scale = fieldQ.scale; + // If fieldQ.type is an Wildcard and scale.type is undefined, it is equivalent + // to scale type is Wildcard. If scale type is an Wildcard, we do not yet know + // what the scale type is, and thus can ignore the constraint. + const sType = scaleType(fieldQ); + if (sType === undefined || sType === null) { + // If still ambiguous, doesn't check the constraint + return true; + } + for (let scaleProp in scale) { + if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') { + // ignore type and properties of wildcards + continue; + } + const sProp = scaleProp; + if (sType === 'point') { + // HACK: our current implementation of scaleType() can return point + // when the scaleType is a band since we didn't pass all parameter to Vega-Lite's scale type method. + if (!scaleTypeSupportProperty('point', sProp) && !scaleTypeSupportProperty('band', sProp)) { + return false; + } + } + else if (!scaleTypeSupportProperty(sType, sProp)) { + return false; + } + } + } + return true; + } + }, + { + name: 'scalePropertiesSupportedByChannel', + description: 'Not all scale properties are supported by all encoding channels', + properties: [].concat(SCALE_PROPS, [Property.SCALE, Property.CHANNEL]), + allowWildcardForProperties: true, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ) { + let channel = fieldQ.channel; + let scale = fieldQ.scale; + if (channel && !isWildcard(channel) && scale) { + if (channel === 'row' || channel === 'column') { + // row / column do not have scale + return false; + } + for (let scaleProp in scale) { + if (!scale.hasOwnProperty(scaleProp)) + continue; + if (scaleProp === 'type' || scaleProp === 'name' || scaleProp === 'enum') { + // ignore type and properties of wildcards + continue; + } + let isSupported = channelScalePropertyIncompatability(channel, scaleProp) === undefined; + if (!isSupported) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'typeMatchesPrimitiveType', + description: "Data type should be supported by field's primitive type.", + properties: [Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (fieldQ.field === '*') { + return true; + } + const primitiveType = schema.primitiveType(fieldQ.field); + const type = fieldQ.type; + if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + switch (primitiveType) { + case PrimitiveType.BOOLEAN: + case PrimitiveType.STRING: + return type !== TYPE.QUANTITATIVE && type !== TYPE.TEMPORAL; + case PrimitiveType.NUMBER: + case PrimitiveType.INTEGER: + return type !== TYPE.TEMPORAL; + case PrimitiveType.DATETIME: + // TODO: add NOMINAL, ORDINAL support after we support this in Vega-Lite + return type === TYPE.TEMPORAL; + case null: + // field does not exist in the schema + return false; + } + throw new Error('Not implemented'); + } + }, + { + name: 'typeMatchesSchemaType', + description: "Enumerated data type of a field should match the field's type in the schema.", + properties: [Property.FIELD, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, encWildcardIndex, opt) => { + if (!encWildcardIndex.has('field') && !encWildcardIndex.has('type') && !opt.constraintManuallySpecifiedValue) { + // Do not have to check this as this is manually specified by users. + return true; + } + if (fieldQ.field === '*') { + return fieldQ.type === TYPE.QUANTITATIVE; + } + return schema.vlType(fieldQ.field) === fieldQ.type; + } + }, + { + name: 'maxCardinalityForCategoricalColor', + description: 'Categorical channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + // TODO: missing case where ordinal / temporal use categorical color + // (once we do so, need to add Property.BIN, Property.TIMEUNIT) + if (fieldQ.channel === CHANNEL.COLOR && (fieldQ.type === TYPE.NOMINAL || fieldQ.type === ExpandedType.KEY)) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForCategoricalColor; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'maxCardinalityForFacet', + description: 'Row/column channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.channel === CHANNEL.ROW || fieldQ.channel === CHANNEL.COLUMN) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForFacet; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'maxCardinalityForShape', + description: 'Shape channel should not have too high cardinality', + properties: [Property.CHANNEL, Property.FIELD, Property.BIN, Property.TIMEUNIT], + allowWildcardForProperties: false, + strict: false, + satisfy: (fieldQ, schema, _, opt) => { + if (fieldQ.channel === CHANNEL.SHAPE) { + return schema.cardinality(fieldQ) <= opt.maxCardinalityForShape; + } + return true; // other channel is irrelevant to this constraint + } + }, + { + name: 'dataTypeAndFunctionMatchScaleType', + description: 'Scale type must match data type', + properties: [ + Property.TYPE, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TIMEUNIT, + Property.BIN + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (fieldQ.scale) { + const type = fieldQ.type; + const sType = scaleType(fieldQ); + if (isDiscrete(type)) { + return sType === undefined || hasDiscreteDomain(sType); + } + else if (type === TYPE.TEMPORAL) { + if (!fieldQ.timeUnit) { + return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType); + } + else { + return contains([ScaleType.TIME, ScaleType.UTC, undefined], sType) || hasDiscreteDomain(sType); + } + } + else if (type === TYPE.QUANTITATIVE) { + if (fieldQ.bin) { + return contains([ScaleType.LINEAR, undefined], sType); + } + else { + return contains([ + ScaleType.LOG, + ScaleType.POW, + ScaleType.SQRT, + ScaleType.QUANTILE, + ScaleType.QUANTIZE, + ScaleType.LINEAR, + undefined + ], sType); + } + } + } + return true; + } + }, + { + name: 'stackIsOnlyUsedWithXY', + description: 'stack should only be allowed for x and y channels', + properties: [Property.STACK, Property.CHANNEL], + allowWildcardForProperties: false, + strict: true, + satisfy: (fieldQ, _, __, ___) => { + if (!!fieldQ.stack) { + return fieldQ.channel === CHANNEL.X || fieldQ.channel === CHANNEL.Y; + } + return true; + } + } +].map((ec) => new EncodingConstraintModel(ec)); +export const FIELD_CONSTRAINT_INDEX = FIELD_CONSTRAINTS.reduce((m, ec) => { + m[ec.name()] = ec; + return m; +}, {}); +export const FIELD_CONSTRAINTS_BY_PROPERTY = FIELD_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + // Initialize array and use it + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; +}, new PropIndex()); +//# sourceMappingURL=field.js.map \ No newline at end of file diff --git a/build/src/constraint/index.js b/build/src/constraint/index.js new file mode 100644 index 00000000..674f57a3 --- /dev/null +++ b/build/src/constraint/index.js @@ -0,0 +1,4 @@ +import * as encoding from './encoding'; +import * as spec from './spec'; +export { encoding, spec }; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/constraint/spec.js b/build/src/constraint/spec.js new file mode 100644 index 00000000..4474b8f9 --- /dev/null +++ b/build/src/constraint/spec.js @@ -0,0 +1,797 @@ +import { SUM_OPS } from 'vega-lite/build/src/aggregate'; +import * as CHANNEL from 'vega-lite/build/src/channel'; +import { NONPOSITION_CHANNELS, supportMark } from 'vega-lite/build/src/channel'; +import * as MARK from 'vega-lite/build/src/mark'; +import { ScaleType } from 'vega-lite/build/src/scale'; +import * as TYPE from 'vega-lite/build/src/type'; +import { getEncodingNestedProp, isEncodingNestedProp, isEncodingProperty, Property } from '../property'; +import { PropIndex } from '../propindex'; +import { isAutoCountQuery, isDimension, isDisabledAutoCountQuery, isEnabledAutoCountQuery, isFieldQuery, isMeasure, isValueQuery, scaleType } from '../query/encoding'; +import { ExpandedType } from '../query/expandedtype'; +import { contains, every, some } from '../util'; +import { isWildcard } from '../wildcard'; +import { AbstractConstraintModel } from './base'; +const NONPOSITION_CHANNELS_INDEX = NONPOSITION_CHANNELS.reduce((m, channel) => { + m[channel] = true; + return m; +}, {}); +export class SpecConstraintModel extends AbstractConstraintModel { + constructor(specConstraint) { + super(specConstraint); + } + hasAllRequiredPropertiesSpecific(specM) { + return every(this.constraint.properties, prop => { + if (prop === Property.MARK) { + return !isWildcard(specM.getMark()); + } + // TODO: transform + if (isEncodingNestedProp(prop)) { + let parent = prop.parent; + let child = prop.child; + return every(specM.getEncodings(), encQ => { + if (!encQ[parent]) { + return true; + } + return !isWildcard(encQ[parent][child]); + }); + } + if (!isEncodingProperty(prop)) { + throw new Error('UNIMPLEMENTED'); + } + return every(specM.getEncodings(), encQ => { + if (!encQ[prop]) { + return true; + } + return !isWildcard(encQ[prop]); + }); + }); + } + satisfy(specM, schema, opt) { + // TODO: Re-order logic to optimize the "allowWildcardForProperties" check + if (!this.constraint.allowWildcardForProperties) { + if (!this.hasAllRequiredPropertiesSpecific(specM)) { + return true; + } + } + return this.constraint.satisfy(specM, schema, opt); + } +} +export const SPEC_CONSTRAINTS = [ + { + name: 'noRepeatedChannel', + description: 'Each encoding channel should only be used once.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: true, + satisfy: (specM, _, __) => { + let usedChannel = {}; + // channel for all encodings should be valid + return every(specM.getEncodings(), encQ => { + if (!isWildcard(encQ.channel)) { + // If channel is specified, it should no be used already + if (usedChannel[encQ.channel]) { + return false; + } + usedChannel[encQ.channel] = true; + return true; + } + return true; // unspecified channel is valid + }); + } + }, + { + name: 'alwaysIncludeZeroInScaleWithBarMark', + description: 'Do not recommend bar mark if scale does not start at zero', + properties: [ + Property.MARK, + Property.SCALE, + getEncodingNestedProp('scale', 'zero'), + Property.CHANNEL, + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + const encodings = specM.getEncodings(); + if (mark === MARK.BAR) { + for (let encQ of encodings) { + if (isFieldQuery(encQ) && + (encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) && + encQ.type === TYPE.QUANTITATIVE && + (encQ.scale && encQ.scale.zero === false)) { + // TODO: zero shouldn't be manually specified + return false; + } + } + } + return true; + } + }, + { + name: 'autoAddCount', + description: 'Automatically adding count only for plots with only ordinal, binned quantitative, or temporal with timeunit fields.', + properties: [Property.BIN, Property.TIMEUNIT, Property.TYPE, Property.AUTOCOUNT], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + const hasAutoCount = some(specM.getEncodings(), (encQ) => isEnabledAutoCountQuery(encQ)); + if (hasAutoCount) { + // Auto count should only be applied if all fields are nominal, ordinal, temporal with timeUnit, binned quantitative, or autoCount + return every(specM.getEncodings(), (encQ) => { + if (isValueQuery(encQ)) { + return true; + } + if (isAutoCountQuery(encQ)) { + return true; + } + switch (encQ.type) { + case TYPE.QUANTITATIVE: + return !!encQ.bin; + case TYPE.TEMPORAL: + return !!encQ.timeUnit; + case TYPE.ORDINAL: + case ExpandedType.KEY: + case TYPE.NOMINAL: + return true; + } + /* istanbul ignore next */ + throw new Error('Unsupported Type'); + }); + } + else { + const autoCountEncIndex = specM.wildcardIndex.encodingIndicesByProperty.get('autoCount') || []; + const neverHaveAutoCount = every(autoCountEncIndex, (index) => { + let encQ = specM.getEncodingQueryByIndex(index); + return isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount); + }); + if (neverHaveAutoCount) { + // If the query surely does not have autoCount + // then one of the field should be + // (1) unbinned quantitative + // (2) temporal without time unit + // (3) nominal or ordinal field + // or at least have potential to be (still ambiguous). + return some(specM.getEncodings(), (encQ) => { + if ((isFieldQuery(encQ) || isAutoCountQuery(encQ)) && encQ.type === TYPE.QUANTITATIVE) { + if (isDisabledAutoCountQuery(encQ)) { + return false; + } + else { + return isFieldQuery(encQ) && (!encQ.bin || isWildcard(encQ.bin)); + } + } + else if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) { + return !encQ.timeUnit || isWildcard(encQ.timeUnit); + } + return false; // nominal or ordinal + }); + } + } + return true; // no auto count, no constraint + } + }, + { + name: 'channelPermittedByMarkType', + description: 'Each encoding channel should be supported by the mark type', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: true, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + // if mark is unspecified, no need to check + if (isWildcard(mark)) + return true; + // TODO: can optimize this to detect only what's the changed property if needed. + return every(specM.getEncodings(), encQ => { + // channel unspecified, no need to check + if (isWildcard(encQ.channel)) + return true; + return !!supportMark(encQ.channel, mark); + }); + } + }, + { + name: 'hasAllRequiredChannelsForMark', + description: 'All required channels for the specified mark should be specified', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + switch (mark) { + case MARK.AREA: + case MARK.LINE: + return specM.channelUsed(CHANNEL.X) && specM.channelUsed(CHANNEL.Y); + case MARK.TEXT: + return specM.channelUsed(CHANNEL.TEXT); + case MARK.BAR: + case MARK.CIRCLE: + case MARK.SQUARE: + case MARK.TICK: + case MARK.RULE: + case MARK.RECT: + return specM.channelUsed(CHANNEL.X) || specM.channelUsed(CHANNEL.Y); + case MARK.POINT: + // This allows generating a point plot if channel was not a wildcard. + return (!specM.wildcardIndex.hasProperty(Property.CHANNEL) || + specM.channelUsed(CHANNEL.X) || + specM.channelUsed(CHANNEL.Y)); + } + /* istanbul ignore next */ + throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + JSON.stringify(mark)); + } + }, + { + name: 'omitAggregate', + description: 'Omit aggregate plots.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + if (specM.isAggregate()) { + return false; + } + return true; + } + }, + { + name: 'omitAggregatePlotWithDimensionOnlyOnFacet', + description: 'Omit aggregate plots with dimensions only on facets as that leads to inefficient use of space.', + properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + let hasNonFacetDim = false, hasDim = false, hasEnumeratedFacetDim = false; + specM.specQuery.encodings.forEach((encQ, index) => { + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + return; // skip unused field + // FieldQuery & !encQ.aggregate + if (isFieldQuery(encQ) && !encQ.aggregate) { + // isDimension + hasDim = true; + if (contains([CHANNEL.ROW, CHANNEL.COLUMN], encQ.channel)) { + if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL)) { + hasEnumeratedFacetDim = true; + } + } + else { + hasNonFacetDim = true; + } + } + }); + if (hasDim && !hasNonFacetDim) { + if (hasEnumeratedFacetDim || opt.constraintManuallySpecifiedValue) { + return false; + } + } + } + return true; + } + }, + { + name: 'omitAggregatePlotWithoutDimension', + description: 'Aggregate plots without dimension should be omitted', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.BIN, Property.TIMEUNIT, Property.TYPE], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (specM.isAggregate()) { + // TODO relax + return some(specM.getEncodings(), (encQ) => { + if (isDimension(encQ) || (isFieldQuery(encQ) && encQ.type === 'temporal')) { + return true; + } + return false; + }); + } + return true; + } + }, + { + // TODO: we can be smarter and check if bar has occlusion based on profiling statistics + name: 'omitBarLineAreaWithOcclusion', + description: "Don't use bar, line or area to visualize raw plot as they often lead to occlusion.", + properties: [Property.MARK, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (contains([MARK.BAR, MARK.LINE, MARK.AREA], specM.getMark())) { + return specM.isAggregate(); + } + return true; + } + }, + { + name: 'omitBarTickWithSize', + description: 'Do not map field to size channel with bar and tick mark', + properties: [Property.CHANNEL, Property.MARK], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + const mark = specM.getMark(); + if (contains([MARK.TICK, MARK.BAR], mark)) { + if (specM.channelEncodingField(CHANNEL.SIZE)) { + if (opt.constraintManuallySpecifiedValue) { + // If size is used and we constraintManuallySpecifiedValue, + // then the spec violates this constraint. + return false; + } + else { + // Otherwise have to search for the size channel and check if it is enumerated + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (encQ.channel === CHANNEL.SIZE) { + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + // If enumerated, then this is bad + return false; + } + else { + // If it's manually specified, no need to continue searching, just return. + return true; + } + } + } + } + } + } + return true; // skip + } + }, + { + name: 'omitBarAreaForLogScale', + description: "Do not use bar and area mark for x and y's log scale", + properties: [ + Property.MARK, + Property.CHANNEL, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + const encodings = specM.getEncodings(); + // TODO: mark or scale type should be enumerated + if (mark === MARK.AREA || mark === MARK.BAR) { + for (let encQ of encodings) { + if (isFieldQuery(encQ) && ((encQ.channel === CHANNEL.X || encQ.channel === CHANNEL.Y) && encQ.scale)) { + let sType = scaleType(encQ); + if (sType === ScaleType.LOG) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'omitMultipleNonPositionalChannels', + description: 'Unless manually specified, do not use multiple non-positional encoding channel to avoid over-encoding.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + // have to use specM.specQuery.encodings insetad of specM.getEncodings() + // since specM.getEncodings() remove encQ with autoCount===false from the array + // and thus might shift the index + const encodings = specM.specQuery.encodings; + let nonPositionChannelCount = 0; + let hasEnumeratedNonPositionChannel = false; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) { + continue; // ignore skipped encoding + } + const channel = encQ.channel; + if (!isWildcard(channel)) { + if (NONPOSITION_CHANNELS_INDEX[channel + '']) { + nonPositionChannelCount += 1; + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + hasEnumeratedNonPositionChannel = true; + } + if (nonPositionChannelCount > 1 && + (hasEnumeratedNonPositionChannel || opt.constraintManuallySpecifiedValue)) { + return false; + } + } + } + } + return true; + } + }, + { + name: 'omitNonPositionalOrFacetOverPositionalChannels', + description: 'Do not use non-positional channels unless all positional channels are used', + properties: [Property.CHANNEL], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + const encodings = specM.specQuery.encodings; + let hasNonPositionalChannelOrFacet = false; + let hasEnumeratedNonPositionOrFacetChannel = false; + let hasX = false, hasY = false; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) { + continue; // ignore skipped encoding + } + const channel = encQ.channel; + if (channel === CHANNEL.X) { + hasX = true; + } + else if (channel === CHANNEL.Y) { + hasY = true; + } + else if (!isWildcard(channel)) { + // All non positional channel / Facet + hasNonPositionalChannelOrFacet = true; + if (specM.wildcardIndex.hasEncodingProperty(i, Property.CHANNEL)) { + hasEnumeratedNonPositionOrFacetChannel = true; + } + } + } + if (hasEnumeratedNonPositionOrFacetChannel || + (opt.constraintManuallySpecifiedValue && hasNonPositionalChannelOrFacet)) { + return hasX && hasY; + } + return true; + } + }, + { + name: 'omitRaw', + description: 'Omit raw plots.', + properties: [Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + if (!specM.isAggregate()) { + return false; + } + return true; + } + }, + { + name: 'omitRawContinuousFieldForAggregatePlot', + description: 'Aggregate plot should not use raw continuous field as group by values. ' + + '(Quantitative should be binned. Temporal should have time unit.)', + properties: [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN, Property.TYPE], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + continue; // skip unused encoding + // TODO: aggregate for ordinal and temporal + if (isFieldQuery(encQ) && encQ.type === TYPE.TEMPORAL) { + // Temporal fields should have timeUnit or is still a wildcard + if (!encQ.timeUnit && + (specM.wildcardIndex.hasEncodingProperty(i, Property.TIMEUNIT) || opt.constraintManuallySpecifiedValue)) { + return false; + } + } + if (encQ.type === TYPE.QUANTITATIVE) { + if (isFieldQuery(encQ) && !encQ.bin && !encQ.aggregate) { + // If Raw Q + if (specM.wildcardIndex.hasEncodingProperty(i, Property.BIN) || + specM.wildcardIndex.hasEncodingProperty(i, Property.AGGREGATE) || + specM.wildcardIndex.hasEncodingProperty(i, Property.AUTOCOUNT)) { + // and it's raw from enumeration + return false; + } + if (opt.constraintManuallySpecifiedValue) { + // or if we constraintManuallySpecifiedValue + return false; + } + } + } + } + } + return true; + } + }, + { + name: 'omitRawDetail', + description: 'Do not use detail channel with raw plot.', + properties: [Property.CHANNEL, Property.AGGREGATE, Property.AUTOCOUNT], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, opt) => { + if (specM.isAggregate()) { + return true; + } + return every(specM.specQuery.encodings, (encQ, index) => { + if (isValueQuery(encQ) || isDisabledAutoCountQuery(encQ)) + return true; // ignore autoCount field + if (encQ.channel === CHANNEL.DETAIL) { + // Detail channel for raw plot is not good, except when its enumerated + // or when it's manually specified but we constraintManuallySpecifiedValue. + if (specM.wildcardIndex.hasEncodingProperty(index, Property.CHANNEL) || + opt.constraintManuallySpecifiedValue) { + return false; + } + } + return true; + }); + } + }, + { + name: 'omitRepeatedField', + description: 'Each field should be mapped to only one channel', + properties: [Property.FIELD], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, opt) => { + let fieldUsed = {}; + let fieldEnumerated = {}; + const encodings = specM.specQuery.encodings; + for (let i = 0; i < encodings.length; i++) { + const encQ = encodings[i]; + if (isValueQuery(encQ) || isAutoCountQuery(encQ)) + continue; + let field; + if (encQ.field && !isWildcard(encQ.field)) { + field = encQ.field; + } + if (isAutoCountQuery(encQ) && !isWildcard(encQ.autoCount)) { + field = 'count_*'; + } + if (field) { + if (specM.wildcardIndex.hasEncodingProperty(i, Property.FIELD)) { + fieldEnumerated[field] = true; + } + // When the field is specified previously, + // if it is enumerated (either previously or in this encQ) + // or if the opt.constraintManuallySpecifiedValue is true, + // then it violates the constraint. + if (fieldUsed[field]) { + if (fieldEnumerated[field] || opt.constraintManuallySpecifiedValue) { + return false; + } + } + fieldUsed[field] = true; + } + } + return true; + } + }, + // TODO: omitShapeWithBin + { + name: 'omitVerticalDotPlot', + description: 'Do not output vertical dot plot.', + properties: [Property.CHANNEL], + allowWildcardForProperties: true, + strict: false, + satisfy: (specM, _, __) => { + const encodings = specM.getEncodings(); + if (encodings.length === 1 && encodings[0].channel === CHANNEL.Y) { + return false; + } + return true; + } + }, + // EXPENSIVE CONSTRAINTS -- check them later! + { + name: 'hasAppropriateGraphicTypeForMark', + description: 'Has appropriate graphic type for mark', + properties: [ + Property.CHANNEL, + Property.MARK, + Property.TYPE, + Property.TIMEUNIT, + Property.BIN, + Property.AGGREGATE, + Property.AUTOCOUNT + ], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, __) => { + const mark = specM.getMark(); + switch (mark) { + case MARK.AREA: + case MARK.LINE: + if (specM.isAggregate()) { + // TODO: refactor based on profiling statistics + const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X); + const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y); + const xIsMeasure = isMeasure(xEncQ); + const yIsMeasure = isMeasure(yEncQ); + // for aggregate line / area, we need at least one group-by axis and one measure axis. + return (xEncQ && + yEncQ && + xIsMeasure !== yIsMeasure && + // and the dimension axis should not be nominal + // TODO: make this clause optional + !(isFieldQuery(xEncQ) && !xIsMeasure && contains(['nominal', 'key'], xEncQ.type)) && + !(isFieldQuery(yEncQ) && !yIsMeasure && contains(['nominal', 'key'], yEncQ.type))); + // TODO: allow connected scatterplot + } + return true; + case MARK.TEXT: + // FIXME correctly when we add text + return true; + case MARK.BAR: + case MARK.TICK: + // Bar and tick should not use size. + if (specM.channelEncodingField(CHANNEL.SIZE)) { + return false; + } + else { + // Tick and Bar should have one and only one measure + const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X); + const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y); + const xIsMeasure = isMeasure(xEncQ); + const yIsMeasure = isMeasure(yEncQ); + if (xIsMeasure !== yIsMeasure) { + return true; + } + return false; + } + case MARK.RECT: + // Until CompassQL supports layering, it only makes sense for + // rect to encode DxD or 1xD (otherwise just use bar). + // Furthermore, color should only be used in a 'heatmap' fashion + // (with a measure field). + const xEncQ = specM.getEncodingQueryByChannel(CHANNEL.X); + const yEncQ = specM.getEncodingQueryByChannel(CHANNEL.Y); + const xIsDimension = isDimension(xEncQ); + const yIsDimension = isDimension(yEncQ); + const colorEncQ = specM.getEncodingQueryByChannel(CHANNEL.COLOR); + const colorIsQuantitative = isMeasure(colorEncQ); + const colorIsOrdinal = isFieldQuery(colorEncQ) ? colorEncQ.type === TYPE.ORDINAL : false; + const correctChannels = (xIsDimension && yIsDimension) || + (xIsDimension && !specM.channelUsed(CHANNEL.Y)) || + (yIsDimension && !specM.channelUsed(CHANNEL.X)); + const correctColor = !colorEncQ || (colorEncQ && (colorIsQuantitative || colorIsOrdinal)); + return correctChannels && correctColor; + case MARK.CIRCLE: + case MARK.POINT: + case MARK.SQUARE: + case MARK.RULE: + return true; + } + /* istanbul ignore next */ + throw new Error('hasAllRequiredChannelsForMark not implemented for mark' + mark); + } + }, + { + name: 'omitInvalidStackSpec', + description: 'If stack is specified, must follow Vega-Lite stack rules', + properties: [ + Property.STACK, + Property.FIELD, + Property.CHANNEL, + Property.MARK, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + if (!specM.wildcardIndex.hasProperty(Property.STACK)) { + return true; + } + const stackProps = specM.getVlStack(); + if (stackProps === null && specM.getStackOffset() !== null) { + return false; + } + if (stackProps.fieldChannel !== specM.getStackChannel()) { + return false; + } + return true; + } + }, + { + name: 'omitNonSumStack', + description: 'Stack specifications that use non-summative aggregates should be omitted (even implicit ones)', + properties: [ + Property.CHANNEL, + Property.MARK, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ], + allowWildcardForProperties: false, + strict: true, + satisfy: (specM, _, __) => { + const specStack = specM.getVlStack(); + if (specStack != null) { + const stackParentEncQ = specM.getEncodingQueryByChannel(specStack.fieldChannel); + if (!contains(SUM_OPS, stackParentEncQ.aggregate)) { + return false; + } + } + return true; + } + }, + { + name: 'omitTableWithOcclusionIfAutoAddCount', + description: 'Plots without aggregation or autocount where x and y are both discrete should be omitted if autoAddCount is enabled as they often lead to occlusion', + properties: [ + Property.CHANNEL, + Property.TYPE, + Property.TIMEUNIT, + Property.BIN, + Property.AGGREGATE, + Property.AUTOCOUNT + ], + allowWildcardForProperties: false, + strict: false, + satisfy: (specM, _, opt) => { + if (opt.autoAddCount) { + const xEncQ = specM.getEncodingQueryByChannel('x'); + const yEncQ = specM.getEncodingQueryByChannel('y'); + if ((!isFieldQuery(xEncQ) || isDimension(xEncQ)) && (!isFieldQuery(yEncQ) || isDimension(yEncQ))) { + if (!specM.isAggregate()) { + return false; + } + else { + return every(specM.getEncodings(), encQ => { + let channel = encQ.channel; + if (channel !== CHANNEL.X && + channel !== CHANNEL.Y && + channel !== CHANNEL.ROW && + channel !== CHANNEL.COLUMN) { + // Non-position fields should not be unaggreated fields + if (isFieldQuery(encQ) && !encQ.aggregate) { + return false; + } + } + return true; + }); + } + } + } + return true; + } + } +].map(sc => new SpecConstraintModel(sc)); +// For testing +export const SPEC_CONSTRAINT_INDEX = SPEC_CONSTRAINTS.reduce((m, c) => { + m[c.name()] = c; + return m; +}, {}); +const SPEC_CONSTRAINTS_BY_PROPERTY = SPEC_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + // Initialize array and use it + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; +}, new PropIndex()); +/** + * Check all encoding constraints for a particular property and index tuple + */ +export function checkSpec(prop, wildcard, specM, schema, opt) { + // Check encoding constraint + const specConstraints = SPEC_CONSTRAINTS_BY_PROPERTY.get(prop) || []; + for (const c of specConstraints) { + // Check if the constraint is enabled + if (c.strict() || !!opt[c.name()]) { + // For strict constraint, or enabled non-strict, check the constraints + const satisfy = c.satisfy(specM, schema, opt); + if (!satisfy) { + let violatedConstraint = '(spec) ' + c.name(); + /* istanbul ignore if */ + if (opt.verbose) { + console.log(violatedConstraint + ' failed with ' + specM.toShorthand() + ' for ' + wildcard.name); + } + return violatedConstraint; + } + } + } + return null; +} +//# sourceMappingURL=spec.js.map \ No newline at end of file diff --git a/build/src/constraint/value.js b/build/src/constraint/value.js new file mode 100644 index 00000000..1fcfa4f0 --- /dev/null +++ b/build/src/constraint/value.js @@ -0,0 +1,28 @@ +import { Property } from '../property'; +import { PropIndex } from '../propindex'; +import { contains } from '../util'; +import { EncodingConstraintModel } from './base'; +export const VALUE_CONSTRAINTS = [ + { + name: 'doesNotSupportConstantValue', + description: 'row, column, x, y, order, and detail should not work with constant values.', + properties: [Property.TYPE, Property.AGGREGATE], + allowWildcardForProperties: false, + strict: true, + satisfy: (valueQ, _, __, ___) => { + return !(contains(['row', 'column', 'x', 'y', 'detail', 'order'], valueQ.channel)); + } + } +].map((ec) => new EncodingConstraintModel(ec)); +export const VALUE_CONSTRAINT_INDEX = VALUE_CONSTRAINTS.reduce((m, ec) => { + m[ec.name()] = ec; + return m; +}, {}); +export const VALUE_CONSTRAINTS_BY_PROPERTY = VALUE_CONSTRAINTS.reduce((index, c) => { + for (const prop of c.properties()) { + index.set(prop, index.get(prop) || []); + index.get(prop).push(c); + } + return index; +}, new PropIndex()); +//# sourceMappingURL=value.js.map \ No newline at end of file diff --git a/build/src/query/encoding.js b/build/src/query/encoding.js new file mode 100644 index 00000000..fe28a218 --- /dev/null +++ b/build/src/query/encoding.js @@ -0,0 +1,196 @@ +import { isObject } from 'datalib/src/util'; +import * as vlChannelDef from 'vega-lite/build/src/channeldef'; +import { scaleType as compileScaleType } from 'vega-lite/build/src/compile/scale/type'; +import * as TYPE from 'vega-lite/build/src/type'; +import { isEncodingNestedParent, Property } from '../property'; +import { isWildcard, SHORT_WILDCARD } from '../wildcard'; +import { ExpandedType } from './expandedtype'; +import { PROPERTY_SUPPORTED_CHANNELS } from './shorthand'; +export function isValueQuery(encQ) { + return encQ !== null && encQ !== undefined && encQ['value'] !== undefined; +} +export function isFieldQuery(encQ) { + return encQ !== null && encQ !== undefined && (encQ['field'] || encQ['aggregate'] === 'count'); +} +export function isAutoCountQuery(encQ) { + return encQ !== null && encQ !== undefined && 'autoCount' in encQ; +} +export function isDisabledAutoCountQuery(encQ) { + return isAutoCountQuery(encQ) && encQ.autoCount === false; +} +export function isEnabledAutoCountQuery(encQ) { + return isAutoCountQuery(encQ) && encQ.autoCount === true; +} +const DEFAULT_PROPS = [ + Property.AGGREGATE, + Property.BIN, + Property.TIMEUNIT, + Property.FIELD, + Property.TYPE, + Property.SCALE, + Property.SORT, + Property.AXIS, + Property.LEGEND, + Property.STACK, + Property.FORMAT +]; +export function toEncoding(encQs, params) { + const { wildcardMode = 'skip' } = params; + let encoding = {}; + for (const encQ of encQs) { + if (isDisabledAutoCountQuery(encQ)) { + continue; // Do not include this in the output. + } + const { channel } = encQ; + // if channel is a wildcard, return null + if (isWildcard(channel)) { + throw new Error('Cannot convert wildcard channel to a fixed channel'); + } + const channelDef = isValueQuery(encQ) ? toValueDef(encQ) : toFieldDef(encQ, params); + if (channelDef === null) { + if (params.wildcardMode === 'null') { + // contains invalid property (e.g., wildcard, thus cannot return a proper spec.) + return null; + } + continue; + } + // Otherwise, we can set the channelDef + encoding[channel] = channelDef; + } + return encoding; +} +export function toValueDef(valueQ) { + const { value } = valueQ; + if (isWildcard(value)) { + return null; + } + return { value }; +} +export function toFieldDef(encQ, params = {}) { + const { props = DEFAULT_PROPS, schema, wildcardMode = 'skip' } = params; + if (isFieldQuery(encQ)) { + const fieldDef = {}; + for (const prop of props) { + let encodingProperty = encQ[prop]; + if (isWildcard(encodingProperty)) { + if (wildcardMode === 'skip') + continue; + return null; + } + if (encodingProperty !== undefined) { + // if the channel supports this prop + const isSupportedByChannel = !PROPERTY_SUPPORTED_CHANNELS[prop] || PROPERTY_SUPPORTED_CHANNELS[prop][encQ.channel]; + if (!isSupportedByChannel) { + continue; + } + if (isEncodingNestedParent(prop) && isObject(encodingProperty)) { + encodingProperty = Object.assign({}, encodingProperty); // Make a shallow copy first + for (const childProp in encodingProperty) { + // ensure nested properties are not wildcard before assigning to field def + if (isWildcard(encodingProperty[childProp])) { + if (wildcardMode === 'null') { + return null; + } + delete encodingProperty[childProp]; // skip + } + } + } + if (prop === 'bin' && encodingProperty === false) { + continue; + } + else if (prop === 'type' && encodingProperty === 'key') { + fieldDef.type = 'nominal'; + } + else { + fieldDef[prop] = encodingProperty; + } + } + if (prop === Property.SCALE && schema && encQ.type === TYPE.ORDINAL) { + const scale = encQ.scale; + const { ordinalDomain } = schema.fieldSchema(encQ.field); + if (scale !== null && ordinalDomain) { + fieldDef[Property.SCALE] = Object.assign({ domain: ordinalDomain }, (isObject(scale) ? scale : {})); + } + } + } + return fieldDef; + } + else { + if (encQ.autoCount === false) { + throw new Error(`Cannot convert {autoCount: false} into a field def`); + } + else { + return { + aggregate: 'count', + field: '*', + type: 'quantitative' + }; + } + } +} +/** + * Is a field query continuous field? + * This method is applicable only for fieldQuery without wildcard + */ +export function isContinuous(encQ) { + if (isFieldQuery(encQ)) { + return vlChannelDef.isContinuous(toFieldDef(encQ, { props: ['bin', 'timeUnit', 'field', 'type'] })); + } + return isAutoCountQuery(encQ); +} +export function isMeasure(encQ) { + if (isFieldQuery(encQ)) { + return !isDimension(encQ) && encQ.type !== 'temporal'; + } + return isAutoCountQuery(encQ); +} +/** + * Is a field query discrete field? + * This method is applicable only for fieldQuery without wildcard + */ +export function isDimension(encQ) { + if (isFieldQuery(encQ)) { + const fieldDef = toFieldDef(encQ, { props: ['bin', 'timeUnit', 'type'] }); + return vlChannelDef.isDiscrete(fieldDef) || !!fieldDef.timeUnit; + } + return false; +} +/** + * Returns the true scale type of an encoding. + * @returns {ScaleType} If the scale type was not specified, it is inferred from the encoding's TYPE. + * @returns {undefined} If the scale type was not specified and Type (or TimeUnit if applicable) is a Wildcard, there is no clear scale type + */ +export function scaleType(fieldQ) { + const scale = fieldQ.scale === true || fieldQ.scale === SHORT_WILDCARD ? {} : fieldQ.scale || {}; + const { type, channel, timeUnit, bin } = fieldQ; + // HACK: All of markType, and scaleConfig only affect + // sub-type of ordinal to quantitative scales (point or band) + // Currently, most of scaleType usage in CompassQL doesn't care about this subtle difference. + // Thus, instead of making this method requiring the global mark, + // we will just call it with mark = undefined . + // Thus, currently, we will always get a point scale unless a CompassQuery specifies band. + const markType = undefined; + if (isWildcard(scale.type) || isWildcard(type) || isWildcard(channel) || isWildcard(bin)) { + return undefined; + } + // If scale type is specified, then use scale.type + if (scale.type) { + return scale.type; + } + // if type is fixed and it's not temporal, we can ignore time unit. + if (type === 'temporal' && isWildcard(timeUnit)) { + return undefined; + } + // if type is fixed and it's not quantitative, we can ignore bin + if (type === 'quantitative' && isWildcard(bin)) { + return undefined; + } + let vegaLiteType = type === ExpandedType.KEY ? 'nominal' : type; + const fieldDef = { + type: vegaLiteType, + timeUnit: timeUnit, + bin: bin + }; + return compileScaleType({ type: scale.type }, channel, fieldDef, markType); +} +//# sourceMappingURL=encoding.js.map \ No newline at end of file diff --git a/build/src/query/expandedtype.js b/build/src/query/expandedtype.js new file mode 100644 index 00000000..a989cf82 --- /dev/null +++ b/build/src/query/expandedtype.js @@ -0,0 +1,13 @@ +import * as TYPE from 'vega-lite/build/src/type'; +export var ExpandedType; +(function (ExpandedType) { + ExpandedType.QUANTITATIVE = TYPE.QUANTITATIVE; + ExpandedType.ORDINAL = TYPE.ORDINAL; + ExpandedType.TEMPORAL = TYPE.TEMPORAL; + ExpandedType.NOMINAL = TYPE.NOMINAL; + ExpandedType.KEY = 'key'; +})(ExpandedType || (ExpandedType = {})); +export function isDiscrete(fieldType) { + return fieldType === TYPE.ORDINAL || fieldType === TYPE.NOMINAL || fieldType === ExpandedType.KEY; +} +//# sourceMappingURL=expandedtype.js.map \ No newline at end of file diff --git a/build/src/query/groupby.js b/build/src/query/groupby.js new file mode 100644 index 00000000..3a0a75ef --- /dev/null +++ b/build/src/query/groupby.js @@ -0,0 +1,69 @@ +import { isArray, isObject } from 'datalib/src/util'; +import { getReplacerIndex } from './shorthand'; +import { Property } from '../property'; +import { PropIndex } from '../propindex'; +import { keys } from '../util'; +export const REPLACE_BLANK_FIELDS = { '*': '' }; +export const REPLACE_XY_CHANNELS = { x: 'xy', y: 'xy' }; +export const REPLACE_FACET_CHANNELS = { row: 'facet', column: 'facet' }; +export const REPLACE_MARK_STYLE_CHANNELS = { color: 'style', opacity: 'style', shape: 'style', size: 'style' }; +export function isExtendedGroupBy(g) { + return isObject(g) && !!g['property']; +} +export function parseGroupBy(groupBy, include, replaceIndex) { + include = include || new PropIndex(); + replaceIndex = replaceIndex || new PropIndex(); + groupBy.forEach((grpBy) => { + if (isExtendedGroupBy(grpBy)) { + include.setByKey(grpBy.property, true); + replaceIndex.setByKey(grpBy.property, grpBy.replace); + } + else { + include.setByKey(grpBy, true); + } + }); + return { + include: include, + replaceIndex: replaceIndex, + replacer: getReplacerIndex(replaceIndex) + }; +} +export function toString(groupBy) { + if (isArray(groupBy)) { + return groupBy.map((g) => { + if (isExtendedGroupBy(g)) { + if (g.replace) { + let replaceIndex = keys(g.replace).reduce((index, valFrom) => { + const valTo = g.replace[valFrom]; + (index[valTo] = index[valTo] || []).push(valFrom); + return index; + }, {}); + return g.property + '[' + keys(replaceIndex).map((valTo) => { + const valsFrom = replaceIndex[valTo].sort(); + return valsFrom.join(',') + '=>' + valTo; + }).join(';') + ']'; + } + return g.property; + } + return g; + }).join(','); + } + else { + return groupBy; + } +} +export const GROUP_BY_FIELD_TRANSFORM = [ + Property.FIELD, Property.TYPE, + Property.AGGREGATE, Property.BIN, Property.TIMEUNIT, Property.STACK +]; +export const GROUP_BY_ENCODING = GROUP_BY_FIELD_TRANSFORM.concat([ + { + property: Property.CHANNEL, + replace: { + 'x': 'xy', 'y': 'xy', + 'color': 'style', 'size': 'style', 'shape': 'style', 'opacity': 'style', + 'row': 'facet', 'column': 'facet' + } + } +]); +//# sourceMappingURL=groupby.js.map \ No newline at end of file diff --git a/build/src/query/index.js b/build/src/query/index.js new file mode 100644 index 00000000..40928603 --- /dev/null +++ b/build/src/query/index.js @@ -0,0 +1,8 @@ +import * as encoding from './encoding'; +import * as groupBy from './groupby'; +import * as shorthand from './shorthand'; +import * as spec from './spec'; +import * as transform from './transform'; +export { normalize } from './normalize'; +export { encoding, groupBy, shorthand, spec, transform }; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/build/src/query/normalize.js b/build/src/query/normalize.js new file mode 100644 index 00000000..d131eaa1 --- /dev/null +++ b/build/src/query/normalize.js @@ -0,0 +1,29 @@ +import { duplicate } from '../util'; +/** + * Normalize the non-nested version of the query + * (basically when you have a `groupBy`) + * to a standardize nested. + */ +export function normalize(q) { + if (q.groupBy) { + let nest = { + groupBy: q.groupBy + }; + if (q.orderBy) { + nest.orderGroupBy = q.orderBy; + } + let normalizedQ = { + spec: duplicate(q.spec), + nest: [nest], + }; + if (q.chooseBy) { + normalizedQ.chooseBy = q.chooseBy; + } + if (q.config) { + normalizedQ.config = q.config; + } + return normalizedQ; + } + return duplicate(q); // We will cause side effect to q.spec in SpecQueryModel.build +} +//# sourceMappingURL=normalize.js.map \ No newline at end of file diff --git a/build/src/query/query.js b/build/src/query/query.js new file mode 100644 index 00000000..47d9eb37 --- /dev/null +++ b/build/src/query/query.js @@ -0,0 +1 @@ +//# sourceMappingURL=query.js.map \ No newline at end of file diff --git a/build/src/query/shorthand.js b/build/src/query/shorthand.js new file mode 100644 index 00000000..8d35c09d --- /dev/null +++ b/build/src/query/shorthand.js @@ -0,0 +1,451 @@ +import { isString } from 'datalib/src/util'; +import { isAggregateOp } from 'vega-lite/build/src/aggregate'; +import { isChannel } from 'vega-lite/build/src/channel'; +import { isTimeUnit } from 'vega-lite/build/src/timeunit'; +import * as TYPE from 'vega-lite/build/src/type'; +import { getFullName } from 'vega-lite/build/src/type'; +import { DEFAULT_PROP_PRECEDENCE, getEncodingNestedProp, isEncodingNestedParent, Property, SORT_PROPS, VIEW_PROPS } from '../property'; +import { PropIndex } from '../propindex'; +import { isArray, isBoolean, keys } from '../util'; +import { isShortWildcard, isWildcard, SHORT_WILDCARD } from '../wildcard'; +import { isAutoCountQuery, isDisabledAutoCountQuery, isEnabledAutoCountQuery, isFieldQuery, isValueQuery } from './encoding'; +import { fromSpec, getVlStack } from './spec'; +export function getReplacerIndex(replaceIndex) { + return replaceIndex.map(r => getReplacer(r)); +} +export function getReplacer(replace) { + return (s) => { + if (replace[s] !== undefined) { + return replace[s]; + } + return s; + }; +} +export function value(v, replacer) { + if (isWildcard(v)) { + // Return the enum array if it's a full wildcard, or just return SHORT_WILDCARD for short ones. + if (!isShortWildcard(v) && v.enum) { + return SHORT_WILDCARD + JSON.stringify(v.enum); + } + else { + return SHORT_WILDCARD; + } + } + if (replacer) { + return replacer(v); + } + return v; +} +export function replace(v, replacer) { + if (replacer) { + return replacer(v); + } + return v; +} +export const REPLACE_NONE = new PropIndex(); +export const INCLUDE_ALL = +// FIXME: remove manual TRANSFORM concat once we really support enumerating transform. +[] + .concat(DEFAULT_PROP_PRECEDENCE, SORT_PROPS, [Property.TRANSFORM, Property.STACK], VIEW_PROPS) + .reduce((pi, prop) => pi.set(prop, true), new PropIndex()); +export function vlSpec(vlspec, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const specQ = fromSpec(vlspec); + return spec(specQ, include, replace); +} +export const PROPERTY_SUPPORTED_CHANNELS = { + axis: { x: true, y: true, row: true, column: true }, + legend: { color: true, opacity: true, size: true, shape: true }, + scale: { x: true, y: true, color: true, opacity: true, row: true, column: true, size: true, shape: true }, + sort: { x: true, y: true, path: true, order: true }, + stack: { x: true, y: true } +}; +/** + * Returns a shorthand for a spec query + * @param specQ a spec query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ +export function spec(specQ, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const parts = []; + if (include.get(Property.MARK)) { + parts.push(value(specQ.mark, replace.get(Property.MARK))); + } + if (specQ.transform && specQ.transform.length > 0) { + parts.push('transform:' + JSON.stringify(specQ.transform)); + } + let stack; + if (include.get(Property.STACK)) { + stack = getVlStack(specQ); + } + if (specQ.encodings) { + const encodings = specQ.encodings + .reduce((encQs, encQ) => { + // Exclude encoding mapping with autoCount=false as they are basically disabled. + if (!isDisabledAutoCountQuery(encQ)) { + let str; + if (!!stack && encQ.channel === stack.fieldChannel) { + str = encoding(Object.assign({}, encQ, { stack: stack.offset }), include, replace); + } + else { + str = encoding(encQ, include, replace); + } + if (str) { + // only add if the shorthand isn't an empty string. + encQs.push(str); + } + } + return encQs; + }, []) + .sort() // sort at the end to ignore order + .join('|'); + if (encodings) { + parts.push(encodings); + } + } + for (let viewProp of VIEW_PROPS) { + const propString = viewProp.toString(); + if (include.get(viewProp) && !!specQ[propString]) { + const value = specQ[propString]; + parts.push(`${propString}=${JSON.stringify(value)}`); + } + } + return parts.join('|'); +} +/** + * Returns a shorthand for an encoding query + * @param encQ an encoding query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ +export function encoding(encQ, include = INCLUDE_ALL, replace = REPLACE_NONE) { + const parts = []; + if (include.get(Property.CHANNEL)) { + parts.push(value(encQ.channel, replace.get(Property.CHANNEL))); + } + if (isFieldQuery(encQ)) { + const fieldDefStr = fieldDef(encQ, include, replace); + if (fieldDefStr) { + parts.push(fieldDefStr); + } + } + else if (isValueQuery(encQ)) { + parts.push(encQ.value); + } + else if (isAutoCountQuery(encQ)) { + parts.push('autocount()'); + } + return parts.join(':'); +} +/** + * Returns a field definition shorthand for an encoding query + * @param encQ an encoding query + * @param include Dict Set listing property types (key) to be included in the shorthand + * @param replace Dictionary of replace function for values of a particular property type (key) + */ +export function fieldDef(encQ, include = INCLUDE_ALL, replacer = REPLACE_NONE) { + if (include.get(Property.AGGREGATE) && isDisabledAutoCountQuery(encQ)) { + return '-'; + } + const fn = func(encQ, include, replacer); + const props = fieldDefProps(encQ, include, replacer); + let fieldAndParams; + if (isFieldQuery(encQ)) { + // field + fieldAndParams = include.get('field') ? value(encQ.field, replacer.get('field')) : '...'; + // type + if (include.get(Property.TYPE)) { + if (isWildcard(encQ.type)) { + fieldAndParams += ',' + value(encQ.type, replacer.get(Property.TYPE)); + } + else { + const typeShort = ((encQ.type || TYPE.QUANTITATIVE) + '').substr(0, 1); + fieldAndParams += ',' + value(typeShort, replacer.get(Property.TYPE)); + } + } + // encoding properties + fieldAndParams += props + .map(p => { + let val = p.value instanceof Array ? '[' + p.value + ']' : p.value; + return ',' + p.key + '=' + val; + }) + .join(''); + } + else if (isAutoCountQuery(encQ)) { + fieldAndParams = '*,q'; + } + if (!fieldAndParams) { + return null; + } + if (fn) { + let fnPrefix = isString(fn) ? fn : SHORT_WILDCARD + (keys(fn).length > 0 ? JSON.stringify(fn) : ''); + return fnPrefix + '(' + fieldAndParams + ')'; + } + return fieldAndParams; +} +/** + * Return function part of + */ +function func(fieldQ, include, replacer) { + if (include.get(Property.AGGREGATE) && fieldQ.aggregate && !isWildcard(fieldQ.aggregate)) { + return replace(fieldQ.aggregate, replacer.get(Property.AGGREGATE)); + } + else if (include.get(Property.AGGREGATE) && isEnabledAutoCountQuery(fieldQ)) { + // autoCount is considered a part of aggregate + return replace('count', replacer.get(Property.AGGREGATE)); + } + else if (include.get(Property.TIMEUNIT) && fieldQ.timeUnit && !isWildcard(fieldQ.timeUnit)) { + return replace(fieldQ.timeUnit, replacer.get(Property.TIMEUNIT)); + } + else if (include.get(Property.BIN) && fieldQ.bin && !isWildcard(fieldQ.bin)) { + return 'bin'; + } + else { + let fn = null; + for (const prop of [Property.AGGREGATE, Property.AUTOCOUNT, Property.TIMEUNIT, Property.BIN]) { + const val = fieldQ[prop]; + if (include.get(prop) && fieldQ[prop] && isWildcard(val)) { + // assign fnEnumIndex[prop] = array of enum values or just "?" if it is SHORT_WILDCARD + fn = fn || {}; + fn[prop] = isShortWildcard(val) ? val : val.enum; + } + } + if (fn && fieldQ.hasFn) { + fn.hasFn = true; + } + return fn; + } +} +/** + * Return key-value of parameters of field defs + */ +function fieldDefProps(fieldQ, include, replacer) { + /** Encoding properties e.g., Scale, Axis, Legend */ + const props = []; + // Parameters of function such as bin will be just top-level properties + if (!isBoolean(fieldQ.bin) && !isShortWildcard(fieldQ.bin)) { + const bin = fieldQ.bin; + for (const child in bin) { + const prop = getEncodingNestedProp('bin', child); + if (prop && include.get(prop) && bin[child] !== undefined) { + props.push({ + key: child, + value: value(bin[child], replacer.get(prop)) + }); + } + } + // Sort to make sure that parameter are ordered consistently + props.sort((a, b) => a.key.localeCompare(b.key)); + } + for (const parent of [Property.SCALE, Property.SORT, Property.STACK, Property.AXIS, Property.LEGEND]) { + if (!isWildcard(fieldQ.channel) && !PROPERTY_SUPPORTED_CHANNELS[parent][fieldQ.channel]) { + continue; + } + if (include.get(parent) && fieldQ[parent] !== undefined) { + const parentValue = fieldQ[parent]; + if (isBoolean(parentValue) || parentValue === null) { + // `scale`, `axis`, `legend` can be false/null. + props.push({ + key: parent + '', + value: parentValue || false // return true or false (false if null) + }); + } + else if (isString(parentValue)) { + // `sort` can be a string (ascending/descending). + props.push({ + key: parent + '', + value: replace(JSON.stringify(parentValue), replacer.get(parent)) + }); + } + else { + let nestedPropChildren = []; + for (const child in parentValue) { + const nestedProp = getEncodingNestedProp(parent, child); + if (nestedProp && include.get(nestedProp) && parentValue[child] !== undefined) { + nestedPropChildren.push({ + key: child, + value: value(parentValue[child], replacer.get(nestedProp)) + }); + } + } + if (nestedPropChildren.length > 0) { + const nestedPropObject = nestedPropChildren + .sort((a, b) => a.key.localeCompare(b.key)) + .reduce((o, item) => { + o[item.key] = item.value; + return o; + }, {}); + // Sort to make sure that parameter are ordered consistently + props.push({ + key: parent + '', + value: JSON.stringify(nestedPropObject) + }); + } + } + } + } + return props; +} +export function parse(shorthand) { + // TODO(https://github.com/uwdata/compassql/issues/259): + // Do not split directly, but use an upgraded version of `getClosingBraceIndex()` + let splitShorthand = shorthand.split('|'); + let specQ = { + mark: splitShorthand[0], + encodings: [] + }; + for (let i = 1; i < splitShorthand.length; i++) { + let part = splitShorthand[i]; + const splitPart = splitWithTail(part, ':', 1); + const splitPartKey = splitPart[0]; + const splitPartValue = splitPart[1]; + if (isChannel(splitPartKey) || splitPartKey === '?') { + const encQ = shorthandParser.encoding(splitPartKey, splitPartValue); + specQ.encodings.push(encQ); + continue; + } + if (splitPartKey === 'transform') { + specQ.transform = JSON.parse(splitPartValue); + continue; + } + } + return specQ; +} +/** + * Split a string n times into substrings with the specified delimiter and return them as an array. + * @param str The string to be split + * @param delim The delimiter string used to separate the string + * @param number The value used to determine how many times the string is split + */ +export function splitWithTail(str, delim, count) { + let result = []; + let lastIndex = 0; + for (let i = 0; i < count; i++) { + let indexOfDelim = str.indexOf(delim, lastIndex); + if (indexOfDelim !== -1) { + result.push(str.substring(lastIndex, indexOfDelim)); + lastIndex = indexOfDelim + 1; + } + else { + break; + } + } + result.push(str.substr(lastIndex)); + // If the specified count is greater than the number of delimiters that exist in the string, + // an empty string will be pushed count minus number of delimiter occurence times. + if (result.length !== count + 1) { + while (result.length !== count + 1) { + result.push(''); + } + } + return result; +} +export var shorthandParser; +(function (shorthandParser) { + function encoding(channel, fieldDefShorthand) { + let encQMixins = fieldDefShorthand.indexOf('(') !== -1 + ? fn(fieldDefShorthand) + : rawFieldDef(splitWithTail(fieldDefShorthand, ',', 2)); + return Object.assign({ channel }, encQMixins); + } + shorthandParser.encoding = encoding; + function rawFieldDef(fieldDefPart) { + const fieldQ = {}; + fieldQ.field = fieldDefPart[0]; + fieldQ.type = getFullName(fieldDefPart[1].toUpperCase()) || '?'; + let partParams = fieldDefPart[2]; + let closingBraceIndex = 0; + let i = 0; + while (i < partParams.length) { + let propEqualSignIndex = partParams.indexOf('=', i); + let parsedValue; + if (propEqualSignIndex !== -1) { + let prop = partParams.substring(i, propEqualSignIndex); + if (partParams[i + prop.length + 1] === '{') { + let openingBraceIndex = i + prop.length + 1; + closingBraceIndex = getClosingIndex(openingBraceIndex, partParams, '}'); + const value = partParams.substring(openingBraceIndex, closingBraceIndex + 1); + parsedValue = JSON.parse(value); + // index after next comma + i = closingBraceIndex + 2; + } + else if (partParams[i + prop.length + 1] === '[') { + // find closing square bracket + let openingBracketIndex = i + prop.length + 1; + let closingBracketIndex = getClosingIndex(openingBracketIndex, partParams, ']'); + const value = partParams.substring(openingBracketIndex, closingBracketIndex + 1); + parsedValue = JSON.parse(value); + // index after next comma + i = closingBracketIndex + 2; + } + else { + let propIndex = i; + // Substring until the next comma (or end of the string) + let nextCommaIndex = partParams.indexOf(',', i + prop.length); + if (nextCommaIndex === -1) { + nextCommaIndex = partParams.length; + } + // index after next comma + i = nextCommaIndex + 1; + parsedValue = JSON.parse(partParams.substring(propIndex + prop.length + 1, nextCommaIndex)); + } + if (isEncodingNestedParent(prop)) { + fieldQ[prop] = parsedValue; + } + else { + // prop is a property of the aggregation function such as bin + fieldQ.bin = fieldQ.bin || {}; + fieldQ.bin[prop] = parsedValue; + } + } + else { + // something is wrong with the format of the partParams + // exits loop if don't have then infintie loop + break; + } + } + return fieldQ; + } + shorthandParser.rawFieldDef = rawFieldDef; + function getClosingIndex(openingBraceIndex, str, closingChar) { + for (let i = openingBraceIndex; i < str.length; i++) { + if (str[i] === closingChar) { + return i; + } + } + } + shorthandParser.getClosingIndex = getClosingIndex; + function fn(fieldDefShorthand) { + const fieldQ = {}; + // Aggregate, Bin, TimeUnit as wildcard case + if (fieldDefShorthand[0] === '?') { + let closingBraceIndex = getClosingIndex(1, fieldDefShorthand, '}'); + let fnEnumIndex = JSON.parse(fieldDefShorthand.substring(1, closingBraceIndex + 1)); + for (let encodingProperty in fnEnumIndex) { + if (isArray(fnEnumIndex[encodingProperty])) { + fieldQ[encodingProperty] = { enum: fnEnumIndex[encodingProperty] }; + } + else { + // Definitely a `SHORT_WILDCARD` + fieldQ[encodingProperty] = fnEnumIndex[encodingProperty]; + } + } + return Object.assign({}, fieldQ, rawFieldDef(splitWithTail(fieldDefShorthand.substring(closingBraceIndex + 2, fieldDefShorthand.length - 1), ',', 2))); + } + else { + let func = fieldDefShorthand.substring(0, fieldDefShorthand.indexOf('(')); + let insideFn = fieldDefShorthand.substring(func.length + 1, fieldDefShorthand.length - 1); + let insideFnParts = splitWithTail(insideFn, ',', 2); + if (isAggregateOp(func)) { + return Object.assign({ aggregate: func }, rawFieldDef(insideFnParts)); + } + else if (isTimeUnit(func)) { + return Object.assign({ timeUnit: func }, rawFieldDef(insideFnParts)); + } + else if (func === 'bin') { + return Object.assign({ bin: {} }, rawFieldDef(insideFnParts)); + } + } + } + shorthandParser.fn = fn; +})(shorthandParser || (shorthandParser = {})); +//# sourceMappingURL=shorthand.js.map \ No newline at end of file diff --git a/build/src/query/spec.js b/build/src/query/spec.js new file mode 100644 index 00000000..9b5e2e89 --- /dev/null +++ b/build/src/query/spec.js @@ -0,0 +1,148 @@ +import { toMap } from 'datalib/src/util'; +import { stack } from 'vega-lite/build/src/stack'; +import { ALL_ENCODING_PROPS, getEncodingNestedProp, isEncodingTopLevelProperty, Property, toKey } from '../property'; +import { contains, extend, isObject, keys, some, without } from '../util'; +import { isWildcard } from '../wildcard'; +import { isDisabledAutoCountQuery, isEnabledAutoCountQuery, isFieldQuery, toEncoding } from './encoding'; +/** + * Convert a Vega-Lite's ExtendedUnitSpec into a CompassQL's SpecQuery + * @param {ExtendedUnitSpec} spec + * @returns + */ +export function fromSpec(spec) { + return extend(spec.data ? { data: spec.data } : {}, spec.transform ? { transform: spec.transform } : {}, spec.width ? { width: spec.width } : {}, spec.height ? { height: spec.height } : {}, spec.background ? { background: spec.background } : {}, spec.padding ? { padding: spec.padding } : {}, spec.title ? { title: spec.title } : {}, { + mark: spec.mark, + encodings: keys(spec.encoding).map((channel) => { + let encQ = { channel: channel }; + let channelDef = spec.encoding[channel]; + for (const prop in channelDef) { + if (isEncodingTopLevelProperty(prop) && channelDef[prop] !== undefined) { + // Currently bin, scale, axis, legend only support boolean, but not null. + // Therefore convert null to false. + if (contains(['bin', 'scale', 'axis', 'legend'], prop) && channelDef[prop] === null) { + encQ[prop] = false; + } + else { + encQ[prop] = channelDef[prop]; + } + } + } + if (isFieldQuery(encQ) && encQ.aggregate === 'count' && !encQ.field) { + encQ.field = '*'; + } + return encQ; + }) + }, spec.config ? { config: spec.config } : {}); +} +export function isAggregate(specQ) { + return some(specQ.encodings, (encQ) => { + return (isFieldQuery(encQ) && !isWildcard(encQ.aggregate) && !!encQ.aggregate) || isEnabledAutoCountQuery(encQ); + }); +} +/** + * @return The Vega-Lite `StackProperties` object that describes the stack + * configuration of `specQ`. Returns `null` if this is not stackable. + */ +export function getVlStack(specQ) { + if (!hasRequiredStackProperties(specQ)) { + return null; + } + const encoding = toEncoding(specQ.encodings, { schema: null, wildcardMode: 'null' }); + const mark = specQ.mark; + return stack(mark, encoding, undefined, { disallowNonLinearStack: true }); +} +/** + * @return The `StackOffset` specified in `specQ`, `undefined` if none + * is specified. + */ +export function getStackOffset(specQ) { + for (const encQ of specQ.encodings) { + if (encQ[Property.STACK] !== undefined && !isWildcard(encQ[Property.STACK])) { + return encQ[Property.STACK]; + } + } + return undefined; +} +/** + * @return The `Channel` in which `stack` is specified in `specQ`, or + * `null` if none is specified. + */ +export function getStackChannel(specQ) { + for (const encQ of specQ.encodings) { + if (encQ[Property.STACK] !== undefined && !isWildcard(encQ.channel)) { + return encQ.channel; + } + } + return null; +} +/** + * Returns true iff the given SpecQuery has the properties defined + * to be a potential Stack spec. + * @param specQ The SpecQuery in question. + */ +export function hasRequiredStackProperties(specQ) { + // TODO(haldenl): make this leaner, a lot of encQ properties aren't required for stack. + // TODO(haldenl): check mark, then encodings + if (isWildcard(specQ.mark)) { + return false; + } + const requiredEncodingProps = [ + Property.STACK, + Property.CHANNEL, + Property.MARK, + Property.FIELD, + Property.AGGREGATE, + Property.AUTOCOUNT, + Property.SCALE, + getEncodingNestedProp('scale', 'type'), + Property.TYPE + ]; + const exclude = toMap(without(ALL_ENCODING_PROPS, requiredEncodingProps)); + const encodings = specQ.encodings.filter(encQ => !isDisabledAutoCountQuery(encQ)); + for (const encQ of encodings) { + if (objectContainsWildcard(encQ, { exclude: exclude })) { + return false; + } + } + return true; +} +/** + * Returns true iff the given object does not contain a nested wildcard. + * @param obj The object in question. + * @param opt With optional `exclude` property, which defines properties to + * ignore when testing for wildcards. + */ +// TODO(haldenl): rename to objectHasWildcard, rename prop to obj +function objectContainsWildcard(obj, opt = {}) { + if (!isObject(obj)) { + return false; + } + for (const childProp in obj) { + if (obj.hasOwnProperty(childProp)) { + const wildcard = isWildcard(obj[childProp]); + if ((wildcard && (!opt.exclude || !opt.exclude[childProp])) || objectContainsWildcard(obj[childProp], opt)) { + return true; + } + } + } + return false; +} +/** + * Returns true iff the given `specQ` contains a wildcard. + * @param specQ The `SpecQuery` in question. + * @param opt With optional `exclude` property, which defines properties to + * ignore when testing for wildcards. + */ +export function hasWildcard(specQ, opt = {}) { + const exclude = opt.exclude ? toMap(opt.exclude.map(toKey)) : {}; + if (isWildcard(specQ.mark) && !exclude['mark']) { + return true; + } + for (const encQ of specQ.encodings) { + if (objectContainsWildcard(encQ, exclude)) { + return true; + } + } + return false; +} +//# sourceMappingURL=spec.js.map \ No newline at end of file diff --git a/build/src/query/transform.js b/build/src/query/transform.js new file mode 100644 index 00000000..2fa3e775 --- /dev/null +++ b/build/src/query/transform.js @@ -0,0 +1 @@ +//# sourceMappingURL=transform.js.map \ No newline at end of file diff --git a/build/src/ranking/aggregation.js b/build/src/ranking/aggregation.js new file mode 100644 index 00000000..c71e4648 --- /dev/null +++ b/build/src/ranking/aggregation.js @@ -0,0 +1,85 @@ +import * as TYPE from 'vega-lite/build/src/type'; +import { isDimension, isEnabledAutoCountQuery, isFieldQuery } from '../query/encoding'; +import { some } from '../util'; +export const name = 'aggregationQuality'; +export function score(specM, schema, opt) { + const feature = aggregationQualityFeature(specM, schema, opt); + return { + score: feature.score, + features: [feature] + }; +} +function aggregationQualityFeature(specM, _, __) { + const encodings = specM.getEncodings(); + if (specM.isAggregate()) { + const isRawContinuous = (encQ) => { + return (isFieldQuery(encQ) && + ((encQ.type === TYPE.QUANTITATIVE && !encQ.bin && !encQ.aggregate) || + (encQ.type === TYPE.TEMPORAL && !encQ.timeUnit))); + }; + if (some(encodings, isRawContinuous)) { + // These are plots that pollute continuous fields as dimension. + // They are often intermediate visualizations rather than what users actually want. + return { + type: name, + score: 0.1, + feature: 'Aggregate with raw continuous' + }; + } + if (some(encodings, encQ => isFieldQuery(encQ) && isDimension(encQ))) { + let hasCount = some(encodings, (encQ) => { + return (isFieldQuery(encQ) && encQ.aggregate === 'count') || isEnabledAutoCountQuery(encQ); + }); + let hasBin = some(encodings, (encQ) => { + return isFieldQuery(encQ) && !!encQ.bin; + }); + if (hasCount) { + // If there is count, we might add additional count field, making it a little less simple + // then when we just apply aggregate to Q field + return { + type: name, + score: 0.8, + feature: 'Aggregate with count' + }; + } + else if (hasBin) { + // This is not as good as binning all the Q and show heatmap + return { + type: name, + score: 0.7, + feature: 'Aggregate with bin but without count' + }; + } + else { + return { + type: name, + score: 0.9, + feature: 'Aggregate without count and without bin' + }; + } + } + // no dimension -- often not very useful + return { + type: name, + score: 0.3, + feature: 'Aggregate without dimension' + }; + } + else { + if (some(encodings, encQ => isFieldQuery(encQ) && !isDimension(encQ))) { + // raw plots with measure -- simplest of all! + return { + type: name, + score: 1, + feature: 'Raw with measure' + }; + } + // raw plots with no measure -- often a lot of occlusion + return { + type: name, + score: 0.2, + feature: 'Raw without measure' + }; + } +} +//# sourceMappingURL=aggregation.js.map \ No newline at end of file diff --git a/build/src/ranking/fieldorder.js b/build/src/ranking/fieldorder.js new file mode 100644 index 00000000..d053f7ea --- /dev/null +++ b/build/src/ranking/fieldorder.js @@ -0,0 +1,51 @@ +import { isFieldQuery } from '../query/encoding'; +export const name = 'fieldOrder'; +/** + * Return ranking score based on indices of encoded fields in the schema. + * If there are multiple fields, prioritize field on the lower indices of encodings. + * + * For example, to compare two specs with two encodings each, + * first we compare the field on the 0-th index + * and only compare the field on the 1-th index only if the fields on the 0-th index are the same. + */ +export function score(specM, schema, _) { + const fieldWildcardIndices = specM.wildcardIndex.encodingIndicesByProperty.get('field'); + if (!fieldWildcardIndices) { + return { + score: 0, + features: [] + }; + } + const encodings = specM.specQuery.encodings; + const numFields = schema.fieldSchemas.length; + const features = []; + let totalScore = 0, base = 1; + for (let i = fieldWildcardIndices.length - 1; i >= 0; i--) { + const index = fieldWildcardIndices[i]; + const encoding = encodings[index]; + // Skip ValueQuery as we only care about order of fields. + let field; + if (isFieldQuery(encoding)) { + field = encoding.field; + } + else { // ignore ValueQuery / AutoCountQuery + continue; + } + const fieldWildcard = specM.wildcardIndex.encodings[index].get('field'); + const fieldIndex = schema.fieldSchema(field).index; + // reverse order field with lower index should get higher score and come first + const score = -fieldIndex * base; + totalScore += score; + features.push({ + score: score, + type: 'fieldOrder', + feature: `field ${fieldWildcard.name} is ${field} (#${fieldIndex} in the schema)` + }); + base *= numFields; + } + return { + score: totalScore, + features: features + }; +} +//# sourceMappingURL=fieldorder.js.map \ No newline at end of file diff --git a/build/src/ranking/ranking.js b/build/src/ranking/ranking.js new file mode 100644 index 00000000..2906d762 --- /dev/null +++ b/build/src/ranking/ranking.js @@ -0,0 +1,87 @@ +import { getTopResultTreeItem } from '../result'; +import { effectiveness } from './effectiveness'; +export * from './effectiveness'; +import * as aggregation from './aggregation'; +import * as fieldOrder from './fieldorder'; +export { aggregation, fieldOrder }; +/** + * Registry for all encoding ranking functions + */ +let rankingRegistry = {}; +/** + * Add an ordering function to the registry. + */ +export function register(name, keyFn) { + rankingRegistry[name] = keyFn; +} +export function get(name) { + return rankingRegistry[name]; +} +export function rank(group, query, schema, level) { + if (!query.nest || level === query.nest.length) { + if (query.orderBy || query.chooseBy) { + group.items.sort(comparatorFactory(query.orderBy || query.chooseBy, schema, query.config)); + if (query.chooseBy) { + if (group.items.length > 0) { + // for chooseBy -- only keep the top-item + group.items.splice(1); + } + } + } + } + else { + // sort lower-level nodes first because our ranking takes top-item in the subgroup + group.items.forEach((subgroup) => { + rank(subgroup, query, schema, level + 1); + }); + if (query.nest[level].orderGroupBy) { + group.items.sort(groupComparatorFactory(query.nest[level].orderGroupBy, schema, query.config)); + } + } + return group; +} +export function comparatorFactory(name, schema, opt) { + return (m1, m2) => { + if (name instanceof Array) { + return getScoreDifference(name, m1, m2, schema, opt); + } + else { + return getScoreDifference([name], m1, m2, schema, opt); + } + }; +} +export function groupComparatorFactory(name, schema, opt) { + return (g1, g2) => { + const m1 = getTopResultTreeItem(g1); + const m2 = getTopResultTreeItem(g2); + if (name instanceof Array) { + return getScoreDifference(name, m1, m2, schema, opt); + } + else { + return getScoreDifference([name], m1, m2, schema, opt); + } + }; +} +function getScoreDifference(name, m1, m2, schema, opt) { + for (let rankingName of name) { + let scoreDifference = getScore(m2, rankingName, schema, opt).score - getScore(m1, rankingName, schema, opt).score; + if (scoreDifference !== 0) { + return scoreDifference; + } + } + return 0; +} +export function getScore(model, rankingName, schema, opt) { + if (model.getRankingScore(rankingName) !== undefined) { + return model.getRankingScore(rankingName); + } + const fn = get(rankingName); + const score = fn(model, schema, opt); + model.setRankingScore(rankingName, score); + return score; +} +export const EFFECTIVENESS = 'effectiveness'; +register(EFFECTIVENESS, effectiveness); +register(aggregation.name, aggregation.score); +register(fieldOrder.name, fieldOrder.score); +//# sourceMappingURL=ranking.js.map \ No newline at end of file