-
Notifications
You must be signed in to change notification settings - Fork 120
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
Conversation
There was a problem hiding this 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. 👍🏼
I'm not really sure what failed with the |
Turns out after I updated the types, that CI fails due to apparent minor changes in the return values of the |
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? |
hey @watson I will take a look at this. |
@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. |
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 |
12ad738
to
de24f8f
Compare
BREAKING CHANGE: the new d3-scale version used ES2015 and our target version needs to align to that.
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 |
Thanks for taking this one on @markov00 and no worries about the delays. We'll get there eventually.
Sounds good 👍 The most important part was upgrading to v2.2.2 or newer. |
Thank you @markov00 for doing all the hard work in making this PR all green!! ❤️❤️❤️ |
There was a problem hiding this 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)) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done here f171590
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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-number
s 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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 NaN
s 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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 096e346
packages/charts/src/chart_types/xy_chart/rendering/__snapshots__/rendering.bands.test.ts.snap
Show resolved
Hide resolved
packages/charts/src/chart_types/xy_chart/state/__snapshots__/chart_state.debug.test.ts.snap
Show resolved
Hide resolved
@@ -39,29 +40,30 @@ export const getElementAtCursorPositionSelector = createCustomCachedSelector( | |||
|
|||
function getElementAtCursorPosition( | |||
orientedProjectedPointerPosition: PointerPosition, | |||
scales: ComputedScales, | |||
{ xScale }: ComputedScales, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 yes it solves it in both the X axis and in the Y one |
I'm performing this upgrade to get a newer version of
d3-color
which is a direct dependency ofd3-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