Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Revert "Remove internal option layout.autosize='initial' (Fixes #537)" by etpinard · Pull Request #633 · plotly/plotly.js · GitHub
Skip to content
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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