Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork2k
fix: Update config diff check method to handle nested arrays#7579
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
src/plot_api/helpers.js Outdated
| returnfalse; | ||
| }; | ||
| constAX_LETTERS=['x','y','z']; |
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.
put at top of file perhaps? I would normally expect constants not inside a function to be defined at the top of the file.
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.
Can do.
src/plot_api/helpers.js Outdated
| *@param {Object|Array} oldCollection: Old version of collection to compare | ||
| *@param {Object|Array} newCollection: New version of collection to compare | ||
| */ | ||
| consthasCollectionChanged=(oldCollection,newCollection)=>{ |
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.
just a nit, but I would expect this function to be called something slightly more general likeareObjectsEqual() since the function itself doesn't care whetheroldCollection andnewCollection are versions of the same object or not; that's a matter of how the function is used.
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 was trying to be generic with the term "collection" since you could be passing in an object or an array, but we could go further as you suggest. WouldareCollectionsEqual be acceptable?
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.
yes,areCollectionsEqual (or maybecollectionsAreEqual?) sounds good to me 👍
Actually, one related question — what is the reason for ignoring keys starting with an underscore? Is that due to a JavaScript implementation detail, or a Plotly.js one? Maybe that should be captured in the function name (since it's a very particular definition of equality)
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.
That's a plotly.js detail, but it's also a JavaScript convention. Variables that start with underscore are labeled as such because they are meant to be used internally by the library. So, you wouldn't see a user changing those values, hence they can be ignored.
src/plot_api/helpers.js Outdated
| if(Object.keys(oldCollection).length!==Object.keys(newCollection).length)returntrue; | ||
| for(constkinoldCollection){ | ||
| if(k.startsWith('_'))returnfalse; |
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 seems wrong, am I missing something? Is it supposed to beif (k.startsWith('_')) continue; ?
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.
Wait, looking closely this whole loop is problematic; it should only ever returntrue from within the loop. Line 535 will returnfalse sometimes and short-circuit the whole loop ifhasCollectionChanged(oldVal, newVal) returnsfalse.
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.
Good catch! I did a poor job of converting this loop from it's previous iteration. I updated it to only return whentrue.
emilykl commentedOct 14, 2025
@camdecoster Infinite loop is resolved, but I am not able to update the modebar buttons successfully by calling This is the line I am running in the browser console: Plotly.react(gd,gd.data,gd.layout,{modeBarButtons:[['zoom2d','pan2d'],['autoScale2d','resetScale2d']]}); I would expect to see new buttons show up in the modebar but I see nothing. I am also seeing that |
emilykl commentedOct 14, 2025
Also have you been able to learn anything about the intentions behindthis test? Unclear whether it was deliberately forbidden for a philosophical reason, or just because it was complicated to implement. |
camdecoster commentedOct 14, 2025
I've only looked at it to understand why it was failing. In this case, it was because of the bad loop conversion. I'll see if I can understand it a bit better and report back. |
emilykl commentedOct 14, 2025
I ask because the wording of the test case ("should not try to transition when theconfig has changed") seems to directly oppose the functionality you've added (making sure a transition happens during |
camdecoster commentedOct 14, 2025
Okay, so config changes shouldn't be animated perthis comment. The second call to So, the test is there to make sure no transitions happen when a config change occurs. This might actually add a new feature that didn't exist before the changes to |
camdecoster commentedOct 15, 2025
This was a consequence of the loop logic error. I tried it after the fix and it worked. Could you try again with the latest changes? |
emilykl commentedOct 15, 2025
@camdecoster Thanks for the clear explanation, that all makes sense. I've tested again and it seems to be working as expected. |
emilykl left a comment
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. Maybe add a few more Jasmine tests forcollectionsAreEqual() if you have the bandwidth, but not required.
be3cd47 intomasterUh oh!
There was an error while loading.Please reload this page.
| }); | ||
| it('Returns false for null values',()=>{ | ||
| expect(helpers.collectionsAreEqual(null,null)).toBe(false); |
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.
Wouldn't it make sense for this case to returntrue?
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 suppose, but that's not how the function is supposed to be used. It would require an additional branch to the conditional check and I didn't feel like adding that. If you feel strongly about it, I'll add 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.
Nah I don't feel strongly about it. My only suggestion would be to note these details in the function docstring.
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.
The JSDoc param specs show the args should be an array or object. Do you think more would be necessary?
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.
Oh yeah my bad I skimmed over the jsdoc, if that conventionally meansnull is not a valid input I'm satisfied 👍
Uh oh!
There was an error while loading.Please reload this page.
Description
Update config diff check to handle nested arrays.
Closes#7572.
Changes
Testing
{"data": [ {"error_x": {"array": [100000.0,100000.0,100000.0],"type":"data","visible":true },"type":"scatter","x": [1554370371547.085,1554370471547.085,1554370571547.085],"y": [6,10,2] } ],"layout": {"xaxis": {"type":"date" } },"config": {"modeBarButtons": [[]] }}reactbefore you do to avoid crashing your browser/computerreactfrom the browser DevTools console with the following command:Notes
reactonce and that was it. The new code can make a call toreactrecursively, which is triggered by the above example.modeBarButtonsconfig option because that's the only one that takes a nested array as a valueTODO