Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deps): update dependency d3-scale to v3.3.0 #1669

Closed
wants to merge 14 commits into from

Conversation

watson
Copy link
Contributor

@watson watson commented May 10, 2022

I'm performing this upgrade to get a newer version of d3-color which is a direct dependency of d3-scale.

I think this is the only commit to d3-scale v2.0.0 with potentially breaking changes: d3/d3-scale@7819336

I think that we should be ok with that in this package, but hopefully CI will let us know.

To Reviewers

This PR also fixes the issue listed here: #1095
The new d3 scale version project a datapoint to the center of its range if the domain min === domain max see d3/d3-scale#117

@watson watson changed the title fix(deps): updaate dependency d3-scale to v2.2.2 fix(deps): update dependency d3-scale to v2.2.2 May 10, 2022
@watson watson marked this pull request as ready for review May 10, 2022 19:16
Copy link
Collaborator

@nickofthyme nickofthyme left a comment

Choose a reason for hiding this comment

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

LGTM provided the visual regression checks pass. 👍🏼

@watson
Copy link
Contributor Author

watson commented May 11, 2022

I'm not really sure what failed with the @elastic/charts CI check (I think it's just an intermittent failure in CI). But I'm not sure how to make it re-run?

@watson
Copy link
Contributor Author

watson commented May 11, 2022

Turns out after I updated the types, that CI fails due to apparent minor changes in the return values of the d3-scale API. I think this is just that the types were always a little bit off and have not just been corrected. But I'm not 100% sure. I'll investigate

@watson
Copy link
Contributor Author

watson commented May 11, 2022

After looking over the TypeScript failures introduced by this PR, I think it's outside my scope of expertise to fix. Would anyone from the @elastic/datavis team be able to help me fix the CI issues?

@markov00
Copy link
Member

markov00 commented May 11, 2022

hey @watson I will take a look at this.
One question: do we need to stick to that version 2.2.2 or can we also upgrade to something more up to date?
We are stuck with such old versions because newer versions are not ES5 compatible and at that time, Kibana was transpiling to es5 but was not transpiling node modules.
If that was changed, I'm happy to upgrade all the d3 deps

@watson
Copy link
Contributor Author

watson commented May 11, 2022

@markov00 Thanks ❤️

Ideally I'd love to upgrade to the latest version (v4.0.2), but I wasn't sure if that was going to be too big of an upgrade in one PR, so I kept it to v2.x in this one. However, if you feel it's not a problem, it would be great to upgrade all the way to v4.x.

@watson
Copy link
Contributor Author

watson commented May 11, 2022

Regarding Kibana and ES modules: Kibana still cannot process ES module style packages. However, this is only an issue if they are direct dependencies. We already have sevel sub-dependencies that are of the ES module variant. So upgrading d3-scale here to an ES module (which v4.x is), shouldn't be a problem for Kibana as it will going to be a sub-dependency and not a direct dependency.

@markov00 markov00 force-pushed the bump-d3-scale branch 2 times, most recently from 12ad738 to de24f8f Compare May 12, 2022 15:44
@markov00 markov00 marked this pull request as draft May 12, 2022 15:45
BREAKING CHANGE: the new d3-scale version used ES2015 and our target version needs to align to that.
@markov00
Copy link
Member

markov00 commented May 17, 2022

Hi @watson sorry for delaying this PR so much, but I'm getting some trouble fixing the new behavior and types of d3-scale. Scales are probably the most important and delicate part of our library so I need to fix those changes carefully.

Upgrading to something 4.x also creates issues at the Jest level, because v4.x used ESM modules and we don't transpile node_modules in our build chain. I will stick to 3.x version for now

@watson
Copy link
Contributor Author

watson commented May 17, 2022

Thanks for taking this one on @markov00 and no worries about the delays. We'll get there eventually.

Upgrading to something 4.x also creates issues at the Jest level, because v4.x used ESM modules and we don't transpile node_modules in our build chain. I will stick to 3.x version for now

Sounds good 👍 The most important part was upgrading to v2.2.2 or newer.

@markov00 markov00 marked this pull request as ready for review May 30, 2022 13:50
@markov00 markov00 requested a review from nickofthyme May 30, 2022 13:50
@markov00 markov00 requested a review from monfera May 30, 2022 13:50
@watson
Copy link
Contributor Author

watson commented May 31, 2022

Thank you @markov00 for doing all the hard work in making this PR all green!! ❤️❤️❤️

@markov00 markov00 changed the title fix(deps): update dependency d3-scale to v2.2.2 fix(deps): update dependency d3-scale to v3.3.0 May 31, 2022
Copy link
Contributor

@monfera monfera left a comment

Choose a reason for hiding this comment

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

LGTM! Added minor comments, maybe the union type avoidance with this.project is actionable in this PR or, if planned, a follow-up one. If the price is not too high

