|
|
|
(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.d3 = global.d3 || {})); |
|
})(this, (function (exports) { 'use strict'; |
|
|
|
function ascending(a, b) { |
|
return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; |
|
} |
|
|
|
function descending(a, b) { |
|
return a == null || b == null ? NaN |
|
: b < a ? -1 |
|
: b > a ? 1 |
|
: b >= a ? 0 |
|
: NaN; |
|
} |
|
|
|
function bisector(f) { |
|
let compare1, compare2, delta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (f.length !== 2) { |
|
compare1 = ascending; |
|
compare2 = (d, x) => ascending(f(d), x); |
|
delta = (d, x) => f(d) - x; |
|
} else { |
|
compare1 = f === ascending || f === descending ? f : zero; |
|
compare2 = f; |
|
delta = f; |
|
} |
|
|
|
function left(a, x, lo = 0, hi = a.length) { |
|
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 = 0, hi = a.length) { |
|
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 = 0, 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 zero() { |
|
return 0; |
|
} |
|
|
|
function number(x) { |
|
return x === null ? NaN : +x; |
|
} |
|
|
|
function* numbers(values, valueof) { |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value != null && (value = +value) >= value) { |
|
yield value; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { |
|
yield value; |
|
} |
|
} |
|
} |
|
} |
|
|
|
const ascendingBisect = bisector(ascending); |
|
const bisectRight = ascendingBisect.right; |
|
const bisectLeft = ascendingBisect.left; |
|
const bisectCenter = bisector(number).center; |
|
var bisect = bisectRight; |
|
|
|
function blur(values, r) { |
|
if (!((r = +r) >= 0)) throw new RangeError("invalid r"); |
|
let length = values.length; |
|
if (!((length = Math.floor(length)) >= 0)) throw new RangeError("invalid length"); |
|
if (!length || !r) return values; |
|
const blur = blurf(r); |
|
const temp = values.slice(); |
|
blur(values, temp, 0, length, 1); |
|
blur(temp, values, 0, length, 1); |
|
blur(values, temp, 0, length, 1); |
|
return values; |
|
} |
|
|
|
const blur2 = Blur2(blurf); |
|
|
|
const blurImage = Blur2(blurfImage); |
|
|
|
function Blur2(blur) { |
|
return function(data, rx, ry = rx) { |
|
if (!((rx = +rx) >= 0)) throw new RangeError("invalid rx"); |
|
if (!((ry = +ry) >= 0)) throw new RangeError("invalid ry"); |
|
let {data: values, width, height} = data; |
|
if (!((width = Math.floor(width)) >= 0)) throw new RangeError("invalid width"); |
|
if (!((height = Math.floor(height !== undefined ? height : values.length / width)) >= 0)) throw new RangeError("invalid height"); |
|
if (!width || !height || (!rx && !ry)) return data; |
|
const blurx = rx && blur(rx); |
|
const blury = ry && blur(ry); |
|
const temp = values.slice(); |
|
if (blurx && blury) { |
|
blurh(blurx, temp, values, width, height); |
|
blurh(blurx, values, temp, width, height); |
|
blurh(blurx, temp, values, width, height); |
|
blurv(blury, values, temp, width, height); |
|
blurv(blury, temp, values, width, height); |
|
blurv(blury, values, temp, width, height); |
|
} else if (blurx) { |
|
blurh(blurx, values, temp, width, height); |
|
blurh(blurx, temp, values, width, height); |
|
blurh(blurx, values, temp, width, height); |
|
} else if (blury) { |
|
blurv(blury, values, temp, width, height); |
|
blurv(blury, temp, values, width, height); |
|
blurv(blury, values, temp, width, height); |
|
} |
|
return data; |
|
}; |
|
} |
|
|
|
function blurh(blur, T, S, w, h) { |
|
for (let y = 0, n = w * h; y < n;) { |
|
blur(T, S, y, y += w, 1); |
|
} |
|
} |
|
|
|
function blurv(blur, T, S, w, h) { |
|
for (let x = 0, n = w * h; x < w; ++x) { |
|
blur(T, S, x, x + n, w); |
|
} |
|
} |
|
|
|
function blurfImage(radius) { |
|
const blur = blurf(radius); |
|
return (T, S, start, stop, step) => { |
|
start <<= 2, stop <<= 2, step <<= 2; |
|
blur(T, S, start + 0, stop + 0, step); |
|
blur(T, S, start + 1, stop + 1, step); |
|
blur(T, S, start + 2, stop + 2, step); |
|
blur(T, S, start + 3, stop + 3, step); |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function blurf(radius) { |
|
const radius0 = Math.floor(radius); |
|
if (radius0 === radius) return bluri(radius); |
|
const t = radius - radius0; |
|
const w = 2 * radius + 1; |
|
return (T, S, start, stop, step) => { |
|
if (!((stop -= step) >= start)) return; |
|
let sum = radius0 * S[start]; |
|
const s0 = step * radius0; |
|
const s1 = s0 + step; |
|
for (let i = start, j = start + s0; i < j; i += step) { |
|
sum += S[Math.min(stop, i)]; |
|
} |
|
for (let i = start, j = stop; i <= j; i += step) { |
|
sum += S[Math.min(stop, i + s0)]; |
|
T[i] = (sum + t * (S[Math.max(start, i - s1)] + S[Math.min(stop, i + s1)])) / w; |
|
sum -= S[Math.max(start, i - s0)]; |
|
} |
|
}; |
|
} |
|
|
|
|
|
function bluri(radius) { |
|
const w = 2 * radius + 1; |
|
return (T, S, start, stop, step) => { |
|
if (!((stop -= step) >= start)) return; |
|
let sum = radius * S[start]; |
|
const s = step * radius; |
|
for (let i = start, j = start + s; i < j; i += step) { |
|
sum += S[Math.min(stop, i)]; |
|
} |
|
for (let i = start, j = stop; i <= j; i += step) { |
|
sum += S[Math.min(stop, i + s)]; |
|
T[i] = sum / w; |
|
sum -= S[Math.max(start, i - s)]; |
|
} |
|
}; |
|
} |
|
|
|
function count(values, valueof) { |
|
let count = 0; |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value != null && (value = +value) >= value) { |
|
++count; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { |
|
++count; |
|
} |
|
} |
|
} |
|
return count; |
|
} |
|
|
|
function length$1(array) { |
|
return array.length | 0; |
|
} |
|
|
|
function empty(length) { |
|
return !(length > 0); |
|
} |
|
|
|
function arrayify(values) { |
|
return typeof values !== "object" || "length" in values ? values : Array.from(values); |
|
} |
|
|
|
function reducer(reduce) { |
|
return values => reduce(...values); |
|
} |
|
|
|
function cross(...values) { |
|
const reduce = typeof values[values.length - 1] === "function" && reducer(values.pop()); |
|
values = values.map(arrayify); |
|
const lengths = values.map(length$1); |
|
const j = values.length - 1; |
|
const index = new Array(j + 1).fill(0); |
|
const product = []; |
|
if (j < 0 || lengths.some(empty)) return product; |
|
while (true) { |
|
product.push(index.map((j, i) => values[i][j])); |
|
let i = j; |
|
while (++index[i] === lengths[i]) { |
|
if (i === 0) return reduce ? product.map(reduce) : product; |
|
index[i--] = 0; |
|
} |
|
} |
|
} |
|
|
|
function cumsum(values, valueof) { |
|
var sum = 0, index = 0; |
|
return Float64Array.from(values, valueof === undefined |
|
? v => (sum += +v || 0) |
|
: v => (sum += +valueof(v, index++, values) || 0)); |
|
} |
|
|
|
function variance(values, valueof) { |
|
let count = 0; |
|
let delta; |
|
let mean = 0; |
|
let sum = 0; |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value != null && (value = +value) >= value) { |
|
delta = value - mean; |
|
mean += delta / ++count; |
|
sum += delta * (value - mean); |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { |
|
delta = value - mean; |
|
mean += delta / ++count; |
|
sum += delta * (value - mean); |
|
} |
|
} |
|
} |
|
if (count > 1) return sum / (count - 1); |
|
} |
|
|
|
function deviation(values, valueof) { |
|
const v = variance(values, valueof); |
|
return v ? Math.sqrt(v) : v; |
|
} |
|
|
|
function extent(values, valueof) { |
|
let min; |
|
let max; |
|
if (valueof === undefined) { |
|
for (const value of values) { |
|
if (value != null) { |
|
if (min === undefined) { |
|
if (value >= value) min = max = value; |
|
} else { |
|
if (min > value) min = value; |
|
if (max < value) max = value; |
|
} |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null) { |
|
if (min === undefined) { |
|
if (value >= value) min = max = value; |
|
} else { |
|
if (min > value) min = value; |
|
if (max < value) max = value; |
|
} |
|
} |
|
} |
|
} |
|
return [min, max]; |
|
} |
|
|
|
|
|
class Adder { |
|
constructor() { |
|
this._partials = new Float64Array(32); |
|
this._n = 0; |
|
} |
|
add(x) { |
|
const p = this._partials; |
|
let i = 0; |
|
for (let j = 0; j < this._n && j < 32; j++) { |
|
const y = p[j], |
|
hi = x + y, |
|
lo = Math.abs(x) < Math.abs(y) ? x - (hi - y) : y - (hi - x); |
|
if (lo) p[i++] = lo; |
|
x = hi; |
|
} |
|
p[i] = x; |
|
this._n = i + 1; |
|
return this; |
|
} |
|
valueOf() { |
|
const p = this._partials; |
|
let n = this._n, x, y, lo, hi = 0; |
|
if (n > 0) { |
|
hi = p[--n]; |
|
while (n > 0) { |
|
x = hi; |
|
y = p[--n]; |
|
hi = x + y; |
|
lo = y - (hi - x); |
|
if (lo) break; |
|
} |
|
if (n > 0 && ((lo < 0 && p[n - 1] < 0) || (lo > 0 && p[n - 1] > 0))) { |
|
y = lo * 2; |
|
x = hi + y; |
|
if (y == x - hi) hi = x; |
|
} |
|
} |
|
return hi; |
|
} |
|
} |
|
|
|
function fsum(values, valueof) { |
|
const adder = new Adder(); |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value = +value) { |
|
adder.add(value); |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if (value = +valueof(value, ++index, values)) { |
|
adder.add(value); |
|
} |
|
} |
|
} |
|
return +adder; |
|
} |
|
|
|
function fcumsum(values, valueof) { |
|
const adder = new Adder(); |
|
let index = -1; |
|
return Float64Array.from(values, valueof === undefined |
|
? v => adder.add(+v || 0) |
|
: v => adder.add(+valueof(v, ++index, values) || 0) |
|
); |
|
} |
|
|
|
class InternMap extends Map { |
|
constructor(entries, key = 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, key = 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({_intern, _key}, value) { |
|
const key = _key(value); |
|
return _intern.has(key) ? _intern.get(key) : value; |
|
} |
|
|
|
function intern_set({_intern, _key}, value) { |
|
const key = _key(value); |
|
if (_intern.has(key)) return _intern.get(key); |
|
_intern.set(key, value); |
|
return value; |
|
} |
|
|
|
function intern_delete({_intern, _key}, value) { |
|
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 identity(x) { |
|
return x; |
|
} |
|
|
|
function group(values, ...keys) { |
|
return nest(values, identity, identity, keys); |
|
} |
|
|
|
function groups(values, ...keys) { |
|
return nest(values, Array.from, identity, keys); |
|
} |
|
|
|
function flatten$1(groups, keys) { |
|
for (let i = 1, n = keys.length; i < n; ++i) { |
|
groups = groups.flatMap(g => g.pop().map(([key, value]) => [...g, key, value])); |
|
} |
|
return groups; |
|
} |
|
|
|
function flatGroup(values, ...keys) { |
|
return flatten$1(groups(values, ...keys), keys); |
|
} |
|
|
|
function flatRollup(values, reduce, ...keys) { |
|
return flatten$1(rollups(values, reduce, ...keys), keys); |
|
} |
|
|
|
function rollup(values, reduce, ...keys) { |
|
return nest(values, identity, reduce, keys); |
|
} |
|
|
|
function rollups(values, reduce, ...keys) { |
|
return nest(values, Array.from, reduce, keys); |
|
} |
|
|
|
function index(values, ...keys) { |
|
return nest(values, identity, unique, keys); |
|
} |
|
|
|
function indexes(values, ...keys) { |
|
return nest(values, Array.from, unique, keys); |
|
} |
|
|
|
function unique(values) { |
|
if (values.length !== 1) throw new Error("duplicate key"); |
|
return values[0]; |
|
} |
|
|
|
function nest(values, map, reduce, keys) { |
|
return (function regroup(values, i) { |
|
if (i >= keys.length) return reduce(values); |
|
const groups = new InternMap(); |
|
const keyof = keys[i++]; |
|
let index = -1; |
|
for (const value of values) { |
|
const key = keyof(value, ++index, values); |
|
const group = groups.get(key); |
|
if (group) group.push(value); |
|
else groups.set(key, [value]); |
|
} |
|
for (const [key, values] of groups) { |
|
groups.set(key, regroup(values, i)); |
|
} |
|
return map(groups); |
|
})(values, 0); |
|
} |
|
|
|
function permute(source, keys) { |
|
return Array.from(keys, key => source[key]); |
|
} |
|
|
|
function sort(values, ...F) { |
|
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable"); |
|
values = Array.from(values); |
|
let [f] = F; |
|
if ((f && f.length !== 2) || F.length > 1) { |
|
const index = Uint32Array.from(values, (d, i) => i); |
|
if (F.length > 1) { |
|
F = F.map(f => values.map(f)); |
|
index.sort((i, j) => { |
|
for (const f of F) { |
|
const c = ascendingDefined(f[i], f[j]); |
|
if (c) return c; |
|
} |
|
}); |
|
} else { |
|
f = values.map(f); |
|
index.sort((i, j) => ascendingDefined(f[i], f[j])); |
|
} |
|
return permute(values, index); |
|
} |
|
return values.sort(compareDefined(f)); |
|
} |
|
|
|
function compareDefined(compare = ascending) { |
|
if (compare === ascending) 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); |
|
} |
|
|
|
function groupSort(values, reduce, key) { |
|
return (reduce.length !== 2 |
|
? sort(rollup(values, reduce, key), (([ak, av], [bk, bv]) => ascending(av, bv) || ascending(ak, bk))) |
|
: sort(group(values, key), (([ak, av], [bk, bv]) => reduce(av, bv) || ascending(ak, bk)))) |
|
.map(([key]) => key); |
|
} |
|
|
|
var array = Array.prototype; |
|
|
|
var slice = array.slice; |
|
|
|
function constant(x) { |
|
return () => x; |
|
} |
|
|
|
const e10 = Math.sqrt(50), |
|
e5 = Math.sqrt(10), |
|
e2 = Math.sqrt(2); |
|
|
|
function tickSpec(start, stop, count) { |
|
const step = (stop - start) / Math.max(0, count), |
|
power = Math.floor(Math.log10(step)), |
|
error = step / Math.pow(10, power), |
|
factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1; |
|
let i1, i2, inc; |
|
if (power < 0) { |
|
inc = Math.pow(10, -power) / factor; |
|
i1 = Math.round(start * inc); |
|
i2 = Math.round(stop * inc); |
|
if (i1 / inc < start) ++i1; |
|
if (i2 / inc > stop) --i2; |
|
inc = -inc; |
|
} else { |
|
inc = Math.pow(10, power) * factor; |
|
i1 = Math.round(start / inc); |
|
i2 = Math.round(stop / inc); |
|
if (i1 * inc < start) ++i1; |
|
if (i2 * inc > stop) --i2; |
|
} |
|
if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2); |
|
return [i1, i2, inc]; |
|
} |
|
|
|
function ticks(start, stop, count) { |
|
stop = +stop, start = +start, count = +count; |
|
if (!(count > 0)) return []; |
|
if (start === stop) return [start]; |
|
const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count); |
|
if (!(i2 >= i1)) return []; |
|
const n = i2 - i1 + 1, ticks = new Array(n); |
|
if (reverse) { |
|
if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc; |
|
else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc; |
|
} else { |
|
if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc; |
|
else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc; |
|
} |
|
return ticks; |
|
} |
|
|
|
function tickIncrement(start, stop, count) { |
|
stop = +stop, start = +start, count = +count; |
|
return tickSpec(start, stop, count)[2]; |
|
} |
|
|
|
function tickStep(start, stop, count) { |
|
stop = +stop, start = +start, count = +count; |
|
const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count); |
|
return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc); |
|
} |
|
|
|
function nice(start, stop, count) { |
|
let prestep; |
|
while (true) { |
|
const step = tickIncrement(start, stop, count); |
|
if (step === prestep || step === 0 || !isFinite(step)) { |
|
return [start, stop]; |
|
} else if (step > 0) { |
|
start = Math.floor(start / step) * step; |
|
stop = Math.ceil(stop / step) * step; |
|
} else if (step < 0) { |
|
start = Math.ceil(start * step) / step; |
|
stop = Math.floor(stop * step) / step; |
|
} |
|
prestep = step; |
|
} |
|
} |
|
|
|
function thresholdSturges(values) { |
|
return Math.max(1, Math.ceil(Math.log(count(values)) / Math.LN2) + 1); |
|
} |
|
|
|
function bin() { |
|
var value = identity, |
|
domain = extent, |
|
threshold = thresholdSturges; |
|
|
|
function histogram(data) { |
|
if (!Array.isArray(data)) data = Array.from(data); |
|
|
|
var i, |
|
n = data.length, |
|
x, |
|
step, |
|
values = new Array(n); |
|
|
|
for (i = 0; i < n; ++i) { |
|
values[i] = value(data[i], i, data); |
|
} |
|
|
|
var xz = domain(values), |
|
x0 = xz[0], |
|
x1 = xz[1], |
|
tz = threshold(values, x0, x1); |
|
|
|
|
|
|
|
if (!Array.isArray(tz)) { |
|
const max = x1, tn = +tz; |
|
if (domain === extent) [x0, x1] = nice(x0, x1, tn); |
|
tz = ticks(x0, x1, tn); |
|
|
|
|
|
|
|
|
|
if (tz[0] <= x0) step = tickIncrement(x0, x1, tn); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tz[tz.length - 1] >= x1) { |
|
if (max >= x1 && domain === extent) { |
|
const step = tickIncrement(x0, x1, tn); |
|
if (isFinite(step)) { |
|
if (step > 0) { |
|
x1 = (Math.floor(x1 / step) + 1) * step; |
|
} else if (step < 0) { |
|
x1 = (Math.ceil(x1 * -step) + 1) / -step; |
|
} |
|
} |
|
} else { |
|
tz.pop(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
var m = tz.length, a = 0, b = m; |
|
while (tz[a] <= x0) ++a; |
|
while (tz[b - 1] > x1) --b; |
|
if (a || b < m) tz = tz.slice(a, b), m = b - a; |
|
|
|
var bins = new Array(m + 1), |
|
bin; |
|
|
|
|
|
for (i = 0; i <= m; ++i) { |
|
bin = bins[i] = []; |
|
bin.x0 = i > 0 ? tz[i - 1] : x0; |
|
bin.x1 = i < m ? tz[i] : x1; |
|
} |
|
|
|
|
|
if (isFinite(step)) { |
|
if (step > 0) { |
|
for (i = 0; i < n; ++i) { |
|
if ((x = values[i]) != null && x0 <= x && x <= x1) { |
|
bins[Math.min(m, Math.floor((x - x0) / step))].push(data[i]); |
|
} |
|
} |
|
} else if (step < 0) { |
|
for (i = 0; i < n; ++i) { |
|
if ((x = values[i]) != null && x0 <= x && x <= x1) { |
|
const j = Math.floor((x0 - x) * step); |
|
bins[Math.min(m, j + (tz[j] <= x))].push(data[i]); |
|
} |
|
} |
|
} |
|
} else { |
|
for (i = 0; i < n; ++i) { |
|
if ((x = values[i]) != null && x0 <= x && x <= x1) { |
|
bins[bisect(tz, x, 0, m)].push(data[i]); |
|
} |
|
} |
|
} |
|
|
|
return bins; |
|
} |
|
|
|
histogram.value = function(_) { |
|
return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; |
|
}; |
|
|
|
histogram.domain = function(_) { |
|
return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; |
|
}; |
|
|
|
histogram.thresholds = function(_) { |
|
return arguments.length ? (threshold = typeof _ === "function" ? _ : constant(Array.isArray(_) ? slice.call(_) : _), histogram) : threshold; |
|
}; |
|
|
|
return histogram; |
|
} |
|
|
|
function max(values, valueof) { |
|
let max; |
|
if (valueof === undefined) { |
|
for (const value of values) { |
|
if (value != null |
|
&& (max < value || (max === undefined && value >= value))) { |
|
max = value; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null |
|
&& (max < value || (max === undefined && value >= value))) { |
|
max = value; |
|
} |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
function maxIndex(values, valueof) { |
|
let max; |
|
let maxIndex = -1; |
|
let index = -1; |
|
if (valueof === undefined) { |
|
for (const value of values) { |
|
++index; |
|
if (value != null |
|
&& (max < value || (max === undefined && value >= value))) { |
|
max = value, maxIndex = index; |
|
} |
|
} |
|
} else { |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null |
|
&& (max < value || (max === undefined && value >= value))) { |
|
max = value, maxIndex = index; |
|
} |
|
} |
|
} |
|
return maxIndex; |
|
} |
|
|
|
function min(values, valueof) { |
|
let min; |
|
if (valueof === undefined) { |
|
for (const value of values) { |
|
if (value != null |
|
&& (min > value || (min === undefined && value >= value))) { |
|
min = value; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null |
|
&& (min > value || (min === undefined && value >= value))) { |
|
min = value; |
|
} |
|
} |
|
} |
|
return min; |
|
} |
|
|
|
function minIndex(values, valueof) { |
|
let min; |
|
let minIndex = -1; |
|
let index = -1; |
|
if (valueof === undefined) { |
|
for (const value of values) { |
|
++index; |
|
if (value != null |
|
&& (min > value || (min === undefined && value >= value))) { |
|
min = value, minIndex = index; |
|
} |
|
} |
|
} else { |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null |
|
&& (min > value || (min === undefined && value >= value))) { |
|
min = value, minIndex = index; |
|
} |
|
} |
|
} |
|
return minIndex; |
|
} |
|
|
|
|
|
|
|
function quickselect(array, k, left = 0, right = Infinity, compare) { |
|
k = Math.floor(k); |
|
left = Math.floor(Math.max(0, left)); |
|
right = Math.floor(Math.min(array.length - 1, right)); |
|
|
|
if (!(left <= k && k <= right)) return array; |
|
|
|
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); |
|
const s = 0.5 * Math.exp(2 * z / 3); |
|
const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); |
|
const newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); |
|
const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); |
|
quickselect(array, k, newLeft, newRight, compare); |
|
} |
|
|
|
const t = array[k]; |
|
let i = left; |
|
let j = right; |
|
|
|
swap(array, left, k); |
|
if (compare(array[right], t) > 0) swap(array, left, right); |
|
|
|
while (i < j) { |
|
swap(array, i, j), ++i, --j; |
|
while (compare(array[i], t) < 0) ++i; |
|
while (compare(array[j], t) > 0) --j; |
|
} |
|
|
|
if (compare(array[left], t) === 0) swap(array, left, j); |
|
else ++j, swap(array, j, right); |
|
|
|
if (j <= k) left = j + 1; |
|
if (k <= j) right = j - 1; |
|
} |
|
|
|
return array; |
|
} |
|
|
|
function swap(array, i, j) { |
|
const t = array[i]; |
|
array[i] = array[j]; |
|
array[j] = t; |
|
} |
|
|
|
function greatest(values, compare = ascending) { |
|
let max; |
|
let defined = false; |
|
if (compare.length === 1) { |
|
let maxValue; |
|
for (const element of values) { |
|
const value = compare(element); |
|
if (defined |
|
? ascending(value, maxValue) > 0 |
|
: ascending(value, value) === 0) { |
|
max = element; |
|
maxValue = value; |
|
defined = true; |
|
} |
|
} |
|
} else { |
|
for (const value of values) { |
|
if (defined |
|
? compare(value, max) > 0 |
|
: compare(value, value) === 0) { |
|
max = value; |
|
defined = true; |
|
} |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
function quantile(values, p, valueof) { |
|
values = Float64Array.from(numbers(values, valueof)); |
|
if (!(n = values.length) || isNaN(p = +p)) return; |
|
if (p <= 0 || n < 2) return min(values); |
|
if (p >= 1) return max(values); |
|
var n, |
|
i = (n - 1) * p, |
|
i0 = Math.floor(i), |
|
value0 = max(quickselect(values, i0).subarray(0, i0 + 1)), |
|
value1 = min(values.subarray(i0 + 1)); |
|
return value0 + (value1 - value0) * (i - i0); |
|
} |
|
|
|
function quantileSorted(values, p, valueof = number) { |
|
if (!(n = values.length) || isNaN(p = +p)) return; |
|
if (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, |
|
i0 = Math.floor(i), |
|
value0 = +valueof(values[i0], i0, values), |
|
value1 = +valueof(values[i0 + 1], i0 + 1, values); |
|
return value0 + (value1 - value0) * (i - i0); |
|
} |
|
|
|
function quantileIndex(values, p, valueof = number) { |
|
if (isNaN(p = +p)) return; |
|
numbers = Float64Array.from(values, (_, i) => number(valueof(values[i], i, values))); |
|
if (p <= 0) return minIndex(numbers); |
|
if (p >= 1) return maxIndex(numbers); |
|
var numbers, |
|
index = Uint32Array.from(values, (_, i) => i), |
|
j = numbers.length - 1, |
|
i = Math.floor(j * p); |
|
quickselect(index, i, 0, j, (i, j) => ascendingDefined(numbers[i], numbers[j])); |
|
i = greatest(index.subarray(0, i + 1), (i) => numbers[i]); |
|
return i >= 0 ? i : -1; |
|
} |
|
|
|
function thresholdFreedmanDiaconis(values, min, max) { |
|
const c = count(values), d = quantile(values, 0.75) - quantile(values, 0.25); |
|
return c && d ? Math.ceil((max - min) / (2 * d * Math.pow(c, -1 / 3))) : 1; |
|
} |
|
|
|
function thresholdScott(values, min, max) { |
|
const c = count(values), d = deviation(values); |
|
return c && d ? Math.ceil((max - min) * Math.cbrt(c) / (3.49 * d)) : 1; |
|
} |
|
|
|
function mean(values, valueof) { |
|
let count = 0; |
|
let sum = 0; |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value != null && (value = +value) >= value) { |
|
++count, sum += value; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { |
|
++count, sum += value; |
|
} |
|
} |
|
} |
|
if (count) return sum / count; |
|
} |
|
|
|
function median(values, valueof) { |
|
return quantile(values, 0.5, valueof); |
|
} |
|
|
|
function medianIndex(values, valueof) { |
|
return quantileIndex(values, 0.5, valueof); |
|
} |
|
|
|
function* flatten(arrays) { |
|
for (const array of arrays) { |
|
yield* array; |
|
} |
|
} |
|
|
|
function merge(arrays) { |
|
return Array.from(flatten(arrays)); |
|
} |
|
|
|
function mode(values, valueof) { |
|
const counts = new InternMap(); |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value != null && value >= value) { |
|
counts.set(value, (counts.get(value) || 0) + 1); |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if ((value = valueof(value, ++index, values)) != null && value >= value) { |
|
counts.set(value, (counts.get(value) || 0) + 1); |
|
} |
|
} |
|
} |
|
let modeValue; |
|
let modeCount = 0; |
|
for (const [value, count] of counts) { |
|
if (count > modeCount) { |
|
modeCount = count; |
|
modeValue = value; |
|
} |
|
} |
|
return modeValue; |
|
} |
|
|
|
function pairs(values, pairof = pair) { |
|
const pairs = []; |
|
let previous; |
|
let first = false; |
|
for (const value of values) { |
|
if (first) pairs.push(pairof(previous, value)); |
|
previous = value; |
|
first = true; |
|
} |
|
return pairs; |
|
} |
|
|
|
function pair(a, b) { |
|
return [a, b]; |
|
} |
|
|
|
function range(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); |
|
|
|
while (++i < n) { |
|
range[i] = start + i * step; |
|
} |
|
|
|
return range; |
|
} |
|
|
|
function rank(values, valueof = ascending) { |
|
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable"); |
|
let V = Array.from(values); |
|
const R = new Float64Array(V.length); |
|
if (valueof.length !== 2) V = V.map(valueof), valueof = ascending; |
|
const compareIndex = (i, j) => valueof(V[i], V[j]); |
|
let k, r; |
|
values = Uint32Array.from(V, (_, i) => i); |
|
|
|
values.sort(valueof === ascending ? (i, j) => ascendingDefined(V[i], V[j]) : compareDefined(compareIndex)); |
|
values.forEach((j, i) => { |
|
const c = compareIndex(j, k === undefined ? j : k); |
|
if (c >= 0) { |
|
if (k === undefined || c > 0) k = j, r = i; |
|
R[j] = r; |
|
} else { |
|
R[j] = NaN; |
|
} |
|
}); |
|
return R; |
|
} |
|
|
|
function least(values, compare = ascending) { |
|
let min; |
|
let defined = false; |
|
if (compare.length === 1) { |
|
let minValue; |
|
for (const element of values) { |
|
const value = compare(element); |
|
if (defined |
|
? ascending(value, minValue) < 0 |
|
: ascending(value, value) === 0) { |
|
min = element; |
|
minValue = value; |
|
defined = true; |
|
} |
|
} |
|
} else { |
|
for (const value of values) { |
|
if (defined |
|
? compare(value, min) < 0 |
|
: compare(value, value) === 0) { |
|
min = value; |
|
defined = true; |
|
} |
|
} |
|
} |
|
return min; |
|
} |
|
|
|
function leastIndex(values, compare = ascending) { |
|
if (compare.length === 1) return minIndex(values, compare); |
|
let minValue; |
|
let min = -1; |
|
let index = -1; |
|
for (const value of values) { |
|
++index; |
|
if (min < 0 |
|
? compare(value, value) === 0 |
|
: compare(value, minValue) < 0) { |
|
minValue = value; |
|
min = index; |
|
} |
|
} |
|
return min; |
|
} |
|
|
|
function greatestIndex(values, compare = ascending) { |
|
if (compare.length === 1) return maxIndex(values, compare); |
|
let maxValue; |
|
let max = -1; |
|
let index = -1; |
|
for (const value of values) { |
|
++index; |
|
if (max < 0 |
|
? compare(value, value) === 0 |
|
: compare(value, maxValue) > 0) { |
|
maxValue = value; |
|
max = index; |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
function scan(values, compare) { |
|
const index = leastIndex(values, compare); |
|
return index < 0 ? undefined : index; |
|
} |
|
|
|
var shuffle = shuffler(Math.random); |
|
|
|
function shuffler(random) { |
|
return function shuffle(array, i0 = 0, i1 = array.length) { |
|
let m = i1 - (i0 = +i0); |
|
while (m) { |
|
const i = random() * m-- | 0, t = array[m + i0]; |
|
array[m + i0] = array[i + i0]; |
|
array[i + i0] = t; |
|
} |
|
return array; |
|
}; |
|
} |
|
|
|
function sum(values, valueof) { |
|
let sum = 0; |
|
if (valueof === undefined) { |
|
for (let value of values) { |
|
if (value = +value) { |
|
sum += value; |
|
} |
|
} |
|
} else { |
|
let index = -1; |
|
for (let value of values) { |
|
if (value = +valueof(value, ++index, values)) { |
|
sum += value; |
|
} |
|
} |
|
} |
|
return sum; |
|
} |
|
|
|
function transpose(matrix) { |
|
if (!(n = matrix.length)) return []; |
|
for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { |
|
for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { |
|
row[j] = matrix[j][i]; |
|
} |
|
} |
|
return transpose; |
|
} |
|
|
|
function length(d) { |
|
return d.length; |
|
} |
|
|
|
function zip() { |
|
return transpose(arguments); |
|
} |
|
|
|
function every(values, test) { |
|
if (typeof test !== "function") throw new TypeError("test is not a function"); |
|
let index = -1; |
|
for (const value of values) { |
|
if (!test(value, ++index, values)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function some(values, test) { |
|
if (typeof test !== "function") throw new TypeError("test is not a function"); |
|
let index = -1; |
|
for (const value of values) { |
|
if (test(value, ++index, values)) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
function filter(values, test) { |
|
if (typeof test !== "function") throw new TypeError("test is not a function"); |
|
const array = []; |
|
let index = -1; |
|
for (const value of values) { |
|
if (test(value, ++index, values)) { |
|
array.push(value); |
|
} |
|
} |
|
return array; |
|
} |
|
|
|
function map(values, mapper) { |
|
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable"); |
|
if (typeof mapper !== "function") throw new TypeError("mapper is not a function"); |
|
return Array.from(values, (value, index) => mapper(value, index, values)); |
|
} |
|
|
|
function reduce(values, reducer, value) { |
|
if (typeof reducer !== "function") throw new TypeError("reducer is not a function"); |
|
const iterator = values[Symbol.iterator](); |
|
let done, next, index = -1; |
|
if (arguments.length < 3) { |
|
({done, value} = iterator.next()); |
|
if (done) return; |
|
++index; |
|
} |
|
while (({done, value: next} = iterator.next()), !done) { |
|
value = reducer(value, next, ++index, values); |
|
} |
|
return value; |
|
} |
|
|
|
function reverse(values) { |
|
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable"); |
|
return Array.from(values).reverse(); |
|
} |
|
|
|
function difference(values, ...others) { |
|
values = new InternSet(values); |
|
for (const other of others) { |
|
for (const value of other) { |
|
values.delete(value); |
|
} |
|
} |
|
return values; |
|
} |
|
|
|
function disjoint(values, other) { |
|
const iterator = other[Symbol.iterator](), set = new InternSet(); |
|
for (const v of values) { |
|
if (set.has(v)) return false; |
|
let value, done; |
|
while (({value, done} = iterator.next())) { |
|
if (done) break; |
|
if (Object.is(v, value)) return false; |
|
set.add(value); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function intersection(values, ...others) { |
|
values = new InternSet(values); |
|
others = others.map(set); |
|
out: for (const value of values) { |
|
for (const other of others) { |
|
if (!other.has(value)) { |
|
values.delete(value); |
|
continue out; |
|
} |
|
} |
|
} |
|
return values; |
|
} |
|
|
|
function set(values) { |
|
return values instanceof InternSet ? values : new InternSet(values); |
|
} |
|
|
|
function superset(values, other) { |
|
const iterator = values[Symbol.iterator](), set = new Set(); |
|
for (const o of other) { |
|
const io = intern(o); |
|
if (set.has(io)) continue; |
|
let value, done; |
|
while (({value, done} = iterator.next())) { |
|
if (done) return false; |
|
const ivalue = intern(value); |
|
set.add(ivalue); |
|
if (Object.is(io, ivalue)) break; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function intern(value) { |
|
return value !== null && typeof value === "object" ? value.valueOf() : value; |
|
} |
|
|
|
function subset(values, other) { |
|
return superset(other, values); |
|
} |
|
|
|
function union(...others) { |
|
const set = new InternSet(); |
|
for (const other of others) { |
|
for (const o of other) { |
|
set.add(o); |
|
} |
|
} |
|
return set; |
|
} |
|
|
|
exports.Adder = Adder; |
|
exports.InternMap = InternMap; |
|
exports.InternSet = InternSet; |
|
exports.ascending = ascending; |
|
exports.bin = bin; |
|
exports.bisect = bisect; |
|
exports.bisectCenter = bisectCenter; |
|
exports.bisectLeft = bisectLeft; |
|
exports.bisectRight = bisectRight; |
|
exports.bisector = bisector; |
|
exports.blur = blur; |
|
exports.blur2 = blur2; |
|
exports.blurImage = blurImage; |
|
exports.count = count; |
|
exports.cross = cross; |
|
exports.cumsum = cumsum; |
|
exports.descending = descending; |
|
exports.deviation = deviation; |
|
exports.difference = difference; |
|
exports.disjoint = disjoint; |
|
exports.every = every; |
|
exports.extent = extent; |
|
exports.fcumsum = fcumsum; |
|
exports.filter = filter; |
|
exports.flatGroup = flatGroup; |
|
exports.flatRollup = flatRollup; |
|
exports.fsum = fsum; |
|
exports.greatest = greatest; |
|
exports.greatestIndex = greatestIndex; |
|
exports.group = group; |
|
exports.groupSort = groupSort; |
|
exports.groups = groups; |
|
exports.histogram = bin; |
|
exports.index = index; |
|
exports.indexes = indexes; |
|
exports.intersection = intersection; |
|
exports.least = least; |
|
exports.leastIndex = leastIndex; |
|
exports.map = map; |
|
exports.max = max; |
|
exports.maxIndex = maxIndex; |
|
exports.mean = mean; |
|
exports.median = median; |
|
exports.medianIndex = medianIndex; |
|
exports.merge = merge; |
|
exports.min = min; |
|
exports.minIndex = minIndex; |
|
exports.mode = mode; |
|
exports.nice = nice; |
|
exports.pairs = pairs; |
|
exports.permute = permute; |
|
exports.quantile = quantile; |
|
exports.quantileIndex = quantileIndex; |
|
exports.quantileSorted = quantileSorted; |
|
exports.quickselect = quickselect; |
|
exports.range = range; |
|
exports.rank = rank; |
|
exports.reduce = reduce; |
|
exports.reverse = reverse; |
|
exports.rollup = rollup; |
|
exports.rollups = rollups; |
|
exports.scan = scan; |
|
exports.shuffle = shuffle; |
|
exports.shuffler = shuffler; |
|
exports.some = some; |
|
exports.sort = sort; |
|
exports.subset = subset; |
|
exports.sum = sum; |
|
exports.superset = superset; |
|
exports.thresholdFreedmanDiaconis = thresholdFreedmanDiaconis; |
|
exports.thresholdScott = thresholdScott; |
|
exports.thresholdSturges = thresholdSturges; |
|
exports.tickIncrement = tickIncrement; |
|
exports.tickStep = tickStep; |
|
exports.ticks = ticks; |
|
exports.transpose = transpose; |
|
exports.union = union; |
|
exports.variance = variance; |
|
exports.zip = zip; |
|
|
|
})); |
|
|