Skip to content

Commit 87d47f3

Browse files
committed
fix css style of container to properly resize in flexbox and grid
1 parent 67a05c7 commit 87d47f3

File tree

4 files changed

+87
-24
lines changed

4 files changed

+87
-24
lines changed

src/plot_api/plot_api.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3195,6 +3195,9 @@ function makePlotFramework(gd) {
31953195
var gd3 = d3.select(gd);
31963196
var fullLayout = gd._fullLayout;
31973197

3198+
// Check if gd has a specified height
3199+
fullLayout._hasZeroHeight = gd.clientHeight === 0;
3200+
31983201
// Plot container
31993202
fullLayout._container = gd3.selectAll('.plot-container').data([0]);
32003203
fullLayout._container.enter().insert('div', ':first-child')

src/plot_api/subroutines.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ function lsInner(gd) {
105105

106106
fullLayout._paperdiv
107107
.style({
108-
width: fullLayout.width + 'px',
109-
height: fullLayout.height + 'px'
108+
width: (fullLayout.autosize) ? '100%' : fullLayout.width + 'px',
109+
height: (fullLayout.autosize && !fullLayout._hasZeroHeight) ? '100%' : fullLayout.height + 'px'
110110
})
111111
.selectAll('.main-svg')
112112
.call(Drawing.setSize, fullLayout.width, fullLayout.height);

src/plots/plots.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,11 +1371,10 @@ plots.plotAutoSize = function plotAutoSize(gd, layout, fullLayout) {
13711371
reservedHeight = reservedMargins.bottom + reservedMargins.top,
13721372
factor = 1 - 2 * frameMargins;
13731373

1374-
var gdBB = fullLayout._container && fullLayout._container.node ?
1375-
fullLayout._container.node().getBoundingClientRect() : {
1376-
width: fullLayout.width,
1377-
height: fullLayout.height
1378-
};
1374+
var gdBB = {
1375+
width: fullLayout.width,
1376+
height: fullLayout.height
1377+
};
13791378

13801379
newWidth = Math.round(factor * (gdBB.width - reservedWidth));
13811380
newHeight = Math.round(factor * (gdBB.height - reservedHeight));

test/jasmine/tests/config_test.js

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -543,23 +543,26 @@ describe('config argument', function() {
543543
});
544544

545545
describe('responsive figure', function() {
546-
var gd;
547-
var startWidth = 960, startHeight = 400;
548-
var newWidth = 400, newHeight = 700;
549-
var data = [{x: [1, 2, 3, 4], y: [5, 10, 2, 8]}];
546+
var gd, data = [{x: [1, 2, 3, 4], y: [5, 10, 2, 8]}];
547+
var width = 960, height = 800;
548+
549+
var parent, elWidth, elHeight;
550550

551551
beforeEach(function() {
552-
viewport.set(startWidth, startHeight);
553-
gd = createGraphDiv();
552+
viewport.set(width, height);
554553

555-
// Make the graph fill the parent
556-
gd.style.width = '100%';
557-
gd.style.height = '100%';
554+
// Prepare a parent container that fills the viewport
555+
parent = document.createElement('div');
556+
parent.style.width = '100vw';
557+
parent.style.height = '100vh';
558+
parent.style.position = 'fixed';
559+
parent.style.top = '0';
560+
parent.style.left = '0';
558561
});
559562

560563
afterEach(function() {
561564
Plotly.purge(gd); // Needed to remove all event listeners
562-
destroyGraphDiv();
565+
document.body.removeChild(parent);
563566
viewport.reset();
564567
});
565568

@@ -573,45 +576,64 @@ describe('config argument', function() {
573576
}
574577

575578
function testResponsive() {
576-
checkLayoutSize(startWidth, startHeight);
577-
viewport.set(newWidth, newHeight);
579+
checkLayoutSize(elWidth, elHeight);
580+
viewport.set(width / 2, height / 2);
578581

579582
return Promise.resolve()
580583
.then(delay(200))
581584
.then(function() {
582-
checkLayoutSize(newWidth, newHeight);
585+
checkLayoutSize(elWidth / 2, elHeight / 2);
583586
})
584587
.catch(failTest);
585588
}
586589

590+
function fillParent(numRows, numCols, cb) {
591+
elWidth = width / numCols, elHeight = height / numRows;
592+
593+
// Fill parent
594+
for(var i = 0; i < (numCols * numRows); i++) {
595+
var col = document.createElement('div');
596+
col.style.height = '100%';
597+
col.style.width = '100%';
598+
if(typeof(cb) === typeof(Function)) cb.call(col, i);
599+
parent.appendChild(col);
600+
}
601+
document.body.appendChild(parent);
602+
gd = parent.childNodes[0];
603+
}
604+
587605
it('should resize when the viewport width/height changes', function(done) {
606+
fillParent(1, 1);
588607
Plotly.plot(gd, data, {}, {responsive: true})
589608
.then(testResponsive)
590609
.then(done);
591610
});
592611

593612
it('should still be responsive if the plot is edited', function(done) {
613+
fillParent(1, 1);
594614
Plotly.plot(gd, data, {}, {responsive: true})
595615
.then(function() {return Plotly.restyle(gd, 'y[0]', data[0].y[0] + 2);})
596616
.then(testResponsive)
597617
.then(done);
598618
});
599619

600620
it('should still be responsive if the plot is purged and replotted', function(done) {
621+
fillParent(1, 1);
601622
Plotly.plot(gd, data, {}, {responsive: true})
602623
.then(function() {return Plotly.newPlot(gd, data, {}, {responsive: true});})
603624
.then(testResponsive)
604625
.then(done);
605626
});
606627

607628
it('should only have one resize handler when plotted more than once', function(done) {
629+
fillParent(1, 1);
608630
var cntWindowResize = 0;
609631
window.addEventListener('resize', function() {cntWindowResize++;});
610632
spyOn(Plotly.Plots, 'resize').and.callThrough();
611633

612634
Plotly.plot(gd, data, {}, {responsive: true})
613635
.then(function() {return Plotly.restyle(gd, 'y[0]', data[0].y[0] + 2);})
614-
.then(function() {viewport.set(newWidth, newHeight);})
636+
.then(function() {viewport.set(width / 2, width / 2);})
615637
.then(delay(200))
616638
// .then(function() {viewport.set(newWidth, 2 * newHeight);}).then(delay(200))
617639
.then(function() {
@@ -623,26 +645,65 @@ describe('config argument', function() {
623645
});
624646

625647
it('should become responsive if configured as such via Plotly.react', function(done) {
648+
fillParent(1, 1);
626649
Plotly.plot(gd, data, {}, {responsive: false})
627650
.then(function() {return Plotly.react(gd, data, {}, {responsive: true});})
628651
.then(testResponsive)
629652
.then(done);
630653
});
631654

632655
it('should stop being responsive if configured as such via Plotly.react', function(done) {
656+
fillParent(1, 1);
633657
Plotly.plot(gd, data, {}, {responsive: true})
634658
// Check initial size
635-
.then(function() {checkLayoutSize(startWidth, startHeight);})
659+
.then(function() {checkLayoutSize(width, height);})
636660
// Turn off responsiveness
637661
.then(function() {return Plotly.react(gd, data, {}, {responsive: false});})
638662
// Resize viewport
639-
.then(function() {viewport.set(newWidth, newHeight);})
663+
.then(function() {viewport.set(width / 2, height / 2);})
640664
// Wait for resize to happen (Plotly.resize has an internal timeout)
641665
.then(delay(200))
642666
// Check that final figure's size hasn't changed
643-
.then(function() {checkLayoutSize(startWidth, startHeight);})
667+
.then(function() {checkLayoutSize(width, height);})
644668
.catch(failTest)
645669
.then(done);
646670
});
671+
672+
// Testing fancier CSS layouts
673+
it('should resize horizontally in a flexbox when responsive: true', function(done) {
674+
parent.style.display = 'flex';
675+
parent.style.flexDirection = 'row';
676+
fillParent(1, 2, function() {
677+
this.style.flexGrow = '1';
678+
});
679+
680+
Plotly.plot(gd, data, {}, { responsive: true })
681+
.then(testResponsive)
682+
.then(done);
683+
});
684+
685+
it('should resize vertically in a flexbox when responsive: true', function(done) {
686+
parent.style.display = 'flex';
687+
parent.style.flexDirection = 'column';
688+
fillParent(2, 1, function() {
689+
this.style.flexGrow = '1';
690+
});
691+
692+
Plotly.plot(gd, data, {}, { responsive: true })
693+
.then(testResponsive)
694+
.then(done);
695+
});
696+
697+
it('should resize in both direction in a grid when responsive: true', function(done) {
698+
var numCols = 2, numRows = 2;
699+
parent.style.display = 'grid';
700+
parent.style.gridTemplateColumns = 'repeat(' + numCols + ', 1fr)';
701+
parent.style.gridTemplateRows = 'repeat(' + numRows + ', 1fr)';
702+
fillParent(numRows, numCols);
703+
704+
Plotly.plot(gd, data, {}, { responsive: true })
705+
.then(testResponsive)
706+
.then(done);
707+
});
647708
});
648709
});

0 commit comments

Comments
 (0)