Relax d3-array parameter definitions to ArrayLike (#18580)

* Relax parameter definitions for most d3-array functions from Array to ArrayLike (#18494)

* Add cases for TypedArrays and ArrayLike (as ReadonlyArray) to d3-array tests (#18494)

* Redefine d3-array shuffle so it fails when called with a ReadonlyArray (#18494)
This commit is contained in:
Andrew Kirkegaard
2017-08-02 18:11:01 -05:00
committed by Sheetal Nandi
parent 17b09d742d
commit 2754522a15
2 changed files with 331 additions and 131 deletions

View File

@@ -54,18 +54,29 @@ let mixedOrUndefinedExtent: [d3Array.Primitive | NumCoercible, d3Array.Primitive
let dateOrUndefinedExtent: [Date, Date] | [undefined, undefined];
let numbersArray = [10, 20, 30, 40, 50];
const numbersOrUndefinedArray = [10, 20, undefined, null, 40, 50];
const stringyNumbersArray = ['10', '20', '30', '40', '50'];
const numericArray = [new NumCoercible(10), new NumCoercible(20), new NumCoercible(30), new NumCoercible(40), new NumCoercible(50)];
const dateArray = [new Date(2016, 6, 1), new Date(2016, 7, 30), new Date(2015, 3, 15)];
const mixedObjectArray = [
let numbersOrUndefinedArray = [10, 20, undefined, null, 40, 50];
let stringyNumbersArray = ['10', '20', '30', '40', '50'];
let numericArray = [new NumCoercible(10), new NumCoercible(20), new NumCoercible(30), new NumCoercible(40), new NumCoercible(50)];
let dateArray = [new Date(2016, 6, 1), new Date(2016, 7, 30), new Date(2015, 3, 15)];
let mixedObjectArray = [
new MixedObject(10, new Date(2016, 6, 1)),
new MixedObject(20, new Date(2016, 7, 30)),
new MixedObject(30, new Date(2015, 3, 15)),
new MixedObject(40, new Date(2014, 3, 15)),
new MixedObject(50, new Date(2017, 4, 15))
];
const mixedObjectOrUndefinedArray = [...mixedObjectArray, undefined];
let mixedObjectOrUndefinedArray = [...mixedObjectArray, undefined];
let typedArray = Uint8Array.from(numbersArray);
let readonlyNumbersArray = numbersArray as ReadonlyArray<number>;
let readonlyNumbersOrUndefinedArray = numbersOrUndefinedArray as ReadonlyArray<number>;
let readonlyStringyNumbersArray = stringyNumbersArray as ReadonlyArray<string>;
let readonlyNumericArray = numericArray as ReadonlyArray<NumCoercible>;
let readonlyDateArray = dateArray as ReadonlyArray<Date>;
let readonlyMixedObjectArray = mixedObjectArray as ReadonlyArray<MixedObject>;
let readonlyMixedObjectOrUndefinedArray = mixedObjectOrUndefinedArray as ReadonlyArray<MixedObject>;
function accessorMixedObjectToNum(datum: MixedObject, index: number, array: MixedObject[]): number {
return datum.num;
@@ -104,6 +115,14 @@ strOrUndefined = d3Array.max(stringyNumbersArray);
numericOrUndefined = d3Array.max(numericArray);
dateOrUndefined = d3Array.max(dateArray);
// ArrayLike test cases
numOrUndefined = d3Array.max(typedArray);
numOrUndefined = d3Array.max(readonlyNumbersOrUndefinedArray);
strOrUndefined = d3Array.max(readonlyStringyNumbersArray);
numericOrUndefined = d3Array.max(readonlyNumericArray);
dateOrUndefined = d3Array.max(readonlyDateArray);
// with accessors
numOrUndefined = d3Array.max(mixedObjectArray, accessorMixedObjectToNum);
@@ -112,6 +131,7 @@ numericOrUndefined = d3Array.max(mixedObjectArray, accessorMixedObjectToNumeric)
dateOrUndefined = d3Array.max(mixedObjectArray, accessorMixedObjectToDate);
numOrUndefined = d3Array.max(mixedObjectArray, accessorMixedObjectToNumOrUndefined);
strOrUndefined = d3Array.max(mixedObjectArray, accessorMixedObjectToStrOrUndefined);
numOrUndefined = d3Array.max(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// min() -----------------------------------------------------------------------
@@ -122,6 +142,14 @@ strOrUndefined = d3Array.min(stringyNumbersArray);
numericOrUndefined = d3Array.min(numericArray);
dateOrUndefined = d3Array.min(dateArray);
// ArrayLike test cases
numOrUndefined = d3Array.min(typedArray);
numOrUndefined = d3Array.min(readonlyNumbersOrUndefinedArray);
strOrUndefined = d3Array.min(readonlyStringyNumbersArray);
numericOrUndefined = d3Array.min(readonlyNumericArray);
dateOrUndefined = d3Array.min(readonlyDateArray);
// with accessors
numOrUndefined = d3Array.min(mixedObjectArray, accessorMixedObjectToNum);
@@ -130,6 +158,7 @@ numericOrUndefined = d3Array.min(mixedObjectArray, accessorMixedObjectToNumeric)
dateOrUndefined = d3Array.min(mixedObjectArray, accessorMixedObjectToDate);
numOrUndefined = d3Array.min(mixedObjectArray, accessorMixedObjectToNumOrUndefined);
strOrUndefined = d3Array.min(mixedObjectArray, accessorMixedObjectToStrOrUndefined);
numOrUndefined = d3Array.max(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// extent() --------------------------------------------------------------------
@@ -140,6 +169,14 @@ strOrUndefinedExtent = d3Array.extent(stringyNumbersArray);
numericOrUndefinedExtent = d3Array.extent(numericArray);
dateOrUndefinedExtent = d3Array.extent(dateArray);
// ArrayLike test cases
numOrUndefinedExtent = d3Array.extent(typedArray);
numOrUndefinedExtent = d3Array.extent(readonlyNumbersOrUndefinedArray);
strOrUndefinedExtent = d3Array.extent(readonlyStringyNumbersArray);
numericOrUndefinedExtent = d3Array.extent(readonlyNumericArray);
dateOrUndefinedExtent = d3Array.extent(readonlyDateArray);
// with accessors
numOrUndefinedExtent = d3Array.extent(mixedObjectArray, accessorMixedObjectToNum);
@@ -148,6 +185,7 @@ mixedOrUndefinedExtent = d3Array.extent(mixedObjectArray, accessorMixedObjectToN
dateMixedOrUndefined = d3Array.extent(mixedObjectArray, accessorMixedObjectToDate);
numOrUndefinedExtent = d3Array.extent(mixedObjectArray, accessorMixedObjectToNumOrUndefined);
strOrUndefinedExtent = d3Array.extent(mixedObjectArray, accessorMixedObjectToStrOrUndefined);
numOrUndefinedExtent = d3Array.extent(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// mean() ----------------------------------------------------------------------
@@ -155,8 +193,14 @@ numOrUndefined = d3Array.mean(numbersArray);
numOrUndefined = d3Array.mean(numericArray);
numOrUndefined = d3Array.mean(numbersOrUndefinedArray);
numOrUndefined = d3Array.mean(typedArray);
numOrUndefined = d3Array.mean(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.mean(readonlyNumericArray);
numOrUndefined = d3Array.mean(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.mean(mixedObjectArray, accessorMixedObjectToNum);
numOrUndefined = d3Array.mean(mixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.mean(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// median() --------------------------------------------------------------------
@@ -164,8 +208,14 @@ numOrUndefined = d3Array.median(numbersArray);
numOrUndefined = d3Array.median(numericArray);
numOrUndefined = d3Array.median(numbersOrUndefinedArray);
numOrUndefined = d3Array.median(typedArray);
numOrUndefined = d3Array.median(readonlyNumbersArray);
numOrUndefined = d3Array.median(readonlyNumericArray);
numOrUndefined = d3Array.median(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.median(mixedObjectArray, accessorMixedObjectToNum);
numOrUndefined = d3Array.median(mixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.median(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// quantile() ------------------------------------------------------------------
@@ -173,8 +223,14 @@ numOrUndefined = d3Array.quantile(numbersArray, 0.5);
numOrUndefined = d3Array.quantile(numericArray, 0.5);
numOrUndefined = d3Array.quantile(numbersOrUndefinedArray, 0.5);
numOrUndefined = d3Array.quantile(typedArray, 0.5);
numOrUndefined = d3Array.quantile(readonlyNumbersArray, 0.5);
numOrUndefined = d3Array.quantile(readonlyNumericArray, 0.5);
numOrUndefined = d3Array.quantile(readonlyNumbersOrUndefinedArray, 0.5);
numOrUndefined = d3Array.quantile(mixedObjectArray, 0.5, accessorMixedObjectToNum);
numOrUndefined = d3Array.quantile(mixedObjectOrUndefinedArray, 0.5, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.quantile(readonlyMixedObjectOrUndefinedArray, 0.5, accessorMixedObjectToNumOrUndefined);
// sum() -----------------------------------------------------------------------
@@ -182,8 +238,14 @@ numOrUndefined = d3Array.sum(numbersArray);
numOrUndefined = d3Array.sum(numericArray);
numOrUndefined = d3Array.sum(numbersOrUndefinedArray);
numOrUndefined = d3Array.sum(typedArray);
numOrUndefined = d3Array.sum(readonlyNumbersArray);
numOrUndefined = d3Array.sum(readonlyNumericArray);
numOrUndefined = d3Array.sum(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.sum(mixedObjectArray, accessorMixedObjectToNum);
numOrUndefined = d3Array.sum(mixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.sum(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// deviation() -----------------------------------------------------------------
@@ -191,8 +253,14 @@ numOrUndefined = d3Array.deviation(numbersArray);
numOrUndefined = d3Array.deviation(numericArray);
numOrUndefined = d3Array.deviation(numbersOrUndefinedArray);
numOrUndefined = d3Array.deviation(typedArray);
numOrUndefined = d3Array.deviation(readonlyNumbersArray);
numOrUndefined = d3Array.deviation(readonlyNumericArray);
numOrUndefined = d3Array.deviation(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.deviation(mixedObjectArray, accessorMixedObjectToNum);
numOrUndefined = d3Array.deviation(mixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.deviation(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// variance() ------------------------------------------------------------------
@@ -200,16 +268,29 @@ numOrUndefined = d3Array.variance(numbersArray);
numOrUndefined = d3Array.variance(numericArray);
numOrUndefined = d3Array.variance(numbersOrUndefinedArray);
numOrUndefined = d3Array.variance(typedArray);
numOrUndefined = d3Array.variance(readonlyNumbersArray);
numOrUndefined = d3Array.variance(readonlyNumericArray);
numOrUndefined = d3Array.variance(readonlyNumbersOrUndefinedArray);
numOrUndefined = d3Array.variance(mixedObjectArray, accessorMixedObjectToNum);
numOrUndefined = d3Array.variance(mixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
numOrUndefined = d3Array.variance(readonlyMixedObjectOrUndefinedArray, accessorMixedObjectToNumOrUndefined);
// -----------------------------------------------------------------------------
// Test Searching Arrays
// -----------------------------------------------------------------------------
numbersArray = [0, 2, 3, 4, 7, 8];
stringyNumbersArray = ['0', '2', '3', '4', '7', '8'];
dateArray = [new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)];
typedArray = Uint8Array.from(numbersArray);
// scan() ----------------------------------------------------------------------
numOrUndefined = d3Array.scan(numbersArray);
numOrUndefined = d3Array.scan(typedArray);
numOrUndefined = d3Array.scan(readonlyNumbersArray);
numOrUndefined = d3Array.scan(mixedObjectArray, (a, b) => {
const aElem: MixedObject = a;
@@ -217,53 +298,113 @@ numOrUndefined = d3Array.scan(mixedObjectArray, (a, b) => {
return a.num - b.num;
});
numOrUndefined = d3Array.scan(readonlyMixedObjectArray, (a, b) => {
const aElem: MixedObject = a;
const bElem: MixedObject = b;
return a.num - b.num;
});
numOrUndefined = d3Array.scan(mixedObjectOrUndefinedArray, (a, b) => {
const aElem: MixedObject | undefined = a;
const bElem: MixedObject | undefined = b;
return a && b ? a.num - b.num : NaN;
});
numOrUndefined = d3Array.scan(readonlyMixedObjectOrUndefinedArray, (a, b) => {
const aElem: MixedObject | undefined = a;
const bElem: MixedObject | undefined = b;
return a && b ? a.num - b.num : NaN;
});
// bisectLeft() ----------------------------------------------------------------
num = d3Array.bisectLeft([0, 2, 3, 4, 7, 8], 4);
num = d3Array.bisectLeft([0, 2, 3, 4, 7, 8], 4, 1);
num = d3Array.bisectLeft([0, 2, 3, 4, 7, 8], 4, 1, 4);
num = d3Array.bisectLeft(numbersArray, 4);
num = d3Array.bisectLeft(numbersArray, 4, 1);
num = d3Array.bisectLeft(numbersArray, 4, 1, 4);
num = d3Array.bisectLeft(['0', '2', '3', '4', '7', '8'], '21');
num = d3Array.bisectLeft(['0', '2', '3', '4', '7', '8'], '21', 1);
num = d3Array.bisectLeft(['0', '2', '3', '4', '7', '8'], '21', 1, 4);
num = d3Array.bisectLeft(stringyNumbersArray, '21');
num = d3Array.bisectLeft(stringyNumbersArray, '21', 1);
num = d3Array.bisectLeft(stringyNumbersArray, '21', 1, 4);
num = d3Array.bisectLeft([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1));
num = d3Array.bisectLeft([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1);
num = d3Array.bisectLeft([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1, 2);
num = d3Array.bisectLeft(dateArray, new Date(2011, 2, 1));
num = d3Array.bisectLeft(dateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisectLeft(dateArray, new Date(2011, 2, 1), 1, 2);
num = d3Array.bisectLeft(typedArray, 4);
num = d3Array.bisectLeft(typedArray, 4, 1);
num = d3Array.bisectLeft(typedArray, 4, 1, 4);
num = d3Array.bisectLeft(readonlyNumbersArray, 4);
num = d3Array.bisectLeft(readonlyNumbersArray, 4, 1);
num = d3Array.bisectLeft(readonlyNumbersArray, 4, 1, 4);
num = d3Array.bisectLeft(readonlyStringyNumbersArray, '21');
num = d3Array.bisectLeft(readonlyStringyNumbersArray, '21', 1);
num = d3Array.bisectLeft(readonlyStringyNumbersArray, '21', 1, 4);
num = d3Array.bisectLeft(readonlyDateArray, new Date(2011, 2, 1));
num = d3Array.bisectLeft(readonlyDateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisectLeft(readonlyDateArray, new Date(2011, 2, 1), 1, 2);
// bisectRight() ---------------------------------------------------------------
num = d3Array.bisectRight([0, 2, 3, 4, 7, 8], 4);
num = d3Array.bisectRight([0, 2, 3, 4, 7, 8], 4, 1);
num = d3Array.bisectRight([0, 2, 3, 4, 7, 8], 4, 1, 4);
num = d3Array.bisectRight(numbersArray, 4);
num = d3Array.bisectRight(numbersArray, 4, 1);
num = d3Array.bisectRight(numbersArray, 4, 1, 4);
num = d3Array.bisectRight(['0', '2', '3', '4', '7', '8'], '21');
num = d3Array.bisectRight(['0', '2', '3', '4', '7', '8'], '21', 1);
num = d3Array.bisectRight(['0', '2', '3', '4', '7', '8'], '21', 1, 4);
num = d3Array.bisectRight(stringyNumbersArray, '21');
num = d3Array.bisectRight(stringyNumbersArray, '21', 1);
num = d3Array.bisectRight(stringyNumbersArray, '21', 1, 4);
num = d3Array.bisectRight([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1));
num = d3Array.bisectRight([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1);
num = d3Array.bisectRight([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1, 2);
num = d3Array.bisectRight(dateArray, new Date(2011, 2, 1));
num = d3Array.bisectRight(dateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisectRight(dateArray, new Date(2011, 2, 1), 1, 2);
num = d3Array.bisectRight(typedArray, 4);
num = d3Array.bisectRight(typedArray, 4, 1);
num = d3Array.bisectRight(typedArray, 4, 1, 4);
num = d3Array.bisectRight(readonlyNumbersArray, 4);
num = d3Array.bisectRight(readonlyNumbersArray, 4, 1);
num = d3Array.bisectRight(readonlyNumbersArray, 4, 1, 4);
num = d3Array.bisectRight(readonlyStringyNumbersArray, '21');
num = d3Array.bisectRight(readonlyStringyNumbersArray, '21', 1);
num = d3Array.bisectRight(readonlyStringyNumbersArray, '21', 1, 4);
num = d3Array.bisectRight(readonlyDateArray, new Date(2011, 2, 1));
num = d3Array.bisectRight(readonlyDateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisectRight(readonlyDateArray, new Date(2011, 2, 1), 1, 2);
// bisect() --------------------------------------------------------------------
num = d3Array.bisect([0, 2, 3, 4, 7, 8], 4);
num = d3Array.bisect([0, 2, 3, 4, 7, 8], 4, 1);
num = d3Array.bisect([0, 2, 3, 4, 7, 8], 4, 1, 4);
num = d3Array.bisect(numbersArray, 4);
num = d3Array.bisect(numbersArray, 4, 1);
num = d3Array.bisect(numbersArray, 4, 1, 4);
num = d3Array.bisect(['0', '2', '3', '4', '7', '8'], '21');
num = d3Array.bisect(['0', '2', '3', '4', '7', '8'], '21', 1);
num = d3Array.bisect(['0', '2', '3', '4', '7', '8'], '21', 1, 4);
num = d3Array.bisect(stringyNumbersArray, '21');
num = d3Array.bisect(stringyNumbersArray, '21', 1);
num = d3Array.bisect(stringyNumbersArray, '21', 1, 4);
num = d3Array.bisect([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1));
num = d3Array.bisect([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1);
num = d3Array.bisect([new Date(2010, 1, 1), new Date(2011, 1, 1), new Date(2012, 1, 1), new Date(2013, 1, 1)], new Date(2011, 2, 1), 1, 2);
num = d3Array.bisect(dateArray, new Date(2011, 2, 1));
num = d3Array.bisect(dateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisect(dateArray, new Date(2011, 2, 1), 1, 2);
num = d3Array.bisect(typedArray, 4);
num = d3Array.bisect(typedArray, 4, 1);
num = d3Array.bisect(typedArray, 4, 1, 4);
num = d3Array.bisect(readonlyNumbersArray, 4);
num = d3Array.bisect(readonlyNumbersArray, 4, 1);
num = d3Array.bisect(readonlyNumbersArray, 4, 1, 4);
num = d3Array.bisect(readonlyStringyNumbersArray, '21');
num = d3Array.bisect(readonlyStringyNumbersArray, '21', 1);
num = d3Array.bisect(readonlyStringyNumbersArray, '21', 1, 4);
num = d3Array.bisect(readonlyDateArray, new Date(2011, 2, 1));
num = d3Array.bisect(readonlyDateArray, new Date(2011, 2, 1), 1);
num = d3Array.bisect(readonlyDateArray, new Date(2011, 2, 1), 1, 2);
// bisector() ------------------------------------------------------------------
@@ -283,11 +424,19 @@ num = mixedObjectDateBisectorObject.left(mixedObjectArray, new Date(2015, 3, 14)
num = mixedObjectDateBisectorObject.left(mixedObjectArray, new Date(2015, 3, 14), 1);
num = mixedObjectDateBisectorObject.left(mixedObjectArray, new Date(2015, 3, 14), 3, 4);
num = mixedObjectDateBisectorObject.left(readonlyMixedObjectArray, new Date(2015, 3, 14));
num = mixedObjectDateBisectorObject.left(readonlyMixedObjectArray, new Date(2015, 3, 14), 1);
num = mixedObjectDateBisectorObject.left(readonlyMixedObjectArray, new Date(2015, 3, 14), 3, 4);
// bisect right
num = mixedObjectDateBisectorObject.right(mixedObjectArray, new Date(2015, 3, 14));
num = mixedObjectDateBisectorObject.right(mixedObjectArray, new Date(2015, 3, 14), 1);
num = mixedObjectDateBisectorObject.right(mixedObjectArray, new Date(2015, 3, 14), 3, 4);
num = mixedObjectDateBisectorObject.right(readonlyMixedObjectArray, new Date(2015, 3, 14));
num = mixedObjectDateBisectorObject.right(readonlyMixedObjectArray, new Date(2015, 3, 14), 1);
num = mixedObjectDateBisectorObject.right(readonlyMixedObjectArray, new Date(2015, 3, 14), 3, 4);
// ascending() -----------------------------------------------------------------
num = d3Array.ascending(undefined, 20);
@@ -308,32 +457,44 @@ num = d3Array.descending(new Date(2016, 6, 13), new Date(2016, 6, 14));
// merge() ---------------------------------------------------------------------
let testArrays: MixedObject[][] = [
[
new MixedObject(10, new Date(2016, 6, 1)),
new MixedObject(20, new Date(2016, 7, 30)),
new MixedObject(30, new Date(2015, 3, 15)),
new MixedObject(40, new Date(2014, 3, 15)),
new MixedObject(50, new Date(2017, 4, 15))
],
[
new MixedObject(40, new Date(2016, 3, 1)),
new MixedObject(50, new Date(2016, 9, 30)),
]
let testArray1 = [
new MixedObject(10, new Date(2016, 6, 1)),
new MixedObject(20, new Date(2016, 7, 30)),
new MixedObject(30, new Date(2015, 3, 15)),
new MixedObject(40, new Date(2014, 3, 15)),
new MixedObject(50, new Date(2017, 4, 15))
];
let testArray2 = [
new MixedObject(40, new Date(2016, 3, 1)),
new MixedObject(50, new Date(2016, 9, 30)),
];
let testArrays: MixedObject[][] = [testArray1, testArray2];
let readonlyTestArray1 = testArray1 as ReadonlyArray<MixedObject>;
let readonlyTestArray2 = testArray2 as ReadonlyArray<MixedObject>;
let readonlyTestArrays = [testArray1, testArray2] as ReadonlyArray<ReadonlyArray<MixedObject>>;
let mergedArray: MixedObject[];
mergedArray = d3Array.merge(testArrays); // inferred type
mergedArray = d3Array.merge<MixedObject>(testArrays); // explicit type
// mergedArray = d3Array.merge<MixedObject>([[10, 40, 30], [15, 30]]); // fails, type mismatch
// mergedArray = d3Array.merge([testArray1, [15, 30]]); // fails, type mismatch
mergedArray = d3Array.merge(readonlyTestArrays); // inferred type
mergedArray = d3Array.merge<MixedObject>(readonlyTestArrays); // explicit type
// cross() ---------------------------------------------------------------------
let crossed: Array<[string, number]>;
crossed = d3Array.cross(['x', 'y'], [1, 2]);
crossed = d3Array.cross<string, number>(['x', 'y'], [1, 2]);
const chars = ['x', 'y'];
const nums = [1, 2];
crossed = d3Array.cross(chars, nums);
crossed = d3Array.cross<string, number>(chars, nums);
let strArray: string[] = d3Array.cross<number, number, string>([2, 3], [5, 6], (a, b) => (a + b) + 'px');
strArray = d3Array.cross([2, 3], [5, 6], (a, b) => {
@@ -342,6 +503,21 @@ strArray = d3Array.cross([2, 3], [5, 6], (a, b) => {
return (aa + bb) + 'px';
});
const readonlyChars = chars as ReadonlyArray<string>;
const readonlyNums = new Uint8Array(nums);
crossed = d3Array.cross(readonlyChars, readonlyNums);
crossed = d3Array.cross<string, number>(readonlyChars, readonlyNums);
strArray = d3Array.cross<number, number, string>([2, 3] as ReadonlyArray<number>, new Uint8ClampedArray([5, 6]), (a, b) => (a + b) + 'px');
strArray = d3Array.cross([2, 3] as ReadonlyArray<number>, new Uint8ClampedArray([5, 6]), (a, b) => {
const aa: number = a;
const bb: number = b;
return (aa + bb) + 'px';
});
d3Array.cross(new Uint8Array([1, 2, 3, 4, 5]), new Uint8Array([10, 20, 30, 40, 50]));
// pairs() ---------------------------------------------------------------------
let pairs: Array<[MixedObject, MixedObject]>;
@@ -355,10 +531,21 @@ numbersArray = d3Array.pairs(mergedArray, (a, b) => {
return bb.num - aa.num;
});
const readonlyMergedArray = mergedArray as ReadonlyArray<MixedObject>;
pairs = d3Array.pairs(readonlyMergedArray);
numbersArray = d3Array.pairs<MixedObject, number>(readonlyMergedArray, (a, b) => b.num - a.num);
numbersArray = d3Array.pairs(readonlyMergedArray, (a, b) => {
const aa: MixedObject = a;
const bb: MixedObject = b;
return bb.num - aa.num;
});
// permute() -------------------------------------------------------------------
// getting a permutation of array elements
mergedArray = d3Array.permute(mergedArray, [1, 0, 2, 5, 3, 4, 6]);
mergedArray = d3Array.permute(readonlyMergedArray, [1, 0, 2, 5, 3, 4, 6]);
// Getting an ordered array with object properties
@@ -380,10 +567,20 @@ numbersArray = d3Array.range(1, 10, 0.5);
// shuffle() -------------------------------------------------------------------
mergedArray = d3Array.shuffle(mergedArray);
mergedArray = d3Array.shuffle(mergedArray, 1);
mergedArray = d3Array.shuffle(mergedArray, 1, 3);
// mergedArray = d3Array.shuffle(readonlyMergedArray); // fails, shuffle mutates input array in-place
// Test each TypedArray explicitly. Can't use ArrayLike in this case because shuffle is mutable and ArrayLike would include ReadonlyArray
let resultInt8: Int8Array = d3Array.shuffle(new Int8Array(numbersArray));
let resultUint8: Uint8Array = d3Array.shuffle(new Uint8Array(numbersArray));
let resultUint8Clamped: Uint8ClampedArray = d3Array.shuffle(new Uint8ClampedArray(numbersArray));
let resultInt16: Int16Array = d3Array.shuffle(new Int16Array(numbersArray));
let resultUint6: Uint16Array = d3Array.shuffle(new Uint16Array(numbersArray));
let resultInt32: Int32Array = d3Array.shuffle(new Int32Array(numbersArray));
let resultUint32: Uint32Array = d3Array.shuffle(new Uint32Array(numbersArray));
let resultFloat32: Float32Array = d3Array.shuffle(new Float32Array(numbersArray));
let resultFloat64: Float64Array = d3Array.shuffle(new Float64Array(numbersArray));
// ticks() ---------------------------------------------------------------------
@@ -399,32 +596,13 @@ numDiff = d3Array.tickStep(1, 10, 5);
// transpose() -----------------------------------------------------------------
testArrays = d3Array.transpose([
[
new MixedObject(10, new Date(2016, 6, 1)),
new MixedObject(50, new Date(2017, 4, 15))
],
[
new MixedObject(40, new Date(2016, 3, 1)),
new MixedObject(50, new Date(2016, 9, 30)),
]
]);
testArrays = d3Array.transpose([testArray1, testArray2]);
testArrays = d3Array.transpose([readonlyTestArray1, readonlyTestArray2] as ReadonlyArray<ReadonlyArray<MixedObject>>);
// zip() -----------------------------------------------------------------------
testArrays = d3Array.zip(
[
new MixedObject(10, new Date(2016, 6, 1)),
new MixedObject(20, new Date(2016, 7, 30)),
new MixedObject(30, new Date(2015, 3, 15)),
new MixedObject(40, new Date(2014, 3, 15)),
new MixedObject(50, new Date(2017, 4, 15))
],
[
new MixedObject(40, new Date(2016, 3, 1)),
new MixedObject(50, new Date(2016, 9, 30)),
]
);
testArrays = d3Array.zip(testArray1, testArray2);
testArrays = d3Array.zip(readonlyTestArray1, readonlyTestArray2);
// -----------------------------------------------------------------------------
// Test Histogram
@@ -447,7 +625,7 @@ testHistogram = d3Array.histogram<MixedObject, Date>();
testHistogram = testHistogram.value((d, i, data) => {
const datum: MixedObject = d; // d is of type MixedObject
const index: number = i; // i is number
const array: MixedObject[] = data; // data is of type MixedObject[]
const array: ArrayLike<MixedObject> = data; // data is of type MixedObject[]
return datum.date;
});
@@ -496,8 +674,10 @@ testHistogram = testHistogram.thresholds(tScale.ticks(timeYear));
// Use histogram generator =====================================================
numbersArray = [-1, 0, 1, 1, 3, 20, 234];
let defaultBins: Array<d3Array.Bin<number, number>>;
defaultBins = defaultHistogram([-1, 0, 1, 1, 3, 20, 234]);
defaultBins = defaultHistogram(numbersArray);
let defaultBin: d3Array.Bin<number, number>;
defaultBin = defaultBins[0];
@@ -509,6 +689,7 @@ num = defaultBin.x1; // bin upper bound is number
let testBins: Array<d3Array.Bin<MixedObject, Date>>;
testBins = testHistogram(mixedObjectArray);
testBins = testHistogram(readonlyMixedObjectArray);
let testBin: d3Array.Bin<MixedObject, Date>;
testBin = testBins[0];
@@ -520,8 +701,18 @@ date = testBin.x1; // bin upper bound is Date
// Histogram Tresholds =========================================================
num = d3Array.thresholdFreedmanDiaconis([-1, 0, 1, 1, 3, 20, 234], -1, 234);
numbersArray = [-1, 0, 1, 1, 3, 20, 234];
typedArray = new Uint8Array(numbersArray);
readonlyNumbersArray = numbersArray as ReadonlyArray<number>;
num = d3Array.thresholdScott([-1, 0, 1, 1, 3, 20, 234], -1, 234);
num = d3Array.thresholdFreedmanDiaconis(numbersArray, -1, 234);
num = d3Array.thresholdFreedmanDiaconis(typedArray, -1, 234);
num = d3Array.thresholdFreedmanDiaconis(readonlyNumbersArray, -1, 234);
num = d3Array.thresholdSturges([-1, 0, 1, 1, 3, 20, 234]);
num = d3Array.thresholdScott(numbersArray, -1, 234);
num = d3Array.thresholdScott(typedArray, -1, 234);
num = d3Array.thresholdScott(readonlyNumbersArray, -1, 234);
num = d3Array.thresholdSturges(numbersArray);
num = d3Array.thresholdSturges(typedArray);
num = d3Array.thresholdSturges(readonlyNumbersArray);

View File

@@ -28,133 +28,133 @@ export interface Numeric {
/**
* Return the maximum value in the array of strings using natural order.
*/
export function max(array: string[]): string | undefined;
export function max(array: ArrayLike<string>): string | undefined;
/**
* Return the maximum value in the array of numbers using natural order.
*/
export function max<T extends Numeric>(array: T[]): T | undefined;
export function max<T extends Numeric>(array: ArrayLike<T>): T | undefined;
/**
* Return the maximum value in the array using natural order and a projection function to map values to strings.
*/
export function max<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => string | undefined | null): string | undefined;
export function max<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => string | undefined | null): string | undefined;
/**
* Return the maximum value in the array using natural order and a projection function to map values to easily-sorted values.
*/
export function max<T, U extends Numeric>(array: T[], accessor: (datum: T, index: number, array: T[]) => U | undefined | null): U | undefined;
export function max<T, U extends Numeric>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => U | undefined | null): U | undefined;
/**
* Return the minimum value in the array using natural order.
*/
export function min(array: string[]): string | undefined;
export function min(array: ArrayLike<string>): string | undefined;
/**
* Return the minimum value in the array using natural order.
*/
export function min<T extends Numeric>(array: T[]): T | undefined;
export function min<T extends Numeric>(array: ArrayLike<T>): T | undefined;
/**
* Return the minimum value in the array using natural order.
*/
export function min<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => string | undefined | null): string | undefined;
export function min<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => string | undefined | null): string | undefined;
/**
* Return the minimum value in the array using natural order.
*/
export function min<T, U extends Numeric>(array: T[], accessor: (datum: T, index: number, array: T[]) => U | undefined | null): U | undefined;
export function min<T, U extends Numeric>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => U | undefined | null): U | undefined;
/**
* Return the min and max simultaneously.
*/
export function extent(array: string[]): [string, string] | [undefined, undefined];
export function extent(array: ArrayLike<string>): [string, string] | [undefined, undefined];
/**
* Return the min and max simultaneously.
*/
export function extent<T extends Numeric>(array: T[]): [T, T] | [undefined, undefined];
export function extent<T extends Numeric>(array: ArrayLike<T>): [T, T] | [undefined, undefined];
/**
* Return the min and max simultaneously.
*/
export function extent<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => string | undefined | null): [string, string] | [undefined, undefined];
export function extent<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => string | undefined | null): [string, string] | [undefined, undefined];
/**
* Return the min and max simultaneously.
*/
export function extent<T, U extends Numeric>(array: T[], accessor: (datum: T, index: number, array: T[]) => U | undefined | null): [U, U] | [undefined, undefined];
export function extent<T, U extends Numeric>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => U | undefined | null): [U, U] | [undefined, undefined];
/**
* Return the mean of an array of numbers
*/
export function mean<T extends Numeric>(array: Array<T | undefined | null>): number | undefined;
export function mean<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => number | undefined | null): number | undefined;
export function mean<T extends Numeric>(array: ArrayLike<T | undefined | null>): number | undefined;
export function mean<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => number | undefined | null): number | undefined;
/**
* Return the median of an array of numbers
*/
export function median<T extends Numeric>(array: Array<T | undefined | null>): number | undefined;
export function median<T>(array: T[], accessor: (element: T, i: number, array: T[]) => number | undefined | null): number | undefined;
export function median<T extends Numeric>(array: ArrayLike<T | undefined | null>): number | undefined;
export function median<T>(array: ArrayLike<T>, accessor: (element: T, i: number, array: ArrayLike<T>) => number | undefined | null): number | undefined;
/**
* Returns the p-quantile of an array of numbers
*/
export function quantile<T extends Numeric>(array: Array<T | undefined | null>, p: number): number | undefined;
export function quantile<T>(array: T[], p: number, accessor: (element: T, i: number, array: T[]) => number | undefined | null): number | undefined;
export function quantile<T extends Numeric>(array: ArrayLike<T | undefined | null>, p: number): number | undefined;
export function quantile<T>(array: ArrayLike<T>, p: number, accessor: (element: T, i: number, array: ArrayLike<T>) => number | undefined | null): number | undefined;
/**
* Compute the sum of an array of numbers.
*/
export function sum<T extends Numeric>(array: Array<T | undefined | null>): number;
export function sum<T extends Numeric>(array: ArrayLike<T | undefined | null>): number;
/**
* Compute the sum of an array, using the given accessor to convert values to numbers.
*/
export function sum<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => number | undefined | null): number;
export function sum<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => number | undefined | null): number;
/**
* Compute the standard deviation, defined as the square root of the bias-corrected variance, of the given array of numbers.
*/
export function deviation<T extends Numeric>(array: Array<T | undefined | null>): number | undefined;
export function deviation<T extends Numeric>(array: ArrayLike<T | undefined | null>): number | undefined;
/**
* Compute the standard deviation, defined as the square root of the bias-corrected variance, of the given array,
* using the given accessor to convert values to numbers.
*/
export function deviation<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => number | undefined | null): number | undefined;
export function deviation<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => number | undefined | null): number | undefined;
/**
* Compute an unbiased estimator of the population variance of the given array of numbers.
*/
export function variance<T extends Numeric>(array: Array<T | undefined | null>): number | undefined;
export function variance<T extends Numeric>(array: ArrayLike<T | undefined | null>): number | undefined;
/**
* Compute an unbiased estimator of the population variance of the given array,
* using the given accessor to convert values to numbers.
*/
export function variance<T>(array: T[], accessor: (datum: T, index: number, array: T[]) => number | undefined | null): number | undefined;
export function variance<T>(array: ArrayLike<T>, accessor: (datum: T, index: number, array: ArrayLike<T>) => number | undefined | null): number | undefined;
// --------------------------------------------------------------------------------------
// Searching Arrays
// --------------------------------------------------------------------------------------
export function scan(array: number[], comparator?: (a: number, b: number) => number): number | undefined;
export function scan<T>(array: T[], comparator: (a: T, b: T) => number): number | undefined;
export function scan(array: ArrayLike<number>, comparator?: (a: number, b: number) => number): number | undefined;
export function scan<T>(array: ArrayLike<T>, comparator: (a: T, b: T) => number): number | undefined;
export function bisectLeft(array: number[], x: number, lo?: number, hi?: number): number;
export function bisectLeft(array: string[], x: string, lo?: number, hi?: number): number;
export function bisectLeft(array: Date[], x: Date, lo?: number, hi?: number): number;
export function bisectLeft(array: ArrayLike<number>, x: number, lo?: number, hi?: number): number;
export function bisectLeft(array: ArrayLike<string>, x: string, lo?: number, hi?: number): number;
export function bisectLeft(array: ArrayLike<Date>, x: Date, lo?: number, hi?: number): number;
export function bisectRight(array: number[], x: number, lo?: number, hi?: number): number;
export function bisectRight(array: string[], x: string, lo?: number, hi?: number): number;
export function bisectRight(array: Date[], x: Date, lo?: number, hi?: number): number;
export function bisectRight(array: ArrayLike<number>, x: number, lo?: number, hi?: number): number;
export function bisectRight(array: ArrayLike<string>, x: string, lo?: number, hi?: number): number;
export function bisectRight(array: ArrayLike<Date>, x: Date, lo?: number, hi?: number): number;
export const bisect: typeof bisectRight;
export interface Bisector<T, U> {
left(array: T[], x: U, lo?: number, hi?: number): number;
right(array: T[], x: U, lo?: number, hi?: number): number;
left(array: ArrayLike<T>, x: U, lo?: number, hi?: number): number;
right(array: ArrayLike<T>, x: U, lo?: number, hi?: number): number;
}
export function bisector<T, U>(comparator: (a: T, b: U) => number): Bisector<T, U>;
@@ -184,7 +184,7 @@ export function descending(a: Primitive | undefined, b: Primitive | undefined):
* @param a First input array.
* @param b Second input array.
*/
export function cross<S, T>(a: S[], b: T[]): Array<[S, T]>;
export function cross<S, T>(a: ArrayLike<S>, b: ArrayLike<T>): Array<[S, T]>;
/**
* Returns the Cartesian product of the two arrays a and b.
@@ -195,12 +195,12 @@ export function cross<S, T>(a: S[], b: T[]): Array<[S, T]>;
* @param b Second input array.
* @param reducer A reducer function taking as input an element from "a" and "b" and returning a reduced value.
*/
export function cross<S, T, U>(a: S[], b: T[], reducer: (a: S, b: T) => U): U[];
export function cross<S, T, U>(a: ArrayLike<S>, b: ArrayLike<T>, reducer: (a: S, b: T) => U): U[];
/**
* Merges the specified arrays into a single array.
*/
export function merge<T>(arrays: T[][]): T[];
export function merge<T>(arrays: ArrayLike<ArrayLike<T>>): T[];
/**
* For each adjacent pair of elements in the specified array, returns a new array of tuples of elements i and i - 1.
@@ -208,7 +208,7 @@ export function merge<T>(arrays: T[][]): T[];
*
* @param array Array of input elements
*/
export function pairs<T>(array: T[]): Array<[T, T]>;
export function pairs<T>(array: ArrayLike<T>): Array<[T, T]>;
/**
* For each adjacent pair of elements in the specified array, in order, invokes the specified reducer function passing the element i and element i - 1.
* Returns the resulting array of pair-wise reduced elements.
@@ -217,17 +217,17 @@ export function pairs<T>(array: T[]): Array<[T, T]>;
* @param array Array of input elements
* @param reducer A reducer function taking as input to adjecent elements of the input array and returning a reduced value.
*/
export function pairs<T, U>(array: T[], reducer: (a: T, b: T) => U): U[];
export function pairs<T, U>(array: ArrayLike<T>, reducer: (a: T, b: T) => U): U[];
/**
* Given the specified array, return an array corresponding to the list of indices in 'keys'.
*/
export function permute<T>(array: { [key: number]: T }, keys: number[]): T[];
export function permute<T>(array: { [key: number]: T }, keys: ArrayLike<number>): T[];
/**
* Given the specified object, return an array corresponding to the list of property names in 'keys'.
*/
export function permute<T>(object: { [key: string]: T }, keys: string[]): T[];
export function permute<T>(object: { [key: string]: T }, keys: ArrayLike<string>): T[];
/**
* Generates a 0-based numeric sequence. The output range does not include 'stop'.
@@ -243,6 +243,15 @@ export function range(start: number, stop: number, step?: number): number[];
* Randomizes the order of the specified array using the FisherYates shuffle.
*/
export function shuffle<T>(array: T[], lo?: number, hi?: number): T[];
export function shuffle(array: Int8Array, lo?: number, hi?: number): Int8Array;
export function shuffle(array: Uint8Array, lo?: number, hi?: number): Uint8Array;
export function shuffle(array: Uint8ClampedArray, lo?: number, hi?: number): Uint8ClampedArray;
export function shuffle(array: Int16Array, lo?: number, hi?: number): Int16Array;
export function shuffle(array: Uint16Array, lo?: number, hi?: number): Uint16Array;
export function shuffle(array: Int32Array, lo?: number, hi?: number): Int32Array;
export function shuffle(array: Uint32Array, lo?: number, hi?: number): Uint32Array;
export function shuffle(array: Float32Array, lo?: number, hi?: number): Float32Array;
export function shuffle(array: Float64Array, lo?: number, hi?: number): Float64Array;
/**
* Generate an array of approximately count + 1 uniformly-spaced, nicely-rounded values between start and stop (inclusive).
@@ -289,14 +298,14 @@ export function tickStep(start: number, stop: number, count: number): number;
/**
* Transpose a matrix provided in Array of Arrays format.
*/
export function transpose<T>(matrix: T[][]): T[][];
export function transpose<T>(matrix: ArrayLike<ArrayLike<T>>): T[][];
/**
* Returns an array of arrays, where the ith array contains the ith element from each of the argument arrays.
* The returned array is truncated in length to the shortest array in arrays. If arrays contains only a single array, the returned array
* contains one-element arrays. With no arguments, the returned array is empty.
*/
export function zip<T>(...arrays: T[][]): T[][];
export function zip<T>(...arrays: Array<ArrayLike<T>>): T[][];
// --------------------------------------------------------------------------------------
// Histogram
@@ -310,20 +319,20 @@ export interface Bin<Datum, Value extends number | Date> extends Array<Datum> {
/**
* Type definition for threshold generator which returns the count of recommended thresholds
*/
export type ThresholdCountGenerator = (values: number[], min?: number, max?: number) => number;
export type ThresholdCountGenerator = (values: ArrayLike<number>, min?: number, max?: number) => number;
/**
* Type definition for threshold generator which returns an array of recommended thresholds
*/
export type ThresholdArrayGenerator<Value extends number | Date> = (values: Value[], min?: Value, max?: Value) => Value[];
export type ThresholdArrayGenerator<Value extends number | Date> = (values: ArrayLike<Value>, min?: Value, max?: Value) => Value[];
export interface HistogramGenerator<Datum, Value extends number | Date> {
(data: Datum[]): Array<Bin<Datum, Value>>;
value(): (d: Datum, i: number, data: Datum[]) => Value;
value(valueAccessor: (d: Datum, i: number, data: Datum[]) => Value): this;
domain(): (values: Value[]) => [Value, Value];
(data: ArrayLike<Datum>): Array<Bin<Datum, Value>>;
value(): (d: Datum, i: number, data: ArrayLike<Datum>) => Value;
value(valueAccessor: (d: Datum, i: number, data: ArrayLike<Datum>) => Value): this;
domain(): (values: ArrayLike<Value>) => [Value, Value];
domain(domain: [Value, Value]): this;
domain(domainAccessor: (values: Value[]) => [Value, Value]): this;
domain(domainAccessor: (values: ArrayLike<Value>) => [Value, Value]): this;
thresholds(): ThresholdCountGenerator | ThresholdArrayGenerator<Value>;
/**
* Divide the domain uniformly into approximately count bins. IMPORTANT: This threshold
@@ -357,7 +366,7 @@ export interface HistogramGenerator<Datum, Value extends number | Date> {
* @param thresholds Array of threshold values used for binning. The elements must
* be of the same type as the materialized values of the histogram.
*/
thresholds(thresholds: Value[]): this;
thresholds(thresholds: ArrayLike<Value>): this;
/**
* Set a threshold accessor function, which returns the array of values to be used as
* thresholds in determining the bins.
@@ -379,8 +388,8 @@ export function histogram<Datum, Value extends number | Date>(): HistogramGenera
// Histogram Thresholds
// --------------------------------------------------------------------------------------
export function thresholdFreedmanDiaconis(values: number[], min: number, max: number): number; // of type ThresholdCountGenerator
export function thresholdFreedmanDiaconis(values: ArrayLike<number>, min: number, max: number): number; // of type ThresholdCountGenerator
export function thresholdScott(values: number[], min: number, max: number): number; // of type ThresholdCountGenerator
export function thresholdScott(values: ArrayLike<number>, min: number, max: number): number; // of type ThresholdCountGenerator
export function thresholdSturges(values: number[]): number; // of type ThresholdCountGenerator
export function thresholdSturges(values: ArrayLike<number>): number; // of type ThresholdCountGenerator