@@ -47,7 +47,7 @@ function getPointerEvent(
return { chartId, type: PointerEventType.Out };
}
const xValue = xScale.invertWithStep(x, geometriesIndexKeys);
if (!xValue) {
if (!Number.isFinite(xValue.value)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't write the original if (!xValue) { and most likely an intended change: it used to evaluate to true for zeros, but not anymore.

Also, current master has four occurrences of if (!xValue) { and this PR replaces three—should the fourth one change too?

Copy link
Member

@markov00 markov00 May 31, 2022

Choose a reason for hiding this comment

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

I will take a look at the fourth one.
The xValue is actually an object and the invertWithStep always returns that object, so the check was actually wrong and wasn't checking the possible NaN value returned

Copy link
Member

Choose a reason for hiding this comment

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

done here f171590

Copy link
Member

Choose a reason for hiding this comment

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

I wrongly considered that check, I will push a commit to fix it, sorry.
The invertWithStep can be also a string in case of categorical scale...

const allTicks: AxisTick[] =
makeRaster && isSingleValueScale && typeof firstTickValue === 'number'
? [
{
value: firstTickValue,
domainClampedValue: firstTickValue,
label: labelFormatter(firstTickValue),
position: (scale.scale(firstTickValue) || 0) + offset,
domainClampedPosition: (scale.scale(firstTickValue) || 0) + offset,
position: (isFiniteNumber(firstTickValueScaled) ? firstTickValueScaled : 0) + offset,
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that isFiniteNumber is a bit more explicit than checking for NaN. But it's more verbose (function call plus ternary). Are there signs that the code can yield non-finite numbers other than NaN, ie. the Infinities? (and non-numbers of course for potentially non-numeric types).

Code size wise, if we know it's either a finite number (incl. zero) or a NaN or other falsey thing like null ur undefined, then the value || 0 is a compact alternative to a ternary. No big deal either way, though I personally prefer smaller/simpler code

Copy link
Member

Choose a reason for hiding this comment

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

there could be potential Infinity values when, for example, the scale is a log scale and the value passed is 0.
What should we do instead? guard for such numbers inputs at the scale level? apply such finite check before returning from the scale method?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be simplified in cases where a default number is desired with a helper function like...

const getFinite = (v: number, fallback: number) => isFiniteNumber(v) ? v : fallback;

const panelAnchor: Point = {
x: horizontal.scale(horizontalValue) || 0,
y: vertical.scale(verticalValue) || 0,
x: isFiniteNumber(x) ? x : 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

A reflection on my own past refactorings too, which solved some things but didn't address this long-lived aspect: there are so many occurrences of this safety valve, it's not good practice to do these checks at the "leafs". Not for this PR, but let's think about an approach where we take care of NaNs close to where they arise, in a centralized way, so we know that it's finite everywhere downstream. Unfortunately TS is quite weak in reasoning and can't express or propagate knowledge that something will be finite, so it may not be feasible or worth it

Copy link
Member

Choose a reason for hiding this comment

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

Agree, but I don't think we have a lot of chances to get this works in TS.

@@ -70,7 +79,7 @@ export class ScaleContinuous implements Scale<number> {
readonly timeZone: string;
readonly barsPadding: number;
readonly isSingleValueHistogram: boolean;
private readonly project: (d: number) => number;
private readonly project: (d: number) => number | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for admitting undefined? I'm not thrilled with increasing our use of ternaries if it's not hard to avoid

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, inverseProject still doesn't admit undefined, so it became a bit of a misnomer, even if it causes no problem in code execution

Copy link
Member

Choose a reason for hiding this comment

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

done in 096e346

@@ -39,29 +40,30 @@ export const getElementAtCursorPositionSelector = createCustomCachedSelector(

function getElementAtCursorPosition(
orientedProjectedPointerPosition: PointerPosition,
scales: ComputedScales,
{ xScale }: ComputedScales,
Copy link
Collaborator

Choose a reason for hiding this comment

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

❤️ you were in a destructuring mode here!

const allTicks: AxisTick[] =
makeRaster && isSingleValueScale && typeof firstTickValue === 'number'
? [
{
value: firstTickValue,
domainClampedValue: firstTickValue,
label: labelFormatter(firstTickValue),
position: (scale.scale(firstTickValue) || 0) + offset,
domainClampedPosition: (scale.scale(firstTickValue) || 0) + offset,
position: (isFiniteNumber(firstTickValueScaled) ? firstTickValueScaled : 0) + offset,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be simplified in cases where a default number is desired with a helper function like...

const getFinite = (v: number, fallback: number) => isFiniteNumber(v) ? v : fallback;

@nickofthyme
Copy link
Collaborator

@markov00 does this fully address #1095?

@markov00
Copy link
Member

markov00 commented Jun 1, 2022

@nickofthyme yes it solves it in both the X axis and in the Y one

@markov00
Copy link
Member

@watson sorry for the long delay in this, we have changed again the route and we merged the update of the dependency in this PR #1696

@markov00 markov00 closed this Jun 15, 2022
@watson watson deleted the bump-d3-scale branch July 11, 2022 07:48
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.

Better handling of linear scale with a single data point and no domain
4 participants