diff --git a/docs/guide/developers.md b/docs/guide/developers.md index 41b9d053..63f57597 100644 --- a/docs/guide/developers.md +++ b/docs/guide/developers.md @@ -42,6 +42,10 @@ Returns the initial scale bounds of each scale before any zooming or panning too Returns whether the chart has been zoomed or panned - i.e. whether the initial scale of any axis is different to the one used currently. +### `chart.isZoomingOrPanning(): boolean` + +Returns whether the user is currently in the middle of a drag operation or pan operation. + ## Custom Scales You can extend chartjs-plugin-zoom with support for [custom scales](https://www.chartjs.org/docs/latest/developers/axes.html) by using the zoom plugin's `zoomFunctions`, `zoomRectFunctions`, and `panFunctions` members. These objects are indexed by scale types (scales' `id` members) and give optional handlers for zoom and pan functionality. diff --git a/src/core.js b/src/core.js index 77bd94c5..336fce6e 100644 --- a/src/core.js +++ b/src/core.js @@ -225,3 +225,8 @@ export function isZoomedOrPanned(chart) { return false; } + +export function isZoomingOrPanning(chart) { + const state = getState(chart); + return state.panning || state.dragging; +} diff --git a/src/plugin.js b/src/plugin.js index 0774f207..bd98b347 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -1,7 +1,7 @@ import Hammer from 'hammerjs'; import {addListeners, computeDragRect, removeListeners} from './handlers'; import {startHammer, stopHammer} from './hammer'; -import {pan, zoom, resetZoom, zoomScale, getZoomLevel, getInitialScaleBounds, isZoomedOrPanned, zoomRect} from './core'; +import {pan, zoom, resetZoom, zoomScale, getZoomLevel, getInitialScaleBounds, isZoomedOrPanned, isZoomingOrPanning, zoomRect} from './core'; import {panFunctions, zoomFunctions, zoomRectFunctions} from './scale.types'; import {getState, removeState} from './state'; import {version} from '../package.json'; @@ -83,11 +83,11 @@ export default { chart.getZoomLevel = () => getZoomLevel(chart); chart.getInitialScaleBounds = () => getInitialScaleBounds(chart); chart.isZoomedOrPanned = () => isZoomedOrPanned(chart); + chart.isZoomingOrPanning = () => isZoomingOrPanning(chart); }, beforeEvent(chart) { - const state = getState(chart); - if (state.panning || state.dragging) { + if (isZoomingOrPanning(chart)) { // cancel any event handling while panning or dragging return false; } diff --git a/src/state.js b/src/state.js index f0425cd9..274738ab 100644 --- a/src/state.js +++ b/src/state.js @@ -7,7 +7,9 @@ export function getState(chart) { originalScaleLimits: {}, updatedScaleLimits: {}, handlers: {}, - panDelta: {} + panDelta: {}, + dragging: false, + panning: false }; chartStates.set(chart, state); } diff --git a/test/specs/zoom.spec.js b/test/specs/zoom.spec.js index add2eb79..6656aa59 100644 --- a/test/specs/zoom.spec.js +++ b/test/specs/zoom.spec.js @@ -791,10 +791,19 @@ describe('zoom', function() { }; const pt2 = {x: pt.x + 20, y: pt.y + 20}; + expect(chart.isZoomingOrPanning()).toBe(false); + jasmine.dispatchEvent(chart, 'mousedown', pt); jasmine.dispatchEvent(chart, 'mousemove', pt2); + + expect(chart.isZoomingOrPanning()).toBe(true); + jasmine.dispatchEvent(chart, 'mouseup', pt2); + // Drag state isn't cleared until a timeout fires (later), so we can't + // easily test this here. + // expect(chart.isZoomingOrPanning()).toBe(false); + expect(startSpy).toHaveBeenCalled(); expect(zoomSpy).toHaveBeenCalled(); }); @@ -830,10 +839,17 @@ describe('zoom', function() { }; const pt2 = {x: pt.x + 20, y: pt.y + 20}; + expect(chart.isZoomingOrPanning()).toBe(false); + jasmine.dispatchEvent(chart, 'mousedown', pt); + + expect(chart.isZoomingOrPanning()).toBe(false); + jasmine.dispatchEvent(chart, 'mousemove', pt2); jasmine.dispatchEvent(chart, 'mouseup', pt2); + expect(chart.isZoomingOrPanning()).toBe(false); + expect(rejectSpy).toHaveBeenCalled(); expect(zoomSpy).not.toHaveBeenCalled(); expect(doneSpy).not.toHaveBeenCalled(); diff --git a/types/index.d.ts b/types/index.d.ts index c74d36ea..864ec453 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -27,6 +27,7 @@ declare module 'chart.js' { getZoomLevel(): number; getInitialScaleBounds(): Record; isZoomedOrPanned(): boolean; + isZoomingOrPanning(): boolean; } } @@ -56,3 +57,4 @@ export function resetZoom(chart: Chart, mode?: UpdateMode): void; export function getZoomLevel(chart: Chart): number; export function getInitialScaleBounds(chart: Chart): Record; export function isZoomedOrPanned(chart: Chart): boolean; +export function isZoomingOrPanning(chart: Chart): boolean;