-
-
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
Fix relayout constrained axes + various multi-subplot perf improvements #2628
Conversation
... by extracting correct prop "leaf" end index which is used to keep track of "altered ranges" which than lead to `flags.calc: true` under axis constraints. In the test added, the # of xgrid ended being the same before and after the relayout call.
- updating axes with constraints triggers a 'calc' edit, so no need to do this here.
- these clip paths are only used for shapes and layout images, which make hasOnlyLargeSploms false, so we don't need them. - this can trim ~50ms on first render at 50 splom dimensions.
- by passing (now correct) alteredRange hash object to doTicksRelayout - by addding new doTicks(gd, [axId, axId2, ...]) call signature - clean up doTicks docstring - N.B. not implemented for Plotly.react (yet)
- so that supplyDefaults and "easy" edits (e.g. axrange, modebar) can be faster. - mv "axrange" react test out of relayout switchboard describe keeping "real" graph div out the relayout switchboard describe
- this way, the Grid component can generate axes with set 'anchor' for all sploms except when `showlowerhalf: false`. Having set anchored axes is a performance boost (~40ms at 50 dimensions).
... which had their y-axis shift a little bit by the previous commit that made their axes anchored.
... which in my opinion is now more "correct" than previously
A few more comments on constrained axes, that should be followed up in #2540:
plotly.js/src/plot_api/plot_api.js Line 2039 in a132b85
with
|
src/plot_api/plot_api.js
Outdated
@@ -2171,7 +2169,9 @@ exports.update = function update(gd, traceUpdate, layoutUpdate, _traces) { | |||
if(relayoutFlags.layoutstyle) seq.push(subroutines.layoutStyles); | |||
if(relayoutFlags.axrange) { | |||
seq.push( | |||
subroutines.doTicksRelayout, | |||
function(gd) { | |||
return subroutines.doTicksRelayout(gd, relayoutSpecs.rangesAltered); |
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.
N.B. @alexcjohnson I didn't implement per-axis "axrange" edit for Plotly.react
. My main concern was improvement perf on dragend axis range relayout calls. I didn't think adding an exception to the react diffing algo was worth it for this case.
@@ -324,6 +329,48 @@ exports.lsInner = function(gd) { | |||
return gd._promises.length && Promise.all(gd._promises); | |||
}; | |||
|
|||
function findMainSubplot(ax, 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.
@alexcjohnson I didn't bother making the "find main subplot" algo faster as you proposed in #2549 (comment), I was happy enough with skipping this whole thing except for sploms with showlowerhalf: false
with c947b2c
Do we have a test of setting mutually-exclusive range values, as per the comment on that line? If we do, and the result correctly fixes them for the constraints, then go for it! |
@@ -1806,7 +1806,7 @@ function _relayout(gd, aobj) { | |||
var plen = p.parts.length; | |||
// p.parts may end with an index integer if the property is an array | |||
var pend = plen - 1; | |||
while(pend > 0 && typeof p.parts[plen - 1] !== 'string') { pend--; } | |||
while(pend > 0 && typeof p.parts[pend] !== 'string') pend--; |
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, nice catch!
src/plots/cartesian/axes.js
Outdated
* | ||
* Signature 5: Axes.doTicks(gd, [axId, axId2, ...]) | ||
* where the items are axis id string, | ||
* use this to update multiple axes in one call |
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 was already a bit out of control, do we really want to add another signature?
Can we perhaps break it into 2 separate functions, one for signatures 1 & 2 and a second for 3, 4, 5? That's how it functions anyway - 3,4,5 just map into a bunch of calls to signature 2 (ignoring skipTitle
) and then 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.
Sure that would be nice. But since doTicks
is one of our most referenced function in existing issues, I'm a little reluctant to do so.
But if you insist, than I'm thinking of making Axes.doTicks
the multi-cartesian-axis version (that accepts ''
, 'redraw'
and arrays of axis ids), and adding Axes.doTicksSingle
(that accepts one axis id string or an axis object).
On master
, we have:
💪 Well done, this is a really fantastic collection of boosts and fixes! Thanks for the #2628 (comment) is non-blocking. |
Moved to #2540 (comment) |
This PR started with a fix for relayout on constrained axes #2540 (comment). This fix made the
rangesAltered
stash in relayoutplotly.js/src/plot_api/plot_api.js
Lines 2028 to 2047 in a132b85
work properly and lead me to use the same stash to implement per-axis "axrange" edits (as planned in #2547). While at it, I added a few more splom-related perf improvements for multi-subplot graphs, namely
Axes.makeClipPaths
underhasOnlyLargeSploms
planned in Unnecessary clipPaths #2595 (comment)supplyDefaults
->lsInner
as planned in Speed up cartesian axes supplyDefaults #2549 (comment)Some benchmarks:
Plotly.relayout(gd, 'xaxis.range[0], 0)
on a 50-dimensions splom. At 15 dimensions (i.e. with svg grid lines), it trims ~100ms.showlowerhalf: false
have a set anchor trims 40-50ms.So, starting with https://codepen.io/etpinard/pen/wjmqmO and benchmarking
Plotly.relayout(gd, 'xaxis.range', [0, 1])
we get: