-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add additional options for automargin property #6193
Add additional options for automargin property #6193
Conversation
'top left', 'top width', 'top right', | ||
'left height', 'right height', | ||
'bottom left', 'bottom width', 'bottom right', | ||
], |
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.
Let's use a flaglist:
valType: 'flaglist',
flags: ['height', 'width', 'left', 'right', 'top', 'bottom'],
extras: [true, false]
That way the order doesn't matter (you use +
- bottom+left
and left+bottom
are both valid), and users could even do bottom+left+right
which would mean the same thing as bottom+width
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.
Are there pre-existing instances of "flaglist or boolean" in the schema? I want to make sure the Python codegen will not choke on this.
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.
flaglist does not support boolean parameters
Line 218 in b194d8c
if(typeof v !== 'string') { |
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.
OK that's pretty good evidence that we don't currently have any flaglists with non-string extras 😉
We could allow this in coerce
pretty easily by pushing the extras test up above that non-string short-circuit.
@nicolaskruchten your concern is warranted, plotly.py also includes the string requirement up front. But I really do think this attribute would be better as a flaglist, I'll be happy to modify the Python validator to allow non-string extras.
I suppose the alternative would be to make this a new attribute like automargindirections
and leave automargin
as a boolean, but that seems a bit cumbersome...
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'm fine with tweaking Plotly.py for this 👍
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.
Changed the schema.
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.
OK that's pretty good evidence that we don't currently have any flaglists with non-string extras wink We could allow this in
coerce
pretty easily by pushing the extras test up above that non-string short-circuit.@nicolaskruchten your concern is warranted, plotly.py also includes the string requirement up front. But I really do think this attribute would be better as a flaglist, I'll be happy to modify the Python validator to allow non-string extras.
I suppose the alternative would be to make this a new attribute like
automargindirections
and leaveautomargin
as a boolean, but that seems a bit cumbersome...
Having a separate attribute could be safer for Python, R, Scala, etc. APIs.
It would be nice to possibly test this at plotly.py
level before merging this PR.
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'm working on a plotly.py PR right now... will post shortly.
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 looks great to me. It'll just need a draftlog entry, @archmoj anything from your side?
I'll make the required plotly.py change for non-string flaglist extras myself.
85cbe5d
to
fa888ab
Compare
fa888ab
to
9dfdb91
Compare
if(typeof v !== 'string') { | ||
propOut.set(dflt); | ||
return; | ||
} |
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.
Could you please elaborate why this change is needed?
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 reversing the order of short-circuits to support non-string extras #6193 (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.
As @alexcjohnson wrote:
OK that's pretty good evidence that we don't currently have any flaglists with non-string extras 😉
We could allow this in coerce pretty easily by pushing the extras test up above that non-string short-circuit.
Without this, the flaglist coerce function does not pass non-string values.
src/plots/cartesian/axes.js
Outdated
@@ -2622,6 +2622,8 @@ axes.drawOne = function(gd, ax, opts) { | |||
rangeSliderPush = Registry.getComponentMethod('rangeslider', 'autoMarginOpts')(gd, ax); | |||
} | |||
|
|||
keepSelectedAutoMargin(ax.automargin, push); |
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 keepSelectedAutoMargin
mutates the push
variable.
It was rather difficult to figure out what this step does here.
How about refactoring like this:
if(typeof automargin === 'string') filterPush(push, ax.automargin);
On another note, wondering if mutating push
should be performed earlier in the process so that the value in mirrorPush
would be accurate?
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 don't see the point of using a mirror if the result would still be cut off. So there is no need to filter the mirrorPush
.
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.
Actually I think it's correct to filter mirrorPush
as well. The whole mirrorPush
construction is inside the if(ax.automargin)
block - implying that if you disable automargin, we're not going to push the margins for mirror axes regardless of whether they end up cut off. Therefore you should be able to choose which directions this applies to just as you can the regular axis automargin.
src/plots/cartesian/axes.js
Outdated
|
||
Object.keys(MARGIN_MAPPING).forEach(function(key) { | ||
if(automargin.indexOf(key) !== -1) { | ||
MARGIN_MAPPING[key].forEach(function(item) { |
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't we simply use one concact
here instead of the inner loop and push?
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.
actually perhaps even better: make keepMargin
an object and set keepMargin[item] = 1
, then the test below doesn't need indexOf
, just if(!keepMargin[key])
@@ -2622,6 +2630,11 @@ axes.drawOne = function(gd, ax, opts) { | |||
rangeSliderPush = Registry.getComponentMethod('rangeslider', 'autoMarginOpts')(gd, ax); | |||
} | |||
|
|||
if(typeof ax.automargin === 'string') { | |||
filterPush(push, ax.automargin); | |||
filterPush(mirrorPush, ax.automargin); |
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.
How about rangeSliderPush
? Should we filter that one too?
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.
ha @nickmelnikov82 asked me the same question, my answer:
that one isn’t controlled by
ax.automargin
so I think no
There are others that aren't even in this section of code, like legends and colorbars. ax.automargin
is only about "are the axes themselves allowed to increase the margins."
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 wonder if we want to implement layout.automargindirections
and inherit from it instead?
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 that's interesting... in principle I like this, one place to control all of this rather than requiring you to set it in each axis separately. But it opens a can of worms: by default axes have automargin: false
while colorbars and legends (and rangesliders) by default DO increase the margins, and putting this at the top level would imply that it applies to everything. So it would need a default value like 'legacy'
or something that gets inherited differently by axes and other objects, and then we would need to extend support for disabling automargin to all these other objects as well.
All that to say: it's a good idea, but it's going to be a bunch of work, so let's not do it now. What we're doing in this PR would be fully compatible with adding that sometime in the future.
Created plotly/plotly.py#3749 to allow non-string flaglist extras on the Python side |
aa8fb3d
to
e26eb02
Compare
e26eb02
to
eed9bbf
Compare
src/plots/cartesian/axes.js
Outdated
@@ -2636,6 +2649,25 @@ axes.drawOne = function(gd, ax, opts) { | |||
return Lib.syncOrAsync(seq); | |||
}; | |||
|
|||
function filterPush(push, automargin) { | |||
if(!push) return push; |
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(!push) return push; | |
if(!push) return; |
src/plots/cartesian/axes.js
Outdated
else delete push[key]; | ||
} | ||
}); | ||
return push; |
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.
return push; |
a2d6fd5
to
ae1b087
Compare
Thanks very much for the PR 💃 |
…, "bottom", "width" and "height" to control the direction of automargin on cartesian axes (plotly/plotly.js#6193)
Feature: Add new options "width" and "height" for the automargin property, which would limit the automargin calculation to one dimension. This way we could make sure the labels are never cut off and that there isn't any whitespace on the left or right border of the figure.