Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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" + '
Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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('^' + ".*" + ' Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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('^' + ".*" + ' Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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" + ' Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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('^' + ".*" + ' Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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('^' + ".*" + ' Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco
, '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); } })(); })(); Refactor plot autosize by etpinard · Pull Request #635 · plotly/plotly.js · GitHub
Skip to content

Refactor plot autosize - #635

Merged
etpinard merged 7 commits into
masterfrom
autosize-refactor
Oct 27, 2016
Merged

Refactor plot autosize#635
etpinard merged 7 commits into
masterfrom
autosize-refactor

Conversation

@etpinard

@etpinardetpinard commented Jun 13, 2016

Copy link
Copy Markdown
Contributor

fixes#537

This PR sets up a base branch for the in-progress autosize refactor starting out by @n-riesco in #577 patched in #629 and then reverted in #633.

Important comments:

Comment threadsrc/lib/index.js
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.

@mdtusz

Copy link
Copy Markdown
Contributor

💃

@etpinard

Copy link
Copy Markdown
ContributorAuthor

dropping this PR from the v1.17.0 milestone because of the numerous merge conflict left to fix ... and let's face it, we're due for a minor bump.

@etpinardetpinard added this to the v1.18.0 milestone Sep 8, 2016
@etpinardetpinard self-assigned this Sep 8, 2016
@fresheneesz

Copy link
Copy Markdown

@etpinard

I created some logic that finds the maximum size an element can be sized to without exceeding the boundaries of its parent. It takes into account margins, borders, padding, percentage widths, max-height/width, and sibling nodes. You can find it here: http://stackoverflow.com/a/39782139/122422

I think this is something that would help autosizing work better, since currently using autosizing seems to frequently exceed the boundaries of the graph's parent.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Dropping from the v1.18.0 milestone.

This will be implemented in v1.19.0 together with layout breakpoints.

@etpinardetpinard modified the milestones: v1.18.0, v1.19.0Oct 9, 2016
@sarendipitee

Copy link
Copy Markdown

I'm super interested in this PR. Is there anything I can contribute?

I am trying to use Plotly in a Flex layout and Plotly is not playing nicely. The major problem is Plotly's use of explicit width/height in pixels. Doing this makes an implicit size on the chart that will then cause the flex layout to never go less than size.

Here's an example pen: http://codepen.io/JonDum/pen/gwEPPA

If you resize horizontally you'll notice that it will grow larger, but never smaller.

If you look at how Chartist.js handles this, they default to setting the <svg> element to a width/height of 100% and they automatically scale to their container's size (which you can see on their demo page)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I (finally) resurrected your PR 🎉

To preserve backward compatibility, I had to add two commits:

  • 77971f4 adds a hacky block in relayout to make sure this relayout case still passes. It's not pretty, but only a few lines. I hope you don't mind.
  • b6c5610 is a little trickier and very important. This commit ensures that graphs with no set width and height have a default autosize of true. Previously, graphs with no set width and height were given the 'initial' autosize value (see here).

I hope you find these two commits compatible with what you had in mind for this PR.

@n-riesco

n-riesco commented Oct 26, 2016

Copy link
Copy Markdown
Contributor

Looks like github didn't get my email. Here's a copy:


On 26/10/16 18:50, Étienne Tétreault-Pinard wrote:

I don't understand how this commit works.

If I read it correctly, something like Plotly.relayout(gd, { width: null }) would be equivalent to Plotly.relayout(gd, { width: 'initial' }).

Since 'initial' is an invalid width, this would make gd._fullLayout.width = 700 (i.e. the default width value).

Would the following work instead?

if(['width','height'].indexOf(ai)!==-1&&vi===null){deletegd._fullLayout._initialAutoSizeIsDone;}

I can look into this tomorrow.


I think this behaviour is better (and necessary to fix #537)

@etpinard

etpinard commented Oct 26, 2016

Copy link
Copy Markdown
ContributorAuthor

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

I think this behaviour is better

By this, you meant behaviour after my last commit (b6c5610) ?

(and necessary to fix #537)

The tests you added to fix #537 are still passing, anything else I should try to confirm that #537 is still fixed?

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco

Would the following work instead?

if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
delete gd._fullLayout._initialAutoSizeIsDone;
}

Let me try. Thanks!

Replacing 77971f4 with your suggestion makes the aforementioned relayout test case fail.

The reason being:

  • clearing _fullLayout._initialAutoSizeDone leads to a plotAutosize call which (in the default context) reaches this line where the new width/height are taken from the DOM
  • The problem is: those width/height value come from the previous relayout call, so line by line:
it('sets null values to their default',function(done){vardefaultWidth;Plotly.plot(gd,[{x: [1,2,3],y: [1,2,3]}]).then(function(){defaultWidth=gd._fullLayout.width;defaultWidth// => 700returnPlotly.relayout(gd,{width: defaultWidth-25});}).then(function(){gd._fullLayout.width// => 675expect(gd._fullLayout.width).toBe(defaultWidth-25);returnPlotly.relayout(gd,{width: null});}).then(function(){gd._fullLayout.width// => 675 BUT should 700 !!expect(gd._fullLayout.width).toBe(defaultWidth);}).then(done);});

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Now, by setting width: 'initial' in relayout in the hacky block of 77971f4, Plots.supplyDefaults now reaches this line, where newLayout.width isn't reset to its old value as 'initial' is truthy. Instead, newLayout.width is set back to its default value of 700.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

Perhaps a better solution would be to cache the initial graph div width / height computed styles and use them in relayout.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco here's a less hacky (I think) fix: 8396018

Let me know what you think.

@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco commit 08069a4 implements an even less hacky solution (I think we now have the correct answer to what relayout should do).

Let me know what you think.

- so that relayout(gd, 'width', null) reset the
graph to its initial width
@etpinard

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I took your 👍 reaction on #635 (comment) as a sign of approval. Commit 5fb7cd1 implement the cache-initial-autosize solution.

@etpinard
etpinard merged commit e01cb00 into masterOct 27, 2016
@etpinard
etpinard deleted the autosize-refactor branch October 27, 2016 14:59
@etpinardetpinard mentioned this pull request Mar 5, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugsomething broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

newPlot doesn't respect layout.height unless layout.autosize is explicitly true

5 participants

@etpinard@mdtusz@fresheneesz@sarendipitee@n-riesco