Skip to content

Commit 216164f

Browse files
authored
Merge pull request #2773 from plotly/emit-afterplot-on-edits
Emit 'plotly_afterplot' on all edits
2 parents 390a8f8 + cb92d7c commit 216164f

File tree

4 files changed

+55
-16
lines changed

4 files changed

+55
-16
lines changed

src/plot_api/plot_api.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ exports.plot = function(gd, data, layout, config) {
152152
Plots.supplyDefaults(gd);
153153

154154
var fullLayout = gd._fullLayout;
155-
156155
var hasCartesian = fullLayout._has('cartesian');
157156

158157
// Legacy polar plots
@@ -375,11 +374,21 @@ exports.plot = function(gd, data, layout, config) {
375374
if(!plotDone || !plotDone.then) plotDone = Promise.resolve();
376375

377376
return plotDone.then(function() {
378-
gd.emit('plotly_afterplot');
377+
emitAfterPlot(gd);
379378
return gd;
380379
});
381380
};
382381

382+
function emitAfterPlot(gd) {
383+
var fullLayout = gd._fullLayout;
384+
385+
if(fullLayout._redrawFromAutoMarginCount) {
386+
fullLayout._redrawFromAutoMarginCount--;
387+
} else {
388+
gd.emit('plotly_afterplot');
389+
}
390+
}
391+
383392
exports.setPlotConfig = function setPlotConfig(obj) {
384393
return Lib.extendFlat(defaultConfig, obj);
385394
};
@@ -1327,6 +1336,8 @@ exports.restyle = function restyle(gd, astr, val, _traces) {
13271336

13281337
if(flags.style) seq.push(subroutines.doTraceStyle);
13291338
if(flags.colorbars) seq.push(subroutines.doColorBars);
1339+
1340+
seq.push(emitAfterPlot);
13301341
}
13311342

13321343
seq.push(Plots.rehover);
@@ -1704,6 +1715,8 @@ exports.relayout = function relayout(gd, astr, val) {
17041715
if(flags.ticks) seq.push(subroutines.doTicksRelayout);
17051716
if(flags.modebar) seq.push(subroutines.doModeBar);
17061717
if(flags.camera) seq.push(subroutines.doCamera);
1718+
1719+
seq.push(emitAfterPlot);
17071720
}
17081721

17091722
seq.push(Plots.rehover);
@@ -2191,6 +2204,8 @@ exports.update = function update(gd, traceUpdate, layoutUpdate, _traces) {
21912204
if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout);
21922205
if(relayoutFlags.modebar) seq.push(subroutines.doModeBar);
21932206
if(relayoutFlags.camera) seq.push(subroutines.doCamera);
2207+
2208+
seq.push(emitAfterPlot);
21942209
}
21952210

21962211
seq.push(Plots.rehover);
@@ -2348,6 +2363,7 @@ exports.react = function(gd, data, layout, config) {
23482363
if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout);
23492364
if(relayoutFlags.modebar) seq.push(subroutines.doModeBar);
23502365
if(relayoutFlags.camera) seq.push(subroutines.doCamera);
2366+
seq.push(emitAfterPlot);
23512367
}
23522368

23532369
seq.push(Plots.rehover);

src/plot_api/subroutines.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var cleanAxisConstraints = axisConstraints.clean;
2828
var doAutoRange = require('../plots/cartesian/autorange').doAutoRange;
2929

3030
exports.layoutStyles = function(gd) {
31-
return Lib.syncOrAsync([Plots.doAutoMargin, exports.lsInner], gd);
31+
return Lib.syncOrAsync([Plots.doAutoMargin, lsInner], gd);
3232
};
3333

