Skip to content

Commit ae02783

Browse files
committed
Add test and fix them
1 parent 113b039 commit ae02783

3 files changed

Lines changed: 194 additions & 3 deletions

File tree

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import * as React from 'react';
2+
import { spy } from 'sinon';
3+
import { createRenderer } from '@mui/internal-test-utils';
4+
import { isJSDOM } from 'test/utils/skipIf';
5+
import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider';
6+
import { ChartsSurface } from '@mui/x-charts/ChartsSurface';
7+
import { useChartCartesianAxis } from './useChartCartesianAxis';
8+
import { UseChartCartesianAxisSignature } from './useChartCartesianAxis.types';
9+
import { useChartInteraction, UseChartInteractionSignature } from '../useChartInteraction';
10+
11+
describe('useChartCartesianAxis - axis highlight', () => {
12+
const { render } = createRenderer();
13+
14+
// can't do Pointer event with JSDom https://github.com/jsdom/jsdom/issues/2527
15+
it.skipIf(isJSDOM)('should call onAxisInteraction when crossing any value', async () => {
16+
const onAxisInteraction = spy();
17+
const { user } = render(
18+
<ChartDataProvider<'bar', [UseChartCartesianAxisSignature, UseChartInteractionSignature]>
19+
plugins={[useChartCartesianAxis, useChartInteraction]}
20+
xAxis={[{ id: 'x-axis', scaleType: 'band', data: ['A', 'B'], position: 'none' }]}
21+
yAxis={[{ id: 'y-axis', min: 0, max: 1, data: [0, 0.5], position: 'none' }]}
22+
width={100}
23+
height={100}
24+
margin={0}
25+
onAxisInteraction={onAxisInteraction}
26+
>
27+
<ChartsSurface />
28+
</ChartDataProvider>,
29+
);
30+
31+
const svg = document.querySelector<HTMLElement>('svg')!;
32+
33+
await user.pointer([
34+
{
35+
keys: '[TouchA>]',
36+
target: svg,
37+
coords: { clientX: 75, clientY: 60 },
38+
},
39+
{
40+
pointerName: 'TouchA',
41+
target: svg,
42+
coords: { clientX: 25, clientY: 70 }, // x-axis : B -> A
43+
},
44+
{
45+
pointerName: 'TouchA',
46+
target: svg,
47+
coords: { clientX: 25, clientY: 90 }, // y-axis : 0.5 -> 0
48+
},
49+
{
50+
keys: '[/TouchA]',
51+
},
52+
]);
53+
54+
expect(onAxisInteraction.callCount).to.equal(4);
55+
56+
expect(onAxisInteraction.getCall(0).firstArg).to.deep.equal([
57+
{ axisId: 'x-axis', dataIndex: 1 },
58+
{ axisId: 'y-axis', dataIndex: 1 },
59+
]);
60+
61+
expect(onAxisInteraction.getCall(1).firstArg).to.deep.equal([
62+
{ axisId: 'x-axis', dataIndex: 0 },
63+
{ axisId: 'y-axis', dataIndex: 1 },
64+
]);
65+
66+
expect(onAxisInteraction.getCall(2).firstArg).to.deep.equal([
67+
{ axisId: 'x-axis', dataIndex: 0 },
68+
{ axisId: 'y-axis', dataIndex: 0 },
69+
]);
70+
71+
expect(onAxisInteraction.getCall(3).firstArg).to.deep.equal(null);
72+
});
73+
74+
it.skipIf(isJSDOM)('should call onAxisInteraction when axis got modified', async () => {
75+
const onAxisInteraction = spy();
76+
const { user, setProps } = render(
77+
<ChartDataProvider<'bar', [UseChartCartesianAxisSignature, UseChartInteractionSignature]>
78+
plugins={[useChartCartesianAxis, useChartInteraction]}
79+
xAxis={[{ id: 'x-axis', scaleType: 'band', data: ['A', 'B'], position: 'none' }]}
80+
yAxis={[{ position: 'none' }]}
81+
width={100}
82+
height={100}
83+
margin={0}
84+
onAxisInteraction={onAxisInteraction}
85+
>
86+
<ChartsSurface />
87+
</ChartDataProvider>,
88+
);
89+
90+
const svg = document.querySelector<HTMLElement>('svg')!;
91+
92+
await user.pointer([{ keys: '[TouchA>]', target: svg, coords: { clientX: 45, clientY: 60 } }]);
93+
94+
expect(onAxisInteraction.callCount).to.equal(1);
95+
expect(onAxisInteraction.lastCall.firstArg).to.deep.equal([{ axisId: 'x-axis', dataIndex: 0 }]);
96+
97+
setProps({
98+
xAxis: [{ id: 'x-axis', scaleType: 'band', data: ['A', 'B', 'C'], position: 'none' }],
99+
});
100+
101+
expect(onAxisInteraction.callCount).to.equal(2);
102+
expect(onAxisInteraction.lastCall.firstArg).to.deep.equal([{ axisId: 'x-axis', dataIndex: 1 }]);
103+
});
104+
105+
it.skipIf(isJSDOM)(
106+
'should not call onAxisInteraction when axis got modified but highlighted item stay the same',
107+
async () => {
108+
const onAxisInteraction = spy();
109+
const { user, setProps } = render(
110+
<ChartDataProvider<'bar', [UseChartCartesianAxisSignature, UseChartInteractionSignature]>
111+
plugins={[useChartCartesianAxis, useChartInteraction]}
112+
xAxis={[{ id: 'x-axis', scaleType: 'band', data: ['A', 'B'], position: 'none' }]}
113+
yAxis={[{ position: 'none' }]}
114+
width={100}
115+
height={100}
116+
margin={0}
117+
onAxisInteraction={onAxisInteraction}
118+
>
119+
<ChartsSurface />
120+
</ChartDataProvider>,
121+
);
122+
123+
const svg = document.querySelector<HTMLElement>('svg')!;
124+
125+
await user.pointer([
126+
{ keys: '[TouchA>]', target: svg, coords: { clientX: 10, clientY: 60 } },
127+
]);
128+
129+
expect(onAxisInteraction.callCount).to.equal(1);
130+
expect(onAxisInteraction.lastCall.firstArg).to.deep.equal([
131+
{ axisId: 'x-axis', dataIndex: 0 },
132+
]);
133+
134+
setProps({
135+
xAxis: [{ id: 'x-axis', scaleType: 'band', data: ['A', 'B', 'C'], position: 'none' }],
136+
});
137+
138+
expect(onAxisInteraction.callCount).to.equal(1);
139+
},
140+
);
141+
142+
it.skipIf(isJSDOM)('should can onAxisInteraction when highlighted axis got removed', async () => {
143+
const onAxisInteraction = spy();
144+
const { user, setProps } = render(
145+
<ChartDataProvider<'bar', [UseChartCartesianAxisSignature, UseChartInteractionSignature]>
146+
plugins={[useChartCartesianAxis, useChartInteraction]}
147+
xAxis={[{ id: 'x-axis', scaleType: 'band', data: ['A', 'B'], position: 'none' }]}
148+
yAxis={[{ position: 'none' }]}
149+
width={100}
150+
height={100}
151+
margin={0}
152+
onAxisInteraction={onAxisInteraction}
153+
>
154+
<ChartsSurface />
155+
</ChartDataProvider>,
156+
);
157+
158+
const svg = document.querySelector<HTMLElement>('svg')!;
159+
160+
await user.pointer([{ keys: '[TouchA>]', target: svg, coords: { clientX: 10, clientY: 60 } }]);
161+
162+
expect(onAxisInteraction.callCount).to.equal(1);
163+
expect(onAxisInteraction.lastCall.firstArg).to.deep.equal([{ axisId: 'x-axis', dataIndex: 0 }]);
164+
165+
setProps({
166+
xAxis: [{ id: 'new-axis', scaleType: 'band', data: ['A', 'B'], position: 'none' }],
167+
});
168+
169+
expect(onAxisInteraction.callCount).to.equal(2);
170+
expect(onAxisInteraction.lastCall.firstArg).to.deep.equal([
171+
{ axisId: 'new-axis', dataIndex: 0 },
172+
]);
173+
});
174+
});

