Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const SCROLL_BAR_END_EVENT_NAME = `dxc-scroll-end${EVENTS_NS}`;

const GESTURE_TIMEOUT = 300;
const MIN_DRAG_DELTA = 5;
export const SCROLL_PREVENTION_TIMEOUT = 500;

const _min = Math.min;
const _max = Math.max;
Expand Down Expand Up @@ -129,6 +130,7 @@ export default {
init() {
const chart = this;
const renderer = this._renderer;
let lastWheelTimer: number | undefined;

function getAxesCopy(zoomAndPan, actionField) {
let axes = [];
Expand Down Expand Up @@ -307,13 +309,23 @@ export default {
return e.offset[coordField] - actionData.offset[coordField];
}

function preventDefaults(e) {
function setLastWheelTimer() {
clearTimeout(lastWheelTimer);
// eslint-disable-next-line no-restricted-globals
lastWheelTimer = setTimeout(() => {
lastWheelTimer = undefined;
}, SCROLL_PREVENTION_TIMEOUT) as unknown as number;
}

function preventDefaults(e, stopChartHandler = true): void {
if (e.cancelable !== false) {
e.preventDefault();
e.stopPropagation();
}

chart._stopCurrentHandling();
if (stopChartHandler) {
chart._stopCurrentHandling();
}
}

const zoomAndPan = {
Expand Down Expand Up @@ -536,12 +548,20 @@ export default {
axesZoomed |= canZoom && zoomAxes(e, chart._argumentAxes, getRange, e.delta > 0, { coord: rotated ? coords.y : coords.x }, chart.getArgumentAxis());
}

const isPanningAvailable = targetAxes ? isAxisAvailablePanning(targetAxes) : zoomAndPan.panningVisualRangeEnabled();

if (axesZoomed) {
chart._requestChange(['VISUAL_RANGE']);
if (targetAxes && isAxisAvailablePanning(targetAxes) || !targetAxes && zoomAndPan.panningVisualRangeEnabled()) {
if (isPanningAvailable) {
preventDefaults(e); // T249548
setLastWheelTimer();
}
}

if ((!axesZoomed || !isPanningAvailable) && lastWheelTimer) {
preventDefaults(e, false);
setLastWheelTimer();
}
},
cleanup() {
renderer.root.off(EVENTS_NS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import $ from 'jquery';
import pointerMock from '../../helpers/pointerMock.js';

import 'viz/chart';
import { SCROLL_PREVENTION_TIMEOUT } from '__internal/viz/chart_components/zoom_and_pan';

const CHART_SVG_SELECTOR = 'svg.dxc.dxc-chart';
const TOOLTIP_CLASS = 'dxc-tooltip';
Expand Down Expand Up @@ -3109,6 +3110,57 @@ QUnit.test('Default behavior - no prevent. On mouse wheel', function(assert) {
assert.equal(this.trackerStopHandling.callCount, 0);
});

QUnit.test('On mouse wheel. Should prevent scroll page after max zoom level reached (T1314606)', function(assert) {
const preventDefault = sinon.spy();
const stopPropagation = sinon.spy();
const onZoomEnd = sinon.spy();
const wholeRange = { startValue: 0, endValue: 5 };
const chart = this.createChart({
argumentAxis: {
visualRange: {
startValue: 0.1,
endValue: 4.9
},
wholeRange,
},
zoomAndPan: {
argumentAxis: 'zoom',
allowMouseWheel: true
},
onZoomEnd: onZoomEnd
});

const $root = $(chart._renderer.root.element);

$root.trigger(new $.Event('dxmousewheel', { d: -10, pageX: 200, pageY: 250, preventDefault: preventDefault, stopPropagation: stopPropagation }));

assert.deepEqual(onZoomEnd.getCall(0).args[0].range, wholeRange, 'chart zoomed out to wholeRange');
assert.strictEqual(preventDefault.callCount, 1, 'after zoom e.preventDefault called');
assert.strictEqual(stopPropagation.callCount, 1, 'after zoom e.stopPropagation called');
assert.strictEqual(this.trackerStopHandling.callCount, 1, 'chart stopped wheel event handling');

this.clock.tick(SCROLL_PREVENTION_TIMEOUT / 2);
$root.trigger(new $.Event('dxmousewheel', { d: -10, pageX: 200, pageY: 250, preventDefault: preventDefault, stopPropagation: stopPropagation }));

assert.equal(preventDefault.callCount, 2, 'e.preventDefault called');
assert.equal(stopPropagation.callCount, 2, 'e.stopPropagation called');
assert.equal(this.trackerStopHandling.callCount, 1, 'chart not passed event handling in SCROLL_PREVENTION_TIMEOUT window after zoom');

this.clock.tick(SCROLL_PREVENTION_TIMEOUT - 10);
$root.trigger(new $.Event('dxmousewheel', { d: -10, pageX: 200, pageY: 250, preventDefault: preventDefault, stopPropagation: stopPropagation }));

assert.equal(preventDefault.callCount, 3, 'e.preventDefault called');
assert.equal(stopPropagation.callCount, 3, 'e.stopPropagation called');
assert.equal(this.trackerStopHandling.callCount, 1, 'chart not passed event handling in SCROLL_PREVENTION_TIMEOUT window after last wheel event on chart');

this.clock.tick(SCROLL_PREVENTION_TIMEOUT + 10);
$root.trigger(new $.Event('dxmousewheel', { d: -10, pageX: 200, pageY: 250, preventDefault: preventDefault, stopPropagation: stopPropagation }));

assert.equal(preventDefault.callCount, 3, 'chart not prevents event handling after SCROLL_PREVENTION_TIMEOUT expires, e.preventDefault not called');
assert.equal(stopPropagation.callCount, 3, 'chart not prevent event propagation after SCROLL_PREVENTION_TIMEOUT expires, e.stopPropagation not called');
assert.equal(this.trackerStopHandling.callCount, 1, 'chart._stopCurrentHandling not called after SCROLL_PREVENTION_TIMEOUT window');
});

QUnit.test('On pinch zoom', function(assert) {
const preventDefault = sinon.spy();
const stopPropagation = sinon.spy();
Expand Down
Loading