3434
function overlappingDomain(xDomain, yDomain, domains) {
@@ -46,7 +46,7 @@ function overlappingDomain(xDomain, yDomain, domains) {
4646
return false;
4747
}
4848

49-
exports.lsInner = function(gd) {
49+
function lsInner(gd) {
5050
var fullLayout = gd._fullLayout;
5151
var gs = fullLayout._size;
5252
var pad = gs.p;
@@ -327,7 +327,7 @@ exports.lsInner = function(gd) {
327327
ModeBar.manage(gd);
328328

329329
return gd._promises.length && Promise.all(gd._promises);
330-
};
330+
}
331331

332332
function findMainSubplot(ax, fullLayout) {
333333
var subplotList = fullLayout._subplots;

src/plots/plots.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -1788,8 +1788,15 @@ plots.doAutoMargin = function(gd) {
17881788
gs.h = Math.round(fullLayout.height) - gs.t - gs.b;
17891789

17901790
// if things changed and we're not already redrawing, trigger a redraw
1791-
if(!fullLayout._replotting && oldmargins !== '{}' &&
1792-
oldmargins !== JSON.stringify(fullLayout._size)) {
1791+
if(!fullLayout._replotting &&
1792+
oldmargins !== '{}' &&
1793+
oldmargins !== JSON.stringify(fullLayout._size)
1794+
) {
1795+
if('_redrawFromAutoMarginCount' in fullLayout) {
1796+
fullLayout._redrawFromAutoMarginCount++;
1797+
} else {
1798+
fullLayout._redrawFromAutoMarginCount = 1;
1799+
}
17931800
return Registry.call('plot', gd);
17941801
}
17951802
};

test/jasmine/tests/plot_api_test.js

+25-9
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ describe('Test plot api', function() {
539539

540540
supplyAllDefaults(gd);
541541
Plots.doCalcdata(gd);
542+
gd.emit = function() {};
542543
return gd;
543544
}
544545

@@ -699,6 +700,7 @@ describe('Test plot api', function() {
699700
gd.calcdata = gd._fullData.map(function(trace) {
700701
return [{x: 1, y: 1, trace: trace}];
701702
});
703+
gd.emit = function() {};
702704
}
703705

704706
it('calls Scatter.arraysToCalcdata and Plots.style on scatter styling', function() {
@@ -2566,11 +2568,14 @@ describe('Test plot api', function() {
25662568
];
25672569

25682570
var gd;
2569-
var plotCalls;
2571+
var afterPlotCnt;
25702572

25712573
beforeEach(function() {
25722574
gd = createGraphDiv();
25732575

2576+
spyOn(plotApi, 'plot').and.callThrough();
2577+
spyOn(Registry, 'call').and.callThrough();
2578+
25742579
mockedMethods.forEach(function(m) {
25752580
spyOn(subroutines, m).and.callThrough();
25762581
subroutines[m].calls.reset();
@@ -2584,13 +2589,14 @@ describe('Test plot api', function() {
25842589
afterEach(destroyGraphDiv);
25852590

25862591
function countPlots() {
2587-
plotCalls = 0;
2588-
2589-
gd.on('plotly_afterplot', function() { plotCalls++; });
2592+
plotApi.plot.calls.reset();
25902593
subroutines.layoutStyles.calls.reset();
25912594
annotations.draw.calls.reset();
25922595
annotations.drawOne.calls.reset();
25932596
images.draw.calls.reset();
2597+
2598+
afterPlotCnt = 0;
2599+
gd.on('plotly_afterplot', function() { afterPlotCnt++; });
25942600
}
25952601

25962602
function countCalls(counts) {
@@ -2602,8 +2608,14 @@ describe('Test plot api', function() {
26022608
subroutines[m].calls.reset();
26032609
});
26042610

2605-
expect(plotCalls).toBe(counts.plot || 0, 'calls to Plotly.plot');
2606-
plotCalls = 0;
2611+
// calls to Plotly.plot via plot_api.js or Registry.call('plot')
2612+
var plotCalls = plotApi.plot.calls.count() +
2613+
Registry.call.calls.all()
2614+
.filter(function(d) { return d.args[0] === 'plot'; })
2615+
.length;
2616+
expect(plotCalls).toBe(counts.plot || 0, 'Plotly.plot calls');
2617+
plotApi.plot.calls.reset();
2618+
Registry.call.calls.reset();
26072619

26082620
// only consider annotation and image draw calls if we *don't* do a full plot.
26092621
if(!counts.plot) {
@@ -2614,6 +2626,9 @@ describe('Test plot api', function() {
26142626
annotations.draw.calls.reset();
26152627
annotations.drawOne.calls.reset();
26162628
images.draw.calls.reset();
2629+
2630+
expect(afterPlotCnt).toBe(1, 'plotly_afterplot should be called only once per edit');
2631+
afterPlotCnt = 0;
26172632
}
26182633

26192634
it('can add / remove traces', function(done) {
@@ -2654,14 +2669,14 @@ describe('Test plot api', function() {
26542669
.then(function() {
26552670
// didn't pick it up, as we modified in place!!!
26562671
expect(d3.selectAll('.point').size()).toBe(3);
2672+
countCalls({plot: 0});
26572673

26582674
data[0].y = [1, 2, 3, 4, 5];
26592675
return Plotly.react(gd, data, layout);
26602676
})
26612677
.then(function() {
26622678
// new object, we picked it up!
26632679
expect(d3.selectAll('.point').size()).toBe(5);
2664-
26652680
countCalls({plot: 1});
26662681
})
26672682
.catch(failTest)
@@ -2683,6 +2698,7 @@ describe('Test plot api', function() {
26832698
.then(function() {
26842699
// didn't pick it up, as we didn't modify datarevision
26852700
expect(d3.selectAll('.point').size()).toBe(3);
2701+
countCalls({plot: 0});
26862702

26872703
data[0].y.push(5);
26882704
layout.datarevision = 'bananas';
@@ -2869,7 +2885,7 @@ describe('Test plot api', function() {
28692885
sizex: 1,
28702886
sizey: 1
28712887
}];
2872-
Plotly.react(gd, data, layout);
2888+
return Plotly.react(gd, data, layout);
28732889
})
28742890
.then(function() {
28752891
countCalls({imageDraw: 1});
@@ -2883,7 +2899,7 @@ describe('Test plot api', function() {
28832899

28842900
layout.images[0].y = 0.8;
28852901
layout.images[0].sizey = 0.4;
2886-
Plotly.react(gd, data, layout);
2902+
return Plotly.react(gd, data, layout);
28872903
})
28882904
.then(function() {
28892905
countCalls({imageDraw: 1});

0 commit comments

Comments
 (0)