diff --git a/src/plots/cartesian/transition_axes.js b/src/plots/cartesian/transition_axes.js index 2994b07efe9..42591e49217 100644 --- a/src/plots/cartesian/transition_axes.js +++ b/src/plots/cartesian/transition_axes.js @@ -100,7 +100,23 @@ module.exports = function transitionAxes(gd, newLayout, transitionOpts, makeOnCo var updatedAxisIds = Object.keys(updates); var affectedSubplots = computeAffectedSubplots(fullLayout, updatedAxisIds, updates); + function updateLayoutObjs() { + function redrawObjs(objArray, method, shortCircuit) { + for(var i = 0; i < objArray.length; i++) { + method(gd, i); + + // once is enough for images (which doesn't use the `i` arg anyway) + if(shortCircuit) return; + } + } + + redrawObjs(fullLayout.annotations || [], Registry.getComponentMethod('annotations', 'drawOne')); + redrawObjs(fullLayout.shapes || [], Registry.getComponentMethod('shapes', 'drawOne')); + redrawObjs(fullLayout.images || [], Registry.getComponentMethod('images', 'draw'), true); + } + if(!affectedSubplots.length) { + updateLayoutObjs(); return false; } @@ -114,7 +130,7 @@ module.exports = function transitionAxes(gd, newLayout, transitionOpts, makeOnCo Axes.doTicks(gd, activeAxIds[i], true); } - function redrawObjs(objArray, method) { + function redrawObjs(objArray, method, shortCircuit) { for(i = 0; i < objArray.length; i++) { var obji = objArray[i]; @@ -122,15 +138,15 @@ module.exports = function transitionAxes(gd, newLayout, transitionOpts, makeOnCo (activeAxIds.indexOf(obji.yref) !== -1)) { method(gd, i); } + + // once is enough for images (which doesn't use the `i` arg anyway) + if(shortCircuit) return; } } - // annotations and shapes 'draw' method is slow, - // use the finer-grained 'drawOne' method instead - redrawObjs(fullLayout.annotations || [], Registry.getComponentMethod('annotations', 'drawOne')); redrawObjs(fullLayout.shapes || [], Registry.getComponentMethod('shapes', 'drawOne')); - redrawObjs(fullLayout.images || [], Registry.getComponentMethod('images', 'draw')); + redrawObjs(fullLayout.images || [], Registry.getComponentMethod('images', 'draw'), true); } function unsetSubplotTransform(subplot) { @@ -202,7 +218,6 @@ module.exports = function transitionAxes(gd, newLayout, transitionOpts, makeOnCo ticksAndAnnotations(subplot.xaxis, subplot.yaxis); - var xa2 = subplot.xaxis; var ya2 = subplot.yaxis; diff --git a/test/jasmine/tests/annotations_test.js b/test/jasmine/tests/annotations_test.js index 485b8b78474..cad65de3123 100644 --- a/test/jasmine/tests/annotations_test.js +++ b/test/jasmine/tests/annotations_test.js @@ -1344,3 +1344,83 @@ describe('annotation effects', function() { .then(done); }); }); + +describe('animating annotations', function() { + var gd; + + // Two slightly different 1x1 pngs: + var img1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQYV2P4z/C/HgAGfgJ+p8YU1AAAAABJRU5ErkJggg=='; + var img2 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQYV2P4//9/PQAJewN9w0ic/wAAAABJRU5ErkJggg=='; + + beforeEach(function() { + gd = createGraphDiv(); + }); + + afterEach(destroyGraphDiv); + + it('updates annoations when no axis update present', function(done) { + + function assertAnnotations(expected) { + var texts = Plotly.d3.select(gd).selectAll('.annotation .annotation-text'); + expect(expected.length).toEqual(texts.size()); + + texts.each(function(d, i) { + expect(Plotly.d3.select(this).text()).toEqual(expected[i]); + }); + } + + function assertShapes(expected) { + var paths = Plotly.d3.select(gd).selectAll('.shapelayer path'); + + expect(expected.length).toEqual(paths.size()); + + paths.each(function(d, i) { + expect(Plotly.d3.select(this).style('fill')).toEqual(expected[i]); + }); + } + + function assertImages(expected) { + var imgs = Plotly.d3.select(gd).selectAll('.imagelayer image'); + + expect(expected.length).toEqual(imgs.size()); + + imgs.each(function(d, i) { + expect(Plotly.d3.select(this).attr('href')).toEqual(expected[i]); + }); + } + + Plotly.plot(gd, + [{y: [1, 2, 3]}], + { + annotations: [{text: 'hello'}], + shapes: [{fillcolor: 'rgb(170, 170, 170)'}], + images: [{source: img1}] + } + ).then(function() { + assertAnnotations(['hello']); + assertShapes(['rgb(170, 170, 170)']); + assertImages([img1]); + + return Plotly.animate(gd, [{ + layout: { + annotations: [{text: 'hi'}], + shapes: [ + {fillcolor: 'rgb(171, 171, 171)'}, + {fillcolor: 'rgb(172, 172, 172)'} + ], + images: [{source: img2}] + } + }], { + frame: {redraw: false, duration: 0} + }); + }).then(function() { + assertAnnotations(['hi']); + assertShapes([ + 'rgb(171, 171, 171)', + 'rgb(172, 172, 172)' + ]); + assertImages([img2]); + + }).catch(failTest).then(done); + }); +});