From 879250688ef9c213650386252e3cda0a6c501597 Mon Sep 17 00:00:00 2001 From: Alexander Kozlovskiy Date: Mon, 20 Jan 2025 19:32:59 +0400 Subject: [PATCH 1/2] Chart: zoom should work correctly on mobile devices when axis type is discrete (T1236028) --- .../js/viz/translators/category_translator.js | 7 +++ .../DevExpress.viz.charts/zoomAndPan.tests.js | 63 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/packages/devextreme/js/viz/translators/category_translator.js b/packages/devextreme/js/viz/translators/category_translator.js index e83e826ffc54..108701e71d08 100644 --- a/packages/devextreme/js/viz/translators/category_translator.js +++ b/packages/devextreme/js/viz/translators/category_translator.js @@ -38,6 +38,13 @@ export default { zoom: function(translate, scale) { const that = this; + const minValidScaleOffset = 0.05; + const scaleOffset = Math.abs(Math.abs(scale) - 1); + + if(scale !== 1 && scaleOffset < minValidScaleOffset) { + scale = this.getMinScale(scale > 1); + } + const categories = that._categories; const canvasOptions = that._canvasOptions; const stick = that._options.stick; diff --git a/packages/devextreme/testing/tests/DevExpress.viz.charts/zoomAndPan.tests.js b/packages/devextreme/testing/tests/DevExpress.viz.charts/zoomAndPan.tests.js index 65bc33c3f653..918337a47520 100644 --- a/packages/devextreme/testing/tests/DevExpress.viz.charts/zoomAndPan.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.viz.charts/zoomAndPan.tests.js @@ -2597,6 +2597,69 @@ QUnit.test('Pinch zoom. Big chart rendering time on start and small time in the assert.deepEqual(valueAxis2.visualRange(), { startValue: 11.5, endValue: 14.5 }, 'Val2 axis visualRange after pinchEnd'); }); +[ + { + axis: 'argument', + zoomAndPan: { + argumentAxis: 'both', + valueAxis: 'none', + allowTouchGestures: true, + }, + }, + { + axis: 'value', + zoomAndPan: { + argumentAxis: 'none', + valueAxis: 'both', + allowTouchGestures: true, + }, + }, +].forEach(({ axis, zoomAndPan }) => { + QUnit.test(`${axis} axis pinch with tiny offset should still zoom on one step (T1236028)`, function(assert) { + const onZoomStart = sinon.spy(); + const onZoomEnd = sinon.spy(); + const dataSource = [ + { arg: '1', val: '1' }, + { arg: '2', val: '2' }, + { arg: '3', val: '3' }, + { arg: '4', val: '4' }, + { arg: '5', val: '5' }, + ]; + + const chart = this.createChart({ + argumentAxis: { + argumentType: 'string', + visualRange: { + startValue: '1', + endValue: '1', + } + }, + valueAxis: { + valueType: 'string', + visualRange: { + startValue: '1', + endValue: '1', + } + }, + dataSource, + zoomAndPan, + onZoomStart: onZoomStart, + onZoomEnd: onZoomEnd + }); + + const targetAxis = axis === 'argument' ? chart.getArgumentAxis() : chart.getValueAxis(); + + const $root = $(chart._renderer.root.element); + $root.trigger($.Event('dxpointerdown', { pointerType: 'touch', pointers: [{ pointerId: 1, pageX: 10, pageY: 10 }, { pointerId: 2, pageX: 100, pageY: 100 }] })); + $root.trigger($.Event('dxpointermove', { pointerType: 'touch', pointers: [{ pointerId: 1, pageX: 11, pageY: 11 }, { pointerId: 2, pageX: 99, pageY: 99 }] })); + $root.trigger($.Event('dxpointerup', { pointerType: 'touch', pointers: [] })); + + assert.equal(onZoomEnd.getCall(0).args[0].axis, targetAxis, `${axis} axis is zoomed`); + assert.deepEqual(onZoomEnd.getCall(0).args[0].previousRange, { startValue: '1', endValue: '1', categories: ['1'] }, 'previous range is correct'); + assert.deepEqual(onZoomEnd.getCall(0).args[0].range, { startValue: '1', endValue: '3', categories: ['1', '2', '3'] }, 'new range is correct'); + }); +}); + QUnit.module('Misc', environment); QUnit.test('argument axis should not restore visual range on dataSource update (T1049139)', function(assert) { From 2fd418ab864374d9bd568f14eecc9e19e5675b90 Mon Sep 17 00:00:00 2001 From: Alexander Kozlovskiy Date: Mon, 20 Jan 2025 20:54:58 +0400 Subject: [PATCH 2/2] small refactor --- .../devextreme/js/viz/translators/category_translator.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/devextreme/js/viz/translators/category_translator.js b/packages/devextreme/js/viz/translators/category_translator.js index 108701e71d08..f9513e2d7046 100644 --- a/packages/devextreme/js/viz/translators/category_translator.js +++ b/packages/devextreme/js/viz/translators/category_translator.js @@ -4,6 +4,8 @@ const round = Math.round; function getValue(value) { return value; } +const MIN_VALID_SCALE_OFFSET = 0.05; + export default { translate: function(category, directionOffset) { const that = this; @@ -38,11 +40,11 @@ export default { zoom: function(translate, scale) { const that = this; - const minValidScaleOffset = 0.05; const scaleOffset = Math.abs(Math.abs(scale) - 1); + const isZoomIn = scale > 1; - if(scale !== 1 && scaleOffset < minValidScaleOffset) { - scale = this.getMinScale(scale > 1); + if(scale !== 1 && scaleOffset < MIN_VALID_SCALE_OFFSET) { + scale = this.getMinScale(isZoomIn); } const categories = that._categories;