Skip to content

Commit 8e16072

Browse files
committed
add BigInt support to the normalize transform
closes #2154
1 parent 0032c11 commit 8e16072

File tree

6 files changed

+240
-3
lines changed

6 files changed

+240
-3
lines changed

src/options.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function maybeTypedMap(data, f, type) {
5454
return map(data, isNumberType(type) ? (d, i) => coerceNumber(f(d, i)) : f, type); // allow conversion from BigInt
5555
}
5656

57-
function maybeTypedArrayify(data, type) {
57+
export function maybeTypedArrayify(data, type) {
5858
return type === undefined
5959
? arrayify(data) // preserve undefined type
6060
: isArrowVector(data)

src/transforms/normalize.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {extent, deviation, max, mean, median, min, sum} from "d3";
22
import {defined} from "../defined.js";
3-
import {percentile, taker} from "../options.js";
3+
import {maybeTypedArrayify, percentile, taker} from "../options.js";
44
import {mapX, mapY} from "./map.js";
55

66
export function normalizeX(basis, options) {
@@ -43,7 +43,8 @@ export function normalize(basis) {
4343
function normalizeBasis(basis) {
4444
return {
4545
mapIndex(I, S, T) {
46-
const b = +basis(I, S);
46+
S = maybeTypedArrayify(S, Float64Array);
47+
const b = basis(I, S);
4748
for (const i of I) {
4849
T[i] = S[i] === null ? NaN : S[i] / b;
4950
}

test/output/bigintNormalize.svg

+117
Loading

test/output/bigintNormalizeMean.svg

+86
Loading

test/plots/bigint.ts

+25
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,28 @@ export async function bigintOrdinal() {
2525
export async function bigintStack() {
2626
return Plot.barY(integers, {x: (d, i) => i % 5, y: "big1"}).plot();
2727
}
28+
29+
async function olympiansByWeight() {
30+
const olympians = await d3.csv<any>("data/athletes.csv", d3.autoType);
31+
return d3
32+
.bin()(olympians.map((d) => d.height))
33+
.map((bin) => ({weightclass: bin.x0, count: BigInt(bin.length)}));
34+
}
35+
36+
export async function bigintNormalize() {
37+
return Plot.rectY(
38+
d3.sort(await olympiansByWeight(), (d) => -d.count),
39+
Plot.normalizeY({x: "weightclass", y: "count"})
40+
).plot();
41+
}
42+
43+
export async function bigintNormalizeMean() {
44+
return Plot.plot({
45+
x: {interval: 0.05},
46+
y: {label: "relative to mean"},
47+
marks: [
48+
Plot.barY(await olympiansByWeight(), Plot.normalizeY("mean", {x: "weightclass", y: "count"})),
49+
Plot.ruleY([1], {stroke: "red"})
50+
]
51+
});
52+
}

test/transforms/normalize-test.js

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ it("Plot.normalize first", () => {
55
testNormalize([1, 2, 4, 5], "first", [1, 2, 4, 5]);
66
});
77

8+
it("Plot.normalize first BigInt", () => {
9+
testNormalize([1n, 2n, 4n, 5n], "first", [1, 2, 4, 5]);
10+
});
11+
812
it("Plot.normalize last", () => {
913
testNormalize([1, 2, 4, 5], "last", [0.2, 0.4, 0.8, 1]);
1014
});
@@ -17,6 +21,10 @@ it("Plot.normalize median", () => {
1721
testNormalize([1, 2, 6, 6], "median", [0.25, 0.5, 1.5, 1.5]);
1822
});
1923

24+
it("Plot.normalize median BigInt", () => {
25+
testNormalize([1n, 2n, 6n, 6n], "median", [0.25, 0.5, 1.5, 1.5]);
26+
});
27+
2028
it("Plot.normalize min", () => {
2129
testNormalize([10, 6, 2], "min", [5, 3, 1]);
2230
});

0 commit comments

Comments
 (0)