Skip to content

Commit f7b122d

Browse files
[charts] Fix axis zoom being disabled when not specified in initialZoom (#17500)
1 parent a167891 commit f7b122d

File tree

2 files changed

+102
-13
lines changed

2 files changed

+102
-13
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { expect } from 'chai';
2+
import { AxisId, DefaultizedZoomOptions, ZoomData } from '@mui/x-charts/internals';
3+
import { initializeZoomData } from './useChartProZoom';
4+
5+
describe('initializeZoomData', () => {
6+
const defaultZoomOptions: DefaultizedZoomOptions = {
7+
axisId: 'x',
8+
axisDirection: 'x',
9+
minStart: 0,
10+
maxEnd: 100,
11+
step: 5,
12+
minSpan: 10,
13+
maxSpan: 100,
14+
panning: true,
15+
filterMode: 'keep',
16+
};
17+
18+
it('should initialize zoom data for all axes based on provided options when no zoom data is given', () => {
19+
const options = {
20+
x: { ...defaultZoomOptions, axisId: 'x', minStart: 0, maxEnd: 100 },
21+
y: { ...defaultZoomOptions, axisDirection: 'y', axisId: 'y', minStart: 10, maxEnd: 50 },
22+
} satisfies Record<AxisId, DefaultizedZoomOptions>;
23+
24+
const result = initializeZoomData(options);
25+
26+
expect(result).to.deep.equal([
27+
{ axisId: 'x', start: 0, end: 100 },
28+
{ axisId: 'y', start: 10, end: 50 },
29+
]);
30+
});
31+
32+
it('should override options with provided zoom data when matching axisId exists', () => {
33+
const options = {
34+
x: { ...defaultZoomOptions, axisId: 'x', minStart: 0, maxEnd: 100 },
35+
y: { ...defaultZoomOptions, axisDirection: 'y', axisId: 'y', minStart: 10, maxEnd: 50 },
36+
} satisfies Record<AxisId, DefaultizedZoomOptions>;
37+
38+
const zoomData: readonly ZoomData[] = [{ axisId: 'x', start: 20, end: 60 }];
39+
const result = initializeZoomData(options, zoomData);
40+
41+
expect(result).to.deep.equal([
42+
{ axisId: 'x', start: 20, end: 60 },
43+
{ axisId: 'y', start: 10, end: 50 },
44+
]);
45+
});
46+
47+
it('should ignore zoom data if its axisId is not present in options', () => {
48+
const options = {
49+
x: { ...defaultZoomOptions, axisId: 'x', minStart: 0, maxEnd: 100 },
50+
} satisfies Record<AxisId, DefaultizedZoomOptions>;
51+
52+
const zoomData: readonly ZoomData[] = [{ axisId: 'y', start: 10, end: 50 }];
53+
const result = initializeZoomData(options, zoomData);
54+
55+
expect(result).to.deep.equal([{ axisId: 'x', start: 0, end: 100 }]);
56+
});
57+
58+
it('should handle an empty options object without errors', () => {
59+
const result = initializeZoomData({});
60+
expect(result).to.deep.equal([]);
61+
});
62+
63+
it('should handle undefined zoomData gracefully', () => {
64+
const options = {
65+
x: { ...defaultZoomOptions, axisId: 'x', minStart: 0, maxEnd: 100 },
66+
} satisfies Record<AxisId, DefaultizedZoomOptions>;
67+
68+
const result = initializeZoomData(options, undefined);
69+
70+
expect(result).to.deep.equal([{ axisId: 'x', start: 0, end: 100 }]);
71+
});
72+
});

packages/x-charts-pro/src/internals/plugins/useChartProZoom/useChartProZoom.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,32 @@ import {
2525
preventDefault,
2626
zoomAtPoint,
2727
} from './useChartProZoom.utils';
28+
2829
// It is helpful to avoid the need to provide the possibly auto-generated id for each axis.
29-
function initializeZoomData(options: Record<AxisId, DefaultizedZoomOptions>) {
30-
return Object.values(options).map(({ axisId, minStart: start, maxEnd: end }) => ({
31-
axisId,
32-
start,
33-
end,
34-
}));
30+
export function initializeZoomData(
31+
options: Record<AxisId, DefaultizedZoomOptions>,
32+
zoomData?: readonly ZoomData[],
33+
) {
34+
const zoomDataMap = new Map<AxisId, ZoomData>();
35+
36+
zoomData?.forEach((zoom) => {
37+
const option = options[zoom.axisId];
38+
if (option) {
39+
zoomDataMap.set(zoom.axisId, zoom);
40+
}
41+
});
42+
43+
return Object.values(options).map(({ axisId, minStart: start, maxEnd: end }) => {
44+
if (zoomDataMap.has(axisId)) {
45+
return zoomDataMap.get(axisId)!;
46+
}
47+
48+
return {
49+
axisId,
50+
start,
51+
end,
52+
};
53+
});
3554
}
3655

3756
export const useChartProZoom: ChartPlugin<UseChartProZoomSignature> = ({
@@ -461,15 +480,13 @@ useChartProZoom.getInitialState = (params) => {
461480
...createZoomLookup('x')(defaultizedXAxis),
462481
...createZoomLookup('y')(defaultizedYAxis),
463482
};
483+
const userZoomData =
484+
// eslint-disable-next-line no-nested-ternary
485+
zoomData !== undefined ? zoomData : initialZoom !== undefined ? initialZoom : undefined;
486+
464487
return {
465488
zoom: {
466-
zoomData:
467-
// eslint-disable-next-line no-nested-ternary
468-
zoomData !== undefined
469-
? zoomData
470-
: initialZoom !== undefined
471-
? initialZoom
472-
: initializeZoomData(optionsLookup),
489+
zoomData: initializeZoomData(optionsLookup, userZoomData),
473490
isInteracting: false,
474491
isControlled: zoomData !== undefined,
475492
},

0 commit comments

Comments
 (0)