d3
Version:
1,904 lines (1,624 loc) • 549 kB
JavaScript
// https://d3js.org v6.0.0-rc.4 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}));
}(this, function (exports) { 'use strict';
var version = "6.0.0-rc.4";
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function bisector(compare) {
if (compare.length === 1) compare = ascendingComparator(compare);
return {
left: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) < 0) lo = mid + 1;
else hi = mid;
}
return lo;
},
right: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid;
else lo = mid + 1;
}
return lo;
}
};
}
function ascendingComparator(f) {
return function(d, x) {
return ascending(f(d), x);
};
}
var ascendingBisect = bisector(ascending);
var bisectRight = ascendingBisect.right;
var bisectLeft = ascendingBisect.left;
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(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);
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 descending(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
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];
}
// https://github.com/python/cpython/blob/a74eea238f5baba15797e2e8b570d153bc8690a7/Modules/mathmodule.c#L1423
class Adder {
constructor() {
this._partials = new Float64Array(32).fill(0);
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 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 rollup(values, reduce, ...keys) {
return nest(values, identity, reduce, keys);
}
function rollups(values, reduce, ...keys) {
return nest(values, Array.from, reduce, keys);
}
function nest(values, map, reduce, keys) {
return (function regroup(values, i) {
if (i >= keys.length) return reduce(values);
const groups = new Map();
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);
}
var array = Array.prototype;
var slice = array.slice;
function constant(x) {
return function() {
return x;
};
}
function sequence(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;
}
var e10 = Math.sqrt(50),
e5 = Math.sqrt(10),
e2 = Math.sqrt(2);
function ticks(start, stop, count) {
var reverse,
i = -1,
n,
ticks,
step;
stop = +stop, start = +start, count = +count;
if (start === stop && count > 0) return [start];
if (reverse = stop < start) n = start, start = stop, stop = n;
if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
if (step > 0) {
start = Math.ceil(start / step);
stop = Math.floor(stop / step);
ticks = new Array(n = Math.ceil(stop - start + 1));
while (++i < n) ticks[i] = (start + i) * step;
} else {
step = -step;
start = Math.floor(start * step);
stop = Math.ceil(stop * step);
ticks = new Array(n = Math.ceil(stop - start + 1));
while (++i < n) ticks[i] = (start + i) / step;
}
if (reverse) ticks.reverse();
return ticks;
}
function tickIncrement(start, stop, count) {
var step = (stop - start) / Math.max(0, count),
power = Math.floor(Math.log(step) / Math.LN10),
error = step / Math.pow(10, power);
return power >= 0
? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
: -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
}
function tickStep(start, stop, count) {
var step0 = Math.abs(stop - start) / Math.max(0, count),
step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
error = step0 / step1;
if (error >= e10) step1 *= 10;
else if (error >= e5) step1 *= 5;
else if (error >= e2) step1 *= 2;
return stop < start ? -step1 : step1;
}
function thresholdSturges(values) {
return 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,
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);
// Convert number of thresholds into uniform thresholds.
if (!Array.isArray(tz)) {
tz = tickStep(x0, x1, tz);
tz = sequence(Math.ceil(x0 / tz) * tz, x1, tz); // exclusive
}
// Remove any thresholds outside the domain.
var m = tz.length;
while (tz[0] <= x0) tz.shift(), --m;
while (tz[m - 1] > x1) tz.pop(), --m;
var bins = new Array(m + 1),
bin;
// Initialize bins.
for (i = 0; i <= m; ++i) {
bin = bins[i] = [];
bin.x0 = i > 0 ? tz[i - 1] : x0;
bin.x1 = i < m ? tz[i] : x1;
}
// Assign data to bins by value, ignoring any outside the domain.
for (i = 0; i < n; ++i) {
x = values[i];
if (x0 <= x && x <= x1) {
bins[bisectRight(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" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), 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 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;
}
// Based on https://github.com/mourner/quickselect
// ISC license, Copyright 2018 Vladimir Agafonkin.
function quickselect(array, k, left = 0, right = array.length - 1, compare = ascending) {
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 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;
}
}
}
}
function quantile(values, p, valueof) {
values = Float64Array.from(numbers(values, valueof));
if (!(n = values.length)) return;
if ((p = +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)) return;
if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);
if (p >= 1) return +valueof(values[n - 1], n - 1, values);
var n,
i = (n - 1) * p,
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 freedmanDiaconis(values, min, max) {
return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(count(values), -1 / 3)));
}
function scott(values, min, max) {
return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(count(values), -1 / 3)));
}
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 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* flatten(arrays) {
for (const array of arrays) {
yield* array;
}
}
function merge(arrays) {
return Array.from(flatten(arrays));
}
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 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 permute(source, keys) {
return Array.from(keys, key => source[key]);
}
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 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 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;
}
function shuffle(array, i0 = 0, i1 = array.length) {
var m = i1 - (i0 = +i0),
t,
i;
while (m) {
i = Math.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$1), 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$1(d) {
return d.length;
}
function zip() {
return transpose(arguments);
}
var slice$1 = Array.prototype.slice;
function identity$1(x) {
return x;
}
var top = 1,
right = 2,
bottom = 3,
left = 4,
epsilon = 1e-6;
function translateX(x) {
return "translate(" + (x + 0.5) + ",0)";
}
function translateY(y) {
return "translate(0," + (y + 0.5) + ")";
}
function number$1(scale) {
return d => +scale(d);
}
function center(scale) {
var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.
if (scale.round()) offset = Math.round(offset);
return function(d) {
return +scale(d) + offset;
};
}
function entering() {
return !this.__axis;
}
function axis(orient, scale) {
var tickArguments = [],
tickValues = null,
tickFormat = null,
tickSizeInner = 6,
tickSizeOuter = 6,
tickPadding = 3,
k = orient === top || orient === left ? -1 : 1,
x = orient === left || orient === right ? "x" : "y",
transform = orient === top || orient === bottom ? translateX : translateY;
function axis(context) {
var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
spacing = Math.max(tickSizeInner, 0) + tickPadding,
range = scale.range(),
range0 = +range[0] + 0.5,
range1 = +range[range.length - 1] + 0.5,
position = (scale.bandwidth ? center : number$1)(scale.copy()),
selection = context.selection ? context.selection() : context,
path = selection.selectAll(".domain").data([null]),
tick = selection.selectAll(".tick").data(values, scale).order(),
tickExit = tick.exit(),
tickEnter = tick.enter().append("g").attr("class", "tick"),
line = tick.select("line"),
text = tick.select("text");
path = path.merge(path.enter().insert("path", ".tick")
.attr("class", "domain")
.attr("stroke", "currentColor"));
tick = tick.merge(tickEnter);
line = line.merge(tickEnter.append("line")
.attr("stroke", "currentColor")
.attr(x + "2", k * tickSizeInner));
text = text.merge(tickEnter.append("text")
.attr("fill", "currentColor")
.attr(x, k * spacing)
.attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
if (context !== selection) {
path = path.transition(context);
tick = tick.transition(context);
line = line.transition(context);
text = text.transition(context);
tickExit = tickExit.transition(context)
.attr("opacity", epsilon)
.attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
tickEnter
.attr("opacity", epsilon)
.attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
}
tickExit.remove();
path
.attr("d", orient === left || orient == right
? (tickSizeOuter ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter : "M0.5," + range0 + "V" + range1)
: (tickSizeOuter ? "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter : "M" + range0 + ",0.5H" + range1));
tick
.attr("opacity", 1)
.attr("transform", function(d) { return transform(position(d)); });
line
.attr(x + "2", k * tickSizeInner);
text
.attr(x, k * spacing)
.text(format);
selection.filter(entering)
.attr("fill", "none")
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
selection
.each(function() { this.__axis = position; });
}
axis.scale = function(_) {
return arguments.length ? (scale = _, axis) : scale;
};
axis.ticks = function() {
return tickArguments = slice$1.call(arguments), axis;
};
axis.tickArguments = function(_) {
return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
};
axis.tickValues = function(_) {
return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
};
axis.tickFormat = function(_) {
return arguments.length ? (tickFormat = _, axis) : tickFormat;
};
axis.tickSize = function(_) {
return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
};
axis.tickSizeInner = function(_) {
return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
};
axis.tickSizeOuter = function(_) {
return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
};
axis.tickPadding = function(_) {
return arguments.length ? (tickPadding = +_, axis) : tickPadding;
};
return axis;
}
function axisTop(scale) {
return axis(top, scale);
}
function axisRight(scale) {
return axis(right, scale);
}
function axisBottom(scale) {
return axis(bottom, scale);
}
function axisLeft(scale) {
return axis(left, scale);
}
var noop = {value: () => {}};
function dispatch() {
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
function Dispatch(_) {
this._ = _;
}
function parseTypenames(typenames, types) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
return {type: t, name: name};
});
}
Dispatch.prototype = dispatch.prototype = {
constructor: Dispatch,
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// If no callback was specified, return the callback of the given type and name.
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// If a type was specified, set the callback for the given type and name.
// Otherwise, if a null callback was specified, remove callbacks of the given name.
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
}
return this;
},
copy: function() {
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
};
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
function set(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}
var xhtml = "http://www.w3.org/1999/xhtml";
var namespaces = {
svg: "http://www.w3.org/2000/svg",
xhtml: xhtml,
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
};
function namespace(name) {
var prefix = name += "", i = prefix.indexOf(":");
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins
}
function creatorInherit(name) {
return function() {
var document = this.ownerDocument,
uri = this.namespaceURI;
return uri === xhtml && document.documentElement.namespaceURI === xhtml
? document.createElement(name)
: document.createElementNS(uri, name);
};
}
function creatorFixed(fullname) {
return function() {
return this.ownerDocument.createElementNS(fullname.space, fullname.local);
};
}
function creator(name) {
var fullname = namespace(name);
return (fullname.local
? creatorFixed
: creatorInherit)(fullname);
}
function none() {}
function selector(selector) {
return selector == null ? none : function() {
return this.querySelector(selector);
};
}
function selection_select(select) {
if (typeof select !== "function") select = selector(select);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
}
}
}
return new Selection(subgroups, this._parents);
}
function array$1(x) {
return typeof x === "object" && "length" in x
? x // Array, TypedArray, NodeList, array-like
: Array.from(x); // Map, Set, iterable, string, or anything else
}
function empty$1() {
return [];
}
function selectorAll(selector) {
return selector == null ? empty$1 : function() {
return this.querySelectorAll(selector);
};
}
function arrayAll(select) {
return function() {
var group = select.apply(this, arguments);
return group == null ? [] : array$1(group);
};
}
function selection_selectAll(select) {
if (typeof select === "function") select = arrayAll(select);
else select = selectorAll(select);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
subgroups.push(select.call(node, node.__data__, i, group));
parents.push(node);
}
}
}
return new Selection(subgroups, parents);
}
function matcher(selector) {
return function() {
return this.matches(selector);
};
}
function childMatcher(selector) {
return function(node) {
return node.matches(selector);
};
}
var find = Array.prototype.find;
function childFind(match) {
return function() {
return find.call(this.children, match);
};
}
function childFirst() {
return this.firstElementChild;
}
function selection_selectChild(match) {
return this.select(match == null ? childFirst
: childFind(typeof match === "function" ? match : childMatcher(match)));
}
var filter = Array.prototype.filter;
function children() {
return this.children;
}
function childrenFilter(match) {
return function() {
return filter.call(this.children, match);
};
}
function selection_selectChildren(match) {
return this.selectAll(match == null ? children
: childrenFilter(typeof match === "function" ? match : childMatcher(match)));
}
function selection_filter(match) {
if (typeof match !== "function") match = matcher(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Selection(subgroups, this._parents);
}
function sparse(update) {
return new Array(update.length);
}
function selection_enter() {
return new Selection(this._enter || this._groups.map(sparse), this._parents);
}
function EnterNode(parent, datum) {
this.ownerDocument = parent.ownerDocument;
this.namespaceURI = parent.namespaceURI;
this._next = null;
this._parent = parent;
this.__data__ = datum;
}
EnterNode.prototype = {
constructor: EnterNode,
appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
querySelector: function(selector) { return this._parent.querySelector(selector); },
querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
};
function constant$1(x) {
return function() {
return x;
};
}
function bindIndex(parent, group, enter, update, exit, data) {
var i = 0,
node,
groupLength = group.length,
dataLength = data.length;
// Put any non-null nodes that fit into update.
// Put any null nodes into enter.
// Put any remaining data into enter.
for (; i < dataLength; ++i) {
if (node = group[i]) {
node.__data__ = data[i];
update[i] = node;
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Put any non-null nodes that don’t fit into exit.
for (; i < groupLength; ++i) {
if (node = group[i]) {
exit[i] = node;
}
}
}
function bindKey(parent, group, enter, update, exit, data, key) {
var i,
node,
nodeByKeyValue = new Map,
groupLength = group.length,
dataLength = data.length,
keyValues = new Array(groupLength),
keyValue;
// Compute the key for each node.
// If multiple nodes have the same key, the duplicates are added to exit.
for (i = 0; i < groupLength; ++i) {
if (node = group[i]) {
keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + "";
if (nodeByKeyValue.has(keyValue)) {
exit[i] = node;
} else {
nodeByKeyValue.set(keyValue, node);
}
}
}
// Compute the key for each datum.
// If there a node associated with this key, join and add it to update.
// If there is not (or the key is a duplicate), add it to enter.
for (i = 0; i < dataLength; ++i) {
keyValue = key.call(parent, data[i], i, data) + "";
if (node = nodeByKeyValue.get(keyValue)) {
update[i] = node;
node.__data__ = data[i];
nodeByKeyValue.delete(keyValue);
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Add any remaining nodes that were not bound to data to exit.
for (i = 0; i < groupLength; ++i) {
if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) {
exit[i] = node;
}
}
}
function datum(node) {
return node.__data__;
}
function selection_data(value, key) {
if (!arguments.length) return Array.from(this, datum);
var bind = key ? bindKey : bindIndex,
parents = this._parents,
groups = this._groups;
if (typeof value !== "function") value = constant$1(value);
for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
var parent = parents[j],
group = groups[j],
groupLength = group.length,
data = array$1(value.call(parent, parent && parent.__data__, j, parents)),
dataLength = data.length,
enterGroup = enter[j] = new Array(dataLength),
updateGroup = update[j] = new Array(dataLength),
exitGroup = exit[j] = new Array(groupLength);
bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
// Now connect the enter nodes to their following update node, such that
// appendChild can insert the materialized enter node before this node,
// rather than at the end of the parent node.
for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
if (previous = enterGroup[i0]) {
if (i0 >= i1) i1 = i0 + 1;
while (!(next = updateGroup[i1]) && ++i1 < dataLength);
previous._next = next || null;
}
}
}
update = new Selection(update, parents);
update._enter = enter;
update._exit = exit;
return update;
}
function selection_exit() {
return new Selection(this._exit || this._groups.map(sparse), this._parents);
}
function selection_join(onenter, onupdate, onexit) {
var enter = this.enter(), update = this, exit = this.exit();
enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + "");
if (onupdate != null) update = onupdate(update);
if (onexit == null) exit.remove(); else onexit(exit);
return enter && update ? enter.merge(update).order() : update;
}
function selection_merge(selection) {
if (!(selection instanceof Selection)) throw new Error("invalid merge");
for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Selection(merges, this._parents);
}
function selection_order() {
for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
if (node = group[i]) {
if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
next = node;
}
}
}
return this;
}
function selection_sort(compare) {
if (!compare) compare = ascending$1;
function compareNode(a, b) {
return a && b ? compare(a.__data__, b.__data__) : !a - !b;
}
for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group[i]) {
sortgroup[i] = node;
}
}
sortgroup.sort(compareNode);
}
return new Selection(sortgroups, this._parents).order();
}
function ascending$1(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function selection_call() {
var callback = arguments[0];
arguments[0] = this;
callback.apply(null, arguments);
return this;
}
function selection_nodes() {
return Array.from(this);
}
function selection_node() {
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
var node = group[i];
if (node) return node;
}
}
return null;
}
function selection_size() {
let size = 0;
for (const node of this) ++size; // eslint-disable-line no-unused-vars
return size;
}
function selection_empty() {
return !this.node();
}
function selection_each(callback) {
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
if (node = group[i]) callback.call(node, node.__data__, i, group);
}
}
return this;
}
function attrRemove(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant(name, value) {
return function() {
this.setAttribute(name, value);
};
}
function attrConstantNS(fullname, value) {
return function() {
this.setAttributeNS(fullname.space, fullname.local, value);
};
}
function attrFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttribute(name);
else this.setAttribute(name, v);
};
}
function attrFunctionNS(fullname, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
else this.setAttributeNS(fullname.space, fullname.local, v);
};
}
function selection_attr(name, value) {
var fullname = namespace(name);
if (arguments.length < 2) {
var node = this.node();
return fullname.local
? node.getAttributeNS(fullname.space, fullname.local)
: node.getAttribute(fullname);
}
return this.each((value == null
? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction)
: (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
}
function defaultView(node) {
return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
|| (node.document && node) // node is a Window
|| node.defaultView; // node is a Document
}
function styleRemove(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant(name, value, priority) {
return function() {
this.style.setProperty(name, value, priority);
};
}
function styleFunction(name, value, priority) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.style.removeProperty(name);
else this.style.setProperty(name, v, priority);
};
}
function selection_style(name, value, priority) {
return arguments.length > 1
? this.each((value == null
? styleRemove : typeof value === "function"
? styleFunction
: styleConstant)(name, value, priority == null ? "" : priority))
: styleValue(this.node(), name);
}
function styleValue(node, name) {
return node.style.getPropertyValue(name)
|| defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
}
function propertyRemove(name) {
return function() {
delete this[name];
};
}
function propertyConstant(name, value) {
return function() {
this[name] = value;
};
}
function propertyFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) delete this[name];
else this[name] = v;
};
}
function selection_property(name, value) {
return arguments.length > 1
? this.each((value == null
? propertyRemove : typeof value === "function"
? propertyFunction
: propertyConstant)(name, value))
: this.node()[name];
}
function classArray(string) {
return string.trim().split(/^|\s+/);
}
function classList(node) {
return node.classList || new ClassList(node);
}
function ClassList(node) {
this._node = node;
this._names = classArray(node.getAttribute("class") || "");
}
ClassList.prototype = {
add: function(name) {
var i = this._names.indexOf(name);
if (i < 0) {
this._names.push(name);
this._node.setAttribute("class", this._names.join(" "));
}
},
remove: function(name) {
var i = this._names.indexOf(name);
if (i >= 0) {
this._names.splice(i, 1);
this._node.setAttribute("class", this._names.join(" "));
}
},
contains: function(name) {
return this._names.indexOf(name) >= 0;
}
};
function classedAdd(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.add(names[i]);
}
function classedRemove(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.remove(names[i]);
}
function classedTrue(names) {
return function() {
classedAdd(this, names);
};
}
function classedFalse(names) {
return function() {
classedRemove(this, names);
};
}
function classedFunction(names, value) {
return function() {
(value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
};
}
function selection_classed(name, value) {
var names = classArray(name + "");
if (arguments.length < 2) {
var list = classList(this.node()), i = -1, n = names.length;
while (++i < n) if (!list.contains(names[i])) return false;
return true;
}
return this.each((typeof value === "function"
? classedFunction : value
? classedTrue
: classedFalse)(names, value));
}
function textRemove() {
this.textContent = "";
}
function textConstant(value) {
return function() {
this.textContent = value;
};
}
function textFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.textContent = v == null ? "" : v;
};
}
function selection_text(value) {
return arguments.length
? this.each(value == null
? textRemove : (typeof value === "function"
? textFunction
: textConstant)(value))
: this.node().textContent;
}
function htmlRemove() {
this.innerHTML = "";
}
function htmlConstant(value) {
return function() {
this.innerHTML = value;
};
}
function htmlFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.innerHTML = v == null ? "" : v;
};
}
function selection_html(value) {
return arguments.length
? this.each(value == null
? htmlRemove : (typeof value === "function"
? htmlFunction
: htmlConstant)(value))
: this.node().innerHTML;
}
function raise() {
if (this.nextSibling) this.parentNode.appendChild(this);
}
function selection_raise() {
return this.each(raise);
}
function lower() {
if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
}
function selection_lower() {
return this.each(lower);
}
function selection_append(name) {
var create = typeof name === "function" ? name : creator(name);
return this.select(function() {
return this.appendChild(create.apply(this, arguments));
});
}
function constantNull() {
return null;
}
function selection_insert(name, before) {
var create = typeof name === "function" ? name : creator(name),
select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
return this.select(function() {
return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
});
}
function remove() {
var parent = this.parentNode;
if (parent) parent.removeChild(this);
}
function selection_remove() {
return this.each(remove);
}
function selection_cloneShallow() {
var clone = this.cloneNode(false), parent = this.parentNode;
return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
}
function selection_cloneDeep() {
var clone = this.cloneNode(true), parent = this.parentNode;
return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
}
function selection_clone(deep) {
return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
}
function selection_datum(value) {
return arguments.length
? this.property("__data__", value)
: this.node().__data__;
}
function contextListener(listener) {
return function(event) {
listener.call(this, event, this.__data__);
};
}
function parseTypenames$1(typenames) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
return {type: t, name: name};
});
}
function onRemove(typename) {
return function() {
var on = this.__on;
if (!on) return;
for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.options);
} else {
on[++i] = o;
}
}
if (++i) on.length = i;
else delete this.__on;
};
}
function onAdd(typename, value, options) {
return function() {
var on = this.__on, o, listener = contextListener(value);
if (on) for (var j = 0, m = on.length; j < m; ++j) {
if ((o = on[j]).type === typename.type && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.options);
this.addEventListener(o.type, o.listener = listener, o.options = options);
o.value = value;
return;
}
}
this.addEventListener(typename.type, listener, options);
o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options};
if (!on) this.__on = [o];
else on.push(o);
};
}
function selection_on(typename, value, options) {
var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
if (arguments.length < 2) {
var on = this.node().__on;
if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
for (i = 0, o = on[j]; i < n; ++i) {
if ((t = typenames[i]).type === o.type && t.name === o.name) {
return o.value;
}
}
}
return;
}
on = value ? onAdd : onRemove;
for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));
return this;
}
function dispatchEvent(node, type, params) {
var window = defaultView(node),
event = window.CustomEvent;
if (typeof event === "function") {
event = new event(type, params);
} else {
event = window.document.createEvent("Event");
if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
else event.initEvent(type, false, false);
}
node.dispatchEvent(event);
}
function dispatchConstant(type, params) {
return function() {
return dispatchEvent(this, type, params);
};
}
function dispatchFunction(type, params) {
return function() {
return dispatchEvent(this, type, params.apply(this, arguments));
};
}
function selection_dispatch(type, params) {
return this.each((typeof params === "function"
? dispatchFunction
: dispatchConstant)(type, params));
}
function* selection_iterator() {
for (var gro