UNPKG

@visactor/vscale

Version:

Scales for visual encoding, used in VGrammar, VTable

1,426 lines (1,368 loc) 129 kB
(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.VScale = {})); })(this, (function (exports) { 'use strict'; var eventemitter3 = {exports: {}}; (function (module) { var has = Object.prototype.hasOwnProperty, prefix = '~'; /** * Constructor to create a storage for our `EE` objects. * An `Events` instance is a plain object whose properties are event names. * * @constructor * @private */ function Events() {} // // We try to not inherit from `Object.prototype`. In some engines creating an // instance in this way is faster than calling `Object.create(null)` directly. // If `Object.create(null)` is not supported we prefix the event names with a // character to make sure that the built-in object properties are not // overridden or used as an attack vector. // if (Object.create) { Events.prototype = Object.create(null); // // This hack is needed because the `__proto__` property is still inherited in // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. // if (!new Events().__proto__) prefix = false; } /** * Representation of a single event listener. * * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} [once=false] Specify if the listener is a one-time listener. * @constructor * @private */ function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } /** * Add a listener for a given event. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} once Specify if the listener is a one-time listener. * @returns {EventEmitter} * @private */ function addListener(emitter, event, fn, context, once) { if (typeof fn !== 'function') { throw new TypeError('The listener must be a function'); } var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } /** * Clear event by name. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} evt The Event name. * @private */ function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events();else delete emitter._events[evt]; } /** * Minimal `EventEmitter` interface that is molded against the Node.js * `EventEmitter` interface. * * @constructor * @public */ function EventEmitter() { this._events = new Events(); this._eventsCount = 0; } /** * Return an array listing the events for which the emitter has registered * listeners. * * @returns {Array} * @public */ EventEmitter.prototype.eventNames = function eventNames() { var names = [], events, name; if (this._eventsCount === 0) return names; for (name in events = this._events) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; /** * Return the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Array} The registered listeners. * @public */ EventEmitter.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event, handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [handlers.fn]; for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { ee[i] = handlers[i].fn; } return ee; }; /** * Return the number of listeners listening to a given event. * * @param {(String|Symbol)} event The event name. * @returns {Number} The number of listeners. * @public */ EventEmitter.prototype.listenerCount = function listenerCount(event) { var evt = prefix ? prefix + event : event, listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; /** * Calls each of the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Boolean} `true` if the event had listeners, else `false`. * @public */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt], len = arguments.length, args, i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len - 1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length, j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; /** * Add a listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.on = function on(event, fn, context) { return addListener(this, event, fn, context, false); }; /** * Add a one-time listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.once = function once(event, fn, context) { return addListener(this, event, fn, context, true); }; /** * Remove the listeners of a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn Only remove the listeners that match this function. * @param {*} context Only remove the listeners that have this context. * @param {Boolean} once Only remove one-time listeners. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return this; if (!fn) { clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) { clearEvent(this, evt); } } else { for (var i = 0, events = [], length = listeners.length; i < length; i++) { if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) { events.push(listeners[i]); } } // // Reset the array, or remove it completely if we have no more listeners. // if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;else clearEvent(this, evt); } return this; }; /** * Remove all listeners, or those of the specified event. * * @param {(String|Symbol)} [event] The event name. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = prefix ? prefix + event : event; if (this._events[evt]) clearEvent(this, evt); } else { this._events = new Events(); this._eventsCount = 0; } return this; }; // // Alias methods names because people roll like that. // EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.addListener = EventEmitter.prototype.on; // // Expose the prefix. // EventEmitter.prefixed = prefix; // // Allow `EventEmitter` to be imported as module namespace. // EventEmitter.EventEmitter = EventEmitter; // // Expose the module. // { module.exports = EventEmitter; } })(eventemitter3); const isType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`; var isType$1 = isType; const isFunction = value => "function" == typeof value; var isFunction$1 = isFunction; const isNil = value => null == value; var isNil$1 = isNil; const isValid = value => null != value; var isValid$1 = isValid; const isString = (value, fuzzy = !1) => { const type = typeof value; return fuzzy ? "string" === type : "string" === type || isType$1(value, "String"); }; var isString$1 = isString; const isArray = value => Array.isArray ? Array.isArray(value) : isType$1(value, "Array"); var isArray$1 = isArray; const isNumber = (value, fuzzy = !1) => { const type = typeof value; return fuzzy ? "number" === type : "number" === type || isType$1(value, "Number"); }; var isNumber$1 = isNumber; const isValidNumber = value => isNumber$1(value) && Number.isFinite(value); var isValidNumber$1 = isValidNumber; function keys(obj) { if (!obj) return []; if (Object.keys) return Object.keys(obj); const keyList = []; for (const key in obj) obj.hasOwnProperty(key) && keyList.push(key); return keyList; } function defaults(target, source, overlay) { const keysArr = keys(source); for (let i = 0; i < keysArr.length; i++) { const key = keysArr[i]; (overlay ? null != source[key] : null == target[key]) && (target[key] = source[key]); } return target; } function mixin(target, source, override = !0) { if (target = "prototype" in target ? target.prototype : target, source = "prototype" in source ? source.prototype : source, Object.getOwnPropertyNames) { const keyList = Object.getOwnPropertyNames(source); for (let i = 0; i < keyList.length; i++) { const key = keyList[i]; "constructor" !== key && (override ? null != source[key] : null == target[key]) && (target[key] = source[key]); } } else defaults(target, source, override); } function arrayEqual(a, b) { if (!isArray$1(a) || !isArray$1(b)) return !1; if (a.length !== b.length) return !1; for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return !1; return !0; } function range(start, stop, step) { isValid$1(stop) || (stop = start, start = 0), isValid$1(step) || (step = 1); let i = -1; const n = 0 | Math.max(0, Math.ceil((stop - start) / step)), range = new Array(n); for (; ++i < n;) range[i] = start + i * step; return range; } function ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } function toNumber(a) { return Number(a); } function quantileSorted(values, percent, valueof = toNumber) { const n = values.length; if (!n) return; if (percent <= 0 || n < 2) return valueof(values[0], 0, values); if (percent >= 1) return valueof(values[n - 1], n - 1, values); const i = (n - 1) * percent, i0 = Math.floor(i), value0 = valueof(values[i0], i0, values); return value0 + (valueof(values[i0 + 1], i0 + 1, values) - value0) * (i - i0); } function bisect(a, x, lo = 0, hi) { for (isNil$1(hi) && (hi = a.length); lo < hi;) { const mid = lo + hi >>> 1; ascending(a[mid], x) > 0 ? hi = mid : lo = mid + 1; } return lo; } const e10$1 = Math.sqrt(50), e5$1 = Math.sqrt(10), e2$1 = Math.sqrt(2); function tickStep(start, stop, count) { const step0 = Math.abs(stop - start) / Math.max(0, count); let step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)); const error = step0 / step1; return error >= e10$1 ? step1 *= 10 : error >= e5$1 ? step1 *= 5 : error >= e2$1 && (step1 *= 2), stop < start ? -step1 : step1; } const DEFAULT_ABSOLUTE_TOLERATE = 1e-10, DEFAULT_RELATIVE_TOLERATE = 1e-10; function isNumberClose(a, b, relTol = DEFAULT_RELATIVE_TOLERATE, absTol = DEFAULT_ABSOLUTE_TOLERATE) { const abs = absTol, rel = relTol * Math.max(a, b); return Math.abs(a - b) <= Math.max(abs, rel); } function isGreater(a, b, relTol, absTol) { return a > b && !isNumberClose(a, b, relTol, absTol); } function isLess(a, b, relTol, absTol) { return a < b && !isNumberClose(a, b, relTol, absTol); } const memoize = func => { let lastArgs = null, lastResult = null; return (...args) => (lastArgs && args.every((val, i) => val === lastArgs[i]) || (lastArgs = args, lastResult = func(...args)), lastResult); }; const repeat = (str, repeatCount = 0) => { let s = "", i = repeatCount - 1; for (; i >= 0;) s = `${s}${str}`, i -= 1; return s; }, pad = (str, length, padChar = " ", align = "right") => { const c = padChar, s = str + "", n = length - s.length; return n <= 0 ? s : "left" === align ? repeat(c, n) + s : "center" === align ? repeat(c, Math.floor(n / 2)) + s + repeat(c, Math.ceil(n / 2)) : s + repeat(c, n); }; var pad$1 = pad; const clamp = function (input, min, max) { return input < min ? min : input > max ? max : input; }; var clamp$1 = clamp; function clamper(a, b) { let t; return a > b && (t = a, a = b, b = t), x => Math.max(a, Math.min(b, x)); } function interpolateNumber(a, b) { return t => a * (1 - t) + b * t; } function interpolateNumberRound(a, b) { return function (t) { return Math.round(a * (1 - t) + b * t); }; } function interpolateDate(a, b) { const aVal = a.valueOf(), bVal = b.valueOf(), d = new Date(); return t => (d.setTime(aVal * (1 - t) + bVal * t), d); } const TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d{1,2})(?::(\d{1,2})(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; function toDate(val) { if (val instanceof Date) return val; if (isString$1(val)) { const match = TIME_REG.exec(val); if (!match) return new Date(NaN); if (!match[8]) return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0); let hour = +match[4] || 0; return "Z" !== match[8].toUpperCase() && (hour -= +match[8].slice(0, 3)), new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0)); } return isNil$1(val) ? new Date(NaN) : new Date(Math.round(val)); } function hslToRgb(h, s, l) { s /= 100, l /= 100; const c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(h / 60 % 2 - 1)), m = l - c / 2; let r = 0, g = 0, b = 0; return 0 <= h && h < 60 ? (r = c, g = x, b = 0) : 60 <= h && h < 120 ? (r = x, g = c, b = 0) : 120 <= h && h < 180 ? (r = 0, g = c, b = x) : 180 <= h && h < 240 ? (r = 0, g = x, b = c) : 240 <= h && h < 300 ? (r = x, g = 0, b = c) : 300 <= h && h < 360 && (r = c, g = 0, b = x), r = Math.round(255 * (r + m)), g = Math.round(255 * (g + m)), b = Math.round(255 * (b + m)), { r: r, g: g, b: b }; } function rgbToHsl(r, g, b) { r /= 255, g /= 255, b /= 255; const cMin = Math.min(r, g, b), cMax = Math.max(r, g, b), delta = cMax - cMin; let h = 0, s = 0, l = 0; return h = 0 === delta ? 0 : cMax === r ? (g - b) / delta % 6 : cMax === g ? (b - r) / delta + 2 : (r - g) / delta + 4, h = Math.round(60 * h), h < 0 && (h += 360), l = (cMax + cMin) / 2, s = 0 === delta ? 0 : delta / (1 - Math.abs(2 * l - 1)), s = +(100 * s).toFixed(1), l = +(100 * l).toFixed(1), { h: h, s: s, l: l }; } const REG_HEX = /^#([0-9a-f]{3,8})$/, DEFAULT_COLORS_OPACITY = { transparent: 4294967040 }; const DEFAULT_COLORS = { aliceblue: 15792383, antiquewhite: 16444375, aqua: 65535, aquamarine: 8388564, azure: 15794175, beige: 16119260, bisque: 16770244, black: 0, blanchedalmond: 16772045, blue: 255, blueviolet: 9055202, brown: 10824234, burlywood: 14596231, cadetblue: 6266528, chartreuse: 8388352, chocolate: 13789470, coral: 16744272, cornflowerblue: 6591981, cornsilk: 16775388, crimson: 14423100, cyan: 65535, darkblue: 139, darkcyan: 35723, darkgoldenrod: 12092939, darkgray: 11119017, darkgreen: 25600, darkgrey: 11119017, darkkhaki: 12433259, darkmagenta: 9109643, darkolivegreen: 5597999, darkorange: 16747520, darkorchid: 10040012, darkred: 9109504, darksalmon: 15308410, darkseagreen: 9419919, darkslateblue: 4734347, darkslategray: 3100495, darkslategrey: 3100495, darkturquoise: 52945, darkviolet: 9699539, deeppink: 16716947, deepskyblue: 49151, dimgray: 6908265, dimgrey: 6908265, dodgerblue: 2003199, firebrick: 11674146, floralwhite: 16775920, forestgreen: 2263842, fuchsia: 16711935, gainsboro: 14474460, ghostwhite: 16316671, gold: 16766720, goldenrod: 14329120, gray: 8421504, green: 32768, greenyellow: 11403055, grey: 8421504, honeydew: 15794160, hotpink: 16738740, indianred: 13458524, indigo: 4915330, ivory: 16777200, khaki: 15787660, lavender: 15132410, lavenderblush: 16773365, lawngreen: 8190976, lemonchiffon: 16775885, lightblue: 11393254, lightcoral: 15761536, lightcyan: 14745599, lightgoldenrodyellow: 16448210, lightgray: 13882323, lightgreen: 9498256, lightgrey: 13882323, lightpink: 16758465, lightsalmon: 16752762, lightseagreen: 2142890, lightskyblue: 8900346, lightslategray: 7833753, lightslategrey: 7833753, lightsteelblue: 11584734, lightyellow: 16777184, lime: 65280, limegreen: 3329330, linen: 16445670, magenta: 16711935, maroon: 8388608, mediumaquamarine: 6737322, mediumblue: 205, mediumorchid: 12211667, mediumpurple: 9662683, mediumseagreen: 3978097, mediumslateblue: 8087790, mediumspringgreen: 64154, mediumturquoise: 4772300, mediumvioletred: 13047173, midnightblue: 1644912, mintcream: 16121850, mistyrose: 16770273, moccasin: 16770229, navajowhite: 16768685, navy: 128, oldlace: 16643558, olive: 8421376, olivedrab: 7048739, orange: 16753920, orangered: 16729344, orchid: 14315734, palegoldenrod: 15657130, palegreen: 10025880, paleturquoise: 11529966, palevioletred: 14381203, papayawhip: 16773077, peachpuff: 16767673, peru: 13468991, pink: 16761035, plum: 14524637, powderblue: 11591910, purple: 8388736, rebeccapurple: 6697881, red: 16711680, rosybrown: 12357519, royalblue: 4286945, saddlebrown: 9127187, salmon: 16416882, sandybrown: 16032864, seagreen: 3050327, seashell: 16774638, sienna: 10506797, silver: 12632256, skyblue: 8900331, slateblue: 6970061, slategray: 7372944, slategrey: 7372944, snow: 16775930, springgreen: 65407, steelblue: 4620980, tan: 13808780, teal: 32896, thistle: 14204888, tomato: 16737095, turquoise: 4251856, violet: 15631086, wheat: 16113331, white: 16777215, whitesmoke: 16119285, yellow: 16776960, yellowgreen: 10145074 }; function hex(value) { return ((value = Math.max(0, Math.min(255, Math.round(value) || 0))) < 16 ? "0" : "") + value.toString(16); } function rgb(value) { return isNumber$1(value) ? new RGB(value >> 16, value >> 8 & 255, 255 & value, 1) : isArray$1(value) ? new RGB(value[0], value[1], value[2]) : new RGB(255, 255, 255); } function rgba(value) { return isNumber$1(value) ? new RGB(value >>> 24, value >>> 16 & 255, value >>> 8 & 255, 255 & value) : isArray$1(value) ? new RGB(value[0], value[1], value[2], value[3]) : new RGB(255, 255, 255, 1); } function SRGBToLinear(c) { return c < .04045 ? .0773993808 * c : Math.pow(.9478672986 * c + .0521327014, 2.4); } function LinearToSRGB(c) { return c < .0031308 ? 12.92 * c : 1.055 * Math.pow(c, .41666) - .055; } const setHex = (formatValue, forceHex) => { const isHex = REG_HEX.exec(formatValue); if (forceHex || isHex) { const hex = parseInt(isHex[1], 16), hexLength = isHex[1].length; return 3 === hexLength ? new RGB((hex >> 8 & 15) + ((hex >> 8 & 15) << 4), (hex >> 4 & 15) + ((hex >> 4 & 15) << 4), (15 & hex) + ((15 & hex) << 4), 1) : 6 === hexLength ? rgb(hex) : 8 === hexLength ? new RGB(hex >> 24 & 255, hex >> 16 & 255, hex >> 8 & 255, (255 & hex) / 255) : null; } }; class Color { static Brighter(source, b = 1) { return 1 === b ? source : new Color(source).brighter(b).toRGBA(); } static SetOpacity(source, o = 1) { return 1 === o ? source : new Color(source).setOpacity(o).toRGBA(); } static getColorBrightness(source, model = "hsl") { const color = source instanceof Color ? source : new Color(source); switch (model) { case "hsv": default: return color.getHSVBrightness(); case "hsl": return color.getHSLBrightness(); case "lum": return color.getLuminance(); case "lum2": return color.getLuminance2(); case "lum3": return color.getLuminance3(); case "wcag": return color.getLuminanceWCAG(); } } static parseColorString(value) { if (isValid$1(DEFAULT_COLORS_OPACITY[value])) return rgba(DEFAULT_COLORS_OPACITY[value]); if (isValid$1(DEFAULT_COLORS[value])) return rgb(DEFAULT_COLORS[value]); const formatValue = `${value}`.trim().toLowerCase(), hexRes = setHex(formatValue); if (void 0 !== hexRes) return hexRes; if (/^(rgb|RGB|rgba|RGBA)/.test(formatValue)) { const aColor = formatValue.replace(/(?:\(|\)|rgba|RGBA|rgb|RGB)*/g, "").split(","); return new RGB(parseInt(aColor[0], 10), parseInt(aColor[1], 10), parseInt(aColor[2], 10), parseFloat(aColor[3])); } if (/^(hsl|HSL|hsla|HSLA)/.test(formatValue)) { const aColor = formatValue.replace(/(?:\(|\)|hsla|HSLA|hsl|HSL)*/g, "").split(","), rgb = hslToRgb(parseInt(aColor[0], 10), parseInt(aColor[1], 10), parseInt(aColor[2], 10)); return new RGB(rgb.r, rgb.g, rgb.b, parseFloat(aColor[3])); } } constructor(value) { const color = Color.parseColorString(value); color ? this.color = color : (console.warn(`Warn: 传入${value}无法解析为Color`), this.color = new RGB(255, 255, 255)); } toRGBA() { return this.color.formatRgb(); } toString() { return this.color.formatRgb(); } toHex() { return this.color.formatHex(); } toHsl() { return this.color.formatHsl(); } brighter(k) { const { r: r, g: g, b: b } = this.color; return this.color.r = Math.max(0, Math.min(255, Math.floor(r * k))), this.color.g = Math.max(0, Math.min(255, Math.floor(g * k))), this.color.b = Math.max(0, Math.min(255, Math.floor(b * k))), this; } add(color) { const { r: r, g: g, b: b } = this.color; return this.color.r += Math.min(255, r + color.color.r), this.color.g += Math.min(255, g + color.color.g), this.color.b += Math.min(255, b + color.color.b), this; } sub(color) { return this.color.r = Math.max(0, this.color.r - color.color.r), this.color.g = Math.max(0, this.color.g - color.color.g), this.color.b = Math.max(0, this.color.b - color.color.b), this; } multiply(color) { const { r: r, g: g, b: b } = this.color; return this.color.r = Math.max(0, Math.min(255, Math.floor(r * color.color.r))), this.color.g = Math.max(0, Math.min(255, Math.floor(g * color.color.g))), this.color.b = Math.max(0, Math.min(255, Math.floor(b * color.color.b))), this; } getHSVBrightness() { return Math.max(this.color.r, this.color.g, this.color.b) / 255; } getHSLBrightness() { return .5 * (Math.max(this.color.r, this.color.g, this.color.b) / 255 + Math.min(this.color.r, this.color.g, this.color.b) / 255); } setHsl(h, s, l) { const opacity = this.color.opacity, hsl = rgbToHsl(this.color.r, this.color.g, this.color.b), rgb = hslToRgb(isNil$1(h) ? hsl.h : clamp$1(h, 0, 360), isNil$1(s) ? hsl.s : s >= 0 && s <= 1 ? 100 * s : s, isNil$1(l) ? hsl.l : l <= 1 && l >= 0 ? 100 * l : l); return this.color = new RGB(rgb.r, rgb.g, rgb.b, opacity), this; } setRGB(r, g, b) { return !isNil$1(r) && (this.color.r = r), !isNil$1(g) && (this.color.g = g), !isNil$1(b) && (this.color.b = b), this; } setHex(value) { const formatValue = `${value}`.trim().toLowerCase(), res = setHex(formatValue, !0); return null != res ? res : this; } setColorName(name) { const hex = DEFAULT_COLORS[name.toLowerCase()]; return void 0 !== hex ? this.setHex(hex) : console.warn("THREE.Color: Unknown color " + name), this; } setScalar(scalar) { return this.color.r = scalar, this.color.g = scalar, this.color.b = scalar, this; } setOpacity(o = 1) { return this.color.opacity = o, this; } getLuminance() { return (.2126 * this.color.r + .7152 * this.color.g + .0722 * this.color.b) / 255; } getLuminance2() { return (.2627 * this.color.r + .678 * this.color.g + .0593 * this.color.b) / 255; } getLuminance3() { return (.299 * this.color.r + .587 * this.color.g + .114 * this.color.b) / 255; } getLuminanceWCAG() { const RsRGB = this.color.r / 255, GsRGB = this.color.g / 255, BsRGB = this.color.b / 255; let R, G, B; R = RsRGB <= .03928 ? RsRGB / 12.92 : Math.pow((RsRGB + .055) / 1.055, 2.4), G = GsRGB <= .03928 ? GsRGB / 12.92 : Math.pow((GsRGB + .055) / 1.055, 2.4), B = BsRGB <= .03928 ? BsRGB / 12.92 : Math.pow((BsRGB + .055) / 1.055, 2.4); return .2126 * R + .7152 * G + .0722 * B; } clone() { return new Color(this.color.toString()); } copyGammaToLinear(color, gammaFactor = 2) { return this.color.r = Math.pow(color.color.r, gammaFactor), this.color.g = Math.pow(color.color.g, gammaFactor), this.color.b = Math.pow(color.color.b, gammaFactor), this; } copyLinearToGamma(color, gammaFactor = 2) { const safeInverse = gammaFactor > 0 ? 1 / gammaFactor : 1; return this.color.r = Math.pow(color.color.r, safeInverse), this.color.g = Math.pow(color.color.g, safeInverse), this.color.b = Math.pow(color.color.b, safeInverse), this; } convertGammaToLinear(gammaFactor) { return this.copyGammaToLinear(this, gammaFactor), this; } convertLinearToGamma(gammaFactor) { return this.copyLinearToGamma(this, gammaFactor), this; } copySRGBToLinear(color) { return this.color.r = SRGBToLinear(color.color.r), this.color.g = SRGBToLinear(color.color.g), this.color.b = SRGBToLinear(color.color.b), this; } copyLinearToSRGB(color) { return this.color.r = LinearToSRGB(color.color.r), this.color.g = LinearToSRGB(color.color.g), this.color.b = LinearToSRGB(color.color.b), this; } convertSRGBToLinear() { return this.copySRGBToLinear(this), this; } convertLinearToSRGB() { return this.copyLinearToSRGB(this), this; } } class RGB { constructor(r, g, b, opacity) { this.r = isNaN(+r) ? 255 : Math.max(0, Math.min(255, +r)), this.g = isNaN(+g) ? 255 : Math.max(0, Math.min(255, +g)), this.b = isNaN(+b) ? 255 : Math.max(0, Math.min(255, +b)), isValid$1(opacity) ? this.opacity = isNaN(+opacity) ? 1 : Math.max(0, Math.min(1, +opacity)) : this.opacity = 1; } formatHex() { return `#${hex(this.r) + hex(this.g) + hex(this.b) + (1 === this.opacity ? "" : hex(255 * this.opacity))}`; } formatRgb() { const opacity = this.opacity; return `${1 === opacity ? "rgb(" : "rgba("}${this.r},${this.g},${this.b}${1 === opacity ? ")" : `,${opacity})`}`; } formatHsl() { const opacity = this.opacity, { h: h, s: s, l: l } = rgbToHsl(this.r, this.g, this.b); return `${1 === opacity ? "hsl(" : "hsla("}${h},${s}%,${l}%${1 === opacity ? ")" : `,${opacity})`}`; } toString() { return this.formatHex(); } } function hexToRgb(str) { let r = "", g = "", b = ""; const strtIndex = "#" === str[0] ? 1 : 0; for (let i = strtIndex; i < str.length; i++) "#" !== str[i] && (i < strtIndex + 2 ? r += str[i] : i < strtIndex + 4 ? g += str[i] : i < strtIndex + 6 && (b += str[i])); return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)]; } function rgbToHex(r, g, b) { return Number((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } function interpolateRgb$1(colorA, colorB) { const redA = colorA.r, redB = colorB.r, greenA = colorA.g, greenB = colorB.g, blueA = colorA.b, blueB = colorB.b, opacityA = colorA.opacity, opacityB = colorB.opacity; return t => { const r = Math.round(redA * (1 - t) + redB * t), g = Math.round(greenA * (1 - t) + greenB * t), b = Math.round(blueA * (1 - t) + blueB * t); return new RGB(r, g, b, opacityA * (1 - t) + opacityB * t); }; } var ColorUtil = /*#__PURE__*/Object.freeze({ __proto__: null, Color: Color, DEFAULT_COLORS: DEFAULT_COLORS, RGB: RGB, hexToRgb: hexToRgb, hslToRgb: hslToRgb, interpolateRgb: interpolateRgb$1, rgbToHex: rgbToHex, rgbToHsl: rgbToHsl }); function fullYearGetterName(isUTC) { return isUTC ? "getUTCFullYear" : "getFullYear"; } function monthGetterName(isUTC) { return isUTC ? "getUTCMonth" : "getMonth"; } function dateGetterName(isUTC) { return isUTC ? "getUTCDate" : "getDate"; } function hoursGetterName(isUTC) { return isUTC ? "getUTCHours" : "getHours"; } function minutesGetterName(isUTC) { return isUTC ? "getUTCMinutes" : "getMinutes"; } function secondsGetterName(isUTC) { return isUTC ? "getUTCSeconds" : "getSeconds"; } function millisecondsGetterName(isUTC) { return isUTC ? "getUTCMilliseconds" : "getMilliseconds"; } function fullYearSetterName(isUTC) { return isUTC ? "setUTCFullYear" : "setFullYear"; } function monthSetterName(isUTC) { return isUTC ? "setUTCMonth" : "setMonth"; } function hoursSetterName(isUTC) { return isUTC ? "setUTCHours" : "setHours"; } function getFormatFromValue(value, isUTC) { const date = toDate(value), M = date[monthGetterName(isUTC)]() + 1, d = date[dateGetterName(isUTC)](), h = date[hoursGetterName(isUTC)](), m = date[minutesGetterName(isUTC)](), s = date[secondsGetterName(isUTC)](), isSecond = 0 === date[millisecondsGetterName(isUTC)](), isMinute = isSecond && 0 === s, isHour = isMinute && 0 === m, isDay = isHour && 0 === h, isMonth = isDay && 1 === d; return isMonth && 1 === M ? "YYYY" : isMonth ? "YYYY-MM" : isDay ? "YYYY-MM-DD" : isHour ? "HH" : isMinute ? "HH:mm" : isSecond ? "HH:mm:ss" : "HH:mm:ss SSS"; } function getTimeFormatter(template, isUTC) { return time => { const date = toDate(time), y = date[fullYearGetterName(isUTC)](), M = date[monthGetterName(isUTC)]() + 1, q = Math.floor((M - 1) / 3) + 1, d = date[dateGetterName(isUTC)](), e = date["get" + (isUTC ? "UTC" : "") + "Day"](), H = date[hoursGetterName(isUTC)](), h = (H - 1) % 12 + 1, m = date[minutesGetterName(isUTC)](), s = date[secondsGetterName(isUTC)](), S = date[millisecondsGetterName(isUTC)](); return (template || "").replace(/YYYY/g, pad$1(y + "", 4, "0", "left")).replace(/yyyy/g, y + "").replace(/yy/g, y % 100 + "").replace(/Q/g, q + "").replace(/MM/g, pad$1(M, 2, "0", "left")).replace(/M/g, M + "").replace(/dd/g, pad$1(d, 2, "0", "left")).replace(/d/g, d + "").replace(/e/g, e + "").replace(/HH/g, pad$1(H, 2, "0", "left")).replace(/H/g, H + "").replace(/hh/g, pad$1(h + "", 2, "0", "left")).replace(/h/g, h + "").replace(/mm/g, pad$1(m, 2, "0", "left")).replace(/m/g, m + "").replace(/ss/g, pad$1(s, 2, "0", "left")).replace(/s/g, s + "").replace(/SSS/g, pad$1(S, 3, "0", "left")).replace(/S/g, S + ""); }; } const SECOND = 1e3; const MINUTE = 6e4; const HOUR = 36e5; const DAY = 24 * HOUR; const MONTH = 31 * DAY; const YEAR = 365 * DAY; const yearFloor = date => (date.setMonth(0, 1), date.setHours(0, 0, 0, 0), date); const yearOffset = (date, step) => (date.setFullYear(date.getFullYear() + step), date); const yearCount = (start, end) => end.getFullYear() - start.getFullYear(); const yearField = date => date.getFullYear(); const utcYearFloor = date => (date.setUTCMonth(0, 1), date.setUTCHours(0, 0, 0, 0), date); const utcYearOffset = (date, step) => (date.setUTCFullYear(date.getUTCFullYear() + step), date); const utcYearCount = (start, end) => end.getUTCFullYear() - start.getUTCFullYear(); const utcYearField = date => date.getUTCFullYear(); const monthFloor = date => (date.setDate(1), date.setHours(0, 0, 0, 0), date); const monthOffset = (date, step) => (date.setMonth(date.getMonth() + step), date); const monthCount = (start, end) => end.getMonth() - start.getMonth() + 12 * (end.getFullYear() - start.getFullYear()); const monthField = date => date.getMonth(); const utcMonthFloor = date => (date.setUTCDate(1), date.setUTCHours(0, 0, 0, 0), date); const utcMonthOffset = (date, step) => (date.setUTCMonth(date.getUTCMonth() + step), date); const utcMonthCount = (start, end) => end.getUTCMonth() - start.getUTCMonth() + 12 * (end.getUTCFullYear() - start.getUTCFullYear()); const utcMonthField = date => date.getUTCMonth(); const dayFloor = date => (date.setHours(0, 0, 0, 0), date); const dayOffset = (date, step) => (date.setDate(date.getDate() + step), date); const dayCount = (start, end) => (+end - +start - 6e4 * (end.getTimezoneOffset() - start.getTimezoneOffset())) / DAY; const dayField = date => date.getDate() - 1; const utcDayFloor = date => (date.setUTCHours(0, 0, 0, 0), date); const utcDayOffset = (date, step) => (date.setUTCDate(date.getUTCDate() + step), date); const utcDayCount = (start, end) => (+end - +start) / DAY; const utcDayField = date => date.getUTCDate() - 1; const hourFloor = date => (date.setTime(+date - date.getMilliseconds() - 1e3 * date.getSeconds() - 6e4 * date.getMinutes()), date); const hourOffset = (date, step) => (date.setHours(date.getHours() + step), date); const hourCount = (start, end) => (+end - +start) / HOUR; const hourField = date => date.getHours(); const utcHourFloor = date => (date.setTime(+date - date.getUTCMilliseconds() - 1e3 * date.getUTCSeconds() - 6e4 * date.getUTCMinutes()), date); const utcHourOffset = (date, step) => (date.setUTCHours(date.getUTCHours() + step), date); const utcHourField = date => date.getUTCHours(); const minuteFloor = date => (date.setTime(+date - date.getMilliseconds() - 1e3 * date.getSeconds()), date); const minuteOffset = (date, step) => (date.setMinutes(date.getMinutes() + step), date); const minuteCount = (start, end) => (+end - +start) / 6e4; const minuteField = date => date.getMinutes(); const utcMinuteFloor = date => (date.setTime(+date - date.getUTCMilliseconds() - 1e3 * date.getUTCSeconds()), date); const utcMinuteOffset = (date, step) => (date.setUTCMinutes(date.getUTCMinutes() + step), date); const utcMinuteField = date => date.getUTCMinutes(); const secondFloor = date => (date.setTime(+date - date.getMilliseconds()), date); const secondOffset = (date, step) => (date.setSeconds(date.getSeconds() + step), date); const secondCount = (start, end) => (+end - +start) / 1e3; const secondField = date => date.getSeconds(); const utcSecondFloor = date => (date.setTime(+date - date.getUTCMilliseconds()), date); const utcSecondOffset = (date, step) => (date.setUTCSeconds(date.getUTCSeconds() + step), date); const utcSecondField = date => date.getUTCSeconds(); const millisecondsFloor = date => date; const millisecondsOffset = (date, step) => (date.setTime(+date + step), date); const millisecondsCount = (start, end) => +end - +start; const generateCeil = (floor, offset) => date => { const n = new Date(+date - 1); return offset(n, 1), floor(n), n; }; const generateCount = (floor, count) => (start, end) => { const a = new Date(), b = new Date(); return a.setTime(+start), b.setTime(+end), floor(a), floor(b), Math.floor(count(a, b)); }; const generateStepInterval = (step, { floor: floor, offset: offset, field: field, count: count }) => { const s = Math.floor(step); if (!Number.isFinite(s) || s <= 0) return null; if (s <= 1) return { floor: floor, offset: offset, ceil: generateCeil(floor, offset) }; const stepCount = generateCount(floor, count), testFunc = field ? d => field(d) % s == 0 : d => stepCount(0, d) % s == 0, stepFloor = date => { if (!Number.isNaN(+date)) for (floor(date); !testFunc(date);) date.setTime(+date - 1), floor(date); return date; }, stepOffset = (date, stepCount) => { if (!Number.isNaN(+date)) if (s < 0) for (; ++stepCount <= 0;) for (offset(date, -1); !testFunc(date);) offset(date, -1);else for (; --stepCount >= 0;) for (offset(date, 1); !testFunc(date);) offset(date, 1); return date; }; return { floor: stepFloor, offset: stepOffset, ceil: generateCeil(stepFloor, stepOffset) }; }; const getIntervalOptions = (type, isUTC) => "year" === type && isUTC ? { floor: utcYearFloor, offset: utcYearOffset, count: utcYearCount, field: utcYearField } : "month" === type && isUTC ? { floor: utcMonthFloor, offset: utcMonthOffset, count: utcMonthCount, field: utcMonthField } : "day" === type && isUTC ? { floor: utcDayFloor, offset: utcDayOffset, count: utcDayCount, field: utcDayField } : "hour" === type && isUTC ? { floor: utcHourFloor, offset: utcHourOffset, count: hourCount, field: utcHourField } : "minute" === type && isUTC ? { floor: utcMinuteFloor, offset: utcMinuteOffset, count: minuteCount, field: utcMinuteField } : "second" === type && isUTC ? { floor: utcSecondFloor, offset: utcSecondOffset, count: secondCount, field: utcSecondField } : "year" === type ? { floor: yearFloor, offset: yearOffset, count: yearCount, field: yearField } : "month" === type ? { floor: monthFloor, offset: monthOffset, count: monthCount, field: monthField } : "day" === type ? { floor: dayFloor, offset: dayOffset, count: dayCount, field: dayField } : "hour" === type ? { floor: hourFloor, offset: hourOffset, count: hourCount, field: hourField } : "minute" === type ? { floor: minuteFloor, offset: minuteOffset, count: minuteCount, field: minuteField } : "second" === type ? { floor: secondFloor, offset: secondOffset, count: secondCount, field: secondField } : { floor: millisecondsFloor, offset: millisecondsOffset, count: millisecondsCount }; exports.ScaleEnum = void 0; (function (ScaleEnum) { ScaleEnum["Identity"] = "identity"; ScaleEnum["Linear"] = "linear"; ScaleEnum["Log"] = "log"; ScaleEnum["Pow"] = "pow"; ScaleEnum["Sqrt"] = "sqrt"; ScaleEnum["Symlog"] = "symlog"; ScaleEnum["Time"] = "time"; ScaleEnum["Quantile"] = "quantile"; ScaleEnum["Quantize"] = "quantize"; ScaleEnum["Threshold"] = "threshold"; ScaleEnum["Ordinal"] = "ordinal"; ScaleEnum["Point"] = "point"; ScaleEnum["Band"] = "band"; })(exports.ScaleEnum || (exports.ScaleEnum = {})); const EnableScaleMap = {}; Object.values(exports.ScaleEnum).forEach(v => { EnableScaleMap[v] = true; }); function isContinuous(type) { switch (type) { case exports.ScaleEnum.Linear: case exports.ScaleEnum.Log: case exports.ScaleEnum.Pow: case exports.ScaleEnum.Sqrt: case exports.ScaleEnum.Symlog: case exports.ScaleEnum.Time: return true; default: return false; } } function isValidScaleType(type) { return !!EnableScaleMap[type]; } function isDiscrete(type) { switch (type) { case exports.ScaleEnum.Ordinal: case exports.ScaleEnum.Point: case exports.ScaleEnum.Band: return true; default: return false; } } function isDiscretizing(type) { switch (type) { case exports.ScaleEnum.Quantile: case exports.ScaleEnum.Quantize: case exports.ScaleEnum.Threshold: return true; default: return false; } } function supportRangeFactor(type) { switch (type) { case exports.ScaleEnum.Linear: case exports.ScaleEnum.Log: case exports.ScaleEnum.Pow: case exports.ScaleEnum.Sqrt: case exports.ScaleEnum.Symlog: case exports.ScaleEnum.Time: case exports.ScaleEnum.Band: case exports.ScaleEnum.Point: return true; default: return false; } } function identity(x) { return x; } const generatePow = (exponent) => { return (x) => { return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); }; }; const sqrt = (x) => { return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x); }; const square = (x) => { return x < 0 ? -x * x : x * x; }; const logNegative = (x) => { return -Math.log(-x); }; const expNegative = (x) => { return -Math.exp(-x); }; const pow10 = (x) => { return isFinite(x) ? Math.pow(10, x) : x < 0 ? 0 : x; }; const powp = (base) => { return base === 10 ? pow10 : base === Math.E ? Math.exp : (x) => Math.pow(base, x); }; const logp = (base) => { return base === Math.E ? Math.log : base === 10 ? Math.log10 : base === 2 ? Math.log2 : ((base = Math.log(base)), (x) => Math.log(x) / base); }; const symlog = (c) => { return (x) => { return Math.sign(x) * Math.log1p(Math.abs(x / c)); }; }; const symexp = (c) => { return (x) => { return Math.sign(x) * Math.expm1(Math.abs(x)) * c; }; }; function normalize(a, b) { a = Number(a); b = Number(b); b -= a; if (b) { return (x) => { return (x - a) / b; }; } const result = Number.isNaN(b) ? NaN : 0.5; return () => { return result; }; } function bimap(domain, range, interpolate) { const d0 = domain[0]; const d1 = domain[1]; const r0 = range[0]; const r1 = range[1]; let d0Fuc; let r0Fuc; if (d1 < d0) { d0Fuc = normalize(d1, d0); r0Fuc = interpolate(r1, r0); } else { d0Fuc = normalize(d0, d1); r0Fuc = interpolate(r0, r1); } return (x) => { return r0Fuc(d0Fuc(x)); }; } function bandSpace(count, paddingInner, paddingOuter) { let space; if (count === 1) { space = count + paddingOuter * 2; } else { space = count - paddingInner + paddingOuter * 2; } return count ? (space > 0 ? space : 1) : 0; } function scaleWholeRangeSize(count, bandwidth, paddingInner, paddingOuter) { if (paddingInner === 1) { paddingInner = 0; } const space = bandSpace(count, paddingInner, paddingOuter); const step = bandwidth / (1 - paddingInner); const wholeSize = space * step; return wholeSize; } function calculateBandwidthFromWholeRangeSize(count, wholeSize, paddingInner, paddingOuter, round) { const space = bandSpace(count, paddingInner, paddingOuter); let step = wholeSize / Math.max(1, space || 1); if (round) { step = Math.floor(step); } let bandwidth = step * (1 - paddingInner); if (round) { bandwidth = Math.round(bandwidth); } return bandwidth; } function calculateWholeRangeFromRangeFactor(range, rangeFactor) { const k = (range[1] - range[0]) / (rangeFactor[1] - rangeFactor[0]); const b = range[0] - k * rangeFactor[0]; const r0 = b; const r1 = k + b; return [r0, r1]; } function polymap(domain, range, interpolate) { const j = Math.min(domain.length, range.length) - 1; const d = new Array(j); const r = new Array(j); let i = -1; if (domain[j] < domain[0]) { domain = domain.slice().reverse(); range = range.slice().reverse(); } while (++i < j) { d[i] = normalize(domain[i], domain[i + 1]); r[i] = interpolate(range[i], range[i + 1]); } return function (x) { const i = bisect(domain, x, 1, j) - 1; return r[i](d[i](x)); }; } const nice = (domain, options) => { const newDomain = domain.slice(); let startIndex = 0; let endIndex = newDomain.length - 1; let x0 = newDomain[startIndex]; let x1 = newDomain[endIndex]; if (x1 < x0) { [startIndex, endIndex] = [endIndex, startIndex]; [x0, x1] = [x1, x0]; } newDomain[startIndex] = options.floor(x0); newDomain[endIndex] = options.ceil(x1); return newDomain; }; const niceNumber = (value, round = false) => { const exponent = Math.floor(Math.log10(value)); const fraction = value / Math.pow(10, exponent); let niceFraction; if (round) { if (fraction < 1.5) { niceFraction = 1; } else if (fraction < 3) { niceFraction = 2; } else if (fraction < 7) { niceFraction = 5; } else { niceFraction = 10; } } else { if (fraction <= 1) { niceFraction = 1; } else if (fraction <= 2) { niceFraction = 2; } else if (fraction <= 5) { niceFraction = 5; } else { niceFraction = 10; } } return niceFraction * Math.pow(10, exponent); }; const restrictNumber = (value, domain) => { let min; let max; if (domain[0] < domain[1]) { min = domain[0]; max = domain[1]; } else { min = domain[1]; max = domain[0]; } return Math.min(Math.max(value, min), max); }; class BaseScale { constructor() { this._rangeFactorStart = null; this._rangeFactorEnd