-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Axes ref cleanup #1431
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
Axes ref cleanup #1431
Conversation
- to show console.log in terminal in karma ^1.5.0 - See karma-runner/karma@89a7a1c#commitcomment-21009216
- make setConvert take fullLayout, use fullLayout._size in setScale instead of gd._fullLayout._size - add _input ref to fullLayout axis, use that in doAutorange to copy back computed range to input layout
- instead of pre-initialization - the pattern is more similar to other subplots (e.g. ternary) and requires one less module
| return Lib.coerce(axLayoutIn, axLayoutOut, layoutAttributes, attr, dflt); | ||
| } | ||
|
|
||
| axesList.forEach(function(axName) { |
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.
as promised in #1261 (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.
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 5eb6202
| var axList = Plotly.Axes.list(gd); | ||
| for(i = 0; i < axList.length; i++) { | ||
| var ax = axList[i]; | ||
| ax._gd = gd; |
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.
@alexcjohnson this commit is very important.
First, no need to keep ax_gd in-sync anymore!
| */ | ||
| module.exports = function setConvert(ax) { | ||
| module.exports = function setConvert(ax, fullLayout) { | ||
| fullLayout = fullLayout || {}; |
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.
Second, make setConvert take in fullLayout
| // set scaling to pixels | ||
| ax.setScale = function(usePrivateRange) { | ||
| var gs = ax._gd._fullLayout._size, | ||
| var gs = fullLayout._size, |
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.
... so that setScale can look into _size.
| 'Something went wrong with axis scaling', | ||
| 'long'); | ||
| ax._gd._replotting = false; | ||
| throw new Error('axis scaling'); |
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.
🔪 ax._gd._replotting = false; on axis scaling errors. Isn't that error throw enough?
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.
If we think the error is fatal to the plot then yes, it's enough. But if there would be a use case for catching the error and continuing, then the plot will be in an odd state without resetting gd._replotting. I suppose at the very least we can move it to fullLayout but we should really figure out a better solution than the fragile _replotting flag to prevent infinite recursion.
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.
Sounds good. I'll try to cook up a test case for this edge case. Any help would be appreciated ;)
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 9612549
src/plots/cartesian/set_convert.js
Outdated
|
|
||
| // copy ref to fullLayout.separators so that | ||
| // methods in Axes can use it w/o having to pass fullLayout | ||
| ax.separators = fullLayout.separators; |
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.
Important: link fullLayout.separators to full axis object, so that Axes method can use it without having to know anything about fullLayout.
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.
shall we call it _separators to distinguish it from regular settings managed by supplyDefaults? That actually adds overhead (as relinkPrivateKeys will look at it) but it does seem to be the pattern we've been using.
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 call here. I was thinking maybe down the road we would add per-axis separators, making this line obsolete (by supply defaults logic). But no, you're right, non-underscore keys in containers should match input attributes.
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 6e25640
| if(!layoutIn[axName] && axLayoutIn.type !== '-') { | ||
| layoutIn[axName] = {type: axLayoutIn.type}; | ||
| } | ||
| axLayoutOut._input = axLayoutIn; |
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 is essentially the new ax_gd. This pattern is similar to other components that require a ref to the user container to mutate it on interactions (e.g. updatemenus and sliders). Moreover, IMHO this pattern is a lot better than having to keep the full gd in-sync.
| } | ||
| var axIn = ax._input; | ||
| axIn.range = ax.range.slice(); | ||
| axIn.autorange = ax.autorange; |
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.
Now, doAutorange writes in ax._input instead of having dig in _gd.layout ... 🎉
|
|
||
| function tickTextObj(ax, x, text) { | ||
| var tf = ax.tickfont || ax._gd._fullLayout.font; | ||
| var tf = ax.tickfont || {}; |
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. I need to double-check this.
Removing the || {} should do the trick - as axis tickfont already default to layout font, but removing || {} makes the fonts.json mock fail. Not sure why.
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.
After investigation, I'll keep the || {} fallback, if ok.
Whenever ax.showticklabels: false, ax.tickfont isn't coerced and isn't defined here.
We could make sure that tickTextObj isn't called when ax.showticklabels: false, but this requires adding a few early returns in axes.js, 3d and gl2d convert routines which I believe isn't 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.
👍
| var ax = this.fullSceneLayout[axisProperties[i]]; | ||
| Axes.setConvert(ax, this.fullLayout); | ||
| } | ||
| }; |
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.
Nice simplification! Why don't we need the containerOut.setScale = Lib.noop; line anymore?
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.
Not anymore. 🔪
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.
To be more precise, 3d doesn't use any of the _m and friends fields that setScale computes at the moment. So setting setScale to a noop might be a minor 🐎 boost. But, for 3d annotations, I'm planning on using / mocking those scale fields. To be continued.
| // See https://github.com/karma-runner/karma/commit/89a7a1c#commitcomment-21009216 | ||
| func.defaultConfig.browserConsoleLogOptions = { | ||
| level: 'log' | ||
| }; |
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 awesome - that'll be super helpful.
- to avoid confusion as separators isn't an axis attribute
|
Thanks for the changes. I guess you're still sorting something out re: fonts but I'm ready to 💃 |
No more
ax_gd!!!