vendor/assets/javascripts/vega.js in vega-0.2.6 vs vendor/assets/javascripts/vega.js in vega-0.2.7

- old
+ new

@@ -1,93 +1,11 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vega = {})); -}(this, (function (exports) { 'use strict'; +})(this, (function (exports) { 'use strict'; - var name = "vega"; - var version$1 = "5.21.0"; - var description = "The Vega visualization grammar."; - var keywords$1 = [ - "vega", - "visualization", - "interaction", - "dataflow", - "library", - "data", - "d3" - ]; - var license = "BSD-3-Clause"; - var author = "UW Interactive Data Lab (http://idl.cs.washington.edu)"; - var main = "build/vega-node.js"; - var module = "build/vega.module.js"; - var unpkg = "build/vega.min.js"; - var jsdelivr = "build/vega.min.js"; - var types = "index.d.ts"; - var repository = "vega/vega"; - var scripts = { - bundle: "rollup -c --config-bundle", - prebuild: "rimraf build && rimraf build-es5", - build: "rollup -c --config-core --config-bundle --config-ie", - postbuild: "node schema-copy", - pretest: "yarn build --config-test", - test: "TZ=America/Los_Angeles tape 'test/**/*-test.js'", - prepublishOnly: "yarn test && yarn build", - postpublish: "./schema-deploy.sh" - }; - var dependencies = { - "vega-crossfilter": "~4.0.5", - "vega-dataflow": "~5.7.4", - "vega-encode": "~4.8.3", - "vega-event-selector": "~3.0.0", - "vega-expression": "~5.0.0", - "vega-force": "~4.0.7", - "vega-format": "~1.0.4", - "vega-functions": "~5.12.1", - "vega-geo": "~4.3.8", - "vega-hierarchy": "~4.0.9", - "vega-label": "~1.1.0", - "vega-loader": "~4.4.1", - "vega-parser": "~6.1.4", - "vega-projection": "~1.4.5", - "vega-regression": "~1.0.9", - "vega-runtime": "~6.1.3", - "vega-scale": "~7.1.1", - "vega-scenegraph": "~4.9.4", - "vega-statistics": "~1.7.10", - "vega-time": "~2.0.4", - "vega-transforms": "~4.9.4", - "vega-typings": "~0.22.0", - "vega-util": "~1.17.0", - "vega-view": "~5.10.1", - "vega-view-transforms": "~4.5.8", - "vega-voronoi": "~4.1.5", - "vega-wordcloud": "~4.1.3" - }; - var devDependencies = { - "vega-schema": "*" - }; - var gitHead = "774165e29850b66ec8b79ba52a7955f1ab936ea6"; - var pkg = { - name: name, - version: version$1, - description: description, - keywords: keywords$1, - license: license, - author: author, - main: main, - module: module, - unpkg: unpkg, - jsdelivr: jsdelivr, - types: types, - repository: repository, - scripts: scripts, - dependencies: dependencies, - devDependencies: devDependencies, - gitHead: gitHead - }; - function accessor(fn, fields, name) { fn.fields = fields || []; fn.fname = name; return fn; } @@ -209,11 +127,12 @@ const Error$1 = 1; const Warn = 2; const Info = 3; const Debug = 4; - function logger(_, method, handler = log$1$1) { + function logger(_, method) { + let handler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : log$1$1; let level = _ || None$2; return { level(_) { if (arguments.length) { level = +_; @@ -252,11 +171,15 @@ return _ === Object(_); } const isLegalKey = key => key !== '__proto__'; - function mergeConfig(...configs) { + function mergeConfig() { + for (var _len = arguments.length, configs = new Array(_len), _key = 0; _key < _len; _key++) { + configs[_key] = arguments[_key]; + } + return configs.reduce((out, source) => { for (const key in source) { if (key === 'signals') { // for signals, we merge the signals arrays // source signals take precedence over @@ -435,16 +358,16 @@ (accessorFields(f) || []).forEach(_ => fmap[_] = 1); }); return get.length === 0 ? null : accessor(gen(get, ord), Object.keys(fmap)); } - const ascending$3 = (u, v) => (u < v || u == null) && v != null ? -1 : (u > v || v == null) && u != null ? 1 : (v = v instanceof Date ? +v : v, u = u instanceof Date ? +u : u) !== u && v === v ? -1 : v !== v && u === u ? 1 : 0; + const ascending$2 = (u, v) => (u < v || u == null) && v != null ? -1 : (u > v || v == null) && u != null ? 1 : (v = v instanceof Date ? +v : v, u = u instanceof Date ? +u : u) !== u && v === v ? -1 : v !== v && u === u ? 1 : 0; const comparator = (fields, orders) => fields.length === 1 ? compare1(fields[0], orders[0]) : compareN(fields, orders, fields.length); const compare1 = (field, order) => function (a, b) { - return ascending$3(field(a), field(b)) * order; + return ascending$2(field(a), field(b)) * order; }; const compareN = (fields, orders, n) => { orders.push(0); // pad zero for convenient lookup @@ -453,11 +376,11 @@ c = 0, i = -1; while (c === 0 && ++i < n) { f = fields[i]; - c = ascending$3(f(a), f(b)); + c = ascending$2(f(a), f(b)); } return c * orders[i]; }; }; @@ -1414,51 +1337,62 @@ if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); return arcs; } - function ascending$2 (a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + function ascending$1(a, b) { + return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } - function bisector$1 (f) { + function bisector(f) { let delta = f; - let compare = f; + let compare1 = f; + let compare2 = f; - if (f.length === 1) { + if (f.length !== 2) { delta = (d, x) => f(d) - x; - compare = ascendingComparator$1(f); + compare1 = ascending$1; + + compare2 = (d, x) => ascending$1(f(d), x); } - function left(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; + function left(a, x) { + let lo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let hi = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : a.length; - while (lo < hi) { - const mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; + if (lo < hi) { + if (compare1(x, x) !== 0) return hi; + + do { + const mid = lo + hi >>> 1; + if (compare2(a[mid], x) < 0) lo = mid + 1;else hi = mid; + } while (lo < hi); } return lo; } - function right(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; + function right(a, x) { + let lo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let hi = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : a.length; - while (lo < hi) { - const mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; + if (lo < hi) { + if (compare1(x, x) !== 0) return hi; + + do { + const mid = lo + hi >>> 1; + if (compare2(a[mid], x) <= 0) lo = mid + 1;else hi = mid; + } while (lo < hi); } return lo; } - function center(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; + function center(a, x) { + let lo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let hi = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : a.length; const i = left(a, x, lo, hi - 1); return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; } return { @@ -1466,15 +1400,11 @@ center, right }; } - function ascendingComparator$1(f) { - return (d, x) => ascending$2(f(d), x); - } - - function number$6 (x) { + function number$6(x) { return x === null ? NaN : +x; } function* numbers$2(values, valueof) { if (valueof === undefined) { for (let value of values) { @@ -1491,14 +1421,14 @@ } } } } - const ascendingBisect = bisector$1(ascending$2); + const ascendingBisect = bisector(ascending$1); const bisectRight$1 = ascendingBisect.right; const bisectLeft$1 = ascendingBisect.left; - bisector$1(number$6).center; + bisector(number$6).center; var bisect$1 = bisectRight$1; function variance(values, valueof) { let count = 0; let delta; @@ -1586,18 +1516,140 @@ return hi; } } - function permute (source, keys) { + class InternMap extends Map { + constructor(entries) { + let key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : keyof; + super(); + Object.defineProperties(this, { + _intern: { + value: new Map() + }, + _key: { + value: key + } + }); + if (entries != null) for (const [key, value] of entries) this.set(key, value); + } + + get(key) { + return super.get(intern_get(this, key)); + } + + has(key) { + return super.has(intern_get(this, key)); + } + + set(key, value) { + return super.set(intern_set(this, key), value); + } + + delete(key) { + return super.delete(intern_delete(this, key)); + } + + } + class InternSet extends Set { + constructor(values) { + let key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : keyof; + super(); + Object.defineProperties(this, { + _intern: { + value: new Map() + }, + _key: { + value: key + } + }); + if (values != null) for (const value of values) this.add(value); + } + + has(value) { + return super.has(intern_get(this, value)); + } + + add(value) { + return super.add(intern_set(this, value)); + } + + delete(value) { + return super.delete(intern_delete(this, value)); + } + + } + + function intern_get(_ref, value) { + let { + _intern, + _key + } = _ref; + + const key = _key(value); + + return _intern.has(key) ? _intern.get(key) : value; + } + + function intern_set(_ref2, value) { + let { + _intern, + _key + } = _ref2; + + const key = _key(value); + + if (_intern.has(key)) return _intern.get(key); + + _intern.set(key, value); + + return value; + } + + function intern_delete(_ref3, value) { + let { + _intern, + _key + } = _ref3; + + const key = _key(value); + + if (_intern.has(key)) { + value = _intern.get(key); + + _intern.delete(key); + } + + return value; + } + + function keyof(value) { + return value !== null && typeof value === "object" ? value.valueOf() : value; + } + + function permute(source, keys) { return Array.from(keys, key => source[key]); } + function compareDefined() { + let compare = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ascending$1; + if (compare === ascending$1) return ascendingDefined; + if (typeof compare !== "function") throw new TypeError("compare is not a function"); + return (a, b) => { + const x = compare(a, b); + if (x || x === 0) return x; + return (compare(b, b) === 0) - (compare(a, a) === 0); + }; + } + function ascendingDefined(a, b) { + return (a == null || !(a >= a)) - (b == null || !(b >= b)) || (a < b ? -1 : a > b ? 1 : 0); + } + var e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2); - function ticks (start, stop, count) { + function ticks(start, stop, count) { var reverse, i = -1, n, ticks, step; @@ -1686,11 +1738,16 @@ return min; } // ISC license, Copyright 2018 Vladimir Agafonkin. - function quickselect(array, k, left = 0, right = array.length - 1, compare = ascending$2) { + function quickselect(array, k) { + let left = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let right = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length - 1; + let compare = arguments.length > 4 ? arguments[4] : undefined; + compare = compare === undefined ? ascendingDefined : compareDefined(compare); + while (right > left) { if (right - left > 600) { const n = right - left + 1; const m = k - left + 1; const z = Math.log(n); @@ -1739,11 +1796,12 @@ i0 = Math.floor(i), value0 = max$2(quickselect(values, i0).subarray(0, i0 + 1)), value1 = min$2(values.subarray(i0 + 1)); return value0 + (value1 - value0) * (i - i0); } - function quantileSorted(values, p, valueof = number$6) { + function quantileSorted(values, p) { + let valueof = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : number$6; if (!(n = values.length)) return; if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); if (p >= 1) return +valueof(values[n - 1], n - 1, values); var n, i = (n - 1) * p, @@ -1774,11 +1832,11 @@ } if (count) return sum / count; } - function median (values, valueof) { + function median(values, valueof) { return quantile$1(values, 0.5, valueof); } function* flatten(arrays) { for (const array of arrays) { @@ -1788,11 +1846,11 @@ function merge$2(arrays) { return Array.from(flatten(arrays)); } - function range$1$1 (start, stop, step) { + function range$3(start, stop, step) { start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0, range = new Array(n); @@ -1801,11 +1859,11 @@ } return range; } - function sum(values, valueof) { + function sum$1(values, valueof) { let sum = 0; if (valueof === undefined) { for (let value of values) { if (value = +value) { @@ -1823,10 +1881,50 @@ } return sum; } + function intersection(values) { + for (var _len = arguments.length, others = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + others[_key - 1] = arguments[_key]; + } + + values = new InternSet(values); + others = others.map(set$4); + + out: for (const value of values) { + for (const other of others) { + if (!other.has(value)) { + values.delete(value); + continue out; + } + } + } + + return values; + } + + function set$4(values) { + return values instanceof InternSet ? values : new InternSet(values); + } + + function union() { + const set = new InternSet(); + + for (var _len = arguments.length, others = new Array(_len), _key = 0; _key < _len; _key++) { + others[_key] = arguments[_key]; + } + + for (const other of others) { + for (const o of other) { + set.add(o); + } + } + + return set; + } + function formatDecimal (x) { return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); } // Computes the decimal coefficient and exponent of the specified number x with // significant digits p, where x is positive and p is in [1, 21] or undefined. // For example, formatDecimalParts(1.23) returns ["123", 0]. @@ -2425,11 +2523,14 @@ return reverse ? ticks.reverse() : ticks; } function tickInterval(start, stop, count) { const target = Math.abs(stop - start) / count; - const i = bisector$1(([,, step]) => step).right(tickIntervals, target); + const i = bisector(_ref => { + let [,, step] = _ref; + return step; + }).right(tickIntervals, target); if (i === tickIntervals.length) return year.every(tickStep(start / durationYear$1, stop / durationYear$1, count)); if (i === 0) return utcMillisecond.every(Math.max(tickStep(start, stop, count), 1)); const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; return t.every(step); } @@ -2461,17 +2562,17 @@ if (!u.length) error('Missing time unit.'); u.forEach(unit => { if (has$1(UNITS, unit)) { m[unit] = 1; } else { - error(`Invalid time unit: ${unit}.`); + error("Invalid time unit: ".concat(unit, ".")); } }); const numTypes = (m[WEEK] || m[DAY] ? 1 : 0) + (m[QUARTER] || m[MONTH] || m[DATE] ? 1 : 0) + (m[DAYOFYEAR] ? 1 : 0); if (numTypes > 1) { - error(`Incompatible time units: ${units}`); + error("Incompatible time units: ".concat(units)); } // ensure proper sort order u.sort((a, b) => UNITS[a] - UNITS[b]); return u; @@ -2487,13 +2588,13 @@ [DAYOFYEAR]: '%j ', [HOURS]: '%H:00', [MINUTES]: '00:%M', [SECONDS]: ':%S', [MILLISECONDS]: '.%L', - [`${YEAR}-${MONTH}`]: '%Y-%m ', - [`${YEAR}-${MONTH}-${DATE}`]: '%Y-%m-%d ', - [`${HOURS}-${MINUTES}`]: '%H:%M' + ["".concat(YEAR, "-").concat(MONTH)]: '%Y-%m ', + ["".concat(YEAR, "-").concat(MONTH, "-").concat(DATE)]: '%Y-%m-%d ', + ["".concat(HOURS, "-").concat(MINUTES)]: '%H:%M' }; function timeUnitSpecifier(units, specifiers) { const s = extend$1({}, defaultSpecifiers, specifiers), u = timeUnits(units), @@ -2752,11 +2853,11 @@ function bin$1(opt) { const ext = opt.extent, max = opt.maxbins || 40, target = Math.abs(span(ext)) / max; - let i = bisector$1(i => i[2]).right(intervals, target), + let i = bisector(i => i[2]).right(intervals, target), units, step; if (i === intervals.length) { units = Year, step = tickStep(ext[0] / durationYear, ext[1] / durationYear, max); @@ -3635,11 +3736,11 @@ function timeMultiFormat(format, interval, spec) { spec = spec || {}; if (!isObject(spec)) { - error(`Invalid time multi-format specifier: ${spec}`); + error("Invalid time multi-format specifier: ".concat(spec)); } const second = interval(SECONDS), minute = interval(MINUTES), hour = interval(HOURS), @@ -4032,16 +4133,16 @@ function read(data, schema, timeParser, utcParser) { schema = schema || {}; const reader = formats$1(schema.type || 'json'); if (!reader) error('Unknown data format type: ' + schema.type); data = reader(data, schema); - if (schema.parse) parse$5(data, schema.parse, timeParser, utcParser); + if (schema.parse) parse$6(data, schema.parse, timeParser, utcParser); if (has$1(data, 'columns')) delete data.columns; return data; } - function parse$5(data, types, timeParser, utcParser) { + function parse$6(data, types, timeParser, utcParser) { if (!data.length) return; // early exit for empty data const locale = timeFormatDefaultLocale(); timeParser = timeParser || locale.timeParse; utcParser = utcParser || locale.utcParse; @@ -4599,11 +4700,11 @@ * @param {boolean} [react=true] - A flag indicating if this operator should * automatically update (react) when parameter values change. In other words, * this flag determines if the operator registers itself as a listener on * any upstream operators included in the parameters. * @param {boolean} [initonly=false] - A flag indicating if this operator - * should calculate an update only upon its initiatal evaluation, then + * should calculate an update only upon its initial evaluation, then * deregister dependencies and suppress all future update invocations. * @return {Operator[]} - An array of upstream dependencies. */ parameters(params, react, initonly) { react = react !== false; @@ -5000,11 +5101,11 @@ } return s; } - function parse$4(data, format) { + function parse$5(data, format) { const locale = this.locale(); return read(data, format, locale.timeParse, locale.utcParse); } /** * Ingests new data into the dataflow. First parses the data using the @@ -5827,11 +5928,11 @@ } // reset pulse map df._input = {}; df._pulse = null; - df.debug(`Pulse ${stamp}: ${count} operators`); + df.debug("Pulse ".concat(stamp, ": ").concat(count, " operators")); if (error) { df._postrun = []; df.error(error); } // invoke callbacks queued via runAfter @@ -6321,11 +6422,11 @@ touch, update: update$6, changeset, // DATA LOADING ingest, - parse: parse$4, + parse: parse$5, preload, request, // EVENT HANDLING events: events$1, on, @@ -6439,11 +6540,11 @@ function quantiles(array, p, f) { const values = Float64Array.from(numbers$1(array, f)); // don't depend on return value from typed array sort call // protects against undefined sort results in Safari (vega/vega-lite#4964) - values.sort(ascending$2); + values.sort(ascending$1); return p.map(_ => quantileSorted(values, _)); } function quartiles(array, f) { return quantiles(array, [0.25, 0.50, 0.75], f); @@ -6539,11 +6640,11 @@ } mu[j] = a / n; } - mu.sort(ascending$2); + mu.sort(ascending$1); return [quantile$1(mu, alpha / 2), quantile$1(mu, 1 - alpha / 2)]; } // Dot density binning for dot plot construction. // Based on Leland Wilkinson, Dot Plots, The American Statistician, 1999. // https://www.cs.uic.edu/~wilkinson/Publications/dotplots.pdf @@ -7492,11 +7593,11 @@ return coef; } const maxiters = 2, - epsilon$5 = 1e-12; // Adapted from science.js by Jason Davies + epsilon$6 = 1e-12; // Adapted from science.js by Jason Davies // Source: https://github.com/jasondavies/science.js/blob/master/src/stats/loess.js // License: https://github.com/jasondavies/science.js/blob/master/LICENSE function loess(data, x, y, bandwidth) { const [xv, yv, ux, uy] = points(data, x, y, true), @@ -7544,17 +7645,17 @@ if (iter === maxiters) { break; } const medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon$5) break; + if (Math.abs(medianResidual) < epsilon$6) break; for (let i = 0, arg, w; i < n; ++i) { arg = residuals[i] / (6 * medianResidual); // default to epsilon (rather than zero) for large deviations // keeping weights tiny but non-zero prevents singularites - robustWeights[i] = arg >= 1 ? epsilon$5 : (w = 1 - arg * arg) * w; + robustWeights[i] = arg >= 1 ? epsilon$6 : (w = 1 - arg * arg) * w; } } return output$1(xv, yhat, ux, uy); } // weighting kernel for local regression @@ -8961,11 +9062,11 @@ * is not provided. Typically this method returns backing * source data for a Pulse object. * @return {object} - The output distribution object. */ - function parse$3(def, data) { + function parse$4(def, data) { const func = def[FUNCTION]; if (!has$1(Distributions, func)) { error('Unknown distribution function: ' + func); } @@ -8976,11 +9077,11 @@ // if data field, extract values if (name === FIELD) { d.data((def.from || data()).map(def[name])); } // if distribution mixture, recurse to parse each definition else if (name === DISTRIBUTIONS) { - d[name](def[name].map(_ => parse$3(_, data))); + d[name](def[name].map(_ => parse$4(_, data))); } // otherwise, simply set the parameter else if (typeof d[name] === FUNCTION) { d[name](def[name]); } } @@ -9128,11 +9229,11 @@ inherits(Density, Transform, { transform(_, pulse) { const out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); if (!this.value || pulse.changed() || _.modified()) { - const dist = parse$3(_.distribution, source$1(pulse)), + const dist = parse$4(_.distribution, source$1(pulse)), minsteps = _.steps || _.minsteps || 25, maxsteps = _.steps || _.maxsteps || 200; let method = _.method || 'pdf'; if (method !== 'pdf' && method !== 'cdf') { @@ -9351,12 +9452,12 @@ } }); if (!Number.isFinite(min) || !Number.isFinite(max)) { let name = accessorName(field); - if (name) name = ` for field "${name}"`; - pulse.dataflow.warn(`Infinite extent${name}: [${min}, ${max}]`); + if (name) name = " for field \"".concat(name, "\""); + pulse.dataflow.warn("Infinite extent".concat(name, ": [").concat(min, ", ").concat(max, "]")); min = max = undefined; } this.value = [min, max]; } @@ -10663,11 +10764,11 @@ if (!map[k]) { map[k] = 1; list.push(k); } }); - list.sort(ascending$3); + list.sort(ascending$2); return limit ? list.slice(0, limit) : list; } /** * Partitions pre-faceted data into tuple subflows. * @constructor @@ -10880,11 +10981,11 @@ const source = pulse.materialize(pulse.SOURCE).source, groups = partition$1$1(source, _.groupby, _.field), names = (_.groupby || []).map(accessorName), values = [], step = _.step || 0.01, - p = _.probs || range$1$1(step / 2, 1 - EPSILON$2, step), + p = _.probs || range$3(step / 2, 1 - EPSILON$2, step), n = p.length; groups.forEach(g => { const q = quantiles(g, p); for (let i = 0; i < n; ++i) { @@ -11114,11 +11215,11 @@ transform(_, pulse) { if (this.value && !_.modified()) return; const out = pulse.materialize().fork(pulse.MOD), as = _.as || 'data'; out.rem = this.value ? pulse.rem.concat(this.value) : pulse.rem; - this.value = range$1$1(_.start, _.stop, _.step || 1).map(v => { + this.value = range$3(_.start, _.stop, _.step || 1).map(v => { const t = {}; t[as] = v; return ingest$1(t); }); out.add = pulse.add.concat(this.value); @@ -11214,11 +11315,11 @@ let min = floor.start || Infinity, max = floor.stop || -Infinity, flag = pulse.ADD; - if (_.modified() || pulse.modified(accessorFields(field))) { + if (_.modified() || pulse.changed(pulse.REM) || pulse.modified(accessorFields(field))) { pulse = pulse.reflow(true); flag = pulse.SOURCE; min = Infinity; max = -Infinity; } @@ -11749,11 +11850,11 @@ range = sort && !_.ignorePeers, frame = _.frame || [null, 0], data = list.data(cmp), // use cmp for stable sort n = data.length, - b = range ? bisector$1(sort) : null, + b = range ? bisector(sort) : null, w = { i0: 0, i1: 0, p0: 0, p1: 0, @@ -11833,12 +11934,12 @@ window: Window }); const pi$3 = Math.PI, tau$3 = 2 * pi$3, - epsilon$4 = 1e-6, - tauEpsilon = tau$3 - epsilon$4; + epsilon$5 = 1e-6, + tauEpsilon = tau$3 - epsilon$5; function Path$1() { this._x0 = this._y0 = // start of current subpath this._x1 = this._y1 = null; // end of current subpath @@ -11882,14 +11983,14 @@ if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x1,y1). if (this._x1 === null) { this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); } // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. - else if (!(l01_2 > epsilon$4)) ; // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + else if (!(l01_2 > epsilon$5)) ; // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? // Equivalently, is (x1,y1) coincident with (x2,y2)? // Or, is the radius zero? Line to (x1,y1). - else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$4) || !r) { + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$5) || !r) { this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); } // Otherwise, draw an arc! else { var x20 = x2 - x0, y20 = y2 - y0, @@ -11899,11 +12000,11 @@ l01 = Math.sqrt(l01_2), l = r * Math.tan((pi$3 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), t01 = l / l01, t21 = l / l21; // If the start tangent is not coincident with (x0,y0), line to. - if (Math.abs(t01 - 1) > epsilon$4) { + if (Math.abs(t01 - 1) > epsilon$5) { this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); } this._ += "A" + r + "," + r + ",0,0," + +(y01 * x20 > x01 * y20) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); } @@ -11920,11 +12021,11 @@ if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x0,y0). if (this._x1 === null) { this._ += "M" + x0 + "," + y0; } // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). - else if (Math.abs(this._x1 - x0) > epsilon$4 || Math.abs(this._y1 - y0) > epsilon$4) { + else if (Math.abs(this._x1 - x0) > epsilon$5 || Math.abs(this._y1 - y0) > epsilon$5) { this._ += "L" + x0 + "," + y0; } // Is this arc empty? We’re done. if (!r) return; // Does the angle go the wrong way? Flip the direction. @@ -11932,11 +12033,11 @@ if (da < 0) da = da % tau$3 + tau$3; // Is this a complete circle? Draw two arcs to complete the circle. if (da > tauEpsilon) { this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); } // Is this arc non-empty? Draw an arc! - else if (da > epsilon$4) { + else if (da > epsilon$5) { this._ += "A" + r + "," + r + ",0," + +(da >= pi$3) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); } }, rect: function (x, y, w, h) { this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + +w + "v" + +h + "h" + -w + "Z"; @@ -11950,21 +12051,21 @@ return function constant() { return x; }; } - var abs$2 = Math.abs; - var atan2$1 = Math.atan2; - var cos$2 = Math.cos; - var max$1 = Math.max; - var min$1 = Math.min; - var sin$2 = Math.sin; - var sqrt$3 = Math.sqrt; - var epsilon$3 = 1e-12; - var pi$2 = Math.PI; - var halfPi$2 = pi$2 / 2; - var tau$2 = 2 * pi$2; + const abs$2 = Math.abs; + const atan2$1 = Math.atan2; + const cos$2 = Math.cos; + const max$1 = Math.max; + const min$1 = Math.min; + const sin$2 = Math.sin; + const sqrt$3 = Math.sqrt; + const epsilon$4 = 1e-12; + const pi$2 = Math.PI; + const halfPi$2 = pi$2 / 2; + const tau$2 = 2 * pi$2; function acos$1(x) { return x > 1 ? 0 : x < -1 ? pi$2 : Math.acos(x); } function asin$2(x) { return x >= 1 ? halfPi$2 : x <= -1 ? -halfPi$2 : Math.asin(x); @@ -11994,11 +12095,11 @@ var x10 = x1 - x0, y10 = y1 - y0, x32 = x3 - x2, y32 = y3 - y2, t = y32 * x10 - x32 * y10; - if (t * t < epsilon$3) return; + if (t * t < epsilon$4) return; t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t; return [x0 + t * x10, y0 + t * y10]; } // Compute perpendicular offset line of length rc. // http://mathworld.wolfram.com/Circle-LineIntersection.html @@ -12063,16 +12164,16 @@ cw = a1 > a0; if (!context) context = buffer = path$3(); // Ensure that the outer radius is always larger than the inner radius. if (r1 < r0) r = r1, r1 = r0, r0 = r; // Is it a point? - if (!(r1 > epsilon$3)) context.moveTo(0, 0); // Or is it a circle or annulus? - else if (da > tau$2 - epsilon$3) { + if (!(r1 > epsilon$4)) context.moveTo(0, 0); // Or is it a circle or annulus? + else if (da > tau$2 - epsilon$4) { context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0)); context.arc(0, 0, r1, a0, a1, !cw); - if (r0 > epsilon$3) { + if (r0 > epsilon$4) { context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1)); context.arc(0, 0, r0, a1, a0, cw); } } // Or is it a circular or annular sector? else { @@ -12081,30 +12182,30 @@ a00 = a0, a10 = a1, da0 = da, da1 = da, ap = padAngle.apply(this, arguments) / 2, - rp = ap > epsilon$3 && (padRadius ? +padRadius.apply(this, arguments) : sqrt$3(r0 * r0 + r1 * r1)), + rp = ap > epsilon$4 && (padRadius ? +padRadius.apply(this, arguments) : sqrt$3(r0 * r0 + r1 * r1)), rc = min$1(abs$2(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), rc0 = rc, rc1 = rc, t0, t1; // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. - if (rp > epsilon$3) { + if (rp > epsilon$4) { var p0 = asin$2(rp / r0 * sin$2(ap)), p1 = asin$2(rp / r1 * sin$2(ap)); - if ((da0 -= p0 * 2) > epsilon$3) p0 *= cw ? 1 : -1, a00 += p0, a10 -= p0;else da0 = 0, a00 = a10 = (a0 + a1) / 2; - if ((da1 -= p1 * 2) > epsilon$3) p1 *= cw ? 1 : -1, a01 += p1, a11 -= p1;else da1 = 0, a01 = a11 = (a0 + a1) / 2; + if ((da0 -= p0 * 2) > epsilon$4) p0 *= cw ? 1 : -1, a00 += p0, a10 -= p0;else da0 = 0, a00 = a10 = (a0 + a1) / 2; + if ((da1 -= p1 * 2) > epsilon$4) p1 *= cw ? 1 : -1, a01 += p1, a11 -= p1;else da1 = 0, a01 = a11 = (a0 + a1) / 2; } var x01 = r1 * cos$2(a01), y01 = r1 * sin$2(a01), x10 = r0 * cos$2(a10), y10 = r0 * sin$2(a10); // Apply rounded corners? - if (rc > epsilon$3) { + if (rc > epsilon$4) { var x11 = r1 * cos$2(a11), y11 = r1 * sin$2(a11), x00 = r0 * cos$2(a00), y00 = r0 * sin$2(a00), oc; // Restrict the corner radius according to the sector angle. @@ -12120,12 +12221,12 @@ rc1 = min$1(rc, (r1 - lc) / (kc + 1)); } } // Is the sector collapsed to a line? - if (!(da1 > epsilon$3)) context.moveTo(x01, y01); // Does the sector’s outer ring have rounded corners? - else if (rc1 > epsilon$3) { + if (!(da1 > epsilon$4)) context.moveTo(x01, y01); // Does the sector’s outer ring have rounded corners? + else if (rc1 > epsilon$4) { t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. @@ -12136,12 +12237,12 @@ } } // Or is the outer ring just a circular arc? else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); // Is there no inner ring, and it’s a circular sector? // Or perhaps it’s an annular sector collapsed due to padding? - if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10); // Does the sector’s inner ring (or point) have rounded corners? - else if (rc0 > epsilon$3) { + if (!(r0 > epsilon$4) || !(da0 > epsilon$4)) context.lineTo(x10, y10); // Does the sector’s inner ring (or point) have rounded corners? + else if (rc0 > epsilon$4) { t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. @@ -12230,11 +12331,11 @@ this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; - // proceed + // falls through default: this._context.lineTo(x, y); break; @@ -12406,24 +12507,25 @@ return area; } var circle$1 = { - draw: function (context, size) { - var r = Math.sqrt(size / pi$2); + draw(context, size) { + const r = sqrt$3(size / pi$2); context.moveTo(r, 0); context.arc(0, 0, r, 0, tau$2); } + }; - function symbol$2 (type, size) { - var context = null; + function Symbol$1(type, size) { + let context = null; type = typeof type === "function" ? type : constant$3(type || circle$1); size = typeof size === "function" ? size : constant$3(size === undefined ? 64 : +size); function symbol() { - var buffer; + let buffer; if (!context) context = buffer = path$3(); type.apply(this, arguments).draw(context, +size.apply(this, arguments)); if (buffer) return context = null, buffer + "" || null; } @@ -12463,11 +12565,11 @@ }, lineEnd: function () { switch (this._point) { case 3: point$5(this, this._x1, this._y1); - // proceed + // falls through case 2: this._context.lineTo(this._x1, this._y1); break; @@ -12492,11 +12594,11 @@ case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); - // proceed + // falls through default: point$5(this, x, y); break; } @@ -12624,11 +12726,11 @@ this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; case 3: this._point = 4; - // proceed + // falls through default: point$5(this, x, y); break; } @@ -12742,11 +12844,11 @@ this._x1 = x, this._y1 = y; break; case 2: this._point = 3; - // proceed + // falls through default: point$4(this, x, y); break; } @@ -12885,11 +12987,11 @@ this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; - // proceed + // falls through default: point$4(this, x, y); break; } @@ -12914,18 +13016,18 @@ var x1 = that._x1, y1 = that._y1, x2 = that._x2, y2 = that._y2; - if (that._l01_a > epsilon$3) { + if (that._l01_a > epsilon$4) { var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, n = 3 * that._l01_a * (that._l01_a + that._l12_a); x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; } - if (that._l23_a > epsilon$3) { + if (that._l23_a > epsilon$4) { var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, m = 3 * that._l23_a * (that._l23_a + that._l12_a); x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; } @@ -12983,11 +13085,11 @@ this._point = 2; break; case 2: this._point = 3; - // proceed + // falls through default: point$3(this, x, y); break; } @@ -13144,11 +13246,11 @@ this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; - // proceed + // falls through default: point$3(this, x, y); break; } @@ -13429,11 +13531,11 @@ this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; - // proceed + // falls through default: { if (this._t <= 0) { this._context.lineTo(this._x, y); @@ -13518,35 +13620,33 @@ return this; } const implicit = Symbol("implicit"); function ordinal() { - var index = new Map(), + var index = new InternMap(), domain = [], range = [], unknown = implicit; function scale(d) { - var key = d + "", - i = index.get(key); + let i = index.get(d); - if (!i) { + if (i === undefined) { if (unknown !== implicit) return unknown; - index.set(key, i = domain.push(d)); + index.set(d, i = domain.push(d) - 1); } - return range[(i - 1) % range.length]; + return range[i % range.length]; } scale.domain = function (_) { if (!arguments.length) return domain.slice(); - domain = [], index = new Map(); + domain = [], index = new InternMap(); for (const value of _) { - const key = value + ""; - if (index.has(key)) continue; - index.set(key, domain.push(value)); + if (index.has(value)) continue; + index.set(value, domain.push(value) - 1); } return scale; }; @@ -14025,27 +14125,27 @@ return hcl2lab(this).rgb(); } })); var A = -0.14861, - B = +1.78277, + B$1 = +1.78277, C$1 = -0.29227, - D = -0.90649, + D$1 = -0.90649, E = +1.97294, - ED = E * D, - EB = E * B, - BC_DA = B * C$1 - D * A; + ED = E * D$1, + EB = E * B$1, + BC_DA = B$1 * C$1 - D$1 * A; function cubehelixConvert(o) { if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); if (!(o instanceof Rgb)) o = rgbConvert(o); var r = o.r / 255, g = o.g / 255, b = o.b / 255, l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), bl = b - l, - k = (E * (g - l) - C$1 * bl) / D, + k = (E * (g - l) - C$1 * bl) / D$1, s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 h = s ? Math.atan2(k, bl) * degrees$2 - 120 : NaN; return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); } @@ -14072,11 +14172,11 @@ var h = isNaN(this.h) ? 0 : (this.h + 120) * radians$1, l = +this.l, a = isNaN(this.s) ? 0 : this.s * l * (1 - l), cosh = Math.cos(h), sinh = Math.sin(h); - return new Rgb(255 * (l + a * (A * cosh + B * sinh)), 255 * (l + a * (C$1 * cosh + D * sinh)), 255 * (l + a * (E * cosh)), this.opacity); + return new Rgb(255 * (l + a * (A * cosh + B$1 * sinh)), 255 * (l + a * (C$1 * cosh + D$1 * sinh)), 255 * (l + a * (E * cosh)), this.opacity); } })); function basis(t1, v0, v1, v2, v3) { var t2 = t1 * t1, @@ -14699,11 +14799,11 @@ var unit = [0, 1]; function identity$2(x) { return x; } - function normalize(a, b) { + function normalize$1(a, b) { return (b -= a = +a) ? function (x) { return (x - a) / b; } : constants(isNaN(b) ? NaN : 0.5); } @@ -14720,11 +14820,11 @@ function bimap(domain, range, interpolate) { var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; - if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); + if (d1 < d0) d0 = normalize$1(d1, d0), r0 = interpolate(r1, r0);else d0 = normalize$1(d0, d1), r0 = interpolate(r0, r1); return function (x) { return r0(d0(x)); }; } @@ -14738,11 +14838,11 @@ domain = domain.slice().reverse(); range = range.slice().reverse(); } while (++i < j) { - d[i] = normalize(domain[i], domain[i + 1]); + d[i] = normalize$1(domain[i], domain[i + 1]); r[i] = interpolate(range[i], range[i + 1]); } return function (x) { var i = bisect$1(domain, x, 1, j) - 1; @@ -14975,33 +15075,27 @@ function pow10(x) { return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; } function powp(base) { - return base === 10 ? pow10 : base === Math.E ? Math.exp : function (x) { - return Math.pow(base, x); - }; + return base === 10 ? pow10 : base === Math.E ? Math.exp : x => Math.pow(base, x); } function logp(base) { - return base === Math.E ? Math.log : base === 10 && Math.log10 || base === 2 && Math.log2 || (base = Math.log(base), function (x) { - return Math.log(x) / base; - }); + return base === Math.E ? Math.log : base === 10 && Math.log10 || base === 2 && Math.log2 || (base = Math.log(base), x => Math.log(x) / base); } function reflect(f) { - return function (x) { - return -f(-x); - }; + return (x, k) => -f(-x, k); } function loggish(transform) { - var scale = transform(transformLog, transformExp), - domain = scale.domain, - base = 10, - logs, - pows; + const scale = transform(transformLog, transformExp); + const domain = scale.domain; + let base = 10; + let logs; + let pows; function rescale() { logs = logp(base), pows = powp(base); if (domain()[0] < 0) { @@ -15020,36 +15114,35 @@ scale.domain = function (_) { return arguments.length ? (domain(_), rescale()) : domain(); }; - scale.ticks = function (count) { - var d = domain(), - u = d[0], - v = d[d.length - 1], - r; - if (r = v < u) i = u, u = v, v = i; - var i = logs(u), - j = logs(v), - p, - k, - t, - n = count == null ? 10 : +count, - z = []; + scale.ticks = count => { + const d = domain(); + let u = d[0]; + let v = d[d.length - 1]; + const r = v < u; + if (r) [u, v] = [v, u]; + let i = logs(u); + let j = logs(v); + let k; + let t; + const n = count == null ? 10 : +count; + let z = []; if (!(base % 1) && j - i < n) { i = Math.floor(i), j = Math.ceil(j); if (u > 0) for (; i <= j; ++i) { - for (k = 1, p = pows(i); k < base; ++k) { - t = p * k; + for (k = 1; k < base; ++k) { + t = i < 0 ? k / pows(-i) : k * pows(i); if (t < u) continue; if (t > v) break; z.push(t); } } else for (; i <= j; ++i) { - for (k = base - 1, p = pows(i); k >= 1; --k) { - t = p * k; + for (k = base - 1; k >= 1; --k) { + t = i > 0 ? k / pows(-i) : k * pows(i); if (t < u) continue; if (t > v) break; z.push(t); } } @@ -15059,43 +15152,42 @@ } return r ? z.reverse() : z; }; - scale.tickFormat = function (count, specifier) { - if (specifier == null) specifier = base === 10 ? ".0e" : ","; - if (typeof specifier !== "function") specifier = format$3(specifier); - if (count === Infinity) return specifier; + scale.tickFormat = (count, specifier) => { if (count == null) count = 10; - var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? + if (specifier == null) specifier = base === 10 ? "s" : ","; - return function (d) { - var i = d / pows(Math.round(logs(d))); + if (typeof specifier !== "function") { + if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true; + specifier = format$3(specifier); + } + + if (count === Infinity) return specifier; + const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? + + return d => { + let i = d / pows(Math.round(logs(d))); if (i * base < base - 0.5) i *= base; return i <= k ? specifier(d) : ""; }; }; - scale.nice = function () { + scale.nice = () => { return domain(nice(domain(), { - floor: function (x) { - return pows(Math.floor(logs(x))); - }, - ceil: function (x) { - return pows(Math.ceil(logs(x))); - } + floor: x => pows(Math.floor(logs(x))), + ceil: x => pows(Math.ceil(logs(x))) })); }; return scale; } function log$2() { - var scale = loggish(transformer$3()).domain([1, 10]); + const scale = loggish(transformer$3()).domain([1, 10]); - scale.copy = function () { - return copy$2(scale, log$2()).base(scale.base()); - }; + scale.copy = () => copy$2(scale, log$2()).base(scale.base()); initRange.apply(scale, arguments); return scale; } @@ -15202,11 +15294,11 @@ if (!arguments.length) return domain.slice(); domain = []; for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d); - domain.sort(ascending$2); + domain.sort(ascending$1); return rescale(); }; scale.range = function (_) { return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); @@ -15660,11 +15752,11 @@ if (round) { start = Math.round(start); bandwidth = Math.round(bandwidth); } - const values = range$1$1(n).map(i => start + step * i); + const values = range$3(n).map(i => start + step * i); return ordinalRange(reverse ? values.reverse() : values); } scale.domain = function (_) { if (arguments.length) { @@ -15895,21 +15987,21 @@ scale$4(Time, time$1, [Continuous, Temporal]); scale$4(UTC, utcTime, [Continuous, Temporal]); // sequential scales scale$4(Sequential, sequential, [Continuous, Interpolating]); // backwards compat - scale$4(`${Sequential}-${Linear}`, sequential, [Continuous, Interpolating]); - scale$4(`${Sequential}-${Log}`, sequentialLog, [Continuous, Interpolating, Log]); - scale$4(`${Sequential}-${Pow}`, sequentialPow, [Continuous, Interpolating]); - scale$4(`${Sequential}-${Sqrt}`, sequentialSqrt, [Continuous, Interpolating]); - scale$4(`${Sequential}-${Symlog}`, sequentialSymlog, [Continuous, Interpolating]); // diverging scales + scale$4("".concat(Sequential, "-").concat(Linear), sequential, [Continuous, Interpolating]); + scale$4("".concat(Sequential, "-").concat(Log), sequentialLog, [Continuous, Interpolating, Log]); + scale$4("".concat(Sequential, "-").concat(Pow), sequentialPow, [Continuous, Interpolating]); + scale$4("".concat(Sequential, "-").concat(Sqrt), sequentialSqrt, [Continuous, Interpolating]); + scale$4("".concat(Sequential, "-").concat(Symlog), sequentialSymlog, [Continuous, Interpolating]); // diverging scales - scale$4(`${Diverging}-${Linear}`, diverging, [Continuous, Interpolating]); - scale$4(`${Diverging}-${Log}`, divergingLog, [Continuous, Interpolating, Log]); - scale$4(`${Diverging}-${Pow}`, divergingPow, [Continuous, Interpolating]); - scale$4(`${Diverging}-${Sqrt}`, divergingSqrt, [Continuous, Interpolating]); - scale$4(`${Diverging}-${Symlog}`, divergingSymlog, [Continuous, Interpolating]); // discretizing scales + scale$4("".concat(Diverging, "-").concat(Linear), diverging, [Continuous, Interpolating]); + scale$4("".concat(Diverging, "-").concat(Log), divergingLog, [Continuous, Interpolating, Log]); + scale$4("".concat(Diverging, "-").concat(Pow), divergingPow, [Continuous, Interpolating]); + scale$4("".concat(Diverging, "-").concat(Sqrt), divergingSqrt, [Continuous, Interpolating]); + scale$4("".concat(Diverging, "-").concat(Symlog), divergingSymlog, [Continuous, Interpolating]); // discretizing scales scale$4(Quantile, quantile, [Discretizing, Quantile]); scale$4(Quantize, quantize$1, Discretizing); scale$4(Threshold, threshold, Discretizing); // discrete scales @@ -16108,11 +16200,11 @@ const DiscreteLegend = 'discrete'; const GradientLegend = 'gradient'; const defaultFormatter = value => isArray(value) ? value.map(v => String(v)) : String(value); - const ascending$1 = (a, b) => a[1] - b[1]; + const ascending = (a, b) => a[1] - b[1]; const descending = (a, b) => b[1] - a[1]; /** * Determine the tick count or interval function. * @param {Scale} scale - The scale for which to generate tick values. @@ -16159,11 +16251,11 @@ function validTicks(scale, ticks, count) { let range = scale.range(), lo = range[0], hi = peek$1(range), - cmp = ascending$1; + cmp = ascending; if (lo > hi) { range = hi; hi = lo; lo = range; @@ -16361,21 +16453,21 @@ fmt = format$1(locale, scale, opt.format, opt.formatType); // if scale breaks domain into bins, describe boundaries if (isDiscretizing(scale.type)) { const v = labelValues(scale).slice(1).map(fmt), n = v.length; - return `${n} boundar${n === 1 ? 'y' : 'ies'}: ${v.join(', ')}`; + return "".concat(n, " boundar").concat(n === 1 ? 'y' : 'ies', ": ").concat(v.join(', ')); } // if scale domain is discrete, list values else if (isDiscrete(scale.type)) { const d = scale.domain(), n = d.length, v = n > max ? d.slice(0, max - 2).map(fmt).join(', ') + ', ending with ' + d.slice(-1).map(fmt) : d.map(fmt).join(', '); - return `${n} value${n === 1 ? '' : 's'}: ${v}`; + return "".concat(n, " value").concat(n === 1 ? '' : 's', ": ").concat(v); } // if scale domain is continuous, describe value range else { const d = scale.domain(); - return `values from ${fmt(d[0])} to ${fmt(peek$1(d))}`; + return "values from ".concat(fmt(d[0]), " to ").concat(fmt(peek$1(d))); } } let gradient_id = 0; @@ -16523,63 +16615,87 @@ curve = curve[entry.tension](tension); } } return curve; - } // Path parsing and rendering code adapted from fabric.js -- Thanks! + } - - const cmdlen = { + const paramCounts = { m: 2, l: 2, h: 1, v: 1, + z: 0, c: 6, s: 4, q: 4, t: 2, a: 7 - }, - regexp = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\.\d+)(\.\d)/g, /(\d)([-+])/g, /\s|,|###/]; + }; + const commandPattern = /[mlhvzcsqta]([^mlhvzcsqta]+|$)/gi; + const numberPattern = /^[+-]?(([0-9]*\.[0-9]+)|([0-9]+\.)|([0-9]+))([eE][+-]?[0-9]+)?/; + const spacePattern = /^((\s+,?\s*)|(,\s*))/; + const flagPattern = /^[01]/; - function pathParse(pathstr) { - const result = []; - let curr, chunks, parsed, param, cmd, len, i, j, n, m; // First, break path into command sequence + function parse$3(path) { + const commands = []; + const matches = path.match(commandPattern) || []; + matches.forEach(str => { + let cmd = str[0]; + const type = cmd.toLowerCase(); // parse parameters - const path = pathstr.slice().replace(regexp[0], '###$1').split(regexp[1]).slice(1); // Next, parse each command in turn + const paramCount = paramCounts[type]; + const params = parseParams(type, paramCount, str.slice(1).trim()); + const count = params.length; // error checking based on parameter count - for (i = 0, n = path.length; i < n; ++i) { - curr = path[i]; - chunks = curr.slice(1).trim().replace(regexp[2], '$1###$2').replace(regexp[3], '$1###$2').split(regexp[4]); - cmd = curr.charAt(0); - parsed = [cmd]; + if (count < paramCount || count && count % paramCount !== 0) { + throw Error('Invalid SVG path, incorrect parameter count'); + } // register the command - for (j = 0, m = chunks.length; j < m; ++j) { - if ((param = +chunks[j]) === param) { - // not NaN - parsed.push(param); - } + + commands.push([cmd, ...params.slice(0, paramCount)]); // exit now if we're done, also handles zero-param 'z' + + if (count === paramCount) { + return; + } // handle implicit line-to + + + if (type === 'm') { + cmd = cmd === 'M' ? 'L' : 'l'; + } // repeat command when given extended param list + + + for (let i = paramCount; i < count; i += paramCount) { + commands.push([cmd, ...params.slice(i, i + paramCount)]); } + }); + return commands; + } - len = cmdlen[cmd.toLowerCase()]; + function parseParams(type, paramCount, segment) { + const params = []; - if (parsed.length - 1 > len) { - const m = parsed.length; - j = 1; - result.push([cmd].concat(parsed.slice(j, j += len))); // handle implicit lineTo (#2803) + for (let index = 0; paramCount && index < segment.length;) { + for (let i = 0; i < paramCount; ++i) { + const pattern = type === 'a' && (i === 3 || i === 4) ? flagPattern : numberPattern; + const match = segment.slice(index).match(pattern); - cmd = cmd === 'M' ? 'L' : cmd === 'm' ? 'l' : cmd; + if (match === null) { + throw Error('Invalid SVG path, incorrect parameter type'); + } - for (; j < m; j += len) { - result.push([cmd].concat(parsed.slice(j, j + len))); + index += match[0].length; + params.push(+match[0]); + const ws = segment.slice(index).match(spacePattern); + + if (ws !== null) { + index += ws[0].length; } - } else { - result.push(parsed); } } - return result; + return params; } const DegToRad = Math.PI / 180; const Epsilon = 1e-14; const HalfPi = Math.PI / 2; @@ -16722,11 +16838,13 @@ controlY = 0, // current control point y tempX, tempY, tempControlX, - tempControlY; + tempControlY, + anchorX = 0, + anchorY = 0; if (l == null) l = 0; if (t == null) t = 0; if (sX == null) sX = 1; if (sY == null) sY = sX; if (context.beginPath) context.beginPath(); @@ -16780,17 +16898,21 @@ case 'm': // moveTo, relative x += current[1]; y += current[2]; + anchorX = x; + anchorY = y; context.moveTo(x + l, y + t); break; case 'M': // moveTo, absolute x = current[1]; y = current[2]; + anchorX = x; + anchorY = y; context.moveTo(x + l, y + t); break; case 'c': // bezierCurveTo, relative @@ -16929,10 +17051,12 @@ y = current[7]; break; case 'z': case 'Z': + x = anchorX; + y = anchorY; context.closePath(); break; } previous = current; @@ -17094,11 +17218,11 @@ var custom = {}; function customSymbol(path) { if (!has$1(custom, path)) { - const parsed = pathParse(path); + const parsed = parse$3(path); custom[path] = { draw: function (context, size) { pathRender(context, parsed, 0, 0, Math.sqrt(size) / 2); } }; @@ -17387,11 +17511,11 @@ const arcShape = arc$2$1().startAngle(sa).endAngle(ea).padAngle(pa).innerRadius(ir).outerRadius(or).cornerRadius(cr), areavShape = area$2$1().x(x$2).y1(y$2).y0(yh).defined(def), areahShape = area$2$1().y(y$2).x1(x$2).x0(xw).defined(def), lineShape = line$2$1().x(x$2).y(y$2).defined(def), rectShape = vg_rect().x(x$2).y(y$2).width(w).height(h).cornerRadius(tl, tr, br, bl), - symbolShape = symbol$2().type(type).size(sz), + symbolShape = Symbol$1().type(type).size(sz), trailShape = vg_trail().x(x$2).y(y$2).defined(def).size(ts); function hasCornerRadius(item) { return item.cornerRadius || item.cornerRadiusTopLeft || item.cornerRadiusTopRight || item.cornerRadiusBottomRight || item.cornerRadiusBottomLeft; } @@ -18710,11 +18834,11 @@ sy = item.scaleY || 1, a = (item.angle || 0) * DegToRad, cache = item.pathCache; if (!cache || cache.path !== path) { - (item.pathCache = cache = pathParse(path)).path = path; + (item.pathCache = cache = parse$3(path)).path = path; } if (a && context.rotate && context.translate) { context.translate(x, y); context.rotate(a); @@ -18851,11 +18975,11 @@ function measureWidth(item, text) { return fontSize(item) <= 0 || !(text = textValue(item, text)) ? 0 : _measureWidth(text, font(item)); } function _measureWidth(text, currentFont) { - const key = `(${currentFont}) ${text}`; + const key = "(".concat(currentFont, ") ").concat(text); let width = widthCache.get(key); if (width === undefined) { context$2.font = currentFont; width = context$2.measureText(text).width; @@ -20228,15 +20352,15 @@ desc: 'legend', caption: legendCaption }, 'title-text': { desc: 'title', - caption: item => `Title text '${titleCaption(item)}'` + caption: item => "Title text '".concat(titleCaption(item), "'") }, 'title-subtitle': { desc: 'subtitle', - caption: item => `Subtitle text '${titleCaption(item)}'` + caption: item => "Subtitle text '".concat(titleCaption(item), "'") } }; // aria properties generated for mark item encoding channels const AriaEncode = { ariaRole: ARIA_ROLE, @@ -20254,11 +20378,11 @@ } } else { const type = item.mark.marktype; emit(ARIA_LABEL, item.description); emit(ARIA_ROLE, item.ariaRole || (type === 'group' ? GRAPHICS_OBJECT : GRAPHICS_SYMBOL)); - emit(ARIA_ROLEDESCRIPTION, item.ariaRoleDescription || `${type} mark`); + emit(ARIA_ROLEDESCRIPTION, item.ariaRoleDescription || "".concat(type, " mark")); } } function ariaMarkAttributes(mark) { return mark.aria === false ? { @@ -20267,11 +20391,11 @@ } function ariaMark(mark) { const type = mark.marktype; const recurse = type === 'group' || type === 'text' || mark.items.some(_ => _.description != null && _.aria !== false); - return bundle(recurse ? GRAPHICS_OBJECT : GRAPHICS_SYMBOL, `${type} mark container`, mark.description); + return bundle(recurse ? GRAPHICS_OBJECT : GRAPHICS_SYMBOL, "".concat(type, " mark container"), mark.description); } function ariaGuide(mark, opt) { try { const item = mark.items[0], @@ -20294,23 +20418,23 @@ ctx = item.context, scale = ctx.scales[datum.scale].value, locale = ctx.dataflow.locale(), type = scale.type, xy = orient === 'left' || orient === 'right' ? 'Y' : 'X'; - return `${xy}-axis` + (title ? ` titled '${title}'` : '') + ` for a ${isDiscrete(type) ? 'discrete' : type} scale` + ` with ${domainCaption(locale, scale, item)}`; + return "".concat(xy, "-axis") + (title ? " titled '".concat(title, "'") : '') + " for a ".concat(isDiscrete(type) ? 'discrete' : type, " scale") + " with ".concat(domainCaption(locale, scale, item)); } function legendCaption(item) { const datum = item.datum, title = datum.title ? extractTitle(item) : null, - type = `${datum.type || ''} legend`.trim(), + type = "".concat(datum.type || '', " legend").trim(), scales = datum.scales, props = Object.keys(scales), ctx = item.context, scale = ctx.scales[scales[props[0]]].value, locale = ctx.dataflow.locale(); - return capitalize(type) + (title ? ` titled '${title}'` : '') + ` for ${channelCaption(props)}` + ` with ${domainCaption(locale, scale, item)}`; + return capitalize(type) + (title ? " titled '".concat(title, "'") : '') + " for ".concat(channelCaption(props)) + " with ".concat(domainCaption(locale, scale, item)); } function extractTitle(item) { try { return array$5(peek$1(item.items).items[0].text).join(' '); @@ -20339,25 +20463,29 @@ const stack = [], clear = () => outer = inner = '', push = tag => { if (outer) { - buf += `${outer}>${inner}`; + buf += "".concat(outer, ">").concat(inner); clear(); } stack.push(tag); }, attr = (name, value) => { - if (value != null) outer += ` ${name}="${attrText(value)}"`; + if (value != null) outer += " ".concat(name, "=\"").concat(attrText(value), "\""); return m; }, m = { - open(tag, ...attrs) { + open(tag) { push(tag); outer = '<' + tag; + for (var _len = arguments.length, attrs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + attrs[_key - 1] = arguments[_key]; + } + for (const set of attrs) { for (const key in set) attr(key, set[key]); } return m; @@ -20365,13 +20493,13 @@ close() { const tag = stack.pop(); if (outer) { - buf += outer + (inner ? `>${inner}</${tag}>` : '/>'); + buf += outer + (inner ? ">".concat(inner, "</").concat(tag, ">") : '/>'); } else { - buf += `</${tag}>`; + buf += "</".concat(tag, ">"); } clear(); return m; }, @@ -20408,22 +20536,24 @@ } return m.close(); } - const styles = { + const stylesAttr = { fill: 'fill', fillOpacity: 'fill-opacity', stroke: 'stroke', strokeOpacity: 'stroke-opacity', strokeWidth: 'stroke-width', strokeCap: 'stroke-linecap', strokeJoin: 'stroke-linejoin', strokeDash: 'stroke-dasharray', strokeDashOffset: 'stroke-dashoffset', strokeMiterLimit: 'stroke-miterlimit', - opacity: 'opacity', + opacity: 'opacity' + }; + const stylesCss = { blend: 'mix-blend-mode' }; // ensure miter limit default is consistent with canvas (#2498) const rootAttributes = { 'fill': 'none', @@ -20511,14 +20641,14 @@ if (this._svg) { setAttributes(this._svg, { width: this._width * this._scale, height: this._height * this._scale, - viewBox: `0 0 ${this._width} ${this._height}` + viewBox: "0 0 ".concat(this._width, " ").concat(this._height) }); - this._root.setAttribute('transform', `translate(${this._origin})`); + this._root.setAttribute('transform', "translate(".concat(this._origin, ")")); } this._dirty = []; return this; }, @@ -20597,11 +20727,11 @@ /** * Check if a mark item is considered dirty. * @param {Item} item - The mark item. */ isDirty(item) { - return this._dirtyAll || !item._svg || item.dirty === this._dirtyID; + return this._dirtyAll || !item._svg || !item._svg.ownerSVGElement || item.dirty === this._dirtyID; }, /** * Internal method to check dirty status and, if possible, * make targetted updates without a full rendering pass. @@ -20674,17 +20804,18 @@ * @param {SVGElement} el - The parent element in the SVG tree. * @param {object} scene - The mark parent to render. * @param {SVGElement} prev - The previous sibling in the SVG tree. */ mark(el, scene, prev) { - if (!this.isDirty(scene)) return scene._svg; + if (!this.isDirty(scene)) { + return scene._svg; + } + const svg = this._svg, mdef = Marks[scene.marktype], events = scene.interactive === false ? 'none' : null, isGroup = mdef.tag === 'g'; - let sibling = null, - i = 0; const parent = bind$1(scene, el, prev, 'g', svg); parent.setAttribute('class', cssClass(scene)); // apply aria attributes to parent container element const aria = ariaMarkAttributes(scene); @@ -20693,10 +20824,12 @@ if (!isGroup) { setAttribute(parent, 'pointer-events', events); } setAttribute(parent, 'clip-path', scene.clip ? clip$1$1(this, scene, scene.group) : null); + let sibling = null, + i = 0; const process = item => { const dirty = this.isDirty(item), node = bind$1(item, parent, sibling, mdef.tag, svg); @@ -20749,14 +20882,14 @@ * @param {Item} item - The mark item. */ style(el, item) { if (item == null) return; - for (const prop in styles) { + for (const prop in stylesAttr) { let value = prop === 'font' ? fontFamily(item) : item[prop]; if (value === values[prop]) continue; - const name = styles[prop]; + const name = stylesAttr[prop]; if (value == null) { el.removeAttribute(name); } else { if (isGradient(value)) { @@ -20766,10 +20899,14 @@ el.setAttribute(name, value + ''); } values[prop] = value; } + + for (const prop in stylesCss) { + setStyle(el, stylesCss[prop], item[prop]); + } }, /** * Render SVG defs, as needed. * Must be called *after* marks have been processed to ensure the @@ -20837,11 +20974,11 @@ }); pt = domChild(pt, 0, 'rect', svgns); setAttributes(pt, { width: 1, height: 1, - fill: `url(${href()}#${grad.id})` + fill: "url(".concat(href(), "#").concat(grad.id, ")") }); el = domChild(el, index++, 'radialGradient', svgns); setAttributes(el, { id: grad.id, fx: grad.x1, @@ -20895,10 +21032,12 @@ return index + 1; } // Recursively process group contents. function recurse(renderer, el, group) { + // child 'g' element is second to last among children (path, g, path) + // other children here are foreground and background path elements el = el.lastChild.previousSibling; let prev, idx = 0; visit(group, item => { prev = renderer.mark(el, item, prev); @@ -21139,11 +21278,11 @@ m.open('svg', extend$1({}, metadata, { class: 'marks', width: this._width * this._scale, height: this._height * this._scale, - viewBox: `0 0 ${this._width} ${this._height}` + viewBox: "0 0 ".concat(this._width, " ").concat(this._height) })); // background, if defined const bg = this._bgcolor; if (bg && bg !== 'transparent' && bg !== 'none') { @@ -21391,10 +21530,11 @@ } }); // Helper function for attr for style presentation attributes function style(s, item, scene, tag, defs) { + let styleList; if (item == null) return s; if (tag === 'bgrect' && scene.interactive === false) { s['pointer-events'] = 'none'; } @@ -21407,33 +21547,46 @@ s.display = 'none'; if (item.fill !== null) return s; } if (tag === 'image' && item.smooth === false) { - s.style = 'image-rendering: optimizeSpeed; image-rendering: pixelated;'; + styleList = ['image-rendering: optimizeSpeed;', 'image-rendering: pixelated;']; } if (tag === 'text') { s['font-family'] = fontFamily(item); s['font-size'] = fontSize(item) + 'px'; s['font-style'] = item.fontStyle; s['font-variant'] = item.fontVariant; s['font-weight'] = item.fontWeight; } - for (const prop in styles) { + for (const prop in stylesAttr) { let value = item[prop]; - const name = styles[prop]; + const name = stylesAttr[prop]; if (value === 'transparent' && (name === 'fill' || name === 'stroke')) ;else if (value != null) { if (isGradient(value)) { value = gradientRef(value, defs.gradient, ''); } s[name] = value; } } + for (const prop in stylesCss) { + const value = item[prop]; + + if (value != null) { + styleList = styleList || []; + styleList.push("".concat(stylesCss[prop], ": ").concat(value, ";")); + } + } + + if (styleList) { + s.style = styleList.join(' '); + } + return s; } const Canvas = 'canvas'; const PNG = 'png'; @@ -21559,11 +21712,11 @@ function sceneEqual(a, b, key) { return a === b ? true : key === 'path' ? pathEqual(a, b) : a instanceof Date && b instanceof Date ? +a === +b : isNumber$1(a) && isNumber$1(b) ? Math.abs(a - b) <= TOLERANCE : !a || !b || !isObject(a) && !isObject(b) ? a == b : objectEqual(a, b); } function pathEqual(a, b) { - return sceneEqual(pathParse(a), pathParse(b)); + return sceneEqual(parse$3(a), parse$3(b)); } function objectEqual(a, b) { var ka = Object.keys(a), kb = Object.keys(b), @@ -23334,11 +23487,11 @@ if (ellipsis) { ellipsis = values[items.length]; items.push(ingest$1({ index: items.length, - label: `\u2026${values.length - items.length} entries`, + label: "\u2026".concat(values.length - items.length, " entries"), value: ellipsis, offset: offset, size: size(ellipsis, _) })); } @@ -23579,12 +23732,12 @@ stop = _.endAngle != null ? _.endAngle : 2 * Math.PI, data = pulse.source, values = data.map(field), n = values.length, a = start, - k = (stop - start) / sum(values), - index = range$1$1(n), + k = (stop - start) / sum$1(values), + index = range$3(n), i, t, v; if (_.sort) { @@ -23766,11 +23919,11 @@ let start = bins.start == null ? lo : bins.start, stop = bins.stop == null ? hi : bins.stop; if (!step) error('Scale bins parameter missing step property.'); if (start < lo) start = step * Math.ceil(lo / step); if (stop > hi) stop = step * Math.floor(hi / step); - bins = range$1$1(start, stop + step / 2, step); + bins = range$3(start, stop + step / 2, step); } if (bins) { // assign bin boundaries to scale instance scale.bins = bins; @@ -23808,11 +23961,11 @@ if (isFunction(range)) { if (scale.interpolator) { return scale.interpolator(range); } else { - error(`Scale type ${type} does not support interpolating color schemes.`); + error("Scale type ".concat(type, " does not support interpolating color schemes.")); } } } // given a range array for an interpolating scale, convert to interpolator @@ -23851,11 +24004,11 @@ if (isArray(_.scheme)) { scheme$1 = interpolateColors(_.scheme, _.interpolate, _.interpolateGamma); } else { name = _.scheme.toLowerCase(); scheme$1 = scheme(name); - if (!scheme$1) error(`Unrecognized scheme name: ${_.scheme}`); + if (!scheme$1) error("Unrecognized scheme name: ".concat(_.scheme)); } // determine size for potential discrete range count = type === Threshold ? count + 1 : type === BinOrdinal ? count - 1 : type === Quantile || type === Quantize ? +_.schemeCount || DEFAULT_COUNT : count; // adjust and/or quantize scheme as appropriate @@ -24070,11 +24223,11 @@ scale: Scale$1, sortitems: SortItems$1, stack: Stack }); - var epsilon$2 = 1e-6; + var epsilon$3 = 1e-6; var epsilon2 = 1e-12; var pi$1 = Math.PI; var halfPi$1 = pi$1 / 2; var quarterPi = pi$1 / 4; var tau$1 = pi$1 * 2; @@ -24310,11 +24463,11 @@ polygonEnd: function () { areaStream$1.polygonEnd(); boundsStream$2.point = boundsPoint$1; boundsStream$2.lineStart = boundsLineStart; boundsStream$2.lineEnd = boundsLineEnd; - if (areaRingSum$1 < 0) lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90);else if (deltaSum > epsilon$2) phi1 = 90;else if (deltaSum < -epsilon$2) phi0 = -90; + if (areaRingSum$1 < 0) lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90);else if (deltaSum > epsilon$3) phi1 = 90;else if (deltaSum < -epsilon$3) phi0 = -90; range$2[0] = lambda0, range$2[1] = lambda1; }, sphere: function () { lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90); } @@ -24406,11 +24559,11 @@ } function boundsRingEnd() { boundsRingPoint(lambda00$1, phi00$1); areaStream$1.lineEnd(); - if (abs$1(deltaSum) > epsilon$2) lambda0 = -(lambda1 = 180); + if (abs$1(deltaSum) > epsilon$3) lambda0 = -(lambda1 = 180); range$2[0] = lambda0, range$2[1] = lambda1; p0 = null; } // Finds the left-right distance between two longitudes. // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want // the distance between ±180° to be 360°. @@ -24581,11 +24734,11 @@ m = hypot(x, y, z); // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. if (m < epsilon2) { x = X1$1, y = Y1$1, z = Z1$1; // If the feature has zero length, fall back to arithmetic mean of point vectors. - if (W1 < epsilon$2) x = X0$1, y = Y0$1, z = Z0$1; + if (W1 < epsilon$3) x = X0$1, y = Y0$1, z = Z0$1; m = hypot(x, y, z); // If the feature still has an undefined ccentroid, then return. if (m < epsilon2) return [NaN, NaN]; } @@ -24690,11 +24843,11 @@ function circleRadius(cosRadius, point) { point = cartesian(point), point[0] -= cosRadius; cartesianNormalizeInPlace(point); var radius = acos(-point[1]); - return ((-point[2] < 0 ? -radius : radius) + tau$1 - epsilon$2) % tau$1; + return ((-point[2] < 0 ? -radius : radius) + tau$1 - epsilon$3) % tau$1; } function clipBuffer () { var lines = [], line; @@ -24717,11 +24870,11 @@ } }; } function pointEqual (a, b) { - return abs$1(a[0] - b[0]) < epsilon$2 && abs$1(a[1] - b[1]) < epsilon$2; + return abs$1(a[0] - b[0]) < epsilon$3 && abs$1(a[1] - b[1]) < epsilon$3; } function Intersection(point, points, other, entry) { this.x = point; this.z = points; @@ -24758,11 +24911,11 @@ stream.lineEnd(); return; } // handle degenerate cases by moving the point - p1[0] += 2 * epsilon$2; + p1[0] += 2 * epsilon$3; } subject.push(x = new Intersection(p0, segment, null, true)); clip.push(x.o = new Intersection(p0, null, x, false)); subject.push(x = new Intersection(p1, segment, null, false)); @@ -24839,22 +24992,22 @@ a.n = b = array[0]; b.p = a; } function longitude(point) { - if (abs$1(point[0]) <= pi$1) return point[0];else return sign(point[0]) * ((abs$1(point[0]) + pi$1) % tau$1 - pi$1); + return abs$1(point[0]) <= pi$1 ? point[0] : sign(point[0]) * ((abs$1(point[0]) + pi$1) % tau$1 - pi$1); } function polygonContains (polygon, point) { var lambda = longitude(point), phi = point[1], sinPhi = sin$1(phi), normal = [sin$1(lambda), -cos$1(lambda), 0], angle = 0, winding = 0; var sum = new Adder(); - if (sinPhi === 1) phi = halfPi$1 + epsilon$2;else if (sinPhi === -1) phi = -halfPi$1 - epsilon$2; + if (sinPhi === 1) phi = halfPi$1 + epsilon$3;else if (sinPhi === -1) phi = -halfPi$1 - epsilon$3; for (var i = 0, n = polygon.length; i < n; ++i) { if (!(m = (ring = polygon[i]).length)) continue; var ring, m, @@ -24901,11 +25054,11 @@ // Second, count the (signed) number of times a segment crosses a lambda // from the point to the South pole. If it is zero, then the point is the // same side as the South pole. - return (angle < -epsilon$2 || angle < epsilon$2 && sum < -epsilon2) ^ winding & 1; + return (angle < -epsilon$3 || angle < epsilon$3 && sum < -epsilon2) ^ winding & 1; } function clip$1 (pointVisible, clipLine, interpolate, start) { return function (sink) { var line = clipLine(sink), @@ -25028,11 +25181,11 @@ } // Intersections are sorted along the clip edge. For both antimeridian cutting // and circle clipping, the same comparison is used. function compareIntersection(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfPi$1 - epsilon$2 : halfPi$1 - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfPi$1 - epsilon$2 : halfPi$1 - b[1]); + return ((a = a.x)[0] < 0 ? a[1] - halfPi$1 - epsilon$3 : halfPi$1 - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfPi$1 - epsilon$3 : halfPi$1 - b[1]); } var clipAntimeridian = clip$1(function () { return true; }, clipAntimeridianLine, clipAntimeridianInterpolate, [-pi$1, -halfPi$1]); // Takes a line and cuts into visible segments. Return values: 0 - there were @@ -25052,24 +25205,24 @@ }, point: function (lambda1, phi1) { var sign1 = lambda1 > 0 ? pi$1 : -pi$1, delta = abs$1(lambda1 - lambda0); - if (abs$1(delta - pi$1) < epsilon$2) { + if (abs$1(delta - pi$1) < epsilon$3) { // line crosses a pole stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$1 : -halfPi$1); stream.point(sign0, phi0); stream.lineEnd(); stream.lineStart(); stream.point(sign1, phi0); stream.point(lambda1, phi0); clean = 0; } else if (sign0 !== sign1 && delta >= pi$1) { // line crosses antimeridian - if (abs$1(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies + if (abs$1(lambda0 - sign0) < epsilon$3) lambda0 -= sign0 * epsilon$3; // handle degeneracies - if (abs$1(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2; + if (abs$1(lambda1 - sign1) < epsilon$3) lambda1 -= sign1 * epsilon$3; phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); stream.point(sign0, phi0); stream.lineEnd(); stream.lineStart(); stream.point(sign1, phi0); @@ -25091,11 +25244,11 @@ function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { var cosPhi0, cosPhi1, sinLambda0Lambda1 = sin$1(lambda0 - lambda1); - return abs$1(sinLambda0Lambda1) > epsilon$2 ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) : (phi0 + phi1) / 2; + return abs$1(sinLambda0Lambda1) > epsilon$3 ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) : (phi0 + phi1) / 2; } function clipAntimeridianInterpolate(from, to, direction, stream) { var phi; @@ -25108,11 +25261,11 @@ stream.point(pi$1, -phi); stream.point(0, -phi); stream.point(-pi$1, -phi); stream.point(-pi$1, 0); stream.point(-pi$1, phi); - } else if (abs$1(from[0] - to[0]) > epsilon$2) { + } else if (abs$1(from[0] - to[0]) > epsilon$3) { var lambda = from[0] < to[0] ? pi$1 : -pi$1; phi = direction * lambda / 2; stream.point(-lambda, phi); stream.point(0, phi); stream.point(lambda, phi); @@ -25123,11 +25276,11 @@ function clipCircle (radius) { var cr = cos$1(radius), delta = 6 * radians, smallRadius = cr > 0, - notHemisphere = abs$1(cr) > epsilon$2; // TODO optimise for this common case + notHemisphere = abs$1(cr) > epsilon$3; // TODO optimise for this common case function interpolate(from, to, direction, stream) { circleStream(stream, radius, delta, direction, from, to); } @@ -25256,15 +25409,15 @@ phi0 = a[1], phi1 = b[1], z; if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; var delta = lambda1 - lambda0, - polar = abs$1(delta - pi$1) < epsilon$2, - meridian = polar || delta < epsilon$2; + polar = abs$1(delta - pi$1) < epsilon$3, + meridian = polar || delta < epsilon$3; if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; // Check that the first point is between a and b. - if (meridian ? polar ? phi0 + phi1 > 0 ^ q[1] < (abs$1(q[0] - lambda0) < epsilon$2 ? phi0 : phi1) : phi0 <= q[1] && q[1] <= phi1 : delta > pi$1 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { + if (meridian ? polar ? phi0 + phi1 > 0 ^ q[1] < (abs$1(q[0] - lambda0) < epsilon$3 ? phi0 : phi1) : phi0 <= q[1] && q[1] <= phi1 : delta > pi$1 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { var q1 = cartesianScale(u, (-w + t) / uu); cartesianAddInPlace(q1, A); return [q, spherical(q1)]; } } // Generates a 4-bit vector representing the location of a point relative to @@ -25368,11 +25521,11 @@ stream.point(to[0], to[1]); } } function corner(p, direction) { - return abs$1(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3 : abs$1(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1 : abs$1(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon + return abs$1(p[0] - x0) < epsilon$3 ? direction > 0 ? 0 : 3 : abs$1(p[0] - x1) < epsilon$3 ? direction > 0 ? 2 : 1 : abs$1(p[1] - y0) < epsilon$3 ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon } function compareIntersection(a, b) { return comparePoint(a.x, b.x); } @@ -25520,20 +25673,20 @@ return clipStream; }; } function graticuleX(y0, y1, dy) { - var y = range$1$1(y0, y1 - epsilon$2, dy).concat(y1); + var y = range$3(y0, y1 - epsilon$3, dy).concat(y1); return function (x) { return y.map(function (y) { return [x, y]; }); }; } function graticuleY(x0, x1, dx) { - var x = range$1$1(x0, x1 - epsilon$2, dx).concat(x1); + var x = range$3(x0, x1 - epsilon$3, dx).concat(x1); return function (y) { return x.map(function (x) { return [x, y]; }); }; @@ -25564,14 +25717,14 @@ coordinates: lines() }; } function lines() { - return range$1$1(ceil(X0 / DX) * DX, X1, DX).map(X).concat(range$1$1(ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(range$1$1(ceil(x0 / dx) * dx, x1, dx).filter(function (x) { - return abs$1(x % DX) > epsilon$2; - }).map(x)).concat(range$1$1(ceil(y0 / dy) * dy, y1, dy).filter(function (y) { - return abs$1(y % DY) > epsilon$2; + return range$3(ceil(X0 / DX) * DX, X1, DX).map(X).concat(range$3(ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(range$3(ceil(x0 / dx) * dx, x1, dx).filter(function (x) { + return abs$1(x % DX) > epsilon$3; + }).map(x)).concat(range$3(ceil(y0 / dy) * dy, y1, dy).filter(function (y) { + return abs$1(y % DY) > epsilon$3; }).map(y)); } graticule.lines = function () { return lines().map(function (coordinates) { @@ -25637,11 +25790,11 @@ X = graticuleX(Y0, Y1, 90); Y = graticuleY(X0, X1, precision); return graticule; }; - return graticule.extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]]).extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]); + return graticule.extentMajor([[-180, -90 + epsilon$3], [180, 90 - epsilon$3]]).extentMinor([[-180, -80 - epsilon$3], [180, 80 + epsilon$3]]); } var identity = (x => x); var areaSum = new Adder(), @@ -26123,11 +26276,11 @@ var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = sqrt$1(a * a + b * b + c * c), phi2 = asin$1(c /= m), - lambda2 = abs$1(abs$1(c) - 1) < epsilon$2 || abs$1(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a), + lambda2 = abs$1(abs$1(c) - 1) < epsilon$3 || abs$1(lambda0 - lambda1) < epsilon$3 ? (lambda0 + lambda1) / 2 : atan2(b, a), p = project(lambda2, phi2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, @@ -26430,11 +26583,11 @@ function conicEqualAreaRaw(y0, y1) { var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2; // Are the parallels symmetrical around the Equator? - if (abs$1(n) < epsilon$2) return cylindricalEqualAreaRaw(y0); + if (abs$1(n) < epsilon$3) return cylindricalEqualAreaRaw(y0); var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt$1(c) / n; function project(x, y) { var r = sqrt$1(c - 2 * n * sin$1(y)) / n; @@ -26553,12 +26706,12 @@ if (!arguments.length) return lower48.translate(); var k = lower48.scale(), x = +_[0], y = +_[1]; lower48Point = lower48.translate(_).clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]).stream(pointStream); - alaskaPoint = alaska.translate([x - 0.307 * k, y + 0.201 * k]).clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]]).stream(pointStream); - hawaiiPoint = hawaii.translate([x - 0.205 * k, y + 0.212 * k]).clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]]).stream(pointStream); + alaskaPoint = alaska.translate([x - 0.307 * k, y + 0.201 * k]).clipExtent([[x - 0.425 * k + epsilon$3, y + 0.120 * k + epsilon$3], [x - 0.214 * k - epsilon$3, y + 0.234 * k - epsilon$3]]).stream(pointStream); + hawaiiPoint = hawaii.translate([x - 0.205 * k, y + 0.212 * k]).clipExtent([[x - 0.214 * k + epsilon$3, y + 0.166 * k + epsilon$3], [x - 0.115 * k - epsilon$3, y + 0.234 * k - epsilon$3]]).stream(pointStream); return reset(); }; albersUsa.fitExtent = function (extent, object) { return fitExtent(albersUsa, extent, object); @@ -26680,13 +26833,13 @@ f = cy0 * pow$1(tany(y0), n) / n; if (!n) return mercatorRaw; function project(x, y) { if (f > 0) { - if (y < -halfPi$1 + epsilon$2) y = -halfPi$1 + epsilon$2; + if (y < -halfPi$1 + epsilon$3) y = -halfPi$1 + epsilon$3; } else { - if (y > halfPi$1 - epsilon$2) y = halfPi$1 - epsilon$2; + if (y > halfPi$1 - epsilon$3) y = halfPi$1 - epsilon$3; } var r = f / pow$1(tany(y), n); return [r * sin$1(n * x), f - r * cos$1(n * x)]; } @@ -26715,11 +26868,11 @@ function conicEquidistantRaw(y0, y1) { var cy0 = cos$1(y0), n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0), g = cy0 / n + y0; - if (abs$1(n) < epsilon$2) return equirectangularRaw; + if (abs$1(n) < epsilon$3) return equirectangularRaw; function project(x, y) { var gy = g - y, nx = n * x; return [gy * sin$1(nx), g - gy * cos$1(nx)]; @@ -26905,11 +27058,11 @@ do { var phi2 = phi * phi, phi4 = phi2 * phi2; phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) / (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4))); - } while (abs$1(delta) > epsilon$2 && --i > 0); + } while (abs$1(delta) > epsilon$3 && --i > 0); return [x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))), phi]; }; function geoNaturalEarth1 () { @@ -26919,11 +27072,11 @@ function orthographicRaw(x, y) { return [cos$1(y) * sin$1(x), sin$1(y)]; } orthographicRaw.invert = azimuthalInvert(asin$1); function geoOrthographic () { - return projection$1(orthographicRaw).scale(249.5).clipAngle(90 + epsilon$2); + return projection$1(orthographicRaw).scale(249.5).clipAngle(90 + epsilon$3); } function stereographicRaw(x, y) { var cy = cos$1(y), k = 1 + cos$1(x) * cy; @@ -26961,11 +27114,11 @@ } var abs = Math.abs; var cos = Math.cos; var sin = Math.sin; - var epsilon$1 = 1e-6; + var epsilon$2 = 1e-6; var pi = Math.PI; var halfPi = pi / 2; var sqrt2 = sqrt(2); function asin(x) { return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x); @@ -26977,11 +27130,11 @@ function mollweideBromleyTheta(cp, phi) { var cpsinPhi = cp * sin(phi), i = 30, delta; - do phi -= delta = (phi + sin(phi) - cpsinPhi) / (1 + cos(phi)); while (abs(delta) > epsilon$1 && --i > 0); + do phi -= delta = (phi + sin(phi) - cpsinPhi) / (1 + cos(phi)); while (abs(delta) > epsilon$2 && --i > 0); return phi / 2; } function mollweideBromleyRaw(cx, cy, cp) { function forward(lambda, phi) { @@ -27316,11 +27469,11 @@ var ex = extent(values), start = zero ? Math.min(ex[0], 0) : ex[0], stop = ex[1], span = stop - start, step = nice ? tickStep(start, stop, k) : span / (k + 1); - return range$1$1(start + step, stop, step); + return range$3(start + step, stop, step); }; } /** * Generate isocontours (level sets) based on input raster grid data. * @constructor @@ -27544,11 +27697,11 @@ values = values1; } // scale density estimates // density in points per square pixel or probability density - const s = counts ? Math.pow(2, -2 * k) : 1 / sum(values); + const s = counts ? Math.pow(2, -2 * k) : 1 / sum$1(values); for (let i = 0, sz = n * m; i < sz; ++i) values[i] *= s; return { values: values, @@ -29380,11 +29533,11 @@ var t = taskHead, e; while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(null, e); + if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e); t = t._next; } --frame; } @@ -30924,11 +31077,12 @@ } var preroot = { depth: -1 }, - ambiguous = {}; + ambiguous = {}, + imputed = {}; function defaultId(d) { return d.id; } @@ -30936,33 +31090,55 @@ return d.parentId; } function stratify () { var id = defaultId, - parentId = defaultParentId; + parentId = defaultParentId, + path; function stratify(data) { var nodes = Array.from(data), - n = nodes.length, + currentId = id, + currentParentId = parentId, + n, d, i, root, parent, node, nodeId, nodeKey, nodeByKey = new Map(); - for (i = 0; i < n; ++i) { + if (path != null) { + const I = nodes.map((d, i) => normalize(path(d, i, data))); + const P = I.map(parentof); + const S = new Set(I).add(""); + + for (const i of P) { + if (!S.has(i)) { + S.add(i); + I.push(i); + P.push(parentof(i)); + nodes.push(imputed); + } + } + + currentId = (_, i) => I[i]; + + currentParentId = (_, i) => P[i]; + } + + for (i = 0, n = nodes.length; i < n; ++i) { d = nodes[i], node = nodes[i] = new Node$1(d); - if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { + if ((nodeId = currentId(d, i, data)) != null && (nodeId += "")) { nodeKey = node.id = nodeId; nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node); } - if ((nodeId = parentId(d, i, data)) != null && (nodeId += "")) { + if ((nodeId = currentParentId(d, i, data)) != null && (nodeId += "")) { node.parent = nodeId; } } for (i = 0; i < n; ++i) { @@ -30978,11 +31154,25 @@ if (root) throw new Error("multiple roots"); root = node; } } - if (!root) throw new Error("no root"); + if (!root) throw new Error("no root"); // When imputing internal nodes, only introduce roots if needed. + // Then replace the imputed marker data with null. + + if (path != null) { + while (root.data === imputed && root.children.length === 1) { + root = root.children[0], --n; + } + + for (let i = nodes.length - 1; i >= 0; --i) { + node = nodes[i]; + if (node.data !== imputed) break; + node.data = null; + } + } + root.parent = preroot; root.eachBefore(function (node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); @@ -30990,18 +31180,58 @@ if (n > 0) throw new Error("cycle"); return root; } stratify.id = function (x) { - return arguments.length ? (id = required(x), stratify) : id; + return arguments.length ? (id = optional(x), stratify) : id; }; stratify.parentId = function (x) { - return arguments.length ? (parentId = required(x), stratify) : parentId; + return arguments.length ? (parentId = optional(x), stratify) : parentId; }; + stratify.path = function (x) { + return arguments.length ? (path = optional(x), stratify) : path; + }; + return stratify; + } // To normalize a path, we coerce to a string, strip the trailing slash if any + // (as long as the trailing slash is not immediately preceded by another slash), + // and add leading slash if missing. + + function normalize(path) { + path = "".concat(path); + let i = path.length; + if (slash(path, i - 1) && !slash(path, i - 2)) path = path.slice(0, -1); + return path[0] === "/" ? path : "/".concat(path); + } // Walk backwards to find the first slash that is not the leading slash, e.g.: + // "/foo/bar" ⇥ "/foo", "/foo" ⇥ "/", "/" ↦ "". (The root is special-cased + // because the id of the root must be a truthy value.) + + + function parentof(path) { + let i = path.length; + if (i < 2) return ""; + + while (--i > 1) if (slash(path, i)) break; + + return path.slice(0, i); + } // Slashes can be escaped; to determine whether a slash is a path delimiter, we + // count the number of preceding backslashes escaping the forward slash: an odd + // number indicates an escaped forward slash. + + + function slash(path, i) { + if (path[i] === "/") { + let k = 0; + + while (i > 0 && path[--i] === "\\") ++k; + + if ((k & 1) === 0) return true; + } + + return false; } function defaultSeparation$1(a, b) { return a.parent === b.parent ? 1 : 2; } // function radialSeparation(a, b) { @@ -32113,54 +32343,68 @@ tree: Tree, treelinks: TreeLinks, treemap: Treemap }); - const ALPHA_MASK = 0xff000000; // alpha value equivalent to opacity 0.0625 + const ALPHA_MASK = 0xff000000; - const INSIDE_OPACITY_IN_ALPHA = 0x10000000; - const INSIDE_OPACITY = 0.0625; - function baseBitmaps($, data) { const bitmap = $.bitmap(); // when there is no base mark but data points are to be avoided (data || []).forEach(d => bitmap.set($(d.boundary[0]), $(d.boundary[3]))); return [bitmap, undefined]; } - function markBitmaps($, avoidMarks, labelInside, isGroupArea) { + function markBitmaps($, baseMark, avoidMarks, labelInside, isGroupArea) { // create canvas const width = $.width, height = $.height, border = labelInside || isGroupArea, - context = domCanvas(width, height).getContext('2d'); // render all marks to be avoided into canvas + context = domCanvas(width, height).getContext('2d'), + baseMarkContext = domCanvas(width, height).getContext('2d'), + strokeContext = border && domCanvas(width, height).getContext('2d'); // render all marks to be avoided into canvas - avoidMarks.forEach(items => draw(context, items, border)); // get canvas buffer, create bitmaps + avoidMarks.forEach(items => draw(context, items, false)); + draw(baseMarkContext, baseMark, false); - const buffer = new Uint32Array(context.getImageData(0, 0, width, height).data.buffer), + if (border) { + draw(strokeContext, baseMark, true); + } // get canvas buffer, create bitmaps + + + const buffer = getBuffer(context, width, height), + baseMarkBuffer = getBuffer(baseMarkContext, width, height), + strokeBuffer = border && getBuffer(strokeContext, width, height), layer1 = $.bitmap(), layer2 = border && $.bitmap(); // populate bitmap layers - let x, y, u, v, alpha; + let x, y, u, v, index, alpha, strokeAlpha, baseMarkAlpha; for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { - alpha = buffer[y * width + x] & ALPHA_MASK; + index = y * width + x; + alpha = buffer[index] & ALPHA_MASK; + baseMarkAlpha = baseMarkBuffer[index] & ALPHA_MASK; + strokeAlpha = border && strokeBuffer[index] & ALPHA_MASK; - if (alpha) { + if (alpha || strokeAlpha || baseMarkAlpha) { u = $(x); v = $(y); - if (!isGroupArea) layer1.set(u, v); // update interior bitmap + if (!isGroupArea && (alpha || baseMarkAlpha)) layer1.set(u, v); // update interior bitmap - if (border && alpha ^ INSIDE_OPACITY_IN_ALPHA) layer2.set(u, v); // update border bitmap + if (border && (alpha || strokeAlpha)) layer2.set(u, v); // update border bitmap } } } return [layer1, layer2]; } + function getBuffer(context, width, height) { + return new Uint32Array(context.getImageData(0, 0, width, height).data.buffer); + } + function draw(context, items, interior) { if (!items.length) return; const type = items[0].mark.marktype; if (type === 'group') { @@ -32181,21 +32425,18 @@ function prepare(source) { const item = rederive(source, {}); - if (item.stroke) { - item.strokeOpacity = 1; + if (item.stroke && item.strokeOpacity !== 0 || item.fill && item.fillOpacity !== 0) { + return { ...item, + strokeOpacity: 1, + stroke: '#000', + fillOpacity: 0 + }; } - if (item.fill) { - item.fillOpacity = INSIDE_OPACITY; - item.stroke = '#000'; - item.strokeOpacity = 1; - item.strokeWidth = 2; - } - return item; } const DIV = 5, // bit shift from x, y index to bit vector array index @@ -32399,44 +32640,22 @@ function outOfBounds(x, y, textWidth, textHeight, width, height) { let r = textWidth / 2; return x - r < 0 || x + r > width || y - (r = textHeight / 2) < 0 || y + r > height; } - function _outOfBounds() { - return false; - } - function collision($, x, y, textHeight, textWidth, h, bm0, bm1) { const w = textWidth * h / (textHeight * 2), x1 = $(x - w), x2 = $(x + w), y1 = $(y - (h = h / 2)), y2 = $(y + h); return bm0.outOfBounds(x1, y1, x2, y2) || bm0.getRange(x1, y1, x2, y2) || bm1 && bm1.getRange(x1, y1, x2, y2); } - function _collision($, x, y, textHeight, textWidth, h, bm0, bm1) { - const w = textWidth * h / (textHeight * 2); - let x1 = $(x - w), - x2 = $(x + w), - y1 = $(y - (h = h / 2)), - y2 = $(y + h); - x1 = x1 > 0 ? x1 : 0; - y1 = y1 > 0 ? y1 : 0; - x2 = x2 < $.width ? x2 : $.width - 1; - y2 = y2 < $.height ? y2 : $.height - 1; - return bm0.getRange(x1, y1, x2, y2) || bm1 && bm1.getRange(x1, y1, x2, y2); - } - - function getTests(infPadding) { - return infPadding ? [_collision, _outOfBounds] : [collision, outOfBounds]; - } - - function placeAreaLabelReducedSearch($, bitmaps, avoidBaseMark, markIndex, infPadding) { + function placeAreaLabelReducedSearch($, bitmaps, avoidBaseMark, markIndex) { const width = $.width, height = $.height, - [collision, outOfBounds] = getTests(infPadding), bm0 = bitmaps[0], // where labels have been placed bm1 = bitmaps[1]; // area outlines function tryLabel(_x, _y, maxSize, textWidth, textHeight) { @@ -32577,14 +32796,13 @@ } const X_DIR = [-1, -1, 1, 1]; const Y_DIR = [-1, 1, -1, 1]; - function placeAreaLabelFloodFill($, bitmaps, avoidBaseMark, markIndex, infPadding) { + function placeAreaLabelFloodFill($, bitmaps, avoidBaseMark, markIndex) { const width = $.width, height = $.height, - [collision, outOfBounds] = getTests(infPadding), bm0 = bitmaps[0], // where labels have been placed bm1 = bitmaps[1], // area outlines bm2 = $.bitmap(); // flood-fill visitations @@ -32702,25 +32920,27 @@ } const Aligns = ['right', 'center', 'left'], Baselines = ['bottom', 'middle', 'top']; - function placeMarkLabel($, bitmaps, anchors, offsets, infPadding) { + function placeMarkLabel($, bitmaps, anchors, offsets) { const width = $.width, height = $.height, bm0 = bitmaps[0], bm1 = bitmaps[1], n = offsets.length; return function (d) { + var _d$textWidth; + const boundary = d.boundary, textHeight = d.datum.fontSize; // can not be placed if the mark is not visible in the graph bound - if (!infPadding && (boundary[2] < 0 || boundary[5] < 0 || boundary[0] > width || boundary[3] > height)) { + if (boundary[2] < 0 || boundary[5] < 0 || boundary[0] > width || boundary[3] > height) { return false; } - let textWidth = 0, + let textWidth = (_d$textWidth = d.textWidth) !== null && _d$textWidth !== void 0 ? _d$textWidth : 0, dx, dy, isInside, sizeFactor, insideFactor, @@ -32748,16 +32968,10 @@ y2 = yc + textHeight / 2; _x1 = $(x1); _y1 = $(y1); _y2 = $(y2); - if (infPadding) { - _x1 = _x1 < 0 ? 0 : _x1; - _y1 = _y1 < 0 ? 0 : _y1; - _y2 = _y2 >= $.height ? $.height - 1 : _y2; - } - if (!textWidth) { // to avoid finding width of text label, if (!test(_x1, _x1, _y1, _y2, bm0, bm1, x1, x1, y1, y2, boundary, isInside)) { // skip this anchor/offset option if we fail to place a label with 1px width continue; @@ -32771,15 +32985,10 @@ x1 = xc - textWidth / 2; x2 = xc + textWidth / 2; _x1 = $(x1); _x2 = $(x2); - if (infPadding) { - _x1 = _x1 < 0 ? 0 : _x1; - _x2 = _x2 >= $.width ? $.width - 1 : _x2; - } - if (test(_x1, _x2, _y1, _y2, bm0, bm1, x1, x2, y1, y2, boundary, isInside)) { // place label if the position is placeable d.x = !dx ? xc : dx * insideFactor < 0 ? x2 : x1; d.y = !dy ? yc : dy * insideFactor < 0 ? y2 : y1; d.align = Aligns[dx * insideFactor + 1]; @@ -32793,17 +33002,13 @@ }; } // Test if a label with the given dimensions can be added without overlap function test(_x1, _x2, _y1, _y2, bm0, bm1, x1, x2, y1, y2, boundary, isInside) { - return !(bm0.outOfBounds(_x1, _y1, _x2, _y2) || (isInside && bm1 ? bm1.getRange(_x1, _y1, _x2, _y2) || !isInMarkBound(x1, y1, x2, y2, boundary) : bm0.getRange(_x1, _y1, _x2, _y2))); + return !(bm0.outOfBounds(_x1, _y1, _x2, _y2) || (isInside && bm1 || bm0).getRange(_x1, _y1, _x2, _y2)); } - function isInMarkBound(x1, y1, x2, y2, boundary) { - return boundary[0] <= x1 && x2 <= boundary[2] && boundary[3] <= y1 && y2 <= boundary[5]; - } - const TOP = 0x0, MIDDLE = 0x4, BOTTOM = 0x8, LEFT = 0x0, CENTER = 0x1, @@ -32835,22 +33040,31 @@ marktype = markType(texts[0].datum), grouptype = marktype === 'group' && texts[0].datum.items[markIndex].marktype, isGroupArea = grouptype === 'area', boundary = markBoundary(marktype, grouptype, lineAnchor, markIndex), infPadding = padding === null || padding === Infinity, - $ = scaler(size[0], size[1], infPadding ? 0 : padding), - isNaiveGroupArea = isGroupArea && method === 'naive'; // prepare text mark data for placing + isNaiveGroupArea = isGroupArea && method === 'naive'; + let maxTextWidth = -1, + maxTextHeight = -1; // prepare text mark data for placing - const data = texts.map(d => ({ - datum: d, - opacity: 0, - x: undefined, - y: undefined, - align: undefined, - baseline: undefined, - boundary: boundary(d) - })); + const data = texts.map(d => { + const textWidth = infPadding ? textMetrics.width(d, d.text) : undefined; + maxTextWidth = Math.max(maxTextWidth, textWidth); + maxTextHeight = Math.max(maxTextHeight, d.fontSize); + return { + datum: d, + opacity: 0, + x: undefined, + y: undefined, + align: undefined, + baseline: undefined, + boundary: boundary(d), + textWidth + }; + }); + padding = padding === null || padding === Infinity ? Math.max(maxTextWidth, maxTextHeight) + Math.max(...offset) : padding; + const $ = scaler(size[0], size[1], padding); let bitmaps; if (!isNaiveGroupArea) { // sort labels in priority order, if comparator is provided if (compare) { @@ -32866,20 +33080,17 @@ labelInside = anchors[i] === 0x5 || offsets[i] < 0; } // extract data information from base mark when base mark is to be avoided // base mark is implicitly avoided if it is a group area - if (marktype && (avoidBaseMark || isGroupArea)) { - avoidMarks = [texts.map(d => d.datum)].concat(avoidMarks); - } // generate bitmaps for layout calculation + const baseMark = (marktype && avoidBaseMark || isGroupArea) && texts.map(d => d.datum); // generate bitmaps for layout calculation - - bitmaps = avoidMarks.length ? markBitmaps($, avoidMarks, labelInside, isGroupArea) : baseBitmaps($, avoidBaseMark && data); + bitmaps = avoidMarks.length || baseMark ? markBitmaps($, baseMark || [], avoidMarks, labelInside, isGroupArea) : baseBitmaps($, avoidBaseMark && data); } // generate label placement function - const place = isGroupArea ? placeAreaLabel[method]($, bitmaps, avoidBaseMark, markIndex, infPadding) : placeMarkLabel($, bitmaps, anchors, offsets, infPadding); // place all labels + const place = isGroupArea ? placeAreaLabel[method]($, bitmaps, avoidBaseMark, markIndex) : placeMarkLabel($, bitmaps, anchors, offsets); // place all labels data.forEach(d => d.opacity = +place(d)); return data; } @@ -32910,11 +33121,11 @@ } /** * Factory function for function for getting base mark boundary, depending * on mark and group type. When mark type is undefined, line or area: boundary * is the coordinate of each data point. When base mark is grouped line, - * boundary is either at the beginning or end of the line depending on the + * boundary is either at the start or end of the line depending on the * value of lineAnchor. Otherwise, use bounds of base mark. */ function markBoundary(marktype, grouptype, lineAnchor, markIndex) { @@ -33324,14 +33535,289 @@ __proto__: null, loess: Loess, regression: Regression }); + const epsilon$1 = 1.1102230246251565e-16; + const splitter = 134217729; + const resulterrbound = (3 + 8 * epsilon$1) * epsilon$1; // fast_expansion_sum_zeroelim routine from oritinal code + + function sum(elen, e, flen, f, h) { + let Q, Qnew, hh, bvirt; + let enow = e[0]; + let fnow = f[0]; + let eindex = 0; + let findex = 0; + + if (fnow > enow === fnow > -enow) { + Q = enow; + enow = e[++eindex]; + } else { + Q = fnow; + fnow = f[++findex]; + } + + let hindex = 0; + + if (eindex < elen && findex < flen) { + if (fnow > enow === fnow > -enow) { + Qnew = enow + Q; + hh = Q - (Qnew - enow); + enow = e[++eindex]; + } else { + Qnew = fnow + Q; + hh = Q - (Qnew - fnow); + fnow = f[++findex]; + } + + Q = Qnew; + + if (hh !== 0) { + h[hindex++] = hh; + } + + while (eindex < elen && findex < flen) { + if (fnow > enow === fnow > -enow) { + Qnew = Q + enow; + bvirt = Qnew - Q; + hh = Q - (Qnew - bvirt) + (enow - bvirt); + enow = e[++eindex]; + } else { + Qnew = Q + fnow; + bvirt = Qnew - Q; + hh = Q - (Qnew - bvirt) + (fnow - bvirt); + fnow = f[++findex]; + } + + Q = Qnew; + + if (hh !== 0) { + h[hindex++] = hh; + } + } + } + + while (eindex < elen) { + Qnew = Q + enow; + bvirt = Qnew - Q; + hh = Q - (Qnew - bvirt) + (enow - bvirt); + enow = e[++eindex]; + Q = Qnew; + + if (hh !== 0) { + h[hindex++] = hh; + } + } + + while (findex < flen) { + Qnew = Q + fnow; + bvirt = Qnew - Q; + hh = Q - (Qnew - bvirt) + (fnow - bvirt); + fnow = f[++findex]; + Q = Qnew; + + if (hh !== 0) { + h[hindex++] = hh; + } + } + + if (Q !== 0 || hindex === 0) { + h[hindex++] = Q; + } + + return hindex; + } + function estimate(elen, e) { + let Q = e[0]; + + for (let i = 1; i < elen; i++) Q += e[i]; + + return Q; + } + function vec(n) { + return new Float64Array(n); + } + + const ccwerrboundA = (3 + 16 * epsilon$1) * epsilon$1; + const ccwerrboundB = (2 + 12 * epsilon$1) * epsilon$1; + const ccwerrboundC = (9 + 64 * epsilon$1) * epsilon$1 * epsilon$1; + const B = vec(4); + const C1 = vec(8); + const C2 = vec(12); + const D = vec(16); + const u = vec(4); + + function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) { + let acxtail, acytail, bcxtail, bcytail; + + let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3; + + const acx = ax - cx; + const bcx = bx - cx; + const acy = ay - cy; + const bcy = by - cy; + s1 = acx * bcy; + c = splitter * acx; + ahi = c - (c - acx); + alo = acx - ahi; + c = splitter * bcy; + bhi = c - (c - bcy); + blo = bcy - bhi; + s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); + t1 = acy * bcx; + c = splitter * acy; + ahi = c - (c - acy); + alo = acy - ahi; + c = splitter * bcx; + bhi = c - (c - bcx); + blo = bcx - bhi; + t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); + _i = s0 - t0; + bvirt = s0 - _i; + B[0] = s0 - (_i + bvirt) + (bvirt - t0); + _j = s1 + _i; + bvirt = _j - s1; + _0 = s1 - (_j - bvirt) + (_i - bvirt); + _i = _0 - t1; + bvirt = _0 - _i; + B[1] = _0 - (_i + bvirt) + (bvirt - t1); + u3 = _j + _i; + bvirt = u3 - _j; + B[2] = _j - (u3 - bvirt) + (_i - bvirt); + B[3] = u3; + let det = estimate(4, B); + let errbound = ccwerrboundB * detsum; + + if (det >= errbound || -det >= errbound) { + return det; + } + + bvirt = ax - acx; + acxtail = ax - (acx + bvirt) + (bvirt - cx); + bvirt = bx - bcx; + bcxtail = bx - (bcx + bvirt) + (bvirt - cx); + bvirt = ay - acy; + acytail = ay - (acy + bvirt) + (bvirt - cy); + bvirt = by - bcy; + bcytail = by - (bcy + bvirt) + (bvirt - cy); + + if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) { + return det; + } + + errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det); + det += acx * bcytail + bcy * acxtail - (acy * bcxtail + bcx * acytail); + if (det >= errbound || -det >= errbound) return det; + s1 = acxtail * bcy; + c = splitter * acxtail; + ahi = c - (c - acxtail); + alo = acxtail - ahi; + c = splitter * bcy; + bhi = c - (c - bcy); + blo = bcy - bhi; + s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); + t1 = acytail * bcx; + c = splitter * acytail; + ahi = c - (c - acytail); + alo = acytail - ahi; + c = splitter * bcx; + bhi = c - (c - bcx); + blo = bcx - bhi; + t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); + _i = s0 - t0; + bvirt = s0 - _i; + u[0] = s0 - (_i + bvirt) + (bvirt - t0); + _j = s1 + _i; + bvirt = _j - s1; + _0 = s1 - (_j - bvirt) + (_i - bvirt); + _i = _0 - t1; + bvirt = _0 - _i; + u[1] = _0 - (_i + bvirt) + (bvirt - t1); + u3 = _j + _i; + bvirt = u3 - _j; + u[2] = _j - (u3 - bvirt) + (_i - bvirt); + u[3] = u3; + const C1len = sum(4, B, 4, u, C1); + s1 = acx * bcytail; + c = splitter * acx; + ahi = c - (c - acx); + alo = acx - ahi; + c = splitter * bcytail; + bhi = c - (c - bcytail); + blo = bcytail - bhi; + s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); + t1 = acy * bcxtail; + c = splitter * acy; + ahi = c - (c - acy); + alo = acy - ahi; + c = splitter * bcxtail; + bhi = c - (c - bcxtail); + blo = bcxtail - bhi; + t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); + _i = s0 - t0; + bvirt = s0 - _i; + u[0] = s0 - (_i + bvirt) + (bvirt - t0); + _j = s1 + _i; + bvirt = _j - s1; + _0 = s1 - (_j - bvirt) + (_i - bvirt); + _i = _0 - t1; + bvirt = _0 - _i; + u[1] = _0 - (_i + bvirt) + (bvirt - t1); + u3 = _j + _i; + bvirt = u3 - _j; + u[2] = _j - (u3 - bvirt) + (_i - bvirt); + u[3] = u3; + const C2len = sum(C1len, C1, 4, u, C2); + s1 = acxtail * bcytail; + c = splitter * acxtail; + ahi = c - (c - acxtail); + alo = acxtail - ahi; + c = splitter * bcytail; + bhi = c - (c - bcytail); + blo = bcytail - bhi; + s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); + t1 = acytail * bcxtail; + c = splitter * acytail; + ahi = c - (c - acytail); + alo = acytail - ahi; + c = splitter * bcxtail; + bhi = c - (c - bcxtail); + blo = bcxtail - bhi; + t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); + _i = s0 - t0; + bvirt = s0 - _i; + u[0] = s0 - (_i + bvirt) + (bvirt - t0); + _j = s1 + _i; + bvirt = _j - s1; + _0 = s1 - (_j - bvirt) + (_i - bvirt); + _i = _0 - t1; + bvirt = _0 - _i; + u[1] = _0 - (_i + bvirt) + (bvirt - t1); + u3 = _j + _i; + bvirt = u3 - _j; + u[2] = _j - (u3 - bvirt) + (_i - bvirt); + u[3] = u3; + const Dlen = sum(C2len, C2, 4, u, D); + return D[Dlen - 1]; + } + + function orient2d(ax, ay, bx, by, cx, cy) { + const detleft = (ay - cy) * (bx - cx); + const detright = (ax - cx) * (by - cy); + const det = detleft - detright; + if (detleft === 0 || detright === 0 || detleft > 0 !== detright > 0) return det; + const detsum = Math.abs(detleft + detright); + if (Math.abs(det) >= ccwerrboundA * detsum) return det; + return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum); + } + const EPSILON = Math.pow(2, -52); const EDGE_STACK = new Uint32Array(512); class Delaunator { - static from(points, getX = defaultGetX, getY = defaultGetY) { + static from(points) { + let getX = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultGetX; + let getY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultGetY; const n = points.length; const coords = new Float64Array(n * 2); for (let i = 0; i < n; i++) { const p = points[i]; @@ -33461,11 +33947,11 @@ this.halfedges = new Uint32Array(0); return; } // swap the order of the seed points for counter-clockwise orientation - if (orient(i0x, i0y, i1x, i1y, i2x, i2y)) { + if (orient2d(i0x, i0y, i1x, i1y, i2x, i2y) < 0) { const i = i1; const x = i1x; const y = i1y; i1 = i2; i1x = i2x; @@ -33522,11 +34008,11 @@ start = hullPrev[start]; let e = start, q; - while (q = hullNext[e], !orient(x, y, coords[2 * e], coords[2 * e + 1], coords[2 * q], coords[2 * q + 1])) { + while (q = hullNext[e], orient2d(x, y, coords[2 * e], coords[2 * e + 1], coords[2 * q], coords[2 * q + 1]) >= 0) { e = q; if (e === start) { e = -1; break; @@ -33544,22 +34030,22 @@ hullSize++; // walk forward through the hull, adding more triangles and flipping recursively let n = hullNext[e]; - while (q = hullNext[n], orient(x, y, coords[2 * n], coords[2 * n + 1], coords[2 * q], coords[2 * q + 1])) { + while (q = hullNext[n], orient2d(x, y, coords[2 * n], coords[2 * n + 1], coords[2 * q], coords[2 * q + 1]) < 0) { t = this._addTriangle(n, i, q, hullTri[i], -1, hullTri[n]); hullTri[i] = this._legalize(t + 2); hullNext[n] = n; // mark as removed hullSize--; n = q; } // walk backward from the other side, adding more triangles and flipping if (e === start) { - while (q = hullPrev[e], orient(x, y, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1])) { + while (q = hullPrev[e], orient2d(x, y, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1]) < 0) { t = this._addTriangle(q, i, e, -1, hullTri[e], hullTri[q]); this._legalize(t + 2); hullTri[q] = t; @@ -33710,23 +34196,10 @@ function dist(ax, ay, bx, by) { const dx = ax - bx; const dy = ay - by; return dx * dx + dy * dy; - } // return 2d orientation sign if we're confident in it through J. Shewchuk's error bound check - - - function orientIfSure(px, py, rx, ry, qx, qy) { - const l = (ry - py) * (qx - px); - const r = (rx - px) * (qy - py); - return Math.abs(l - r) >= 3.3306690738754716e-16 * Math.abs(l + r) ? l - r : 0; - } // a more robust orientation test that's stable in a given triangle (to fix robustness issues) - - - function orient(rx, ry, qx, qy, px, py) { - const sign = orientIfSure(px, py, rx, ry, qx, qy) || orientIfSure(rx, ry, qx, qy, px, py) || orientIfSure(qx, qy, px, py, rx, ry); - return sign < 0; } function inCircle(ax, ay, bx, by, cx, cy, px, py) { const dx = ax - px; const dy = ay - py; @@ -33835,36 +34308,36 @@ this._ = ""; } moveTo(x, y) { - this._ += `M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`; + this._ += "M".concat(this._x0 = this._x1 = +x, ",").concat(this._y0 = this._y1 = +y); } closePath() { if (this._x1 !== null) { this._x1 = this._x0, this._y1 = this._y0; this._ += "Z"; } } lineTo(x, y) { - this._ += `L${this._x1 = +x},${this._y1 = +y}`; + this._ += "L".concat(this._x1 = +x, ",").concat(this._y1 = +y); } arc(x, y, r) { x = +x, y = +y, r = +r; const x0 = x + r; const y0 = y; if (r < 0) throw new Error("negative radius"); - if (this._x1 === null) this._ += `M${x0},${y0}`;else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) this._ += "L" + x0 + "," + y0; + if (this._x1 === null) this._ += "M".concat(x0, ",").concat(y0);else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) this._ += "L" + x0 + "," + y0; if (!r) return; - this._ += `A${r},${r},0,1,1,${x - r},${y}A${r},${r},0,1,1,${this._x1 = x0},${this._y1 = y0}`; + this._ += "A".concat(r, ",").concat(r, ",0,1,1,").concat(x - r, ",").concat(y, "A").concat(r, ",").concat(r, ",0,1,1,").concat(this._x1 = x0, ",").concat(this._y1 = y0); } rect(x, y, w, h) { - this._ += `M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${+w}v${+h}h${-w}Z`; + this._ += "M".concat(this._x0 = this._x1 = +x, ",").concat(this._y0 = this._y1 = +y, "h").concat(+w, "v").concat(+h, "h").concat(-w, "Z"); } value() { return this._ || null; } @@ -33893,11 +34366,12 @@ } } class Voronoi$1 { - constructor(delaunay, [xmin, ymin, xmax, ymax] = [0, 0, 960, 500]) { + constructor(delaunay) { + let [xmin, ymin, xmax, ymax] = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0, 0, 960, 500]; if (!((xmax = +xmax) >= (xmin = +xmin)) || !((ymax = +ymax) >= (ymin = +ymin))) throw new Error("invalid bounds"); this.delaunay = delaunay; this._circumcenters = new Float64Array(delaunay.points.length * 2); this.vectors = new Float64Array(delaunay.points.length * 2); this.xmax = xmax, this.xmin = xmin; @@ -33938,24 +34412,30 @@ const y3 = points[t3 + 1]; const dx = x2 - x1; const dy = y2 - y1; const ex = x3 - x1; const ey = y3 - y1; - const bl = dx * dx + dy * dy; - const cl = ex * ex + ey * ey; const ab = (dx * ey - dy * ex) * 2; - if (!ab) { + if (Math.abs(ab) < 1e-9) { // degenerate case (collinear diagram) - x = (x1 + x3) / 2 - 1e8 * ey; - y = (y1 + y3) / 2 + 1e8 * ex; - } else if (Math.abs(ab) < 1e-8) { // almost equal points (degenerate triangle) - x = (x1 + x3) / 2; - y = (y1 + y3) / 2; + // the circumcenter is at the infinity, in a + // direction that is: + // 1. orthogonal to the halfedge. + let a = 1e9; // 2. points away from the center; since the list of triangles starts + // in the center, the first point of the first triangle + // will be our reference + + const r = triangles[0] * 2; + a *= Math.sign((points[r] - x1) * ey - (points[r + 1] - y1) * ex); + x = (x1 + x3) / 2 - a * ey; + y = (y1 + y3) / 2 + a * ex; } else { const d = 1 / ab; + const bl = dx * dx + dy * dy; + const cl = ex * ex + ey * ey; x = x1 + (ey * bl - dy * cl) * d; y = y1 + (dx * cl - ex * bl) * d; } circumcenters[j] = x; @@ -34160,11 +34640,12 @@ y1 = points[n - 1]; let c0, c1 = this._regioncode(x1, y1); - let e0, e1; + let e0, + e1 = 0; for (let j = 0; j < n; j += 2) { x0 = x1, y0 = y1, x1 = points[j], y1 = points[j + 1]; c0 = c1, c1 = this._regioncode(x1, y1); @@ -34273,12 +34754,14 @@ case 0b0001: e0 = 0b0101, x = this.xmin, y = this.ymin; break; // left - } + } // Note: this implicitly checks for out of bounds: if P[j] or P[j+1] are + // undefined, the conditional statement will be executed. + if ((P[j] !== x || P[j + 1] !== y) && this.contains(i, x, y)) { P.splice(j, 0, x, y), j += 2; } } @@ -34364,11 +34847,14 @@ function jitter(x, y, r) { return [x + Math.sin(x + y) * r, y + Math.cos(x - y) * r]; } class Delaunay { - static from(points, fx = pointX, fy = pointY, that) { + static from(points) { + let fx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : pointX; + let fy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : pointY; + let that = arguments.length > 3 ? arguments[3] : undefined; return new Delaunay("length" in points ? flatArray(points, fx, fy, that) : Float64Array.from(flatIterable(points, fx, fy, that))); } constructor(points) { this._delaunator = new Delaunator(points); @@ -34434,14 +34920,17 @@ if (hull.length <= 2 && hull.length > 0) { this.triangles = new Int32Array(3).fill(-1); this.halfedges = new Int32Array(3).fill(-1); this.triangles[0] = hull[0]; - this.triangles[1] = hull[1]; - this.triangles[2] = hull[1]; inedges[hull[0]] = 1; - if (hull.length === 2) inedges[hull[1]] = 0; + + if (hull.length === 2) { + inedges[hull[1]] = 0; + this.triangles[1] = hull[1]; + this.triangles[2] = hull[1]; + } } } voronoi(bounds) { return new Voronoi$1(this, bounds); @@ -34483,11 +34972,12 @@ return; } } while (e !== e0); } - find(x, y, i = 0) { + find(x, y) { + let i = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; if ((x = +x, x !== x) || (y = +y, y !== y)) return -1; const i0 = i; let c; while ((c = this._step(i, x, y)) >= 0 && c !== i && c !== i0) i = c; @@ -34552,11 +35042,13 @@ this.renderHull(context); return buffer && buffer.value(); } - renderPoints(context, r = 2) { + renderPoints(context, r) { + if (r === undefined && (!context || typeof context.moveTo !== "function")) r = context, context = null; + r = r == undefined ? 2 : +r; const buffer = context == null ? context = new Path() : undefined; const { points } = this; @@ -36066,10 +36558,12 @@ __proto__: null, crossfilter: CrossFilter, resolvefilter: ResolveFilter }); + var version = "5.22.1"; + const RawCode = 'RawCode'; const Literal = 'Literal'; const Property = 'Property'; const Identifier = 'Identifier'; const ArrayExpression = 'ArrayExpression'; @@ -36246,15 +36740,24 @@ return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029; } // 7.6 Identifier Names and Identifiers function isIdentifierStart(ch) { - return ch === 0x24 || ch === 0x5F || ch >= 0x41 && ch <= 0x5A || ch >= 0x61 && ch <= 0x7A || ch === 0x5C || ch >= 0x80 && RegexNonAsciiIdentifierStart.test(String.fromCharCode(ch)); + return ch === 0x24 || ch === 0x5F || // $ (dollar) and _ (underscore) + ch >= 0x41 && ch <= 0x5A || // A..Z + ch >= 0x61 && ch <= 0x7A || // a..z + ch === 0x5C || // \ (backslash) + ch >= 0x80 && RegexNonAsciiIdentifierStart.test(String.fromCharCode(ch)); } function isIdentifierPart(ch) { - return ch === 0x24 || ch === 0x5F || ch >= 0x41 && ch <= 0x5A || ch >= 0x61 && ch <= 0x7A || ch >= 0x30 && ch <= 0x39 || ch === 0x5C || ch >= 0x80 && RegexNonAsciiIdentifierPart.test(String.fromCharCode(ch)); + return ch === 0x24 || ch === 0x5F || // $ (dollar) and _ (underscore) + ch >= 0x41 && ch <= 0x5A || // A..Z + ch >= 0x61 && ch <= 0x7A || // a..z + ch >= 0x30 && ch <= 0x39 || // 0..9 + ch === 0x5C || // \ (backslash) + ch >= 0x80 && RegexNonAsciiIdentifierPart.test(String.fromCharCode(ch)); } // 7.6.1.1 Keywords const keywords = { 'if': 1, @@ -37740,11 +38243,11 @@ forbidden = opt.forbidden ? toSet(opt.forbidden) : {}, constants = opt.constants || Constants, functions = (opt.functions || Functions)(visit), globalvar = opt.globalvar, fieldvar = opt.fieldvar, - outputGlobal = isFunction(globalvar) ? globalvar : id => `${globalvar}["${id}"]`; + outputGlobal = isFunction(globalvar) ? globalvar : id => "".concat(globalvar, "[\"").concat(id, "\"]"); let globals = {}, fields = {}, memberDepth = 0; function visit(ast) { @@ -37825,74 +38328,19 @@ codegen.functions = functions; codegen.constants = constants; return codegen; } - function ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } - - function bisector(f) { - let delta = f; - let compare = f; - - if (f.length === 1) { - delta = (d, x) => f(d) - x; - - compare = ascendingComparator(f); - } - - function left(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - - while (lo < hi) { - const mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; - } - - return lo; - } - - function right(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - - while (lo < hi) { - const mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; - } - - return lo; - } - - function center(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - const i = left(a, x, lo, hi - 1); - return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; - } - - return { - left, - center, - right - }; - } - - function ascendingComparator(f) { - return (d, x) => ascending(f(d), x); - } - const Intersect = 'intersect'; const Union = 'union'; const VlMulti = 'vlMulti'; const VlPoint = 'vlPoint'; const Or = 'or'; const And = 'and'; - const SELECTION_ID = '_vgsid_', - TYPE_ENUM = 'E', + const SelectionId = '_vgsid_'; + const $selectionId = field$1(SelectionId); + const TYPE_ENUM = 'E', TYPE_RANGE_INC = 'R', TYPE_RANGE_EXC = 'R-E', TYPE_RANGE_LE = 'R-LE', TYPE_RANGE_RE = 'R-RE', UNIT_INDEX = 'index:unit'; // TODO: revisit date coercion? @@ -37992,24 +38440,23 @@ return n && intersect; } - const selectionId = field$1(SELECTION_ID), - bisect = bisector(selectionId), + const bisect = bisector($selectionId), bisectLeft = bisect.left, bisectRight = bisect.right; function selectionIdTest(name, datum, op) { const data = this.context.data[name], entries = data ? data.values.value : [], unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined, intersect = op === Intersect, - value = selectionId(datum), + value = $selectionId(datum), index = bisectLeft(entries, value); if (index === entries.length) return false; - if (selectionId(entries[index]) !== value) return false; + if ($selectionId(entries[index]) !== value) return false; if (unitIdx && intersect) { if (unitIdx.size === 1) return true; if (bisectRight(entries, value) - index < unitIdx.size) return false; } @@ -38017,19 +38464,21 @@ return true; } /** * Maps an array of scene graph items to an array of selection tuples. * @param {string} name - The name of the dataset representing the selection. - * @param {string} unit - The name of the unit view. + * @param {string} base - The base object that generated tuples extend. * * @returns {array} An array of selection entries for the given unit. */ function selectionTuples(array, base) { - return array.map(x => extend$1({ + return array.map(x => extend$1(base.fields ? { values: base.fields.map(f => (f.getter || (f.getter = field$1(f.field)))(x.datum)) + } : { + [SelectionId]: $selectionId(x.datum) }, base)); } /** * Resolves selection for use as a scale domain or reads via the API. * @param {string} name - The name of the dataset representing the selection @@ -38054,10 +38503,11 @@ entry, fields, values, unit, field, + value, res, resUnit, type, union, n = entries.length, @@ -38069,36 +38519,59 @@ entry = entries[i]; unit = entry.unit; fields = entry.fields; values = entry.values; - for (j = 0, m = fields.length; j < m; ++j) { - field = fields[j]; - res = resolved[field.field] || (resolved[field.field] = {}); - resUnit = res[unit] || (res[unit] = []); - types[field.field] = type = field.type.charAt(0); - union = ops[type + '_union']; - res[unit] = union(resUnit, array$5(values[j])); - } // If the same multi-selection is repeated over views and projected over - // an encoding, it may operate over different fields making it especially - // tricky to reliably resolve it. At best, we can de-dupe identical entries - // but doing so may be more computationally expensive than it is worth. - // Instead, for now, we simply transform our store representation into - // a more human-friendly one. + if (fields && values) { + // Intentional selection stores + for (j = 0, m = fields.length; j < m; ++j) { + field = fields[j]; + res = resolved[field.field] || (resolved[field.field] = {}); + resUnit = res[unit] || (res[unit] = []); + types[field.field] = type = field.type.charAt(0); + union = ops["".concat(type, "_union")]; + res[unit] = union(resUnit, array$5(values[j])); + } // If the same multi-selection is repeated over views and projected over + // an encoding, it may operate over different fields making it especially + // tricky to reliably resolve it. At best, we can de-dupe identical entries + // but doing so may be more computationally expensive than it is worth. + // Instead, for now, we simply transform our store representation into + // a more human-friendly one. - if (isMulti) { - resUnit = multiRes[unit] || (multiRes[unit] = []); - resUnit.push(array$5(values).reduce((obj, curr, j) => (obj[fields[j].field] = curr, obj), {})); + if (isMulti) { + resUnit = multiRes[unit] || (multiRes[unit] = []); + resUnit.push(array$5(values).reduce((obj, curr, j) => (obj[fields[j].field] = curr, obj), {})); + } + } else { + // Short circuit extensional selectionId stores which hold sorted IDs unique to each unit. + field = SelectionId; + value = $selectionId(entry); + res = resolved[field] || (resolved[field] = {}); + resUnit = res[unit] || (res[unit] = []); + resUnit.push(value); + + if (isMulti) { + resUnit = multiRes[unit] || (multiRes[unit] = []); + resUnit.push({ + [SelectionId]: value + }); + } } } // Then resolve fields across units as per the op. op = op || Union; - Object.keys(resolved).forEach(field => { - resolved[field] = Object.keys(resolved[field]).map(unit => resolved[field][unit]).reduce((acc, curr) => acc === undefined ? curr : ops[types[field] + '_' + op](acc, curr)); - }); + + if (resolved[SelectionId]) { + resolved[SelectionId] = ops["".concat(SelectionId, "_").concat(op)](...Object.values(resolved[SelectionId])); + } else { + Object.keys(resolved).forEach(field => { + resolved[field] = Object.keys(resolved[field]).map(unit => resolved[field][unit]).reduce((acc, curr) => acc === undefined ? curr : ops["".concat(types[field], "_").concat(op)](acc, curr)); + }); + } + entries = Object.keys(multiRes); if (isMulti && entries.length) { const key = vl5 ? VlPoint : VlMulti; resolved[key] = op === Union ? { @@ -38112,10 +38585,12 @@ return resolved; } var ops = { + ["".concat(SelectionId, "_union")]: union, + ["".concat(SelectionId, "_intersect")]: intersection, E_union: function (base, value) { if (!base.length) return value; var i = 0, n = value.length; @@ -38320,13 +38795,13 @@ const ref = arg => '_[' + (arg.type === Literal ? $(ScalePrefix + arg.value) : $(ScalePrefix) + '+' + codegen(arg)) + ']'; // define and return internal scale function code generators // these internal functions are called by mark encoders return { - _bandwidth: args => `this.__bandwidth(${ref(args[0])})`, - _range: args => `${ref(args[0])}.range()`, - _scale: args => `${ref(args[0])}(${codegen(args[1])})` + _bandwidth: args => "this.__bandwidth(".concat(ref(args[0]), ")"), + _range: args => "".concat(ref(args[0]), ".range()"), + _scale: args => "".concat(ref(args[0]), "(").concat(codegen(args[1]), ")") }; } function geoMethod(methodName, globalMethod) { return function (projection, geojson, group) { @@ -38514,23 +38989,39 @@ function sequence(seq) { return array(seq) || (isString(seq) ? seq : null); } - function join(seq, ...args) { + function join(seq) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + return array(seq).join(...args); } - function indexof(seq, ...args) { + function indexof(seq) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + return sequence(seq).indexOf(...args); } - function lastindexof(seq, ...args) { + function lastindexof(seq) { + for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { + args[_key3 - 1] = arguments[_key3]; + } + return sequence(seq).lastIndexOf(...args); } - function slice(seq, ...args) { + function slice(seq) { + for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { + args[_key4 - 1] = arguments[_key4]; + } + return sequence(seq).slice(...args); } function replace(str, pattern, repl) { if (isFunction(repl)) error('Function argument passed to replace.'); @@ -38608,11 +39099,11 @@ } function pathShape(path) { let p = null; return function (context) { - return context ? pathRender(context, p = p || pathParse(path)) : path; + return context ? pathRender(context, p = p || parse$3(path)) : path; }; } const datum = d => d.data; @@ -38671,11 +39162,106 @@ p = _ => (!types.length || types.some(t => _.marktype === t)) && (!names.length || names.some(s => _.name === s)); } return p; } + /** + * Appends a new point to the lasso + * + * @param {*} lasso the lasso in pixel space + * @param {*} x the x coordinate in pixel space + * @param {*} y the y coordinate in pixel space + * @param {*} minDist the minimum distance, in pixels, that thenew point needs to be apart from the last point + * @returns a new array containing the lasso with the new point + */ + + function lassoAppend(lasso, x, y) { + let minDist = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5; + const last = lasso[lasso.length - 1]; // Add point to lasso if distance to last point exceed minDist or its the first point + + if (last === undefined || Math.sqrt((last[0] - x) ** 2 + (last[1] - y) ** 2) > minDist) { + lasso.push([x, y]); + return [...lasso]; + } + + return lasso; + } + /** + * Generates a svg path command which draws a lasso + * + * @param {*} lasso the lasso in pixel space in the form [[x,y], [x,y], ...] + * @returns the svg path command that draws the lasso + */ + + + function lassoPath(lasso) { + return (lasso !== null && lasso !== void 0 ? lasso : []).reduce((svg, _ref, i) => { + let [x, y] = _ref; + return svg += i == 0 ? "M ".concat(x, ",").concat(y, " ") : i === lasso.length - 1 ? ' Z' : "L ".concat(x, ",").concat(y, " "); + }, ''); + } + /** + * Inverts the lasso from pixel space to an array of vega scenegraph tuples + * + * @param {*} data the dataset + * @param {*} pixelLasso the lasso in pixel space, [[x,y], [x,y], ...] + * @param {*} unit the unit where the lasso is defined + * + * @returns an array of vega scenegraph tuples + */ + + + function intersectLasso(markname, pixelLasso, unit) { + const { + x, + y, + mark + } = unit; + const bb = new Bounds().set(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); // Get bounding box around lasso + + for (const [px, py] of pixelLasso) { + if (px < bb.x1) bb.x1 = px; + if (px > bb.x2) bb.x2 = px; + if (py < bb.y1) bb.y1 = py; + if (py > bb.y2) bb.y2 = py; + } // Translate bb against unit coordinates + + + bb.translate(x, y); + const intersection = intersect([[bb.x1, bb.y1], [bb.x2, bb.y2]], markname, mark); // Check every point against the lasso + + return intersection.filter(tuple => pointInPolygon(tuple.x, tuple.y, pixelLasso)); + } + /** + * Performs a test if a point is inside a polygon based on the idea from + * https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html + * + * This method will not need the same start/end point since it wraps around the edges of the array + * + * @param {*} test a point to test against + * @param {*} polygon a polygon in the form [[x,y], [x,y], ...] + * @returns true if the point lies inside the polygon, false otherwise + */ + + + function pointInPolygon(testx, testy, polygon) { + let intersections = 0; + + for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { + const [prevX, prevY] = polygon[j]; + const [x, y] = polygon[i]; // count intersections + + if (y > testy != prevY > testy && testx < (prevX - x) * (testy - y) / (prevY - y) + x) { + intersections++; + } + } // point is in polygon if intersection count is odd + + + return intersections & 1; + } + const functionContext = { random() { return exports.random(); }, @@ -38709,11 +39295,16 @@ isValid(_) { return _ != null && _ === _; }, toBoolean, - toDate, + + toDate(_) { + return toDate(_); + }, + + // suppress extra arguments toNumber, toString, indexof, join, lastindexof, @@ -38733,11 +39324,11 @@ lab: lab$1, hcl: hcl$2, hsl: hsl$2, luminance, contrast, - sequence: range$1$1, + sequence: range$3, format, utcFormat, utcParse, utcOffset, utcSequence, @@ -38757,11 +39348,16 @@ dayofyear, utcdayofyear, warn, info, debug, - extent, + + extent(_) { + return extent(_); + }, + + // suppress extra arguments inScope, intersect, clampRange, pinchDistance, pinchAngle, @@ -38778,11 +39374,14 @@ zoomLinear, zoomLog, zoomPow, zoomSymlog, encode, - modify + modify, + lassoAppend, + lassoPath, + intersectLasso }; const eventFunctions = ['view', 'item', 'group', 'xy', 'x', 'y'], // event functions eventPrefix = 'event.vega.', // event function prefix @@ -38793,11 +39392,11 @@ const codegenParams = { forbidden: ['_'], allowed: ['datum', 'event', 'item'], fieldvar: 'datum', - globalvar: id => `_[${$(SignalPrefix + id)}]`, + globalvar: id => "_[".concat($(SignalPrefix + id), "]"), functions: buildFunctions, constants: Constants, visitors: astVisitors }; // export code generator @@ -38991,14 +39590,11 @@ return ctx && ctx.functions ? fn.bind(ctx.functions) : fn; } // generate code for comparing a single field function _compare(u, v, lt, gt) { - return `((u = ${u}) < (v = ${v}) || u == null) && v != null ? ${lt} - : (u > v || v == null) && u != null ? ${gt} - : ((v = v instanceof Date ? +v : v), (u = u instanceof Date ? +u : u)) !== u && v === v ? ${lt} - : v !== v && u === u ? ${gt} : `; + return "((u = ".concat(u, ") < (v = ").concat(v, ") || u == null) && v != null ? ").concat(lt, "\n : (u > v || v == null) && u != null ? ").concat(gt, "\n : ((v = v instanceof Date ? +v : v), (u = u instanceof Date ? +u : u)) !== u && v === v ? ").concat(lt, "\n : v !== v && u === u ? ").concat(gt, " : "); } var expressionCodegen = { /** * Parse an expression used to update an operator value. @@ -39017,11 +39613,11 @@ /** * Parse an expression used to handle an event-driven operator update. */ handler: (ctx, expr) => { - const code = `var datum=event.item&&event.item.datum;return ${expr.code};`; + const code = "var datum=event.item&&event.item.datum;return ".concat(expr.code, ";"); return expression(ctx, ['_', 'event'], code); }, /** * Parse an expression that performs visual encoding. @@ -39033,11 +39629,11 @@ } = encode; let code = 'var o=item,datum=o.datum,m=0,$;'; for (const name in channels) { const o = 'o[' + $(name) + ']'; - code += `$=${channels[name].code};if(${o}!==$)${o}=$,m=1;`; + code += "$=".concat(channels[name].code, ";if(").concat(o, "!==$)").concat(o, "=$,m=1;"); } code += adjustSpatial(channels, marktype); code += 'return m;'; return expression(ctx, ['item', '_'], code); @@ -39046,12 +39642,12 @@ /** * Optimized code generators for access and comparison. */ codegen: { get(path) { - const ref = `[${path.map($).join('][')}]`; - const get = Function('_', `return _${ref};`); + const ref = "[".concat(path.map($).join(']['), "]"); + const get = Function('_', "return _".concat(ref, ";")); get.path = ref; return get; }, comparator(fields, orders) { @@ -39060,16 +39656,16 @@ const map = (f, i) => { const o = orders[i]; let u, v; if (f.path) { - u = `a${f.path}`; - v = `b${f.path}`; + u = "a".concat(f.path); + v = "b".concat(f.path); } else { (t = t || {})['f' + i] = f; - u = `this.f${i}(a)`; - v = `this.f${i}(b)`; + u = "this.f".concat(i, "(a)"); + v = "this.f".concat(i, "(b)"); } return _compare(u, v, -o, o); }; @@ -39842,11 +40438,11 @@ function permit(view, key, type) { const rule = view._eventConfig && view._eventConfig[key]; if (rule === false || isObject(rule) && !rule[type]) { - view.warn(`Blocked ${key} ${type} event listener.`); + view.warn("Blocked ".concat(key, " ").concat(type, " event listener.")); return false; } return true; } @@ -40328,11 +40924,11 @@ } } if (el && clear) { try { - el.innerHTML = ''; + el.textContent = ''; } catch (e) { el = null; view.error(e); } } @@ -41343,47 +41939,47 @@ } : { value: value }; } - const scaleRef = scale => isString(scale) ? $(scale) : scale.signal ? `(${scale.signal})` : field(scale); + const scaleRef = scale => isString(scale) ? $(scale) : scale.signal ? "(".concat(scale.signal, ")") : field(scale); function entry$1(enc) { if (enc.gradient != null) { return gradient(enc); } - let value = enc.signal ? `(${enc.signal})` : enc.color ? color(enc.color) : enc.field != null ? field(enc.field) : enc.value !== undefined ? $(enc.value) : undefined; + let value = enc.signal ? "(".concat(enc.signal, ")") : enc.color ? color(enc.color) : enc.field != null ? field(enc.field) : enc.value !== undefined ? $(enc.value) : undefined; if (enc.scale != null) { value = scale(enc, value); } if (value === undefined) { value = null; } if (enc.exponent != null) { - value = `pow(${value},${property(enc.exponent)})`; + value = "pow(".concat(value, ",").concat(property(enc.exponent), ")"); } if (enc.mult != null) { - value += `*${property(enc.mult)}`; + value += "*".concat(property(enc.mult)); } if (enc.offset != null) { - value += `+${property(enc.offset)}`; + value += "+".concat(property(enc.offset)); } if (enc.round) { - value = `round(${value})`; + value = "round(".concat(value, ")"); } return value; } - const _color = (type, x, y, z) => `(${type}(${[x, y, z].map(entry$1).join(',')})+'')`; + const _color = (type, x, y, z) => "(".concat(type, "(").concat([x, y, z].map(entry$1).join(','), ")+'')"); function color(enc) { return enc.c ? _color('hcl', enc.h, enc.c, enc.l) : enc.h || enc.s ? _color('hsl', enc.h, enc.s, enc.l) : enc.l || enc.a ? _color('lab', enc.l, enc.a, enc.b) : enc.r || enc.g || enc.b ? _color('rgb', enc.r, enc.g, enc.b) : null; } @@ -41392,11 +41988,11 @@ const args = [enc.start, enc.stop, enc.count].map(_ => _ == null ? null : $(_)); // trim null inputs from the end while (args.length && peek$1(args) == null) args.pop(); args.unshift(scaleRef(enc.gradient)); - return `gradient(${args.join(',')})`; + return "gradient(".concat(args.join(','), ")"); } function property(property) { return isObject(property) ? '(' + entry$1(property) + ')' : property; } @@ -41444,21 +42040,21 @@ function scale(enc, value) { const scale = scaleRef(enc.scale); if (enc.range != null) { // pull value from scale range - value = `lerp(_range(${scale}), ${+enc.range})`; + value = "lerp(_range(".concat(scale, "), ").concat(+enc.range, ")"); } else { // run value through scale and/or pull scale bandwidth - if (value !== undefined) value = `_scale(${scale}, ${value})`; + if (value !== undefined) value = "_scale(".concat(scale, ", ").concat(value, ")"); if (enc.band) { - value = (value ? value + '+' : '') + `_bandwidth(${scale})` + (+enc.band === 1 ? '' : '*' + property(enc.band)); + value = (value ? value + '+' : '') + "_bandwidth(".concat(scale, ")") + (+enc.band === 1 ? '' : '*' + property(enc.band)); if (enc.extra) { // include logic to handle extraneous elements - value = `(datum.extra ? _scale(${scale}, datum.extra.value) : ${value})`; + value = "(datum.extra ? _scale(".concat(scale, ", datum.extra.value) : ").concat(value, ")"); } } if (value == null) value = '0'; } @@ -41468,11 +42064,11 @@ function rule(enc) { let code = ''; enc.forEach(rule => { const value = entry$1(rule); - code += rule.test ? `(${rule.test})?${value}:` : value; + code += rule.test ? "(".concat(rule.test, ")?").concat(value, ":") : value; }); // if no else clause, terminate with null (#1366) if (peek$1(code) === ':') { code += 'null'; } @@ -42227,11 +42823,11 @@ const s = scope.config.style[style]; return s && s[name]; } function anchorExpr(s, e, m) { - return `item.anchor === '${Start}' ? ${s} : item.anchor === '${End}' ? ${e} : ${m}`; + return "item.anchor === '".concat(Start, "' ? ").concat(s, " : item.anchor === '").concat(End, "' ? ").concat(e, " : ").concat(m); } const alignExpr$1 = anchorExpr($(Left), $(Right), $(Center)); function tickBand(_) { @@ -42246,19 +42842,19 @@ band = _('bandPosition'); extra = _('tickExtra'); } else if (v.signal) { // if signal, augment code to interpret values band = { - signal: `(${v.signal}) === 'extent' ? 1 : 0.5` + signal: "(".concat(v.signal, ") === 'extent' ? 1 : 0.5") }; extra = { - signal: `(${v.signal}) === 'extent'` + signal: "(".concat(v.signal, ") === 'extent'") }; if (!isObject(offset)) { offset = { - signal: `(${v.signal}) === 'extent' ? 0 : ${offset}` + signal: "(".concat(v.signal, ") === 'extent' ? 0 : ").concat(offset) }; } } else if (v === 'extent') { // if constant, simply set values band = 1; @@ -42404,12 +43000,12 @@ from: dataRef, encode }, userEncode); } - const alignExpr = `datum.${Perc}<=0?"${Left}":datum.${Perc}>=1?"${Right}":"${Center}"`, - baselineExpr = `datum.${Perc}<=0?"${Bottom}":datum.${Perc}>=1?"${Top}":"${Middle}"`; + const alignExpr = "datum.".concat(Perc, "<=0?\"").concat(Left, "\":datum.").concat(Perc, ">=1?\"").concat(Right, "\":\"").concat(Center, "\""), + baselineExpr = "datum.".concat(Perc, "<=0?\"").concat(Bottom, "\":datum.").concat(Perc, ">=1?\"").concat(Top, "\":\"").concat(Middle, "\""); function legendGradientLabels(spec, config, userEncode, dataRef) { const _ = lookup(spec, config), vertical = _.isVertical(), thickness = encoder(_.gradientThickness()), @@ -42498,16 +43094,16 @@ height = _('clipHeight'), symbolOffset = _('symbolOffset'), valueRef = { data: 'value' }, - xSignal = `(${columns}) ? datum.${Offset} : datum.${Size}`, + xSignal = "(".concat(columns, ") ? datum.").concat(Offset, " : datum.").concat(Size), yEncode = height ? encoder(height) : { field: Size }, - index = `datum.${Index}`, - ncols = `max(1, ${columns})`; + index = "datum.".concat(Index), + ncols = "max(1, ".concat(columns, ")"); let encode, enter, update, nrows, sort; yEncode.mult = 0.5; // -- LEGEND SYMBOLS -- encode = { @@ -42632,26 +43228,26 @@ } } }; // annotate and sort groups to ensure correct ordering if (_.isVertical(true)) { - nrows = `ceil(item.mark.items.length / ${ncols})`; - update.row.signal = `${index}%${nrows}`; - update.column.signal = `floor(${index} / ${nrows})`; + nrows = "ceil(item.mark.items.length / ".concat(ncols, ")"); + update.row.signal = "".concat(index, "%").concat(nrows); + update.column.signal = "floor(".concat(index, " / ").concat(nrows, ")"); sort = { field: ['row', index] }; } else { - update.row.signal = `floor(${index} / ${ncols})`; - update.column.signal = `${index} % ${ncols}`; + update.row.signal = "floor(".concat(index, " / ").concat(ncols, ")"); + update.column.signal = "".concat(index, " % ").concat(ncols); sort = { field: index }; } // handle zero column case (implies infinite columns) - update.column.signal = `(${columns})?${update.column.signal}:${index}`; // facet legend entries into sub-groups + update.column.signal = "(".concat(columns, ")?").concat(update.column.signal, ":").concat(index); // facet legend entries into sub-groups dataRef = { facet: { data: dataRef, name: 'value', @@ -42687,18 +43283,18 @@ }; } const isL = 'item.orient === "left"', isR = 'item.orient === "right"', - isLR = `(${isL} || ${isR})`, - isVG = `datum.vgrad && ${isLR}`, + isLR = "(".concat(isL, " || ").concat(isR, ")"), + isVG = "datum.vgrad && ".concat(isLR), baseline = anchorExpr('"top"', '"bottom"', '"middle"'), alignFlip = anchorExpr('"right"', '"left"', '"center"'), - exprAlign = `datum.vgrad && ${isR} ? (${alignFlip}) : (${isLR} && !(datum.vgrad && ${isL})) ? "left" : ${alignExpr$1}`, - exprAnchor = `item._anchor || (${isLR} ? "middle" : "start")`, - exprAngle = `${isVG} ? (${isL} ? -90 : 90) : 0`, - exprBaseline = `${isLR} ? (datum.vgrad ? (${isR} ? "bottom" : "top") : ${baseline}) : "top"`; + exprAlign = "datum.vgrad && ".concat(isR, " ? (").concat(alignFlip, ") : (").concat(isLR, " && !(datum.vgrad && ").concat(isL, ")) ? \"left\" : ").concat(alignExpr$1), + exprAnchor = "item._anchor || (".concat(isLR, " ? \"middle\" : \"start\")"), + exprAngle = "".concat(isVG, " ? (").concat(isL, " ? -90 : 90) : 0"), + exprBaseline = "".concat(isLR, " ? (datum.vgrad ? (").concat(isR, " ? \"bottom\" : \"top\") : ").concat(baseline, ") : \"top\""); function legendTitle(spec, config, userEncode, dataRef) { const _ = lookup(spec, config); const encode = { @@ -43427,11 +44023,11 @@ }))); // continuous gradient legend if (type === Gradient) { children = [legendGradient(spec, scale, config, encode.gradient), legendGradientLabels(spec, config, encode.labels, entryRef)]; // adjust default tick count based on the gradient length - params.count = params.count || scope.signalRef(`max(2,2*floor((${deref(_.gradientLength())})/100))`); + params.count = params.count || scope.signalRef("max(2,2*floor((".concat(deref(_.gradientLength()), ")/100))")); } // discrete gradient legend else if (type === Discrete) { children = [legendGradientDiscrete(spec, scale, config, encode.gradient, entryRef), legendGradientLabels(spec, config, encode.labels, entryRef)]; } // symbol legend else { @@ -43511,22 +44107,22 @@ function sizeExpression(spec, scope, marks) { const size = deref(getChannel('size', spec, marks)), strokeWidth = deref(getChannel('strokeWidth', spec, marks)), fontSize = deref(getFontSize(marks[1].encode, scope, GuideLabelStyle)); - return parser(`max(ceil(sqrt(${size})+${strokeWidth}),${fontSize})`, scope); + return parser("max(ceil(sqrt(".concat(size, ")+").concat(strokeWidth, "),").concat(fontSize, ")"), scope); } function getChannel(name, spec, marks) { - return spec[name] ? `scale("${spec[name]}",datum)` : getEncoding(name, marks[0].encode); + return spec[name] ? "scale(\"".concat(spec[name], "\",datum)") : getEncoding(name, marks[0].encode); } function getFontSize(encode, scope, style) { return getEncoding('fontSize', encode) || getStyle('fontSize', scope, style); } - const angleExpr = `item.orient==="${Left}"?-90:item.orient==="${Right}"?90:0`; + const angleExpr = "item.orient===\"".concat(Left, "\"?-90:item.orient===\"").concat(Right, "\"?90:0"); function parseTitle(spec, scope) { spec = isString(spec) ? { text: spec } : spec; @@ -43839,19 +44435,19 @@ value: a } : { value: b }; - const ifXEnc = ($orient, a, b) => ifEnc(`${$orient} === '${Top}' || ${$orient} === '${Bottom}'`, a, b); + const ifXEnc = ($orient, a, b) => ifEnc("".concat($orient, " === '").concat(Top, "' || ").concat($orient, " === '").concat(Bottom, "'"), a, b); - const ifYEnc = ($orient, a, b) => ifEnc(`${$orient} !== '${Top}' && ${$orient} !== '${Bottom}'`, a, b); + const ifYEnc = ($orient, a, b) => ifEnc("".concat($orient, " !== '").concat(Top, "' && ").concat($orient, " !== '").concat(Bottom, "'"), a, b); - const ifLeftTopExpr = ($orient, a, b) => ifExpr(`${$orient} === '${Left}' || ${$orient} === '${Top}'`, a, b); + const ifLeftTopExpr = ($orient, a, b) => ifExpr("".concat($orient, " === '").concat(Left, "' || ").concat($orient, " === '").concat(Top, "'"), a, b); - const ifTopExpr = ($orient, a, b) => ifExpr(`${$orient} === '${Top}'`, a, b); + const ifTopExpr = ($orient, a, b) => ifExpr("".concat($orient, " === '").concat(Top, "'"), a, b); - const ifRightExpr = ($orient, a, b) => ifExpr(`${$orient} === '${Right}'`, a, b); + const ifRightExpr = ($orient, a, b) => ifExpr("".concat($orient, " === '").concat(Right, "'"), a, b); const ifEnc = (test, a, b) => { // ensure inputs are encoder objects (or null) a = a != null ? encoder(a) : a; b = b != null ? encoder(b) : b; @@ -43859,11 +44455,11 @@ if (isSimple(a) && isSimple(b)) { // if possible generate simple signal expression a = a ? a.signal || $(a.value) : null; b = b ? b.signal || $(b.value) : null; return { - signal: `${test} ? (${a}) : (${b})` + signal: "".concat(test, " ? (").concat(a, ") : (").concat(b, ")") }; } else { // otherwise generate rule set return [extend$1({ test @@ -43872,21 +44468,21 @@ }; const isSimple = enc => enc == null || Object.keys(enc).length === 1; const ifExpr = (test, a, b) => ({ - signal: `${test} ? (${toExpr(a)}) : (${toExpr(b)})` + signal: "".concat(test, " ? (").concat(toExpr(a), ") : (").concat(toExpr(b), ")") }); const ifOrient = ($orient, t, b, l, r) => ({ - signal: (l != null ? `${$orient} === '${Left}' ? (${toExpr(l)}) : ` : '') + (b != null ? `${$orient} === '${Bottom}' ? (${toExpr(b)}) : ` : '') + (r != null ? `${$orient} === '${Right}' ? (${toExpr(r)}) : ` : '') + (t != null ? `${$orient} === '${Top}' ? (${toExpr(t)}) : ` : '') + '(null)' + signal: (l != null ? "".concat($orient, " === '").concat(Left, "' ? (").concat(toExpr(l), ") : ") : '') + (b != null ? "".concat($orient, " === '").concat(Bottom, "' ? (").concat(toExpr(b), ") : ") : '') + (r != null ? "".concat($orient, " === '").concat(Right, "' ? (").concat(toExpr(r), ") : ") : '') + (t != null ? "".concat($orient, " === '").concat(Top, "' ? (").concat(toExpr(t), ") : ") : '') + '(null)' }); const toExpr = v => isSignal(v) ? v.signal : v == null ? null : $(v); const mult = (sign, value) => value === 0 ? 0 : isSignal(sign) ? { - signal: `(${sign.signal}) * ${value}` + signal: "(".concat(sign.signal, ") * ").concat(value) } : { value: sign * value }; const patch = (value, base) => { @@ -44097,20 +44693,20 @@ } function offsetValue(offset, sign) { if (sign === 1) ;else if (!isObject(offset)) { offset = isSignal(sign) ? { - signal: `(${sign.signal}) * (${offset || 0})` + signal: "(".concat(sign.signal, ") * (").concat(offset || 0, ")") } : sign * (offset || 0); } else { let entry = offset = extend$1({}, offset); while (entry.mult != null) { if (!isObject(entry.mult)) { entry.mult = isSignal(sign) // no offset if sign === 1 ? { - signal: `(${entry.mult}) * (${sign.signal})` + signal: "(".concat(entry.mult, ") * (").concat(sign.signal, ")") } : entry.mult * sign; return offset; } else { entry = entry.mult = extend$1({}, entry.mult); } @@ -44203,11 +44799,11 @@ value: 'center' }, ifRight(orient, 'left', 'right')); const baseline = ifX(orient, ifTop(orient, 'bottom', 'top'), flushOn ? flushExpr(scale, flush, '"top"', '"bottom"', '"middle"') : { value: 'middle' }); - const offsetExpr = flushExpr(scale, flush, `-(${flushOffset})`, flushOffset, 0); + const offsetExpr = flushExpr(scale, flush, "-(".concat(flushOffset, ")"), flushOffset, 0); flushOn = flushOn && flushOffset; const enter = { opacity: zero, x: ifX(orient, tickPos, tickSize), y: ifY(orient, tickPos, tickSize) @@ -44305,11 +44901,11 @@ exit: { opacity: zero } }; const titlePos = { - signal: `lerp(range("${spec.scale}"), ${anchorExpr(0, 1, 0.5)})` + signal: "lerp(range(\"".concat(spec.scale, "\"), ").concat(anchorExpr(0, 1, 0.5), ")") }; update.x = ifX(orient, titlePos); update.y = ifY(orient, titlePos); enter.angle = ifX(orient, zero, mult(sign, 90)); enter.baseline = ifX(orient, ifTop(orient, Bottom, Top), { @@ -44439,11 +45035,11 @@ position: value(spec.position, 0), titlePadding: _('titlePadding'), minExtent: _('minExtent'), maxExtent: _('maxExtent'), range: { - signal: `abs(span(range("${spec.scale}")))` + signal: "abs(span(range(\"".concat(spec.scale, "\")))") }, translate: _('translate'), // accessibility support format: spec.format, formatType: spec.formatType @@ -45266,12 +45862,10 @@ } // -- Transforms ----- extend$1(transforms, tx, vtx, encode$1, geo, force, label, tree, reg, voronoi, wordcloud, xf); // -- Exports ----- - const version = pkg.version; - exports.Bounds = Bounds; exports.CanvasHandler = CanvasHandler; exports.CanvasRenderer = CanvasRenderer; exports.DATE = DATE; exports.DAY = DAY; @@ -45312,11 +45906,11 @@ exports.YEAR = YEAR; exports.accessor = accessor; exports.accessorFields = accessorFields; exports.accessorName = accessorName; exports.array = array$5; - exports.ascending = ascending$3; + exports.ascending = ascending$2; exports.bandwidthNRD = estimateBandwidth; exports.bin = bin; exports.bootstrapCI = bootstrapCI; exports.boundClip = boundClip; exports.boundContext = boundContext; @@ -45402,13 +45996,14 @@ exports.panPow = panPow; exports.panSymlog = panSymlog; exports.parse = parse; exports.parseExpression = parser$1; exports.parseSelector = eventSelector; + exports.path = path$3; exports.pathCurves = curves; exports.pathEqual = pathEqual; - exports.pathParse = pathParse; + exports.pathParse = parse$3; exports.pathRectangle = vg_rect; exports.pathRender = pathRender; exports.pathSymbols = symbols; exports.pathTrail = vg_trail; exports.peek = peek$1; @@ -45497,6 +46092,6 @@ exports.zoomPow = zoomPow; exports.zoomSymlog = zoomSymlog; Object.defineProperty(exports, '__esModule', { value: true }); -}))); +}));