Skip to content

Commit 8360ef9

Browse files
authored
Revert "Remove internal option layout.autosize='initial' (Fixes #537)"
1 parent 2c7c2db commit 8360ef9

13 files changed

+129
-401
lines changed

src/lib/index.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,7 @@ lib.getPlotDiv = function(el) {
379379

380380
lib.isPlotDiv = function(el) {
381381
var el3 = d3.select(el);
382-
return el3.node() instanceof HTMLElement &&
383-
el3.size() &&
384-
el3.classed('js-plotly-plot');
382+
return el3.size() && el3.classed('js-plotly-plot');
385383
};
386384

387385
lib.removeElement = function(el) {

src/plot_api/plot_api.js

+106-15
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ function plotPolar(gd, data, layout) {
409409
if(layout) gd.layout = layout;
410410
Plotly.micropolar.manager.fillLayout(gd);
411411

412+
if(gd._fullLayout.autosize === 'initial' && gd._context.autosizable) {
413+
plotAutoSize(gd, {});
414+
gd._fullLayout.autosize = layout.autosize = true;
415+
}
412416
// resize canvas
413417
paperDiv.style({
414418
width: gd._fullLayout.width + 'px',
@@ -2144,6 +2148,8 @@ Plotly.relayout = function relayout(gd, astr, val) {
21442148
return (fullLayout[axName] || {}).autorange;
21452149
}
21462150

2151+
var hw = ['height', 'width'];
2152+
21472153
// alter gd.layout
21482154
for(var ai in aobj) {
21492155
var p = Lib.nestedProperty(layout, ai),
@@ -2166,8 +2172,14 @@ Plotly.relayout = function relayout(gd, astr, val) {
21662172
// op and has no flag.
21672173
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();
21682174

2169-
// check autorange vs range
2170-
if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
2175+
// check autosize or autorange vs size and range
2176+
if(hw.indexOf(ai) !== -1) {
2177+
doextra('autosize', false);
2178+
}
2179+
else if(ai === 'autosize') {
2180+
doextra(hw, undefined);
2181+
}
2182+
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
21712183
doextra(ptrunk + '.autorange', false);
21722184
}
21732185
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.autorange$/)) {
@@ -2346,20 +2358,11 @@ Plotly.relayout = function relayout(gd, astr, val) {
23462358
Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]);
23472359
}
23482360

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

2352-
// coerce the updated layout
2353-
Plots.supplyDefaults(gd);
2354-
2355-
// calculate autosizing
2356-
if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, gd._fullLayout);
2357-
2358-
// avoid unnecessary redraws
2359-
var changed = aobj.height || aobj.width ||
2360-
(gd._fullLayout.width !== oldWidth) ||
2361-
(gd._fullLayout.height !== oldHeight);
2362-
if(changed) docalc = true;
2365+
if(aobj.height || aobj.width || aobj.autosize) docalc = true;
23632366

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

23852389
if(dolegend) {
@@ -2488,6 +2492,86 @@ Plotly.purge = function purge(gd) {
24882492
return gd;
24892493
};
24902494

2495+
/**
2496+
* Reduce all reserved margin objects to a single required margin reservation.
2497+
*
2498+
* @param {Object} margins
2499+
* @returns {{left: number, right: number, bottom: number, top: number}}
2500+
*/
2501+
function calculateReservedMargins(margins) {
2502+
var resultingMargin = {left: 0, right: 0, bottom: 0, top: 0},
2503+
marginName;
2504+
2505+
if(margins) {
2506+
for(marginName in margins) {
2507+
if(margins.hasOwnProperty(marginName)) {
2508+
resultingMargin.left += margins[marginName].left || 0;
2509+
resultingMargin.right += margins[marginName].right || 0;
2510+
resultingMargin.bottom += margins[marginName].bottom || 0;
2511+
resultingMargin.top += margins[marginName].top || 0;
2512+
}
2513+
}
2514+
}
2515+
return resultingMargin;
2516+
}
2517+
2518+
function plotAutoSize(gd, aobj) {
2519+
var fullLayout = gd._fullLayout,
2520+
context = gd._context,
2521+
computedStyle;
2522+
2523+
var newHeight, newWidth;
2524+
2525+
gd.emit('plotly_autosize');
2526+
2527+
// embedded in an iframe - just take the full iframe size
2528+
// if we get to this point, with no aspect ratio restrictions
2529+
if(gd._context.fillFrame) {
2530+
newWidth = window.innerWidth;
2531+
newHeight = window.innerHeight;
2532+
2533+
// somehow we get a few extra px height sometimes...
2534+
// just hide it
2535+
document.body.style.overflow = 'hidden';
2536+
}
2537+
else if(isNumeric(context.frameMargins) && context.frameMargins > 0) {
2538+
var reservedMargins = calculateReservedMargins(gd._boundingBoxMargins),
2539+
reservedWidth = reservedMargins.left + reservedMargins.right,
2540+
reservedHeight = reservedMargins.bottom + reservedMargins.top,
2541+
gdBB = fullLayout._container.node().getBoundingClientRect(),
2542+
factor = 1 - 2 * context.frameMargins;
2543+
2544+
newWidth = Math.round(factor * (gdBB.width - reservedWidth));
2545+
newHeight = Math.round(factor * (gdBB.height - reservedHeight));
2546+
}
2547+
else {
2548+
// plotly.js - let the developers do what they want, either
2549+
// provide height and width for the container div,
2550+
// specify size in layout, or take the defaults,
2551+
// but don't enforce any ratio restrictions
2552+
computedStyle = window.getComputedStyle(gd);
2553+
newHeight = parseFloat(computedStyle.height) || fullLayout.height;
2554+
newWidth = parseFloat(computedStyle.width) || fullLayout.width;
2555+
}
2556+
2557+
if(Math.abs(fullLayout.width - newWidth) > 1 ||
2558+
Math.abs(fullLayout.height - newHeight) > 1) {
2559+
fullLayout.height = gd.layout.height = newHeight;
2560+
fullLayout.width = gd.layout.width = newWidth;
2561+
}
2562+
// if there's no size change, update layout but
2563+
// delete the autosize attr so we don't redraw
2564+
// but can't call layoutStyles for initial autosize
2565+
else if(fullLayout.autosize !== 'initial') {
2566+
delete(aobj.autosize);
2567+
fullLayout.autosize = gd.layout.autosize = true;
2568+
}
2569+
2570+
Plots.sanitizeMargins(fullLayout);
2571+
2572+
return aobj;
2573+
}
2574+
24912575
// -------------------------------------------------------
24922576
// makePlotFramework: Create the plot container and axes
24932577
// -------------------------------------------------------
@@ -2507,6 +2591,13 @@ function makePlotFramework(gd) {
25072591
.classed('svg-container', true)
25082592
.style('position', 'relative');
25092593

2594+
// Initial autosize
2595+
if(fullLayout.autosize === 'initial') {
2596+
plotAutoSize(gd, {});
2597+
fullLayout.autosize = true;
2598+
gd.layout.autosize = true;
2599+
}
2600+
25102601
// Make the graph containers
25112602
// start fresh each time we get here, so we know the order comes out
25122603
// right, rather than enter/exit which can muck up the order

src/plot_api/plot_config.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ module.exports = {
2626
// we can edit titles, move annotations, etc
2727
editable: false,
2828

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

3332
// if we DO autosize, do we fill the container or the screen?

src/plots/layout_attributes.js

+5-9
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,13 @@ module.exports = {
4545
description: 'Sets the title font.'
4646
}),
4747
autosize: {
48-
valType: 'boolean',
48+
valType: 'enumerated',
4949
role: 'info',
50-
dflt: false,
50+
// TODO: better handling of 'initial'
51+
values: [true, false, 'initial'],
5152
description: [
52-
'Determines whether or not a layout width or height',
53-
'that has been left undefined by the user',
54-
'is initialized on each relayout.',
55-
56-
'Note that, regardless of this attribute,',
57-
'an undefined layout width or height',
58-
'is always initialized on the first call to plot.'
53+
'Determines whether or not the dimensions of the figure are',
54+
'computed as a function of the display size.'
5955
].join(' ')
6056
},
6157
width: {

0 commit comments

Comments
 (0)