packages/x-charts/src/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ export const useChartCartesianAxis: ChartPlugin<UseChartCartesianAxisSignature<a
145145
let isSame = true;
146146

147147
for (const axisId of newXAxisIds) {
148-
const prevAxisIndex = selectorChartsInteractionXAxisIndex(prevStoreState, axisId);
148+
const prevAxisIndex =
149+
prevXAxis.axis[axisId] === undefined
150+
? null
151+
: selectorChartsInteractionXAxisIndex(prevStoreState, axisId);
149152
const nextAxisIndex = selectorChartsInteractionXAxisIndex(newStoreState, axisId);
150153

151154
if (prevAxisIndex !== nextAxisIndex) {
@@ -158,7 +161,10 @@ export const useChartCartesianAxis: ChartPlugin<UseChartCartesianAxisSignature<a
158161
}
159162

160163
for (const axisId of newYAxisIds) {
161-
const prevAxisIndex = selectorChartsInteractionYAxisIndex(prevStoreState, axisId);
164+
const prevAxisIndex =
165+
prevYAxis.axis[axisId] === undefined
166+
? null
167+
: selectorChartsInteractionYAxisIndex(prevStoreState, axisId);
162168
const nextAxisIndex = selectorChartsInteractionYAxisIndex(newStoreState, axisId);
163169

164170
if (prevAxisIndex !== nextAxisIndex) {
@@ -238,6 +244,11 @@ export const useChartCartesianAxis: ChartPlugin<UseChartCartesianAxisSignature<a
238244
) {
239245
(target as HTMLElement).releasePointerCapture(event.pointerId);
240246
}
247+
248+
const svgPoint = getSVGPoint(element, event);
249+
if (instance.isPointInside(svgPoint.x, svgPoint.y, event.target as SVGElement)) {
250+
instance.setPointerCoordinate?.(svgPoint);
251+
}
241252
};
242253

243254
element.addEventListener('pointerdown', handleDown);

packages/x-charts/src/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ export const selectChartsInteractionAxisIndex = (
3030
value: number | null,
3131
axes: ComputeResult<ChartsAxisProps>,
3232
id?: AxisId,
33-
) => (value === null ? null : indexGetter(value, axes, id));
33+
) => {
34+
if (value === null) {
35+
return null;
36+
}
37+
const index = indexGetter(value, axes, id);
38+
return index === -1 ? null : index;
39+
};
3440

3541
export const selectorChartsInteractionXAxisIndex = createSelector(
3642
[selectorChartsInteractionPointerX, selectorChartXAxis, optionalGetAxisId],

0 commit comments

Comments
 (0)