Skip to content

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

Merged
merged 10 commits into from
Mar 2, 2017
Merged

Axes ref cleanup #1431

merged 10 commits into from
Mar 2, 2017

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Mar 1, 2017

No more ax_gd !!!

etpinard added 6 commits March 1, 2017 15:06
- 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) {
Copy link
Contributor Author

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)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still two maps and a filter 🐎

Copy link
Contributor Author

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;
Copy link
Contributor Author

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 || {};
Copy link
Contributor Author

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,
Copy link
Contributor Author

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.

@@ -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');
Copy link
Contributor Author

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?

Copy link
Collaborator

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.

Copy link
Contributor Author

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 ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 9612549

@@ -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;
Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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;
Copy link
Contributor Author

@etpinard etpinard Mar 1, 2017

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;
Copy link
Contributor Author

@etpinard etpinard Mar 1, 2017

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 || {};
Copy link
Contributor Author

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.

Copy link
Contributor Author

@etpinard etpinard Mar 2, 2017

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.

Copy link
Collaborator

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);
}
};
Copy link
Collaborator

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore. 🔪

Copy link
Contributor Author

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'
};
Copy link
Collaborator

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.

@alexcjohnson
Copy link
Collaborator

Thanks for the changes. I guess you're still sorting something out re: fonts but I'm ready to 💃

@etpinard etpinard merged commit 8a310b3 into master Mar 2, 2017
@etpinard etpinard deleted the axes-ref-cleanup branch March 2, 2017 20:37
@etpinard etpinard mentioned this pull request Mar 9, 2017
44 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants