Skip to content

Commit d3a5bcf

Browse files
authored
Chart: zoom should work correctly on mobile devices when axis type is discrete (T1236028) (#28797)
1 parent f70b96b commit d3a5bcf

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

packages/devextreme/js/viz/translators/category_translator.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const round = Math.round;
44

55
function getValue(value) { return value; }
66

7+
const MIN_VALID_SCALE_OFFSET = 0.05;
8+
79
export default {
810
translate: function(category, directionOffset) {
911
const that = this;
@@ -38,6 +40,13 @@ export default {
3840

3941
zoom: function(translate, scale) {
4042
const that = this;
43+
const scaleOffset = Math.abs(Math.abs(scale) - 1);
44+
const isZoomIn = scale > 1;
45+
46+
if(scale !== 1 && scaleOffset < MIN_VALID_SCALE_OFFSET) {
47+
scale = this.getMinScale(isZoomIn);
48+
}
49+
4150
const categories = that._categories;
4251
const canvasOptions = that._canvasOptions;
4352
const stick = that._options.stick;

packages/devextreme/testing/tests/DevExpress.viz.charts/zoomAndPan.tests.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,69 @@ QUnit.test('Pinch zoom. Big chart rendering time on start and small time in the
25972597
assert.deepEqual(valueAxis2.visualRange(), { startValue: 11.5, endValue: 14.5 }, 'Val2 axis visualRange after pinchEnd');
25982598
});
25992599

2600+
[
2601+
{
2602+
axis: 'argument',
2603+
zoomAndPan: {
2604+
argumentAxis: 'both',
2605+
valueAxis: 'none',
2606+
allowTouchGestures: true,
2607+
},
2608+
},
2609+
{
2610+
axis: 'value',
2611+
zoomAndPan: {
2612+
argumentAxis: 'none',
2613+
valueAxis: 'both',
2614+
allowTouchGestures: true,
2615+
},
2616+
},
2617+
].forEach(({ axis, zoomAndPan }) => {
2618+
QUnit.test(`${axis} axis pinch with tiny offset should still zoom on one step (T1236028)`, function(assert) {
2619+
const onZoomStart = sinon.spy();
2620+
const onZoomEnd = sinon.spy();
2621+
const dataSource = [
2622+
{ arg: '1', val: '1' },
2623+
{ arg: '2', val: '2' },
2624+
{ arg: '3', val: '3' },
2625+
{ arg: '4', val: '4' },
2626+
{ arg: '5', val: '5' },
2627+
];
2628+
2629+
const chart = this.createChart({
2630+
argumentAxis: {
2631+
argumentType: 'string',
2632+
visualRange: {
2633+
startValue: '1',
2634+
endValue: '1',
2635+
}
2636+
},
2637+
valueAxis: {
2638+
valueType: 'string',
2639+
visualRange: {
2640+
startValue: '1',
2641+
endValue: '1',
2642+
}
2643+
},
2644+
dataSource,
2645+
zoomAndPan,
2646+
onZoomStart: onZoomStart,
2647+
onZoomEnd: onZoomEnd
2648+
});
2649+
2650+
const targetAxis = axis === 'argument' ? chart.getArgumentAxis() : chart.getValueAxis();
2651+
2652+
const $root = $(chart._renderer.root.element);
2653+
$root.trigger($.Event('dxpointerdown', { pointerType: 'touch', pointers: [{ pointerId: 1, pageX: 10, pageY: 10 }, { pointerId: 2, pageX: 100, pageY: 100 }] }));
2654+
$root.trigger($.Event('dxpointermove', { pointerType: 'touch', pointers: [{ pointerId: 1, pageX: 11, pageY: 11 }, { pointerId: 2, pageX: 99, pageY: 99 }] }));
2655+
$root.trigger($.Event('dxpointerup', { pointerType: 'touch', pointers: [] }));
2656+
2657+
assert.equal(onZoomEnd.getCall(0).args[0].axis, targetAxis, `${axis} axis is zoomed`);
2658+
assert.deepEqual(onZoomEnd.getCall(0).args[0].previousRange, { startValue: '1', endValue: '1', categories: ['1'] }, 'previous range is correct');
2659+
assert.deepEqual(onZoomEnd.getCall(0).args[0].range, { startValue: '1', endValue: '3', categories: ['1', '2', '3'] }, 'new range is correct');
2660+
});
2661+
});
2662+
26002663
QUnit.module('Misc', environment);
26012664

26022665
QUnit.test('argument axis should not restore visual range on dataSource update (T1049139)', function(assert) {

0 commit comments

Comments
 (0)