Skip to content
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

Autosize / autorange fixes #2437

Merged
merged 11 commits into from
Mar 6, 2018
7 changes: 4 additions & 3 deletions src/components/rangeslider/calc_autorange.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

'use strict';

var Axes = require('../../plots/cartesian/axes');
var listAxes = require('../../plots/cartesian/axis_ids').list;
var getAutoRange = require('../../plots/cartesian/autorange').getAutoRange;
var constants = require('./constants');

module.exports = function calcAutorange(gd) {
var axes = Axes.list(gd, 'x', true);
var axes = listAxes(gd, 'x', true);

// Compute new slider range using axis autorange if necessary.
//
Expand All @@ -28,7 +29,7 @@ module.exports = function calcAutorange(gd) {

if(opts && opts.visible && opts.autorange && ax._min.length && ax._max.length) {
opts._input.autorange = true;
opts._input.range = opts.range = Axes.getAutoRange(ax);
opts._input.range = opts.range = getAutoRange(ax);
}
}
};
54 changes: 37 additions & 17 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var cartesianConstants = require('../plots/cartesian/constants');
var axisConstraints = require('../plots/cartesian/constraints');
var enforceAxisConstraints = axisConstraints.enforce;
var cleanAxisConstraints = axisConstraints.clean;
var axisIds = require('../plots/cartesian/axis_ids');
var doAutoRange = require('../plots/cartesian/autorange').doAutoRange;

var numericNameWarningCount = 0;
var numericNameWarningCountLimit = 5;
Expand Down Expand Up @@ -283,7 +283,7 @@ exports.plot = function(gd, data, layout, config) {

function positionAndAutorange() {
if(!recalc) {
enforceAxisConstraints(gd);
doAutoRangeAndConstraints();
return;
}

Expand Down Expand Up @@ -332,7 +332,7 @@ exports.plot = function(gd, data, layout, config) {
var ax = axList[i];
cleanAxisConstraints(gd, ax);

Axes.doAutoRange(ax);
doAutoRange(ax);
}

enforceAxisConstraints(gd);
Expand Down Expand Up @@ -1846,7 +1846,7 @@ function _relayout(gd, aobj) {
var axId;

function recordAlteredAxis(pleafPlus) {
var axId = axisIds.name2id(pleafPlus.split('.')[0]);
var axId = Axes.name2id(pleafPlus.split('.')[0]);
rangesAltered[axId] = 1;
return axId;
}
Expand Down Expand Up @@ -2093,25 +2093,18 @@ function _relayout(gd, aobj) {
flags.calc = true;
for(var groupAxId in group) {
if(!rangesAltered[groupAxId]) {
axisIds.getFromId(gd, groupAxId)._constraintShrinkable = true;
Axes.getFromId(gd, groupAxId)._constraintShrinkable = true;
}
}
}
}
}

var oldWidth = fullLayout.width,
oldHeight = fullLayout.height;

// calculate autosizing
if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, fullLayout);

// avoid unnecessary redraws
var hasSizechanged = aobj.height || aobj.width ||
(fullLayout.width !== oldWidth) ||
(fullLayout.height !== oldHeight);

if(hasSizechanged) flags.calc = true;
// If the autosize changed or height or width was explicitly specified,
// this triggers a redraw
// TODO: do we really need special aobj.height/width handling here?
// couldn't editType do this?
if(updateAutosize(gd) || aobj.height || aobj.width) flags.plot = true;

if(flags.plot || flags.calc) {
flags.layoutReplot = true;
Expand All @@ -2128,6 +2121,22 @@ function _relayout(gd, aobj) {
};
}

/*
* updateAutosize: we made a change, does it change the autosize result?
* puts the new size into fullLayout
* returns true if either height or width changed
*/
function updateAutosize(gd) {
var fullLayout = gd._fullLayout;
var oldWidth = fullLayout.width;
var oldHeight = fullLayout.height;

// calculate autosizing
if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, fullLayout);

return (fullLayout.width !== oldWidth) || (fullLayout.height !== oldHeight);
}

// for editing annotations or shapes - is it on autoscaled axes?
function refAutorange(gd, obj, axLetter) {
if(!Lib.isPlainObject(obj)) return false;
Expand Down Expand Up @@ -2313,6 +2322,17 @@ exports.react = function(gd, data, layout, config) {
var restyleFlags = diffData(gd, oldFullData, newFullData, immutable);
var relayoutFlags = diffLayout(gd, oldFullLayout, newFullLayout, immutable);

// TODO: how to translate this part of relayout to Plotly.react?
// // Setting width or height to null must reset the graph's width / height
// // back to its initial value as computed during the first pass in Plots.plotAutoSize.
// //
// // To do so, we must manually set them back here using the _initialAutoSize cache.
// if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
// fullLayout[ai] = gd._initialAutoSize[ai];
// }
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On closer inspection I think I understand what this is about, but I don't think it's actually the correct behavior, for example if gd was resized external to plotly.js it wouldn't make sense to revert to when the plot was first drawn. I'm not quite sure how to handle this though.

Copy link
Contributor

Choose a reason for hiding this comment

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

😬 auto-sizing always has a way to make my brain hurt.

Referencing #635 which did a lot of damage the streambed 🤕

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oy, I think we've all fought with that one at various points... If you don't mind, I'm going to leave this as it is now - with the TODO here to remind us about it if a related bug pops up, but without trying to implement anything around it. We have some great tests in config_test that I extended to make sure that all of those test cases work the same in relayout and react, I'd like to just freeze it until we have more test cases to look at.


if(updateAutosize(gd)) relayoutFlags.layoutReplot = true;

// clear calcdata if required
if(restyleFlags.calc || relayoutFlags.calc) gd.calcdata = undefined;
if(relayoutFlags.margins) helpers.clearAxisAutomargins(gd);
Expand Down
Loading