Skip to content

Commit f6de650

Browse files
committed
maybeTypedArrayify
1 parent b3f9815 commit f6de650

File tree

3 files changed

+28
-31
lines changed

3 files changed

+28
-31
lines changed

src/marks/contour.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import {blur2, contours, geoPath, map, max, min, nice, range, ticks, thresholdSturges} from "d3";
1+
import {blur2, contours, geoPath, max, min, nice, range, ticks, thresholdSturges} from "d3";
22
import {Channels} from "../channel.js";
33
import {create} from "../context.js";
4-
import {labelof, identity, arrayify} from "../options.js";
4+
import {labelof, identity, arrayify, map} from "../options.js";
55
import {Position} from "../projection.js";
66
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, styles} from "../style.js";
77
import {initializer} from "../transforms/basic.js";
@@ -156,7 +156,9 @@ function contourGeometry({thresholds, interval, ...options}) {
156156
const {contour} = contours().size([w, h]).smooth(this.smooth);
157157
const contourData = [];
158158
const contourFacets = [];
159-
for (const V of VV) contourFacets.push(range(contourData.length, contourData.push(...T.map((t) => contour(V, t)))));
159+
for (const V of VV) {
160+
contourFacets.push(range(contourData.length, contourData.push(...map(T, (t) => contour(V, t)))));
161+
}
160162

161163
// Rescale the contour multipolygon from grid to screen coordinates.
162164
for (const {coordinates} of contourData) {
@@ -188,7 +190,7 @@ function contourGeometry({thresholds, interval, ...options}) {
188190
function maybeTicks(thresholds, V, min, max) {
189191
if (typeof thresholds?.range === "function") return thresholds.range(thresholds.floor(min), max);
190192
if (typeof thresholds === "function") thresholds = thresholds(V, min, max);
191-
if (typeof thresholds !== "number") return arrayify(thresholds, Array);
193+
if (typeof thresholds !== "number") return arrayify(thresholds);
192194
const tz = ticks(...nice(min, max, thresholds), thresholds);
193195
while (tz[tz.length - 1] >= max) tz.pop();
194196
while (tz[1] < min) tz.shift();

src/marks/density.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {contourDensity, create, geoPath} from "d3";
22
import {Mark} from "../mark.js";
3-
import {coerceNumbers, isTypedArray, maybeTuple, maybeZ} from "../options.js";
3+
import {coerceNumbers, maybeTuple, maybeZ, TypedArray} from "../options.js";
44
import {Position} from "../projection.js";
55
import {
66
applyFrameAnchor,
@@ -128,7 +128,7 @@ function densityInitializer(options, fillDensity, strokeDensity) {
128128
// If explicit thresholds were not specified, find the maximum density of
129129
// all grids and use this to compute thresholds.
130130
let T = thresholds;
131-
if (!isTypedArray(T)) {
131+
if (!(T instanceof TypedArray)) {
132132
let maxValue = 0;
133133
for (const facetContours of facetsContours) {
134134
for (const [, contour] of facetContours) {

src/options.js

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {color, descending, range as rangei, quantile} from "d3";
33
import {maybeTimeInterval, maybeUtcInterval} from "./time.js";
44

55
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
6-
const TypedArray = Object.getPrototypeOf(Uint8Array);
6+
export const TypedArray = Object.getPrototypeOf(Uint8Array);
77
const objectToString = Object.prototype.toString;
88

99
/** @jsdoc valueof */
@@ -16,14 +16,26 @@ export function valueof(data, value, type) {
1616
: valueType === "number" || value instanceof Date || valueType === "boolean"
1717
? map(data, constant(value), type)
1818
: value && typeof value.transform === "function"
19-
? arrayify(value.transform(data), type)
20-
: arrayify(value, type); // preserve undefined type
19+
? maybedTypedArrayify(value.transform(data), type)
20+
: maybedTypedArrayify(value, type);
2121
}
2222

2323
// When valueof is asked to produce a typed array (i.e., numbers) we implicitly
2424
// apply null-safe type coercion.
2525
function maybeTypedMap(data, f, type) {
26-
return map(data, isTypedArray(type?.prototype) ? floater(f) : f, type);
26+
return map(data, type?.prototype instanceof TypedArray ? floater(f) : f, type);
27+
}
28+
29+
// When valueof is asked to produce a typed array (i.e., numbers) we implicitly
30+
// apply null-safe type coercion.
31+
function maybedTypedArrayify(data, type) {
32+
return type === undefined
33+
? arrayify(data) // preserve undefined type
34+
: data instanceof type
35+
? data
36+
: type.prototype instanceof TypedArray && !(data instanceof TypedArray)
37+
? type.from(data, coerceNumber)
38+
: type.from(data);
2739
}
2840

2941
function floater(f) {
@@ -54,7 +66,7 @@ export function percentile(reduce) {
5466

5567
// If the values are specified as a typed array, no coercion is required.
5668
export function coerceNumbers(values) {
57-
return isTypedArray(values) ? values : map(values, coerceNumber, Float64Array);
69+
return values instanceof TypedArray ? values : map(values, coerceNumber, Float64Array);
5870
}
5971

6072
// Unlike Mark’s number, here we want to convert null and undefined to NaN since
@@ -114,22 +126,9 @@ export function keyword(input, name, allowed) {
114126
return i;
115127
}
116128

117-
// Promotes the specified data to an array or typed array as needed. If an array
118-
// type is provided (e.g., Array), then the returned array will strictly be of
119-
// the specified type; otherwise, any array or typed array may be returned. If
120-
// the specified data is null or undefined, returns the value as-is. When
121-
// converting a non-typed array to a typed array, null-safe number coercion is
122-
// implicitly applied.
123-
export function arrayify(data, type) {
124-
return data == null
125-
? data
126-
: type === undefined
127-
? data instanceof Array || data instanceof TypedArray
128-
? data
129-
: Array.from(data)
130-
: data instanceof type
131-
? data
132-
: type.from(data, isTypedArray(type.prototype) && !isTypedArray(data) ? coerceNumber : undefined);
129+
// Promotes the specified data to an array as needed.
130+
export function arrayify(data) {
131+
return data == null || data instanceof Array || data instanceof TypedArray ? data : Array.from(data);
133132
}
134133

135134
// An optimization of type.from(values, f): if the given values are already an
@@ -144,10 +143,6 @@ export function slice(values, type = Array) {
144143
return values instanceof type ? values.slice() : type.from(values);
145144
}
146145

147-
export function isTypedArray(values) {
148-
return values instanceof TypedArray;
149-
}
150-
151146
// Disambiguates an options object (e.g., {y: "x2"}) from a primitive value.
152147
export function isObject(option) {
153148
return option?.toString === objectToString;

0 commit comments

Comments
 (0)