-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
|
||
function coerce(attr, dflt) { | ||
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!
@@ -61,7 +61,8 @@ function num(v) { | |||
* also clears the autorange bounds ._min and ._max | |||
* and the autotick constraints ._minDtick, ._forceTick0 | |||
*/ | |||
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
@@ -319,7 +320,7 @@ module.exports = function setConvert(ax) { | |||
|
|||
// 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
.
src/plots/cartesian/set_convert.js
Outdated
@@ -360,7 +361,6 @@ module.exports = function setConvert(ax) { | |||
Lib.notifier( | |||
'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
@@ -417,6 +417,10 @@ module.exports = function setConvert(ax) { | |||
ax._min = []; | |||
ax._max = []; | |||
|
|||
// 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 ...
🎉
@@ -1137,7 +1133,7 @@ axes.tickText = function(ax, x, hover) { | |||
}; | |||
|
|||
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.
test/jasmine/karma.conf.js
Outdated
// 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
!!!