@@ -64,6 +64,54 @@ function directionEnabled(mode, dir, chart) {
64
64
return false ;
65
65
}
66
66
67
+ /** This function use for check what axis now under mouse cursor.
68
+ * @param {number } [x] X position
69
+ * @param {number } [y] Y position
70
+ * @param {import('chart.js').Chart } [chart] instance of the chart in question
71
+ */
72
+ function getScaleUnderPoint ( x , y , chart ) {
73
+ var scales = chart . scales ;
74
+ var scaleIds = Object . keys ( scales ) ;
75
+ for ( var i = 0 ; i < scaleIds . length ; i ++ ) {
76
+ var scale = scales [ scaleIds [ i ] ] ;
77
+ if ( y >= scale . top && y <= scale . bottom && x >= scale . left && x <= scale . right ) {
78
+ return scale ;
79
+ }
80
+ }
81
+ return null ;
82
+ }
83
+
84
+ /** This function return only one scale whose position is under mouse cursor and which direction is enabled.
85
+ * If under mouse hasn't scale, then return all other scales which 'mode' is diffrent with overScaleMode.
86
+ * So 'overScaleMode' works as a limiter to scale the user-selected scale (in 'mode') only when the cursor is under the scale,
87
+ * and other directions in 'mode' works as before.
88
+ * Example: mode = 'xy', overScaleMode = 'y' -> it's means 'x' - works as before, and 'y' only works for one scale when cursor is under it.
89
+ * options.overScaleMode can be a function if user want zoom only one scale of many for example.
90
+ * @param {any } [options] pan or zoom options
91
+ * @param {number } [x] X position
92
+ * @param {number } [y] Y position
93
+ * @param {import('chart.js').Chart } [chart] instance of the chart in question
94
+ */
95
+ function getEnabledScalesByPoint ( options , x , y , chart ) {
96
+ if ( options . enabled && options . overScaleMode ) {
97
+ var scale = getScaleUnderPoint ( x , y , chart ) ;
98
+ var mode = typeof options . overScaleMode === 'function' ? options . overScaleMode ( { chart : chart } , scale ) : options . overScaleMode ;
99
+
100
+ if ( scale && directionEnabled ( mode , scale . axis , chart ) ) {
101
+ return [ scale ] ;
102
+ }
103
+
104
+ var enabledScales = [ ] ;
105
+ each ( chart . scales , function ( scaleItem ) {
106
+ if ( ! directionEnabled ( mode , scaleItem . axis , chart ) ) {
107
+ enabledScales . push ( scaleItem ) ;
108
+ }
109
+ } ) ;
110
+ return enabledScales ;
111
+ }
112
+ return null ;
113
+ }
114
+
67
115
function rangeMaxLimiter ( zoomPanOptions , newMax ) {
68
116
if ( zoomPanOptions . scaleAxes && zoomPanOptions . rangeMax &&
69
117
! isNullOrUndef ( zoomPanOptions . rangeMax [ zoomPanOptions . scaleAxes ] ) ) {
@@ -164,7 +212,13 @@ function doZoom(chart, percentZoomX, percentZoomY, focalPoint, whichAxes, animat
164
212
_whichAxes = 'xy' ;
165
213
}
166
214
215
+ var enabledScales = getEnabledScalesByPoint ( zoomOptions , focalPoint . x , focalPoint . y , chart ) ;
216
+
167
217
each ( chart . scales , function ( scale ) {
218
+ if ( enabledScales && enabledScales . indexOf ( scale ) === - 1 ) {
219
+ return ;
220
+ }
221
+
168
222
if ( scale . isHorizontal ( ) && directionEnabled ( zoomMode , 'x' , chart ) && directionEnabled ( _whichAxes , 'x' , chart ) ) {
169
223
zoomOptions . scaleAxes = 'x' ;
170
224
zoomScale ( scale , percentZoomX , focalPoint , zoomOptions ) ;
@@ -245,13 +299,17 @@ function panScale(scale, delta, panOptions) {
245
299
}
246
300
}
247
301
248
- function doPan ( chartInstance , deltaX , deltaY ) {
302
+ function doPan ( chartInstance , deltaX , deltaY , panningScales ) {
249
303
storeOriginalOptions ( chartInstance ) ;
250
304
var panOptions = chartInstance . $zoom . _options . pan ;
251
305
if ( panOptions . enabled ) {
252
306
var panMode = typeof panOptions . mode === 'function' ? panOptions . mode ( { chart : chartInstance } ) : panOptions . mode ;
253
307
254
308
each ( chartInstance . scales , function ( scale ) {
309
+ if ( panningScales && panningScales . indexOf ( scale ) === - 1 ) {
310
+ return ;
311
+ }
312
+
255
313
if ( scale . isHorizontal ( ) && directionEnabled ( panMode , 'x' , chartInstance ) && deltaX !== 0 ) {
256
314
panOptions . scaleAxes = 'x' ;
257
315
panScale ( scale , deltaX , panOptions ) ;
@@ -538,24 +596,33 @@ var zoomPlugin = {
538
596
var currentDeltaX = null ;
539
597
var currentDeltaY = null ;
540
598
var panning = false ;
599
+ var panningScales = null ;
541
600
var handlePan = function ( e ) {
542
601
if ( currentDeltaX !== null && currentDeltaY !== null ) {
543
602
panning = true ;
544
603
var deltaX = e . deltaX - currentDeltaX ;
545
604
var deltaY = e . deltaY - currentDeltaY ;
546
605
currentDeltaX = e . deltaX ;
547
606
currentDeltaY = e . deltaY ;
548
- doPan ( chartInstance , deltaX , deltaY ) ;
607
+ doPan ( chartInstance , deltaX , deltaY , panningScales ) ;
549
608
}
550
609
} ;
551
610
552
611
mc . on ( 'panstart' , function ( e ) {
612
+ if ( panOptions . enabled ) {
613
+ var rect = e . target . getBoundingClientRect ( ) ;
614
+ var x = e . center . x - rect . left ;
615
+ var y = e . center . y - rect . top ;
616
+ panningScales = getEnabledScalesByPoint ( panOptions , x , y , chartInstance ) ;
617
+ }
618
+
553
619
currentDeltaX = 0 ;
554
620
currentDeltaY = 0 ;
555
621
handlePan ( e ) ;
556
622
} ) ;
557
623
mc . on ( 'panmove' , handlePan ) ;
558
624
mc . on ( 'panend' , function ( ) {
625
+ panningScales = null ;
559
626
currentDeltaX = null ;
560
627
currentDeltaY = null ;
561
628
setTimeout ( function ( ) {
0 commit comments