diff --git a/src/options.js b/src/options.js index ac9caca472..e69b7bf4f9 100644 --- a/src/options.js +++ b/src/options.js @@ -69,6 +69,8 @@ function maybeTypedArrowify(vector, type) { ? vector : (type === undefined || type === Array) && isArrowDateType(vector.type) ? coerceDates(vector.toArray()) + : (type === undefined || type === Array) && isArrowBigIntType(vector.type) + ? (type ?? Float64Array).from(vector.toArray(), Number) : maybeTypedArrayify(vector.toArray(), type); } @@ -625,6 +627,7 @@ function isArrowVector(value) { // Apache Arrow now represents dates as numbers. We currently only support // implicit coercion to JavaScript Date objects when the numbers represent // milliseconds since Unix epoch. +// https://github.com/apache/arrow/blob/cd50c324882ab1419d1728e9adad20d47b185508/js/src/enum.ts#L52-L72 function isArrowDateType(type) { return ( type && @@ -633,3 +636,12 @@ function isArrowDateType(type) { type.unit === 1 // millisecond ); } + +// https://github.com/apache/arrow/blob/cd50c324882ab1419d1728e9adad20d47b185508/js/src/enum.ts#L52-L72 +function isArrowBigIntType(type) { + return ( + type && + type.typeId === 2 && // int + type.bitWidth >= 64 + ); +} diff --git a/test/output/bigintNormalize.svg b/test/output/bigintNormalize.svg new file mode 100644 index 0000000000..2d7b5e15b5 --- /dev/null +++ b/test/output/bigintNormalize.svg @@ -0,0 +1,173 @@ + + + + + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 + 2.2 + + + ↑ height + + + + + 0.0 + 0.5 + 1.0 + 1.5 + 2.0 + 2.5 + 3.0 + 3.5 + 4.0 + 4.5 + 5.0 + + + frequency (%) → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/bigint.ts b/test/plots/bigint.ts index 0d526f75ca..b50d02ed2f 100644 --- a/test/plots/bigint.ts +++ b/test/plots/bigint.ts @@ -1,5 +1,6 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +import * as Arrow from "apache-arrow"; const integers = d3.range(40).map((int) => ({ big1: BigInt(int), @@ -25,3 +26,21 @@ export async function bigintOrdinal() { export async function bigintStack() { return Plot.barY(integers, {x: (d, i) => i % 5, y: "big1"}).plot(); } + +export async function bigintNormalize() { + const heights = await d3.csv("data/athletes.csv").then((data) => data.map((d) => d.height)); + const table = Arrow.tableFromJSON( + d3.groups(heights, (d) => (d ? +d : NaN)).map(([height, {length}]) => ({height, frequency: BigInt(length)})) + ); + return Plot.plot({ + height: 500, + x: {percent: true, grid: true}, + marks: [ + Plot.ruleX([0]), + Plot.ruleY( + table, + Plot.normalizeX("sum", {strokeWidth: 2, y: "height", x: "frequency", tip: {format: {y: ".2f"}}}) + ) + ] + }); +}