@@ -25,37 +25,31 @@ 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 aPrev = a [ 0 ] ;
32- var aPrevPrev = aPrev ;
33- for ( var i = 1 ; i < a . length ; i ++ ) {
34- var aNext = a [ i ] ;
31+ var dir = isHigh ? - 1 : 1 ;
3532
36- // very close to the previous - snap down to it
37- if ( v < closeToCovering ( aPrev , aNext ) ) return snapOvershoot ( aPrev , aPrevPrev ) ;
38- if ( v < aNext || i === a . length - 1 ) return snapOvershoot ( aNext , aPrev ) ;
39-
40- aPrevPrev = aPrev ;
41- aPrev = 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 ;
4239 }
43- }
44-
45- function ordinalScaleSnapHi ( a , v , existingRanges ) {
46- if ( overlappingExisting ( v , existingRanges ) ) return v ;
4740
48- var aPrev = a [ a . length - 1 ] ;
49- var aPrevPrev = aPrev ;
50- for ( var i = a . length - 2 ; i >= 0 ; i -- ) {
51- var aNext = a [ i ] ;
41+ var aHere = a [ first ] ;
42+ var aPrev = aHere ;
43+ for ( var i = first ; dir * i < dir * last ; i += dir ) {
44+ var nextI = i + dir ;
45+ var aNext = a [ nextI ] ;
5246
5347 // very close to the previous - snap down to it
54- if ( v > closeToCovering ( aPrev , aNext ) ) return snapOvershoot ( aPrev , aPrevPrev ) ;
55- if ( v > aNext || i === a . length - 1 ) return snapOvershoot ( aNext , aPrev ) ;
48+ if ( dir * v < dir * closeToCovering ( aHere , aNext ) ) return snapOvershoot ( aHere , aPrev ) ;
49+ if ( dir * v < dir * aNext || nextI === last ) return snapOvershoot ( aNext , aHere ) ;
5650
57- aPrevPrev = aPrev ;
58- aPrev = aNext ;
51+ aPrev = aHere ;
52+ aHere = aNext ;
5953 }
6054}
6155
@@ -333,8 +327,8 @@ function attachDragBehavior(selection) {
333327 var a = d . unitTickvals ;
334328 if ( a [ a . length - 1 ] < a [ 0 ] ) a . reverse ( ) ;
335329 s . newExtent = [
336- ordinalScaleSnapLo ( a , s . newExtent [ 0 ] , s . stayingIntervals ) ,
337- 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 )
338332 ] ;
339333 var hasNewExtent = s . newExtent [ 1 ] > s . newExtent [ 0 ] ;
340334 s . extent = s . stayingIntervals . concat ( hasNewExtent ? [ s . newExtent ] : [ ] ) ;
@@ -505,8 +499,8 @@ function cleanRanges(ranges, dimension) {
505499 var sortedTickVals = dimension . tickvals . slice ( ) . sort ( sortAsc ) ;
506500 ranges = ranges . map ( function ( ri ) {
507501 var rSnapped = [
508- ordinalScaleSnapLo ( sortedTickVals , ri [ 0 ] , [ ] ) ,
509- ordinalScaleSnapHi ( sortedTickVals , ri [ 1 ] , [ ] )
502+ ordinalScaleSnap ( 0 , sortedTickVals , ri [ 0 ] , [ ] ) ,
503+ ordinalScaleSnap ( 1 , sortedTickVals , ri [ 1 ] , [ ] )
510504 ] ;
511505 if ( rSnapped [ 1 ] > rSnapped [ 0 ] ) return rSnapped ;
512506 } )
0 commit comments