@@ -25,36 +25,28 @@ function closeToCovering(v, vAdjacent) { return v * (1 - snapClose) + vAdjacent
2525// so it's clear we're covering it
2626// find the interval we're in, and snap to 1/4 the distance to the next
2727// these two could be unified at a slight loss of readability / perf
28- function ordinalScaleSnapLo ( a , v , existingRanges ) {
28+ function ordinalScaleSnap ( isHigh , a , v , existingRanges ) {
2929 if ( overlappingExisting ( v , existingRanges ) ) return v ;
3030
31- var aHere = a [ 0 ] ;
32- var aPrev = aHere ;
33- for ( var i = 0 ; i < a . length - 1 ; i ++ ) {
34- var nextI = i + 1 ;
35- var aNext = a [ nextI ] ;
31+ var dir = isHigh ? - 1 : 1 ;
3632
37- // very close to the previous - snap down to it
38- if ( v < closeToCovering ( aHere , aNext ) ) return snapOvershoot ( aHere , aPrev ) ;
39- if ( v < aNext || nextI === a . length - 1 ) return snapOvershoot ( aNext , aHere ) ;
40-
41- aPrev = aHere ;
42- aHere = aNext ;
33+ var first = 0 ;
34+ var last = a . length - 1 ;
35+ if ( dir < 0 ) {
36+ var tmp = first ;
37+ first = last ;
38+ last = tmp ;
4339 }
44- }
45-
46- function ordinalScaleSnapHi ( a , v , existingRanges ) {
47- if ( overlappingExisting ( v , existingRanges ) ) return v ;
4840
49- var aHere = a [ a . length - 1 ] ;
41+ var aHere = a [ first ] ;
5042 var aPrev = aHere ;
51- for ( var i = a . length - 1 ; i > 0 ; i -- ) {
52- var nextI = i - 1 ;
43+ for ( var i = first ; dir * i < dir * last ; i += dir ) {
44+ var nextI = i + dir ;
5345 var aNext = a [ nextI ] ;
5446
5547 // very close to the previous - snap down to it
56- if ( v > closeToCovering ( aHere , aNext ) ) return snapOvershoot ( aHere , aPrev ) ;
57- if ( v > aNext || nextI === 0 ) return snapOvershoot ( aNext , aHere ) ;
48+ if ( dir * v < dir * closeToCovering ( aHere , aNext ) ) return snapOvershoot ( aHere , aPrev ) ;
49+ if ( dir * v < dir * aNext || nextI === last ) return snapOvershoot ( aNext , aHere ) ;
5850
5951 aPrev = aHere ;
6052 aHere = aNext ;
@@ -335,8 +327,8 @@ function attachDragBehavior(selection) {
335327 var a = d . unitTickvals ;
336328 if ( a [ a . length - 1 ] < a [ 0 ] ) a . reverse ( ) ;
337329 s . newExtent = [
338- ordinalScaleSnapLo ( a , s . newExtent [ 0 ] , s . stayingIntervals ) ,
339- ordinalScaleSnapHi ( a , s . newExtent [ 1 ] , s . stayingIntervals )
330+ ordinalScaleSnap ( 0 , a , s . newExtent [ 0 ] , s . stayingIntervals ) ,
331+ ordinalScaleSnap ( 1 , a , s . newExtent [ 1 ] , s . stayingIntervals )
340332 ] ;
341333 var hasNewExtent = s . newExtent [ 1 ] > s . newExtent [ 0 ] ;
342334 s . extent = s . stayingIntervals . concat ( hasNewExtent ? [ s . newExtent ] : [ ] ) ;
@@ -507,8 +499,8 @@ function cleanRanges(ranges, dimension) {
507499 var sortedTickVals = dimension . tickvals . slice ( ) . sort ( sortAsc ) ;
508500 ranges = ranges . map ( function ( ri ) {
509501 var rSnapped = [
510- ordinalScaleSnapLo ( sortedTickVals , ri [ 0 ] , [ ] ) ,
511- ordinalScaleSnapHi ( sortedTickVals , ri [ 1 ] , [ ] )
502+ ordinalScaleSnap ( 0 , sortedTickVals , ri [ 0 ] , [ ] ) ,
503+ ordinalScaleSnap ( 1 , sortedTickVals , ri [ 1 ] , [ ] )
512504 ] ;
513505 if ( rSnapped [ 1 ] > rSnapped [ 0 ] ) return rSnapped ;
514506 } )
0 commit comments