@@ -189,67 +189,58 @@ module.exports = function setConvert(ax, fullLayout) {
189189 } ;
190190
191191 if ( ax . breaks ) {
192- if ( axLetter === 'y' ) {
193- l2p = function ( v ) {
194- if ( ! isNumeric ( v ) ) return BADNUM ;
195- if ( ! ax . _breaks . length ) return _l2p ( v , ax . _m , ax . _b ) ;
196-
197- var b = ax . _B [ 0 ] ;
198- for ( var i = 0 ; i < ax . _breaks . length ; i ++ ) {
199- var brk = ax . _breaks [ i ] ;
200- if ( v <= brk . min ) b = ax . _B [ i + 1 ] ;
201- else if ( v > brk . min && v < brk . max ) {
202- // when v falls into break, pick offset 'closest' to it
203- if ( v - brk . min <= brk . max - v ) b = ax . _B [ i + 1 ] ;
204- else b = ax . _B [ i ] ;
205- break ;
206- } else if ( v > brk . max ) break ;
207- }
208- return _l2p ( v , - ax . _m2 , b ) ;
209- } ;
210- p2l = function ( px ) {
211- if ( ! isNumeric ( px ) ) return BADNUM ;
212- if ( ! ax . _breaks . length ) return _p2l ( px , ax . _m , ax . _b ) ;
213-
214- var b = ax . _B [ 0 ] ;
215- for ( var i = 0 ; i < ax . _breaks . length ; i ++ ) {
216- var brk = ax . _breaks [ i ] ;
217- if ( px >= brk . pmin ) b = ax . _B [ i + 1 ] ;
218- else if ( px < brk . pmax ) break ;
219- }
220- return _p2l ( px , - ax . _m2 , b ) ;
221- } ;
222- } else {
223- l2p = function ( v ) {
224- if ( ! isNumeric ( v ) ) return BADNUM ;
225- if ( ! ax . _breaks . length ) return _l2p ( v , ax . _m , ax . _b ) ;
226-
227- var b = ax . _B [ 0 ] ;
228- for ( var i = 0 ; i < ax . _breaks . length ; i ++ ) {
229- var brk = ax . _breaks [ i ] ;
230- if ( v >= brk . max ) b = ax . _B [ i + 1 ] ;
231- else if ( v > brk . min && v < brk . max ) {
232- // when v falls into break, pick offset 'closest' to it
233- if ( v - brk . min <= brk . max - v ) b = ax . _B [ i ] ;
234- else b = ax . _B [ i + 1 ] ;
235- break ;
236- } else if ( v < brk . min ) break ;
192+ l2p = function ( v ) {
193+ if ( ! isNumeric ( v ) ) return BADNUM ;
194+ var len = ax . _breaks . length ;
195+ if ( ! len ) return _l2p ( v , ax . _m , ax . _b ) ;
196+
197+ var isY = axLetter === 'y' ;
198+ var pos = isY ? - v : v ;
199+
200+ var q = 0 ;
201+ for ( var i = 0 ; i < len ; i ++ ) {
202+ var nextI = i + 1 ;
203+ var brk = ax . _breaks [ i ] ;
204+
205+ var min = isY ? - brk . max : brk . min ;
206+ var max = isY ? - brk . min : brk . max ;
207+
208+ if ( pos < min ) break ;
209+ if ( pos > max ) q = nextI ;
210+ else {
211+ // when falls into break, pick 'closest' offset
212+ q = pos > ( min + max ) / 2 ? nextI : i ;
213+ break ;
237214 }
238- return _l2p ( v , ax . _m2 , b ) ;
239- } ;
240- p2l = function ( px ) {
241- if ( ! isNumeric ( px ) ) return BADNUM ;
242- if ( ! ax . _breaks . length ) return _p2l ( px , ax . _m , ax . _b ) ;
243-
244- var b = ax . _B [ 0 ] ;
245- for ( var i = 0 ; i < ax . _breaks . length ; i ++ ) {
246- var brk = ax . _breaks [ i ] ;
247- if ( px >= brk . pmax ) b = ax . _B [ i + 1 ] ;
248- else if ( px < brk . pmin ) break ;
215+ }
216+ return _l2p ( v , ( isY ? - 1 : 1 ) * ax . _m2 , ax . _B [ q ] ) ;
217+ } ;
218+
219+ p2l = function ( px ) {
220+ if ( ! isNumeric ( px ) ) return BADNUM ;
221+ var len = ax . _breaks . length ;
222+ if ( ! len ) return _p2l ( px , ax . _m , ax . _b ) ;
223+
224+ var isY = axLetter === 'y' ;
225+ var pos = isY ? - px : px ;
226+
227+ var q = 0 ;
228+ for ( var i = 0 ; i < len ; i ++ ) {
229+ var nextI = i + 1 ;
230+ var brk = ax . _breaks [ i ] ;
231+
232+ var min = isY ? - brk . pmax : brk . pmin ;
233+ var max = isY ? - brk . pmin : brk . pmax ;
234+
235+ if ( pos < min ) break ;
236+ if ( pos > max ) q = nextI ;
237+ else {
238+ q = i ;
239+ break ;
249240 }
250- return _p2l ( px , ax . _m2 , b ) ;
251- } ;
252- }
241+ }
242+ return _p2l ( px , ( isY ? - 1 : 1 ) * ax . _m2 , ax . _B [ q ] ) ;
243+ } ;
253244 }
254245
255246 // conversions among c/l/p are fairly simple - do them together for all axis types
@@ -561,7 +552,7 @@ module.exports = function setConvert(ax, fullLayout) {
561552
562553 // set of "N" disjoint breaks inside the range
563554 ax . _breaks = [ ] ;
564- // length of these breaks in value space
555+ // length of these breaks in value space - negative on reversed axes
565556 ax . _lBreaks = 0 ;
566557 // l2p slope (same for all intervals)
567558 ax . _m2 = 0 ;
@@ -575,12 +566,13 @@ module.exports = function setConvert(ax, fullLayout) {
575566 Math . min ( rl0 , rl1 ) ,
576567 Math . max ( rl0 , rl1 )
577568 ) ;
578- var signAx = rl0 > rl1 ? - 1 : 1 ;
569+ var axReverse = rl0 > rl1 ;
570+ var signAx = axReverse ? - 1 : 1 ;
579571
580572 if ( ax . _breaks . length ) {
581573 for ( i = 0 ; i < ax . _breaks . length ; i ++ ) {
582574 brk = ax . _breaks [ i ] ;
583- ax . _lBreaks += ( brk . max - brk . min ) ;
575+ ax . _lBreaks += brk . max - brk . min ;
584576 }
585577
586578 ax . _m2 = ax . _length / ( rl1 - rl0 - ax . _lBreaks * signAx ) ;
@@ -597,17 +589,16 @@ module.exports = function setConvert(ax, fullLayout) {
597589 brk = ax . _breaks [ i ] ;
598590 ax . _B . push ( ax . _B [ ax . _B . length - 1 ] - ax . _m2 * ( brk . max - brk . min ) * signAx ) ;
599591 }
600-
601- if ( signAx === - 1 ) {
592+ if ( axReverse ) {
602593 ax . _B . reverse ( ) ;
603594 }
604595
605596 // fill pixel (i.e. 'p') min/max here,
606597 // to not have to loop through the _breaks twice during `p2l`
607598 for ( i = 0 ; i < ax . _breaks . length ; i ++ ) {
608599 brk = ax . _breaks [ i ] ;
609- brk . pmin = l2p ( brk . min ) ;
610- brk . pmax = l2p ( brk . max ) ;
600+ brk . pmin = l2p ( axReverse ? brk . max : brk . min ) ;
601+ brk . pmax = l2p ( axReverse ? brk . min : brk . max ) ;
611602 }
612603 }
613604 }
0 commit comments