From 4faebbc00e73c317823da89a94fac5c7eef0af4e Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 28 Jul 2024 13:47:00 -0400 Subject: [PATCH] a few more dataify --- src/mark.js | 6 +----- src/options.js | 7 ++++++- src/plot.js | 8 ++++---- src/transforms/basic.js | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mark.js b/src/mark.js index a5c0788b9e..462af1577e 100644 --- a/src/mark.js +++ b/src/mark.js @@ -2,7 +2,7 @@ import {channelDomain, createChannels, valueObject} from "./channel.js"; import {defined} from "./defined.js"; import {maybeFacetAnchor} from "./facet.js"; import {maybeClip, maybeNamed, maybeValue} from "./options.js"; -import {arrayify, isArrowTable, isDomainSort, isObject, isOptions, keyword, range, singleton} from "./options.js"; +import {dataify, isDomainSort, isObject, isOptions, keyword, range, singleton} from "./options.js"; import {project} from "./projection.js"; import {styles} from "./style.js"; import {basic, initializer} from "./transforms/basic.js"; @@ -130,10 +130,6 @@ export class Mark { } } -function dataify(data) { - return isArrowTable(data) ? data : arrayify(data); -} - export function marks(...marks) { marks.plot = Mark.prototype.plot; return marks; diff --git a/src/options.js b/src/options.js index 40fa4a8f3b..934a5966cf 100644 --- a/src/options.js +++ b/src/options.js @@ -156,6 +156,11 @@ export function keyword(input, name, allowed) { return i; } +// Like arrayify, but also allows data to be an Apache Arrow Table. +export function dataify(data) { + return isArrowTable(data) ? data : arrayify(data); +} + // Promotes the specified data to an array as needed. export function arrayify(values) { if (values == null || isArray(values)) return values; @@ -261,7 +266,7 @@ export function maybeZ({z, fill, stroke} = {}) { } export function lengthof(data) { - return isArray(data) ? data.length : data.numRows; + return isArray(data) ? data.length : data?.numRows; } // Returns a Uint32Array with elements [0, 1, 2, … data.length - 1]. diff --git a/src/plot.js b/src/plot.js index a091d8d8a8..23dc93f7f7 100644 --- a/src/plot.js +++ b/src/plot.js @@ -10,7 +10,7 @@ import {axisFx, axisFy, axisX, axisY, gridFx, gridFy, gridX, gridY} from "./mark import {frame} from "./marks/frame.js"; import {tip} from "./marks/tip.js"; import {isColor, isIterable, isNone, isScaleOptions} from "./options.js"; -import {arrayify, map, yes, maybeIntervalTransform, subarray} from "./options.js"; +import {dataify, lengthof, map, yes, maybeIntervalTransform, subarray} from "./options.js"; import {createProjection, getGeometryChannels, hasProjection} from "./projection.js"; import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js"; import {innerDimensions, outerDimensions} from "./scales.js"; @@ -459,7 +459,7 @@ function maybeTopFacet(facet, options) { if (facet == null) return; const {x, y} = facet; if (x == null && y == null) return; - const data = arrayify(facet.data); + const data = dataify(facet.data); if (data == null) throw new Error("missing facet data"); const channels = {}; if (x != null) channels.fx = createChannel(data, {value: x, scale: "fx"}); @@ -478,7 +478,7 @@ function maybeMarkFacet(mark, topFacetState, options) { // here with maybeTopFacet that we could reduce. const {fx, fy} = mark; if (fx != null || fy != null) { - const data = arrayify(mark.data ?? fx ?? fy); + const data = dataify(mark.data ?? fx ?? fy); if (data === undefined) throw new Error(`missing facet data in ${mark.ariaLabel}`); if (data === null) return; // ignore channel definitions if no data is provided TODO this right? const channels = {}; @@ -500,7 +500,7 @@ function maybeMarkFacet(mark, topFacetState, options) { if ( data.length > 0 && (groups.size > 1 || (groups.size === 1 && channels.fx && channels.fy && [...groups][0][1].size > 1)) && - arrayify(mark.data)?.length === data.length + lengthof(dataify(mark.data)) === lengthof(data) ) { warn( `Warning: the ${mark.ariaLabel} mark appears to use faceted data, but isn’t faceted. The mark data has the same length as the facet data and the mark facet option is "auto", but the mark data and facet data are distinct. If this mark should be faceted, set the mark facet option to true; otherwise, suppress this warning by setting the mark facet option to false.` diff --git a/src/transforms/basic.js b/src/transforms/basic.js index 573032fa47..cd846d8ef1 100644 --- a/src/transforms/basic.js +++ b/src/transforms/basic.js @@ -1,6 +1,6 @@ import {randomLcg} from "d3"; import {ascendingDefined, descendingDefined} from "../defined.js"; -import {arrayify, isDomainSort, isOptions, maybeValue, valueof} from "../options.js"; +import {dataify, isDomainSort, isOptions, maybeValue, valueof} from "../options.js"; export function basic({filter: f1, sort: s1, reverse: r1, transform: t1, initializer: i1, ...options} = {}, transform) { // If both t1 and t2 are defined, returns a composite transform that first @@ -40,7 +40,7 @@ function composeTransform(t1, t2) { if (t2 == null) return t1 === null ? undefined : t1; return function (data, facets, plotOptions) { ({data, facets} = t1.call(this, data, facets, plotOptions)); - return t2.call(this, arrayify(data), facets, plotOptions); + return t2.call(this, dataify(data), facets, plotOptions); }; }