Skip to content

Conversation

@Fil
Copy link
Contributor

@Fil Fil commented Mar 2, 2023

Addressing this comment.

One tiny additional thing we could do is make Float64Array the default, since we only ever use this specific type when calling typedMap. But, I don't know, it feels a bit noisy.

@Fil Fil changed the title more support for bigint split map and typedMap Mar 2, 2023
@Fil Fil requested a review from mbostock March 2, 2023 12:00
Copy link
Member

@mbostock mbostock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think based on our usage we should remove the type argument to typedMap entirely and always use float64. We could call it floatMap or numberMap if you prefer.

@Fil
Copy link
Contributor Author

Fil commented Mar 2, 2023

Does this mean we retire the type argument from the public API of Plot.valueof?

Internally we use it once, in

const Y = valueof(data, y, Float64Array);

and we miss an opportunity to use it in

if (R) R = coerceNumbers(valueof(R.value, scales[R.scale] || identity));

@mbostock
Copy link
Member

mbostock commented Mar 2, 2023

No, I don’t think we should retire it if it’s part of the public API.

@mbostock
Copy link
Member

mbostock commented Mar 2, 2023

I want to think about this one a little more and push a few commits. In a case like this

floatMap(X2, (x2, i) => Math.abs(x2 - X1[i]))

we are doing too much work because we are coercing the result of the accessor even though we already know that it can only return a number.

@mbostock
Copy link
Member

mbostock commented Mar 2, 2023

In 0e74a1e I reverted the addition of floatMap, and instead isolated the implicit number coercion to valueof. This change avoids unnecessary coercion when we call map and we know that the provided accessor is already number-safe.

(Well, I also changed arrayify, but I actually think that’s a bit of mistake since this implicit coercion is only needed when arrayify is used to create a typed array, and that only happens via valueof. So I’d like to follow this up with another slight change.)

@Fil Fil marked this pull request as ready for review March 2, 2023 21:03
import {Channels} from "../channel.js";
import {create} from "../context.js";
import {labelof, identity, arrayify} from "../options.js";
import {labelof, identity, arrayify, map} from "../options.js";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this fixes the calls here: 😳

plot/src/marks/contour.js

Lines 125 to 126 in 1186b5b

const IX = map(X, (x) => (x - x1) * kx, Float64Array);
const IY = map(Y, (y) => (y - y1) * ky, Float64Array);

if (typeof thresholds?.range === "function") return thresholds.range(thresholds.floor(min), max);
if (typeof thresholds === "function") thresholds = thresholds(V, min, max);
if (typeof thresholds !== "number") return arrayify(thresholds, Array);
if (typeof thresholds !== "number") return arrayify(thresholds);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I removed the type argument to arrayify, I adopted map(T, …) above instead of T.map(…).

// all grids and use this to compute thresholds.
let T = thresholds;
if (!isTypedArray(T)) {
if (!(T instanceof TypedArray)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Taking your advice on using instanceof directly… though I think the performance will be the same and maybe it’s slightly more readable to have the helper. I’m happy either way.)

import {curveAuto, PathCurve} from "../curve.js";
import {Mark} from "../mark.js";
import {coerceNumbers} from "../scales.js";
import {coerceNumbers} from "../options.js";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the coercion routines up to options.js since coerceNumbers is now needed for valueof. I wanted to keep coerceDates together, but I left coerceSymbols where it was since that has more dependencies…

? arrayify(data) // preserve undefined type
: data instanceof type
? data
: type.prototype instanceof TypedArray && !(data instanceof TypedArray)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus: if we already have a typed array, we can skip the coercion (even if we have to change the array type)!

Copy link
Member

@mbostock mbostock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. What do you think @Fil?

@Fil
Copy link
Contributor Author

Fil commented Mar 2, 2023

Overall it's a good cleanup. I'm still a bit nervous with all the changes, but hopefully the tests have good coverage.

@mbostock mbostock merged commit 1186b5b into fil/bigint-map Mar 2, 2023
@mbostock mbostock deleted the fil/typedmap branch March 2, 2023 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants