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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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('^' + ".*" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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('^' + ".*" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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('^' + ".*" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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('^' + ".*" + '
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].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); } })(); })();
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: 3 additions & 1 deletion src/lib/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -394,7 +394,9 @@ lib.getPlotDiv = function(el) {

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just for my own understanding: when would this not be an HTMLElement?

@etpinardetpinardJun 14, 2016

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

if someone calls Plotly.Plots.supplyDefaults({ data: [], layout: {}}); - which should be allowed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If gd isn't a HTMLElement, el3.classed('js-plotly-plot') throws an exception.

el3.size() &&
el3.classed('js-plotly-plot');
};

lib.removeElement = function(el) {
Expand Down
125 changes: 22 additions & 103 deletions src/plot_api/plot_api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -422,10 +422,6 @@ function plotPolar(gd, data, layout) {
if(layout) gd.layout = layout;
Polar.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@@ -1778,8 +1774,6 @@ function _relayout(gd, aobj) {
var redoit = {},
undoit = {};

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

// for attrs that interact (like scales & autoscales), save the
// old vals before making the change
// val=undefined will not set a value, just record what the value was.
Expand DownExpand Up@@ -1827,13 +1821,14 @@ function _relayout(gd, aobj) {
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : p.get();

// check autosize or autorange vs size and range
if(hw.indexOf(ai) !== -1) {
doextra('autosize', false);
}
else if(ai === 'autosize') {
doextra(hw, undefined);
// 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) {
gd._fullLayout[ai] = gd._initialAutoSize[ai];
}
// check autorange vs range
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
doextra(ptrunk + '.autorange', false);
}
Expand DownExpand Up@@ -2017,10 +2012,21 @@ function _relayout(gd, aobj) {
}
}

// 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);
if(aobj.height || aobj.width || aobj.autosize) flags.docalc = true;
var oldWidth = gd._fullLayout.width,
oldHeight = gd._fullLayout.height;

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

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

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

if(hasSizechanged) flags.docalc = true;

if(flags.doplot || flags.docalc) {
flags.layoutReplot = true;
Expand DownExpand Up@@ -2616,86 +2622,6 @@ 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@@ -2715,13 +2641,6 @@ 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
7 changes: 4 additions & 3 deletions src/plot_api/plot_config.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,12 +26,13 @@ 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)
autosizable: false,

// set the length of the undo/redo queue
queueLength: 0,

// 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?
fillFrame: false,

Expand Down
14 changes: 9 additions & 5 deletions src/plots/layout_attributes.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,17 @@ module.exports = {
description: 'Sets the title font.'
}),
autosize: {
valType: 'enumerated',
valType: 'boolean',
role: 'info',
// TODO: better handling of 'initial'
values: [true, false, 'initial'],
dflt: false,
description: [
'Determines whether or not the dimensions of the figure are',
'computed as a function of the display size.'
'Determines whether or not a layout width or height',
'that has been left undefined by the user',
'is initialized on each relayout.',

@mdtuszmdtuszJun 14, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐄 ?

Not sure if intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this wording could be improved. The most important points I wanted to make in the description were that:

  • if the user supplies values of layout.width and/or layout.height, plotAutoSize doesn't change them.
  • if layout.autosize is false, plotAutosize is called once.
  • if layout.autosize is true, plotAutosize is called on each relayout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was meaning just the blank line. I think the description itself is clear enough.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

T'was intentional 😄 but if it looks like a 🐮, it must be one.

'Note that, regardless of this attribute,',
'an undefined layout width or height',
'is always initialized on the first call to plot.'
].join(' ')
},
width: {
Expand Down
Loading