@@ -21,6 +21,7 @@ var Drawing = require('../../components/drawing');
21
21
var setCursor = require ( '../../lib/setcursor' ) ;
22
22
var dragElement = require ( '../../components/dragelement' ) ;
23
23
var FROM_TL = require ( '../../constants/alignment' ) . FROM_TL ;
24
+ var Axes = require ( '../../plots/cartesian/axes' ) ;
24
25
25
26
var Plots = require ( '../plots' ) ;
26
27
@@ -363,6 +364,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
363
364
return Lib . pauseEvent ( e ) ;
364
365
}
365
366
367
+ // If autoscaleYAxis, then disable y axis scale:
368
+ if ( gd . _context . autoscaleYAxis ) {
369
+ ns = '' ;
370
+ }
371
+
366
372
var pc = gd . querySelector ( '.plotly' ) ;
367
373
368
374
recomputeAxisLists ( ) ;
@@ -662,6 +668,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
662
668
// ticksAndAnnotations again - it's unnecessary and would overwrite `updates`
663
669
updateSubplots ( [ 0 , 0 , pw , ph ] ) ;
664
670
671
+ // change Y axis range and overwrite 'updates'
672
+ if ( gd . _context . autoscaleYAxis ) {
673
+ autoscaleYAxis ( ) ;
674
+ }
675
+
665
676
// since we may have been redrawing some things during the drag, we may have
666
677
// accumulated MathJax promises - wait for them before we relayout.
667
678
Lib . syncOrAsync ( [
@@ -770,6 +781,70 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
770
781
}
771
782
}
772
783
784
+ // Find new range for y axis according new x axis range
785
+ function autoscaleYAxis ( ) {
786
+ var plotinfos = fullLayout . _plots ;
787
+ var subplots = Object . keys ( plotinfos ) ;
788
+ var i ;
789
+ for ( i = 0 ; i < subplots . length ; i ++ ) {
790
+ var subplot = plotinfos [ subplots [ i ] ] ;
791
+ var ya = subplot . yaxis ;
792
+ var xa = subplot . xaxis ;
793
+ var xRange = [ updates [ xa . _name + '.range[0]' ] , updates [ xa . _name + '.range[1]' ] ] ;
794
+ var fitData = [ ] ;
795
+ var traces = subplot . plot . selectAll ( '.trace' ) ;
796
+ var newRange ;
797
+
798
+ traces . call ( processTraces , subplot , xRange , fitData ) ;
799
+
800
+ if ( fitData . length ) {
801
+ ya . _min = [ ] ;
802
+ ya . _max = [ ] ;
803
+ ya . autorange = true ;
804
+ Axes . expand ( ya , fitData , { padded : true } ) ;
805
+ newRange = Axes . getAutoRange ( ya ) ;
806
+ updates [ ya . _name + '.range[0]' ] = newRange [ 0 ] ;
807
+ updates [ ya . _name + '.range[1]' ] = newRange [ 1 ] ;
808
+
809
+ // Do not change y range if only one point is on the screen
810
+ if ( fitData . length === 1 ) {
811
+ updates [ ya . _name + '.range[0]' ] = ya . range [ 0 ] ;
812
+ updates [ ya . _name + '.range[1]' ] = ya . range [ 1 ] ;
813
+ }
814
+ }
815
+ }
816
+ }
817
+
818
+ function processTraces ( traces , subplot , newRange , result ) {
819
+ traces . each ( function ( d ) {
820
+ getDataInRange ( d , subplot , newRange , result ) ;
821
+ } ) ;
822
+ }
823
+
824
+ // Find data points within the x axis range to build y range
825
+ function getDataInRange ( data , subplot , newRange , result ) {
826
+ var xa = subplot . xaxis ;
827
+
828
+ data . forEach ( function ( d ) {
829
+ isPtWithinRange ( xa , d , newRange ) ? result . push ( d . y ) : null ;
830
+ } ) ;
831
+ }
832
+
833
+ function isPtWithinRange ( ax , d , newRange ) {
834
+ var data = d . x ;
835
+ var reversed = newRange [ 0 ] > newRange [ 1 ] ;
836
+
837
+ if ( ax . type === 'date' ) {
838
+ data = ax . l2d ( data ) ;
839
+ } else if ( ax . type === 'log' ) {
840
+ data = ax . c2r ( data ) ;
841
+ }
842
+
843
+ return reversed ?
844
+ data >= newRange [ 1 ] && data <= newRange [ 0 ] :
845
+ data >= newRange [ 0 ] && data <= newRange [ 1 ] ;
846
+ }
847
+
773
848
return dragger ;
774
849
} ;
775
850
0 commit comments