@@ -659,80 +659,88 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
659659 // affected by this drag, and update them. look for all plots
660660 // sharing an affected axis (including the one being dragged)
661661 function updateSubplots ( viewBox ) {
662- var j ;
663- var plotinfos = fullLayout . _plots ,
664- subplots = Object . keys ( plotinfos ) ;
662+ var plotinfos = fullLayout . _plots ;
663+ var subplots = Object . keys ( plotinfos ) ;
664+ var xScaleFactor = viewBox [ 2 ] / xa [ 0 ] . _length ;
665+ var yScaleFactor = viewBox [ 3 ] / ya [ 0 ] . _length ;
666+ var editX = ew || isSubplotConstrained ;
667+ var editY = ns || isSubplotConstrained ;
668+
669+ var i , xScaleFactor2 , yScaleFactor2 , clipDx , clipDy ;
670+
671+ // Find the appropriate scaling for this axis, if it's linked to the
672+ // dragged axes by constraints. 0 is special, it means this axis shouldn't
673+ // ever be scaled (will be converted to 1 if the other axis is scaled)
674+ function getLinkedScaleFactor ( ax ) {
675+ if ( ax . fixedrange ) return 0 ;
676+
677+ if ( editX && xaLinked . indexOf ( ax ) !== - 1 ) {
678+ return xScaleFactor ;
679+ }
680+ if ( editY && ( isSubplotConstrained ? xaLinked : yaLinked ) . indexOf ( ax ) !== - 1 ) {
681+ return yScaleFactor ;
682+ }
683+ return 0 ;
684+ }
685+
686+ function scaleAndGetShift ( ax , scaleFactor ) {
687+ if ( scaleFactor ) {
688+ ax . range = ax . _r . slice ( ) ;
689+ scaleZoom ( ax , scaleFactor ) ;
690+ return ax . _length * ( 1 - scaleFactor ) / 2 ;
691+ }
692+ return 0 ;
693+ }
665694
666- for ( var i = 0 ; i < subplots . length ; i ++ ) {
695+ for ( i = 0 ; i < subplots . length ; i ++ ) {
667696
668697 var subplot = plotinfos [ subplots [ i ] ] ,
669698 xa2 = subplot . xaxis ,
670699 ya2 = subplot . yaxis ,
671- editX = ( viewBox [ 0 ] !== 0 || viewBox [ 2 ] !== pw ) && ! xa2 . fixedrange ,
672- editY = ( viewBox [ 1 ] !== 0 || viewBox [ 3 ] !== ph ) && ! ya2 . fixedrange ;
673-
674- if ( editX ) {
675- // TODO: now that we're doing recomputeAxisLists can this be turned into
676- // just xa.indexOf(xa2) !== -1?
677- var isInX = false ;
678- for ( j = 0 ; j < xa . length ; j ++ ) {
679- if ( xa [ j ] . _id === xa2 . _id ) {
680- isInX = true ;
681- break ;
682- }
683- }
684- editX = editX && isInX ;
685- }
700+ editX2 = editX && ! xa2 . fixedrange && ( xa . indexOf ( xa2 ) !== - 1 ) ,
701+ editY2 = editY && ! ya2 . fixedrange && ( ya . indexOf ( ya2 ) !== - 1 ) ;
686702
687- if ( editY ) {
688- var isInY = false ;
689- for ( j = 0 ; j < ya . length ; j ++ ) {
690- if ( ya [ j ] . _id === ya2 . _id ) {
691- isInY = true ;
692- break ;
693- }
694- }
695- editY = editY && isInY ;
703+ if ( editX2 ) {
704+ xScaleFactor2 = xScaleFactor ;
705+ clipDx = viewBox [ 0 ] ;
706+ }
707+ else {
708+ xScaleFactor2 = getLinkedScaleFactor ( xa2 ) ;
709+ clipDx = scaleAndGetShift ( xa2 , xScaleFactor2 ) ;
696710 }
697711
698- var xScaleFactor = editX ? viewBox [ 2 ] / xa2 . _length : 1 ,
699- yScaleFactor = editY ? viewBox [ 3 ] / ya2 . _length : 1 ;
700-
701- var clipDx = editX ? viewBox [ 0 ] : 0 ,
702- clipDy = editY ? viewBox [ 1 ] : 0 ;
703-
704- // modify these if needed for linked axes
705- if ( editX && ! editY && xaLinked . indexOf ( ya2 ) !== - 1 ) {
706- yScaleFactor = xScaleFactor ;
707- clipDy = ya2 . _length * ( 1 - yScaleFactor ) / 2 ;
708-
709- // update range for the linked axis.
710- ya2 . range = ya2 . _r . slice ( ) ;
711- scaleZoom ( ya2 , yScaleFactor ) ;
712+ if ( editY2 ) {
713+ yScaleFactor2 = yScaleFactor ;
714+ clipDy = viewBox [ 1 ] ;
712715 }
713- if ( editY && ! editX && ( isSubplotConstrained ? xaLinked : yaLinked ) . indexOf ( xa2 ) !== - 1 ) {
714- xScaleFactor = yScaleFactor ;
715- clipDx = xa2 . _length * ( 1 - xScaleFactor ) / 2 ;
716- xa2 . range = xa2 . _r . slice ( ) ;
717- scaleZoom ( xa2 , xScaleFactor ) ;
716+ else {
717+ yScaleFactor2 = getLinkedScaleFactor ( ya2 ) ;
718+ clipDy = scaleAndGetShift ( ya2 , yScaleFactor2 ) ;
718719 }
719720
720- var plotDx = xa2 . _offset - clipDx / xScaleFactor ,
721- plotDy = ya2 . _offset - clipDy / yScaleFactor ;
721+ // don't scale at all if neither axis is scalable here
722+ if ( ! xScaleFactor2 && ! yScaleFactor2 ) continue ;
723+
724+ // but if only one is, reset the other axis scaling
725+ if ( ! xScaleFactor2 ) xScaleFactor2 = 1 ;
726+ if ( ! yScaleFactor2 ) yScaleFactor2 = 1 ;
727+
728+ var plotDx = xa2 . _offset - clipDx / xScaleFactor2 ,
729+ plotDy = ya2 . _offset - clipDy / yScaleFactor2 ;
722730
723731 fullLayout . _defs . selectAll ( '#' + subplot . clipId )
724732 . call ( Drawing . setTranslate , clipDx , clipDy )
725- . call ( Drawing . setScale , xScaleFactor , yScaleFactor ) ;
733+ . call ( Drawing . setScale , xScaleFactor2 , yScaleFactor2 ) ;
726734
727735 subplot . plot
728736 . call ( Drawing . setTranslate , plotDx , plotDy )
729- . call ( Drawing . setScale , 1 / xScaleFactor , 1 / yScaleFactor )
737+ . call ( Drawing . setScale , 1 / xScaleFactor2 , 1 / yScaleFactor2 )
730738
731739 // This is specifically directed at scatter traces, applying an inverse
732740 // scale to individual points to counteract the scale of the trace
733741 // as a whole:
734742 . select ( '.scatterlayer' ) . selectAll ( '.points' ) . selectAll ( '.point' )
735- . call ( Drawing . setPointGroupScale , xScaleFactor , yScaleFactor ) ;
743+ . call ( Drawing . setPointGroupScale , xScaleFactor2 , yScaleFactor2 ) ;
736744 }
737745 }
738746
0 commit comments