@@ -184,6 +184,9 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
184184 zb ,
185185 corners ;
186186
187+ // collected changes to be made to the plot by relayout at the end
188+ var updates = { } ;
189+
187190 function zoomPrep ( e , startX , startY ) {
188191 var dragBBox = dragger . getBoundingClientRect ( ) ;
189192 x0 = startX - dragBBox . left ;
@@ -282,8 +285,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
282285 }
283286
284287 // TODO: edit linked axes in zoomAxRanges and in dragTail
285- if ( zoomMode === 'xy' || zoomMode === 'x' ) zoomAxRanges ( xa , box . l / pw , box . r / pw , xaLinked ) ;
286- if ( zoomMode === 'xy' || zoomMode === 'y' ) zoomAxRanges ( ya , ( ph - box . b ) / ph , ( ph - box . t ) / ph , yaLinked ) ;
288+ if ( zoomMode === 'xy' || zoomMode === 'x' ) zoomAxRanges ( xa , box . l / pw , box . r / pw , updates , xaLinked ) ;
289+ if ( zoomMode === 'xy' || zoomMode === 'y' ) zoomAxRanges ( ya , ( ph - box . b ) / ph , ( ph - box . t ) / ph , updates , yaLinked ) ;
287290
288291 removeZoombox ( gd ) ;
289292 dragTail ( zoomMode ) ;
@@ -335,11 +338,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
335338 }
336339
337340 // scroll zoom, on all draggers except corners
338- var scrollViewBox = [ 0 , 0 , pw , ph ] ,
339- // wait a little after scrolling before redrawing
340- redrawTimer = null ,
341- REDRAWDELAY = constants . REDRAWDELAY ,
342- mainplot = plotinfo . mainplot ?
341+ var scrollViewBox = [ 0 , 0 , pw , ph ] ;
342+ // wait a little after scrolling before redrawing
343+ var redrawTimer = null ;
344+ var REDRAWDELAY = constants . REDRAWDELAY ;
345+ var mainplot = plotinfo . mainplot ?
343346 fullLayout . _plots [ plotinfo . mainplot ] : plotinfo ;
344347
345348 function zoomWheel ( e ) {
@@ -524,6 +527,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
524527 ticksAndAnnotations ( yActive , xActive ) ;
525528 }
526529
530+ // Draw ticks and annotations (and other components) when ranges change.
531+ // Also records the ranges that have changed for use by update at the end.
527532 function ticksAndAnnotations ( ns , ew ) {
528533 var activeAxIds = [ ] ,
529534 i ;
@@ -543,8 +548,12 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
543548 pushActiveAxIds ( yaLinked ) ;
544549 }
545550
551+ updates = { } ;
546552 for ( i = 0 ; i < activeAxIds . length ; i ++ ) {
547- doTicks ( gd , activeAxIds [ i ] , true ) ;
553+ var axId = activeAxIds [ i ] ;
554+ doTicks ( gd , axId , true ) ;
555+ var ax = getFromId ( gd , axId ) ;
556+ updates [ ax . _name + '.range' ] = ax . range . slice ( ) ;
548557 }
549558
550559 function redrawObjs ( objArray , method , shortCircuit ) {
@@ -641,29 +650,17 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
641650 function dragTail ( zoommode ) {
642651 if ( zoommode === undefined ) zoommode = ( ew ? 'x' : '' ) + ( ns ? 'y' : '' ) ;
643652
644- var attrs = { } ;
645- // revert to the previous axis settings, then apply the new ones
646- // through relayout - this lets relayout manage undo/redo
647- var axesToModify ;
648- if ( zoommode === 'xy' ) axesToModify = xa . concat ( ya ) ;
649- else if ( zoommode === 'x' ) axesToModify = xa ;
650- else if ( zoommode === 'y' ) axesToModify = ya ;
651-
652- for ( var i = 0 ; i < axesToModify . length ; i ++ ) {
653- var axi = axesToModify [ i ] ;
654- if ( axi . _r [ 0 ] !== axi . range [ 0 ] ) attrs [ axi . _name + '.range[0]' ] = axi . range [ 0 ] ;
655- if ( axi . _r [ 1 ] !== axi . range [ 1 ] ) attrs [ axi . _name + '.range[1]' ] = axi . range [ 1 ] ;
656-
657- axi . range = axi . _input . range = axi . _r . slice ( ) ;
658- }
659-
653+ // put the subplot viewboxes back to default (Because we're going to)
654+ // be repositioning the data in the relayout. But DON'T call
655+ // ticksAndAnnotations again - it's unnecessary and would overwrite `updates`
660656 updateSubplots ( [ 0 , 0 , pw , ph ] ) ;
661- Plotly . relayout ( gd , attrs ) ;
657+ Plotly . relayout ( gd , updates ) ;
662658 }
663659
664660 // updateSubplots - find all plot viewboxes that should be
665661 // affected by this drag, and update them. look for all plots
666662 // sharing an affected axis (including the one being dragged)
663+ // returns all the new axis ranges as an update object
667664 function updateSubplots ( viewBox ) {
668665 var plotinfos = fullLayout . _plots ;
669666 var subplots = Object . keys ( plotinfos ) ;
@@ -674,6 +671,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
674671
675672 var i , xScaleFactor2 , yScaleFactor2 , clipDx , clipDy ;
676673
674+ var attrs = { } ;
675+
677676 // Find the appropriate scaling for this axis, if it's linked to the
678677 // dragged axes by constraints. 0 is special, it means this axis shouldn't
679678 // ever be scaled (will be converted to 1 if the other axis is scaled)
@@ -693,6 +692,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
693692 if ( scaleFactor ) {
694693 ax . range = ax . _r . slice ( ) ;
695694 scaleZoom ( ax , scaleFactor ) ;
695+ attrs [ ax . _name + '.range' ] = ax . range . slice ( ) ;
696696 return getShift ( ax , scaleFactor ) ;
697697 }
698698 return 0 ;
@@ -758,6 +758,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
758758 . selectAll ( '.points' ) . selectAll ( '.textpoint' )
759759 . call ( Drawing . setTextPointsScale , xScaleFactor2 , yScaleFactor2 ) ;
760760 }
761+
762+ return attrs ;
761763 }
762764
763765 return dragger ;
@@ -806,7 +808,7 @@ function getEndText(ax, end) {
806808 }
807809}
808810
809- function zoomAxRanges ( axList , r0Fraction , r1Fraction , linkedAxes ) {
811+ function zoomAxRanges ( axList , r0Fraction , r1Fraction , updates , linkedAxes ) {
810812 var i ,
811813 axi ,
812814 axRangeLinear0 ,
@@ -822,13 +824,14 @@ function zoomAxRanges(axList, r0Fraction, r1Fraction, linkedAxes) {
822824 axi . l2r ( axRangeLinear0 + axRangeLinearSpan * r0Fraction ) ,
823825 axi . l2r ( axRangeLinear0 + axRangeLinearSpan * r1Fraction )
824826 ] ;
827+ updates [ axi . _name + '.range' ] = axi . range . slice ( ) ;
825828 }
826829
827830 // zoom linked axes about their centers
828831 if ( linkedAxes && linkedAxes . length ) {
829832 var linkedR0Fraction = ( r0Fraction + ( 1 - r1Fraction ) ) / 2 ;
830833
831- zoomAxRanges ( linkedAxes , linkedR0Fraction , 1 - linkedR0Fraction ) ;
834+ zoomAxRanges ( linkedAxes , linkedR0Fraction , 1 - linkedR0Fraction , updates ) ;
832835 }
833836}
834837
0 commit comments