Skip to content

Revert "Remove internal option layout.autosize='initial' (Fixes #537)" #633

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 2 commits into from
Jun 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,7 @@ lib.getPlotDiv = function(el) {

lib.isPlotDiv = function(el) {
var el3 = d3.select(el);
return el3.node() instanceof HTMLElement &&
el3.size() &&
el3.classed('js-plotly-plot');
return el3.size() && el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
121 changes: 106 additions & 15 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,10 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Plotly.micropolar.manager.fillLayout(gd);

if(gd._fullLayout.autosize === 'initial' && gd._context.autosizable) {
plotAutoSize(gd, {});
gd._fullLayout.autosize = layout.autosize = true;
}
// resize canvas
paperDiv.style({
width: gd._fullLayout.width + 'px',
Expand Down Expand Up @@ -2144,6 +2148,8 @@ Plotly.relayout = function relayout(gd, astr, val) {
return (fullLayout[axName] || {}).autorange;
}

var hw = ['height', 'width'];

// alter gd.layout
for(var ai in aobj) {
var p = Lib.nestedProperty(layout, ai),
Expand All @@ -2166,8 +2172,14 @@ Plotly.relayout = function relayout(gd, astr, val) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autorange vs range
if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
}
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.autorange$/)) {
Expand Down Expand Up @@ -2346,20 +2358,11 @@ Plotly.relayout = function relayout(gd, astr, val) {
Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]);
}

var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;
// calculate autosizing - if size hasn't changed,
// will remove h&w so we don't need to redraw
if(aobj.autosize) aobj = plotAutoSize(gd, aobj);

// coerce the updated layout
Plots.supplyDefaults(gd);

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

// avoid unnecessary redraws
var changed = aobj.height || aobj.width ||
(gd._fullLayout.width !== oldWidth) ||
(gd._fullLayout.height !== oldHeight);
if(changed) docalc = true;
if(aobj.height || aobj.width || aobj.autosize) docalc = true;

// redraw
// first check if there's still anything to do
Expand All @@ -2380,6 +2383,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
}
else if(ak.length) {
// if we didn't need to redraw entirely, just do the needed parts
Plots.supplyDefaults(gd);
fullLayout = gd._fullLayout;

if(dolegend) {
Expand Down Expand Up @@ -2488,6 +2492,86 @@ Plotly.purge = function purge(gd) {
return gd;
};

/**
* Reduce all reserved margin objects to a single required margin reservation.
*
* @param {Object} margins
* @returns {{left: number, right: number, bottom: number, top: number}}
*/
function calculateReservedMargins(margins) {
var resultingMargin = {left: 0, right: 0, bottom: 0, top: 0},
marginName;

if(margins) {
for(marginName in margins) {
if(margins.hasOwnProperty(marginName)) {
resultingMargin.left += margins[marginName].left || 0;
resultingMargin.right += margins[marginName].right || 0;
resultingMargin.bottom += margins[marginName].bottom || 0;
resultingMargin.top += margins[marginName].top || 0;
}
}
}
return resultingMargin;
}

function plotAutoSize(gd, aobj) {
var fullLayout = gd._fullLayout,
context = gd._context,
computedStyle;

var newHeight, newWidth;

gd.emit('plotly_autosize');

// embedded in an iframe - just take the full iframe size
// if we get to this point, with no aspect ratio restrictions
if(gd._context.fillFrame) {
newWidth = window.innerWidth;
newHeight = window.innerHeight;

// somehow we get a few extra px height sometimes...
// just hide it
document.body.style.overflow = 'hidden';
}
else if(isNumeric(context.frameMargins) && context.frameMargins > 0) {
var reservedMargins = calculateReservedMargins(gd._boundingBoxMargins),
reservedWidth = reservedMargins.left + reservedMargins.right,
reservedHeight = reservedMargins.bottom + reservedMargins.top,
gdBB = fullLayout._container.node().getBoundingClientRect(),
factor = 1 - 2 * context.frameMargins;

newWidth = Math.round(factor * (gdBB.width - reservedWidth));
newHeight = Math.round(factor * (gdBB.height - reservedHeight));
}
else {
// plotly.js - let the developers do what they want, either
// provide height and width for the container div,
// specify size in layout, or take the defaults,
// but don't enforce any ratio restrictions
computedStyle = window.getComputedStyle(gd);
newHeight = parseFloat(computedStyle.height) || fullLayout.height;
newWidth = parseFloat(computedStyle.width) || fullLayout.width;
}

if(Math.abs(fullLayout.width - newWidth) > 1 ||
Math.abs(fullLayout.height - newHeight) > 1) {
fullLayout.height = gd.layout.height = newHeight;
fullLayout.width = gd.layout.width = newWidth;
}
// if there's no size change, update layout but
// delete the autosize attr so we don't redraw
// but can't call layoutStyles for initial autosize
else if(fullLayout.autosize !== 'initial') {
delete(aobj.autosize);
fullLayout.autosize = gd.layout.autosize = true;
}

Plots.sanitizeMargins(fullLayout);

return aobj;
}

// -------------------------------------------------------
// makePlotFramework: Create the plot container and axes
// -------------------------------------------------------
Expand All @@ -2507,6 +2591,13 @@ function makePlotFramework(gd) {
.classed('svg-container', true)
.style('position', 'relative');

// Initial autosize
if(fullLayout.autosize === 'initial') {
plotAutoSize(gd, {});
fullLayout.autosize = true;
gd.layout.autosize = true;
}

// Make the graph containers
// start fresh each time we get here, so we know the order comes out
// right, rather than enter/exit which can muck up the order
Expand Down
3 changes: 1 addition & 2 deletions src/plot_api/plot_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ module.exports = {
// we can edit titles, move annotations, etc
editable: false,

// DO autosize once regardless of layout.autosize
// (use default width or height values otherwise)
// plot will respect layout.autosize=true and infer its container size
autosizable: false,

// if we DO autosize, do we fill the container or the screen?
Expand Down
14 changes: 5 additions & 9 deletions src/plots/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,13 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'boolean',
valType: 'enumerated',
role: 'info',
dflt: false,
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
description: [
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
].join(' ')
},
width: {
Expand Down
Loading