vega-scale
Advanced tools
Comparing version 7.2.0 to 7.3.0
@@ -1,2 +0,2 @@ | ||
import { toNumber, peek, hasOwnProperty, toSet, array, constant, isNumber, span, isObject, isString, error, isArray } from 'vega-util'; | ||
import { toNumber, peek, toSet, array, constant, isNumber, span, isObject, isString, error, isArray } from 'vega-util'; | ||
import { bisectRight, range, bisect } from 'd3-array'; | ||
@@ -30,4 +30,5 @@ import * as $ from 'd3-scale'; | ||
const Band = 'band'; | ||
const BinOrdinal = 'bin-ordinal'; // categories | ||
const BinOrdinal = 'bin-ordinal'; | ||
// categories | ||
const Continuous = 'continuous'; | ||
@@ -42,5 +43,4 @@ const Discrete = 'discrete'; | ||
let lo = _[0], | ||
hi = _[1], | ||
t; | ||
hi = _[1], | ||
t; | ||
if (hi < lo) { | ||
@@ -51,3 +51,2 @@ t = lo; | ||
} | ||
return [scale.invert(lo), scale.invert(hi)]; | ||
@@ -61,9 +60,8 @@ }; | ||
let lo = _[0], | ||
hi = _[1], | ||
min = -1, | ||
max, | ||
t, | ||
i, | ||
n; | ||
hi = _[1], | ||
min = -1, | ||
max, | ||
t, | ||
i, | ||
n; | ||
if (hi < lo) { | ||
@@ -74,3 +72,2 @@ t = lo; | ||
} | ||
for (i = 0, n = range.length; i < n; ++i) { | ||
@@ -82,3 +79,2 @@ if (range[i] >= lo && range[i] <= hi) { | ||
} | ||
if (min < 0) return undefined; | ||
@@ -93,28 +89,24 @@ lo = scale.invertExtent(range[min]); | ||
const scale = scaleOrdinal().unknown(undefined), | ||
domain = scale.domain, | ||
ordinalRange = scale.range; | ||
domain = scale.domain, | ||
ordinalRange = scale.range; | ||
let range$1 = [0, 1], | ||
step, | ||
bandwidth, | ||
round = false, | ||
paddingInner = 0, | ||
paddingOuter = 0, | ||
align = 0.5; | ||
step, | ||
bandwidth, | ||
round = false, | ||
paddingInner = 0, | ||
paddingOuter = 0, | ||
align = 0.5; | ||
delete scale.unknown; | ||
function rescale() { | ||
const n = domain().length, | ||
reverse = range$1[1] < range$1[0], | ||
stop = range$1[1 - reverse], | ||
space = bandSpace(n, paddingInner, paddingOuter); | ||
reverse = range$1[1] < range$1[0], | ||
stop = range$1[1 - reverse], | ||
space = bandSpace(n, paddingInner, paddingOuter); | ||
let start = range$1[reverse - 0]; | ||
step = (stop - start) / (space || 1); | ||
if (round) { | ||
step = Math.floor(step); | ||
} | ||
start += (stop - start - step * (n - paddingInner)) * align; | ||
bandwidth = step * (1 - paddingInner); | ||
if (round) { | ||
@@ -124,7 +116,5 @@ start = Math.round(start); | ||
} | ||
const values = range(n).map(i => start + step * i); | ||
return ordinalRange(reverse ? values.reverse() : values); | ||
} | ||
scale.domain = function (_) { | ||
@@ -138,3 +128,2 @@ if (arguments.length) { | ||
}; | ||
scale.range = function (_) { | ||
@@ -148,3 +137,2 @@ if (arguments.length) { | ||
}; | ||
scale.rangeRound = function (_) { | ||
@@ -155,11 +143,8 @@ range$1 = [+_[0], +_[1]]; | ||
}; | ||
scale.bandwidth = function () { | ||
return bandwidth; | ||
}; | ||
scale.step = function () { | ||
return step; | ||
}; | ||
scale.round = function (_) { | ||
@@ -173,3 +158,2 @@ if (arguments.length) { | ||
}; | ||
scale.padding = function (_) { | ||
@@ -184,3 +168,2 @@ if (arguments.length) { | ||
}; | ||
scale.paddingInner = function (_) { | ||
@@ -194,3 +177,2 @@ if (arguments.length) { | ||
}; | ||
scale.paddingOuter = function (_) { | ||
@@ -204,3 +186,2 @@ if (arguments.length) { | ||
}; | ||
scale.align = function (_) { | ||
@@ -214,3 +195,2 @@ if (arguments.length) { | ||
}; | ||
scale.invertRange = function (_) { | ||
@@ -220,12 +200,14 @@ // bail if range has null or undefined values | ||
const reverse = range$1[1] < range$1[0], | ||
values = reverse ? ordinalRange().reverse() : ordinalRange(), | ||
n = values.length - 1; | ||
values = reverse ? ordinalRange().reverse() : ordinalRange(), | ||
n = values.length - 1; | ||
let lo = +_[0], | ||
hi = +_[1], | ||
a, | ||
b, | ||
t; // bail if either range endpoint is invalid | ||
hi = +_[1], | ||
a, | ||
b, | ||
t; | ||
if (lo !== lo || hi !== hi) return; // order range inputs, bail if outside of scale range | ||
// bail if either range endpoint is invalid | ||
if (lo !== lo || hi !== hi) return; | ||
// order range inputs, bail if outside of scale range | ||
if (hi < lo) { | ||
@@ -236,10 +218,10 @@ t = lo; | ||
} | ||
if (hi < values[0] || lo > range$1[1 - reverse]) return; | ||
if (hi < values[0] || lo > range$1[1 - reverse]) return; // binary search to index into scale range | ||
// binary search to index into scale range | ||
a = Math.max(0, bisectRight(values, lo) - 1); | ||
b = lo === hi ? a : bisectRight(values, hi) - 1; // increment index a if lo is within padding gap | ||
b = lo === hi ? a : bisectRight(values, hi) - 1; | ||
// increment index a if lo is within padding gap | ||
if (lo - values[a] > bandwidth + 1e-10) ++a; | ||
if (reverse) { | ||
@@ -251,6 +233,4 @@ // map + swap | ||
} | ||
return a > b ? undefined : domain().slice(a, b + 1); | ||
}; | ||
scale.invert = function (_) { | ||
@@ -260,10 +240,7 @@ const value = scale.invertRange([_, _]); | ||
}; | ||
scale.copy = function () { | ||
return band().domain(domain()).range(range$1).round(round).paddingInner(paddingInner).paddingOuter(paddingOuter).align(align); | ||
}; | ||
return rescale(); | ||
} | ||
function pointish(scale) { | ||
@@ -273,10 +250,7 @@ const copy = scale.copy; | ||
delete scale.paddingInner; | ||
scale.copy = function () { | ||
return pointish(copy()); | ||
}; | ||
return scale; | ||
} | ||
function point() { | ||
@@ -295,8 +269,6 @@ return pointish(band().paddingInner(1)); | ||
let domain = [], | ||
range = []; | ||
range = []; | ||
function scale(x) { | ||
return x == null || x !== x ? undefined : range[(bisect(domain, x) - 1) % range.length]; | ||
} | ||
scale.domain = function (_) { | ||
@@ -310,3 +282,2 @@ if (arguments.length) { | ||
}; | ||
scale.range = function (_) { | ||
@@ -320,31 +291,38 @@ if (arguments.length) { | ||
}; | ||
scale.tickFormat = function (count, specifier) { | ||
return tickFormat$1(domain[0], peek(domain), count == null ? 10 : count, specifier); | ||
}; | ||
scale.copy = function () { | ||
return scaleBinOrdinal().domain(scale.domain()).range(scale.range()); | ||
}; | ||
return scale; | ||
} | ||
/** Private scale registry: should not be exported */ | ||
const scales = new Map(); | ||
const VEGA_SCALE = Symbol('vega_scale'); | ||
function registerScale(scale) { | ||
scale[VEGA_SCALE] = true; | ||
return scale; | ||
} | ||
const scales = {}; | ||
/** | ||
* Return true if object was created by a constructor from the vega-scale `scale` function. | ||
*/ | ||
function isRegisteredScale(scale) { | ||
return scale && scale[VEGA_SCALE] === true; | ||
} | ||
/** | ||
* Augment scales with their type and needed inverse methods. | ||
*/ | ||
function create(type, constructor, metadata) { | ||
const ctr = function scale() { | ||
const s = constructor(); | ||
if (!s.invertRange) { | ||
s.invertRange = s.invert ? invertRange(s) : s.invertExtent ? invertRangeExtent(s) : undefined; | ||
} | ||
s.type = type; | ||
return s; | ||
return registerScale(s); | ||
}; | ||
ctr.metadata = toSet(array(metadata)); | ||
@@ -354,13 +332,31 @@ return ctr; | ||
/** | ||
* Registry function for adding and accessing scale constructor functions. | ||
* The *type* argument is a String indicating the name of the scale type. | ||
* | ||
* If the *scale* argument is not specified, this method returns the matching scale constructor in the registry, or `null` if not found. | ||
* If the *scale* argument is provided, it must be a scale constructor function to add to the registry under the given *type* name. | ||
* The *metadata* argument provides additional information to guide appropriate use of scales within Vega. | ||
* | ||
* *metadata* can be either a string or string array. The valid string values are: | ||
* - `"continuous"` - the scale is defined over a continuous-valued domain. | ||
* - `"discrete"` - the scale is defined over a discrete domain and range. | ||
* - `"discretizing"` - the scale discretizes a continuous domain to a discrete range. | ||
* - `"interpolating"` - the scale range is defined using a color interpolator. | ||
* - `"log"` - the scale performs a logarithmic transform of the continuous domain. | ||
* - `"temporal"` - the scale domain is defined over date-time values. | ||
*/ | ||
function scale(type, scale, metadata) { | ||
if (arguments.length > 1) { | ||
scales[type] = create(type, scale, metadata); | ||
scales.set(type, create(type, scale, metadata)); | ||
return this; | ||
} else { | ||
return isValidScaleType(type) ? scales[type] : undefined; | ||
return isValidScaleType(type) ? scales.get(type) : undefined; | ||
} | ||
} // identity scale | ||
} | ||
scale(Identity, $.scaleIdentity); // continuous scales | ||
// identity scale | ||
scale(Identity, $.scaleIdentity); | ||
// continuous scales | ||
scale(Linear, $.scaleLinear, Continuous); | ||
@@ -372,22 +368,25 @@ scale(Log, $.scaleLog, [Continuous, Log]); | ||
scale(Time, $.scaleTime, [Continuous, Temporal]); | ||
scale(UTC, $.scaleUtc, [Continuous, Temporal]); // sequential scales | ||
scale(UTC, $.scaleUtc, [Continuous, Temporal]); | ||
// sequential scales | ||
scale(Sequential, $.scaleSequential, [Continuous, Interpolating]); // backwards compat | ||
scale(`${Sequential}-${Linear}`, $.scaleSequential, [Continuous, Interpolating]); | ||
scale(`${Sequential}-${Log}`, $.scaleSequentialLog, [Continuous, Interpolating, Log]); | ||
scale(`${Sequential}-${Pow}`, $.scaleSequentialPow, [Continuous, Interpolating]); | ||
scale(`${Sequential}-${Sqrt}`, $.scaleSequentialSqrt, [Continuous, Interpolating]); | ||
scale(`${Sequential}-${Symlog}`, $.scaleSequentialSymlog, [Continuous, Interpolating]); | ||
scale("".concat(Sequential, "-").concat(Linear), $.scaleSequential, [Continuous, Interpolating]); | ||
scale("".concat(Sequential, "-").concat(Log), $.scaleSequentialLog, [Continuous, Interpolating, Log]); | ||
scale("".concat(Sequential, "-").concat(Pow), $.scaleSequentialPow, [Continuous, Interpolating]); | ||
scale("".concat(Sequential, "-").concat(Sqrt), $.scaleSequentialSqrt, [Continuous, Interpolating]); | ||
scale("".concat(Sequential, "-").concat(Symlog), $.scaleSequentialSymlog, [Continuous, Interpolating]); // diverging scales | ||
// diverging scales | ||
scale(`${Diverging}-${Linear}`, $.scaleDiverging, [Continuous, Interpolating]); | ||
scale(`${Diverging}-${Log}`, $.scaleDivergingLog, [Continuous, Interpolating, Log]); | ||
scale(`${Diverging}-${Pow}`, $.scaleDivergingPow, [Continuous, Interpolating]); | ||
scale(`${Diverging}-${Sqrt}`, $.scaleDivergingSqrt, [Continuous, Interpolating]); | ||
scale(`${Diverging}-${Symlog}`, $.scaleDivergingSymlog, [Continuous, Interpolating]); | ||
scale("".concat(Diverging, "-").concat(Linear), $.scaleDiverging, [Continuous, Interpolating]); | ||
scale("".concat(Diverging, "-").concat(Log), $.scaleDivergingLog, [Continuous, Interpolating, Log]); | ||
scale("".concat(Diverging, "-").concat(Pow), $.scaleDivergingPow, [Continuous, Interpolating]); | ||
scale("".concat(Diverging, "-").concat(Sqrt), $.scaleDivergingSqrt, [Continuous, Interpolating]); | ||
scale("".concat(Diverging, "-").concat(Symlog), $.scaleDivergingSymlog, [Continuous, Interpolating]); // discretizing scales | ||
// discretizing scales | ||
scale(Quantile, $.scaleQuantile, [Discretizing, Quantile]); | ||
scale(Quantize, $.scaleQuantize, Discretizing); | ||
scale(Threshold, $.scaleThreshold, Discretizing); // discrete scales | ||
scale(Threshold, $.scaleThreshold, Discretizing); | ||
// discrete scales | ||
scale(BinOrdinal, scaleBinOrdinal, [Discrete, Discretizing]); | ||
@@ -398,10 +397,8 @@ scale(Ordinal, $.scaleOrdinal, Discrete); | ||
function isValidScaleType(type) { | ||
return hasOwnProperty(scales, type); | ||
return scales.has(type); | ||
} | ||
function hasType(key, type) { | ||
const s = scales[key]; | ||
const s = scales.get(key); | ||
return s && s.metadata[type]; | ||
} | ||
function isContinuous(key) { | ||
@@ -432,3 +429,3 @@ return hasType(key, Continuous); | ||
const start = range[0], | ||
span = peek(range) - start; | ||
span = peek(range) - start; | ||
return function (i) { | ||
@@ -443,6 +440,4 @@ return interpolator(start + i * span); | ||
const samples = new Array(count), | ||
n = count + 1; | ||
n = count + 1; | ||
for (let i = 0; i < count;) samples[i] = interpolator(++i / n); | ||
return samples; | ||
@@ -452,3 +447,3 @@ } | ||
const t = scale.type, | ||
s = scale.copy(); | ||
s = scale.copy(); | ||
s.type = t; | ||
@@ -460,3 +455,2 @@ return s; | ||
let i, t, s; | ||
if (!delta || !Number.isFinite(delta)) { | ||
@@ -476,3 +470,2 @@ return constant(0.5); | ||
} | ||
function method(type) { | ||
@@ -556,15 +549,11 @@ return 'interpolate' + type.toLowerCase().split('-').map(s => s[0].toUpperCase() + s.slice(1)).join(''); | ||
const n = palette.length / 6 | 0, | ||
c = new Array(n); | ||
c = new Array(n); | ||
for (let i = 0; i < n;) { | ||
c[i] = '#' + palette.slice(i * 6, ++i * 6); | ||
} | ||
return c; | ||
} | ||
function apply(_, f) { | ||
for (const k in _) scheme(k, f(_[k])); | ||
} | ||
const schemes = {}; | ||
@@ -575,3 +564,2 @@ apply(discrete, colors); | ||
name = name && name.toLowerCase(); | ||
if (arguments.length > 1) { | ||
@@ -590,6 +578,5 @@ schemes[name] = scheme; | ||
const defaultFormatter = value => isArray(value) ? value.map(v => String(v)) : String(value); | ||
const ascending = (a, b) => a[1] - b[1]; | ||
const descending = (a, b) => b[1] - a[1]; | ||
const descending = (a, b) => b[1] - a[1]; | ||
/** | ||
@@ -602,7 +589,4 @@ * Determine the tick count or interval function. | ||
*/ | ||
function tickCount(scale, count, minStep) { | ||
let step; | ||
if (isNumber(count)) { | ||
@@ -612,3 +596,2 @@ if (scale.bins) { | ||
} | ||
if (minStep != null) { | ||
@@ -618,3 +601,2 @@ count = Math.min(count, Math.floor(span(scale.domain()) / minStep || 1)); | ||
} | ||
if (isObject(count)) { | ||
@@ -624,3 +606,2 @@ step = count.step; | ||
} | ||
if (isString(count)) { | ||
@@ -630,5 +611,5 @@ count = scale.type === Time ? timeInterval(count) : scale.type == UTC ? utcInterval(count) : error('Only time and utc scales accept interval strings.'); | ||
} | ||
return count; | ||
} | ||
/** | ||
@@ -642,9 +623,7 @@ * Filter a set of candidate tick values, ensuring that only tick values | ||
*/ | ||
function validTicks(scale, ticks, count) { | ||
let range = scale.range(), | ||
lo = range[0], | ||
hi = peek(range), | ||
cmp = ascending; | ||
lo = range[0], | ||
hi = peek(range), | ||
cmp = ascending; | ||
if (lo > hi) { | ||
@@ -656,16 +635,13 @@ range = hi; | ||
} | ||
lo = Math.floor(lo); | ||
hi = Math.ceil(hi); | ||
lo = Math.floor(lo); | ||
hi = Math.ceil(hi); // filter ticks to valid values within the range | ||
// filter ticks to valid values within the range | ||
// additionally sort ticks in range order (#2579) | ||
ticks = ticks.map(v => [v, scale(v)]).filter(_ => lo <= _[1] && _[1] <= hi).sort(cmp).map(_ => _[0]); | ||
if (count > 0 && ticks.length > 1) { | ||
const endpoints = [ticks[0], peek(ticks)]; | ||
while (ticks.length > count && ticks.length >= 3) { | ||
ticks = ticks.filter((_, i) => !(i % 2)); | ||
} | ||
if (ticks.length < 3) { | ||
@@ -675,5 +651,5 @@ ticks = endpoints; | ||
} | ||
return ticks; | ||
} | ||
/** | ||
@@ -688,6 +664,6 @@ * Generate tick values for the given scale and approximate tick count or | ||
*/ | ||
function tickValues(scale, count) { | ||
return scale.bins ? validTicks(scale, scale.bins) : scale.ticks ? scale.ticks(count) : scale.domain(); | ||
} | ||
/** | ||
@@ -708,7 +684,5 @@ * Generate a label format function for a scale. If the scale has a | ||
*/ | ||
function tickFormat(locale, scale, count, specifier, formatType, noSkip) { | ||
const type = scale.type; | ||
let format = defaultFormatter; | ||
if (type === Time || formatType === Time) { | ||
@@ -720,3 +694,2 @@ format = locale.timeFormat(specifier); | ||
const varfmt = locale.formatFloat(specifier); | ||
if (noSkip || scale.bins) { | ||
@@ -726,3 +699,2 @@ format = varfmt; | ||
const test = tickLog(scale, count, false); | ||
format = _ => test(_) ? varfmt(_) : ''; | ||
@@ -737,3 +709,2 @@ } | ||
} | ||
return format; | ||
@@ -743,6 +714,7 @@ } | ||
const ticks = tickValues(scale, count), | ||
base = scale.base(), | ||
logb = Math.log(base), | ||
k = Math.max(1, base * count / ticks.length); // apply d3-scale's log format filter criteria | ||
base = scale.base(), | ||
logb = Math.log(base), | ||
k = Math.max(1, base * count / ticks.length); | ||
// apply d3-scale's log format filter criteria | ||
const test = d => { | ||
@@ -753,3 +725,2 @@ let i = d / Math.pow(base, Math.round(Math.log(d) / logb)); | ||
}; | ||
return values ? ticks.filter(test) : test; | ||
@@ -772,15 +743,12 @@ } | ||
const _ = scale[formats[scale.type]](), | ||
n = _.length; | ||
n = _.length; | ||
let d = n > 1 ? _[1] - _[0] : _[0], | ||
i; | ||
i; | ||
for (i = 1; i < n; ++i) { | ||
d = Math.min(d, _[i] - _[i - 1]); | ||
} // tickCount = 3 ticks times 10 for increased resolution | ||
} | ||
// tickCount = 3 ticks times 10 for increased resolution | ||
return locale.formatSpan(0, d, 3 * 10, specifier); | ||
} | ||
function thresholdValues(thresholds) { | ||
@@ -791,3 +759,2 @@ const values = [-Infinity].concat(thresholds); | ||
} | ||
function binValues(bins) { | ||
@@ -798,5 +765,3 @@ const values = bins.slice(0, -1); | ||
} | ||
const isDiscreteRange = scale => symbols[scale.type] || scale.bins; | ||
function labelFormat(locale, scale, count, type, specifier, formatType, noSkip) { | ||
@@ -806,25 +771,18 @@ const format = formats[scale.type] && formatType !== Time && formatType !== UTC ? thresholdFormat(locale, scale, specifier) : tickFormat(locale, scale, count, specifier, formatType, noSkip); | ||
} | ||
const formatRange = format => (value, index, array) => { | ||
const limit = get(array[index + 1], get(array.max, +Infinity)), | ||
lo = formatValue(value, format), | ||
hi = formatValue(limit, format); | ||
lo = formatValue(value, format), | ||
hi = formatValue(limit, format); | ||
return lo && hi ? lo + ' \u2013 ' + hi : hi ? '< ' + hi : '\u2265 ' + lo; | ||
}; | ||
const get = (value, dflt) => value != null ? value : dflt; | ||
const formatDiscrete = format => (value, index) => index ? format(value) : null; | ||
const formatPoint = format => value => format(value); | ||
const formatValue = (value, format) => Number.isFinite(value) ? format(value) : null; | ||
function labelFraction(scale) { | ||
const domain = scale.domain(), | ||
count = domain.length - 1; | ||
count = domain.length - 1; | ||
let lo = +domain[0], | ||
hi = +peek(domain), | ||
span = hi - lo; | ||
hi = +peek(domain), | ||
span = hi - lo; | ||
if (scale.type === Threshold) { | ||
@@ -836,3 +794,2 @@ const adjust = count ? span / count : 0.1; | ||
} | ||
return value => (value - lo) / span; | ||
@@ -842,33 +799,37 @@ } | ||
function format(locale, scale, specifier, formatType) { | ||
const type = formatType || scale.type; // replace abbreviated time specifiers to improve screen reader experience | ||
const type = formatType || scale.type; | ||
// replace abbreviated time specifiers to improve screen reader experience | ||
if (isString(specifier) && isTemporal(type)) { | ||
specifier = specifier.replace(/%a/g, '%A').replace(/%b/g, '%B'); | ||
} | ||
return !specifier && type === Time ? locale.timeFormat('%A, %d %B %Y, %X') : !specifier && type === UTC ? locale.utcFormat('%A, %d %B %Y, %X UTC') : labelFormat(locale, scale, 5, null, specifier, formatType, true); | ||
} | ||
function domainCaption(locale, scale, opt) { | ||
opt = opt || {}; | ||
const max = Math.max(3, opt.maxlen || 7), | ||
fmt = format(locale, scale, opt.format, opt.formatType); // if scale breaks domain into bins, describe boundaries | ||
fmt = format(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 "".concat(n, " boundar").concat(n === 1 ? 'y' : 'ies', ": ").concat(v.join(', ')); | ||
} // if scale domain is discrete, list values | ||
n = v.length; | ||
return `${n} boundar${n === 1 ? 'y' : 'ies'}: ${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 "".concat(n, " value").concat(n === 1 ? '' : 's', ": ").concat(v); | ||
} // if scale domain is continuous, describe value range | ||
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}`; | ||
} | ||
// if scale domain is continuous, describe value range | ||
else { | ||
const d = scale.domain(); | ||
return "values from ".concat(fmt(d[0]), " to ").concat(fmt(peek(d))); | ||
return `values from ${fmt(d[0])} to ${fmt(peek(d))}`; | ||
} | ||
} | ||
export { Band, BinOrdinal, DiscreteLegend, Diverging, GradientLegend, Identity, Linear, Log, Ordinal, Point, Pow, Quantile, Quantize, Sequential, Sqrt, SymbolLegend, Symlog, Threshold, Time, UTC, bandSpace, domainCaption, interpolate, interpolateColors, interpolateRange, isContinuous, isDiscrete, isDiscretizing, isInterpolating, isLogarithmic, isQuantile, isTemporal, isValidScaleType, labelFormat, labelFraction, labelValues, quantizeInterpolator, scale, scaleCopy, scaleFraction, scheme, tickCount, tickFormat, tickValues, validTicks }; | ||
export { Band, BinOrdinal, DiscreteLegend, Diverging, GradientLegend, Identity, Linear, Log, Ordinal, Point, Pow, Quantile, Quantize, Sequential, Sqrt, SymbolLegend, Symlog, Threshold, Time, UTC, bandSpace, domainCaption, interpolate, interpolateColors, interpolateRange, isContinuous, isDiscrete, isDiscretizing, isInterpolating, isLogarithmic, isQuantile, isRegisteredScale, isTemporal, isValidScaleType, labelFormat, labelFraction, labelValues, quantizeInterpolator, registerScale, scale, scaleCopy, scaleFraction, scheme, tickCount, tickFormat, tickValues, validTicks }; |
@@ -36,2 +36,4 @@ export { | ||
scale, | ||
registerScale, | ||
isRegisteredScale, | ||
isValidScaleType, | ||
@@ -38,0 +40,0 @@ isContinuous, |
{ | ||
"name": "vega-scale", | ||
"version": "7.2.0", | ||
"version": "7.3.0", | ||
"description": "Scales and color schemes for visual encoding.", | ||
@@ -19,3 +19,3 @@ "keywords": [ | ||
"prebuild": "rimraf build", | ||
"build": "rollup -c", | ||
"build": "rollup -c rollup.config.mjs", | ||
"pretest": "yarn build --config-test", | ||
@@ -26,9 +26,9 @@ "test": "tape 'test/**/*-test.js'", | ||
"dependencies": { | ||
"d3-array": "^3.1.1", | ||
"d3-array": "^3.2.2", | ||
"d3-interpolate": "^3.0.1", | ||
"d3-scale": "^4.0.2", | ||
"vega-time": "^2.1.0", | ||
"vega-util": "^1.17.0" | ||
"vega-time": "^2.1.1", | ||
"vega-util": "^1.17.1" | ||
}, | ||
"gitHead": "9a3faca4395cade9ecdfde90af98f1c53e9916b2" | ||
"gitHead": "fb1092f6b931d450f9c210b67ae4752bd3dd461b" | ||
} |
@@ -1,2 +0,2 @@ | ||
import {array, hasOwnProperty, toSet} from 'vega-util'; | ||
import { array, toSet } from 'vega-util'; | ||
import invertRange from './scales/invertRange'; | ||
@@ -29,6 +29,20 @@ import invertRangeExtent from './scales/invertRangeExtent'; | ||
// scale registry | ||
const scales = {}; | ||
/** Private scale registry: should not be exported */ | ||
const scales = new Map(); | ||
const VEGA_SCALE = Symbol('vega_scale'); | ||
export function registerScale(scale) { | ||
scale[VEGA_SCALE] = true; | ||
return scale; | ||
} | ||
/** | ||
* Return true if object was created by a constructor from the vega-scale `scale` function. | ||
*/ | ||
export function isRegisteredScale(scale) { | ||
return scale && scale[VEGA_SCALE] === true; | ||
} | ||
/** | ||
* Augment scales with their type and needed inverse methods. | ||
@@ -47,3 +61,3 @@ */ | ||
s.type = type; | ||
return s; | ||
return registerScale(s); | ||
}; | ||
@@ -56,8 +70,24 @@ | ||
/** | ||
* Registry function for adding and accessing scale constructor functions. | ||
* The *type* argument is a String indicating the name of the scale type. | ||
* | ||
* If the *scale* argument is not specified, this method returns the matching scale constructor in the registry, or `null` if not found. | ||
* If the *scale* argument is provided, it must be a scale constructor function to add to the registry under the given *type* name. | ||
* The *metadata* argument provides additional information to guide appropriate use of scales within Vega. | ||
* | ||
* *metadata* can be either a string or string array. The valid string values are: | ||
* - `"continuous"` - the scale is defined over a continuous-valued domain. | ||
* - `"discrete"` - the scale is defined over a discrete domain and range. | ||
* - `"discretizing"` - the scale discretizes a continuous domain to a discrete range. | ||
* - `"interpolating"` - the scale range is defined using a color interpolator. | ||
* - `"log"` - the scale performs a logarithmic transform of the continuous domain. | ||
* - `"temporal"` - the scale domain is defined over date-time values. | ||
*/ | ||
export function scale(type, scale, metadata) { | ||
if (arguments.length > 1) { | ||
scales[type] = create(type, scale, metadata); | ||
scales.set(type, create(type, scale, metadata)); | ||
return this; | ||
} else { | ||
return isValidScaleType(type) ? scales[type] : undefined; | ||
return isValidScaleType(type) ? scales.get(type) : undefined; | ||
} | ||
@@ -105,7 +135,7 @@ } | ||
export function isValidScaleType(type) { | ||
return hasOwnProperty(scales, type); | ||
return scales.has(type); | ||
} | ||
function hasType(key, type) { | ||
const s = scales[key]; | ||
const s = scales.get(key); | ||
return s && s.metadata[type]; | ||
@@ -112,0 +142,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
539182
5829
Updatedd3-array@^3.2.2
Updatedvega-time@^2.1.1
Updatedvega-util@^1.17.1