-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[charts] Fix selector behavior affecting datagrid intergration #20083
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
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think this only works because
getNormalizedAxisScalealways returns a new scale, making thisisDeepEqualunnecessary because it will always return false.The reason for
isDeepEqualin the normalized domain was to avoid recomputing scale selectors if the domain didn't change, so I think this is negating the performance improvements from #19790 since we'll always be re-creating theFlatbushdata structure.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 is
resultEqualityCheckandequalityCheck. This is checking the parameters, not the result. The in the original, theselectorChartFilteredXDomainsalways re-runs regardless of value, then it checks if the result is equal and return it if they are different.This is kinda useless, since in
selectorChartNormalizedXScales, which is the only placeselectorChartFilteredXDomainsis used, we depend onselectorChartRawXAxiswhich is pretty much always different.Our options are to either memoize the parameters of
selectorChartNormalizedXScales, at the cost of traversing and checking the scales, or not memoize at all at the cost of re-render.The general cause seems to be that @arminmeh mentioned in the body of the issue #20082
But I fail to understand why exactly it happens.
It seems that due to the memoization, the incoming
xAxis[].datagets desynced from the actual data used in thescaleBand(domain), where the original arrays change, but their content doesn't.I believe the solution proposed here solves that by syncing the result of the nomalizer selector to retrigger downstream selectors whenever the deep equal of its
inputschanges, at the cost of having to deep traverse the axes every time.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 realize that, thanks for calling it out. I wonder if it'll end up being more expensive, though, as checking an object of size-2 arrays is probably cheaper than doing a deep equal of all the arguments. Especially since
selectorChartRawXAxiscan contain thedataarray in line and bar charts, which can be a large array.selectorChartFilteredXDomainsindirectly depends onselectorChartZoomMap. The use case for memoizing the result of the filtered domain was to avoid re-creating the normalized scales when the zoom map changed but didn't cause the domains to change. In that case, we don't want to re-create the scales because it'll cause the flatbush to be re-indexed which is somewhat expensive.When the axis changes, it'll recompute the world, it's true. We need additional selector work to fix that.
It seems the root cause isn't entirely known. I'll spend some time investigating this to understand the issue
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 think I found the issue and why this fix works.
It seems that the line @arminmeh mentioned (
xScale(baseValue)) finds thebaseValuewithin thexScale.domain().d3's
ordinalscale uses internmap to find compare non-primitives, but it relies onvalueOf(). For dates, this works because itsvalueOf()is a unix timestamp, which is a primitive that can be compared. For arrays, however, this doesn't work (['a','b'].valueOf() === ['a','b'].valueOf()returns false).Our
datais an array of arrays because we're using grouping. The initial render works fine because they're the same reference. However, due to domain memoization, whenever a re-render happens, the arrays indatawill be different from the arrays in the scale's domains, causingxScale(baseValue)to return an invalid value.The change from this PR fixes the issue by breaking memoization whenever the axis changes, which causes the reference to be the same, but to be honest this doesn't address the root cause.
To me, the issue at the root of this problem is how d3 is comparing values when they aren't primitives. IMO, that's what we need to fix.
You can reproduce my assertion by adding the following code here:
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.
One more piece of information that might help
When I was debugging this, I noticed that the
datafromuseBarPlotDatais calculated twice when I do the change that breaks the chart.First time the data seems to be correct, but the second time the
xvalue becomesNaN(reasons mentioned above)