Skip to content

Commit

Permalink
[charts] Fix tooltip with horizontal layout (#14337)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfauquette authored Aug 27, 2024
1 parent 95da5e3 commit 89350ce
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function ChartsAxisTooltipContent(props: {
}) {
const { content, contentProps, axisData, sx, classes } = props;

const isXaxis = (axisData.x && axisData.x.index) !== undefined;
const isXaxis = axisData.x && axisData.x.index !== -1;

const dataIndex = isXaxis ? axisData.x && axisData.x.index : axisData.y && axisData.y.index;
const axisValue = isXaxis ? axisData.x && axisData.x.value : axisData.y && axisData.y.value;
Expand Down
251 changes: 251 additions & 0 deletions packages/x-charts/src/ChartsTooltip/contentDisplayed.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import * as React from 'react';
import { expect } from 'chai';
import { createRenderer, fireEvent } from '@mui/internal-test-utils';
import { BarChart } from '@mui/x-charts/BarChart';
import { firePointerEvent } from '../tests/firePointerEvent';

const config = {
dataset: [
{ x: 'A', v1: 4, v2: 2 },
{ x: 'B', v1: 1, v2: 1 },
],
margin: { top: 0, left: 0, bottom: 0, right: 0 },
width: 400,
height: 400,
};

// Plot as follow to simplify click position
//
// | X
// | X
// | X X
// | X X X X
// ---A---B-

const isJSDOM = /jsdom/.test(window.navigator.userAgent);

describe('ChartsTooltip', () => {
const { render } = createRenderer();

describe('axis trigger', () => {
it('should show right values with vertical layout', function test() {
if (isJSDOM) {
// can't do Pointer event with JSDom https://github.com/jsdom/jsdom/issues/2527
this.skip();
}

render(
<div
style={{
margin: -8, // Removes the body default margins
width: 400,
height: 400,
}}
>
<BarChart
{...config}
series={[
{ dataKey: 'v1', id: 's1', label: 'S1' },
{ dataKey: 'v2', id: 's2', label: 'S2' },
]}
xAxis={[{ scaleType: 'band', dataKey: 'x' }]}
/>
</div>,
);
const svg = document.querySelector<HTMLElement>('svg')!;

firePointerEvent(svg, 'pointermove', {
clientX: 198,
clientY: 60,
});

let cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal([
// Header
'A',
// First row
'', // mark
'S1', // label
'4', // value
// Second row
'',
'S2',
'2',
]);

firePointerEvent(svg, 'pointermove', {
clientX: 201,
clientY: 60,
});

cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal([
// Header
'B',
// First row
'',
'S1',
'1',
// Second row
'',
'S2',
'1',
]);
});

it('should show right values with horizontal layout', function test() {
if (isJSDOM) {
// can't do Pointer event with JSDom https://github.com/jsdom/jsdom/issues/2527
this.skip();
}

render(
<div
style={{
margin: -8, // Removes the body default margins
width: 400,
height: 400,
}}
>
<BarChart
{...config}
layout="horizontal"
series={[
{ dataKey: 'v1', id: 's1', label: 'S1' },
{ dataKey: 'v2', id: 's2', label: 'S2' },
]}
yAxis={[{ scaleType: 'band', dataKey: 'x' }]}
/>
</div>,
);
const svg = document.querySelector<HTMLElement>('svg')!;

firePointerEvent(svg, 'pointermove', {
clientX: 150,
clientY: 60,
});

let cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal([
// Header
'A',
// First row
'',
'S1',
'4',
// Second row
'',
'S2',
'2',
]);

firePointerEvent(svg, 'pointermove', {
clientX: 150,
clientY: 220,
});

cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal([
// Header
'B',
// First row
'',
'S1',
'1',
// Second row
'',
'S2',
'1',
]);
});
});

describe('item trigger', () => {
it('should show right values with vertical layout', function test() {
if (isJSDOM) {
// can't do Pointer event with JSDom https://github.com/jsdom/jsdom/issues/2527
this.skip();
}

render(
<div
style={{
margin: -8, // Removes the body default margins
width: 400,
height: 400,
}}
>
<BarChart
{...config}
series={[
{ dataKey: 'v1', id: 's1', label: 'S1' },
{ dataKey: 'v2', id: 's2', label: 'S2' },
]}
xAxis={[{ scaleType: 'band', dataKey: 'x' }]}
tooltip={{ trigger: 'item' }}
/>
</div>,
);
const svg = document.querySelector<HTMLElement>('svg')!;
const rectangles = document.querySelectorAll<HTMLElement>('rect');

fireEvent.pointerEnter(rectangles[0]);

firePointerEvent(svg, 'pointermove', {
clientX: 150,
clientY: 60,
}); // Only to set the tooltip position

let cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal(['', 'S1', '4']);

fireEvent.pointerEnter(rectangles[3]);
cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal(['', 'S2', '1']);
});

it('should show right values with horizontal layout', function test() {
if (isJSDOM) {
// can't do Pointer event with JSDom https://github.com/jsdom/jsdom/issues/2527
this.skip();
}

render(
<div
style={{
margin: -8, // Removes the body default margins
width: 400,
height: 400,
}}
>
<BarChart
{...config}
series={[
{ dataKey: 'v1', id: 's1', label: 'S1' },
{ dataKey: 'v2', id: 's2', label: 'S2' },
]}
layout="horizontal"
yAxis={[{ scaleType: 'band', dataKey: 'x' }]}
tooltip={{ trigger: 'item' }}
/>
</div>,
);
const svg = document.querySelector<HTMLElement>('svg')!;
const rectangles = document.querySelectorAll<HTMLElement>('rect');

fireEvent.pointerEnter(rectangles[0]);

firePointerEvent(svg, 'pointermove', {
clientX: 150,
clientY: 60,
}); // Only to set the tooltip position

let cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal(['', 'S1', '4']);

fireEvent.pointerEnter(rectangles[3]);
cells = document.querySelectorAll<HTMLElement>('.MuiChartsTooltip-root td');
expect([...cells].map((cell) => cell.textContent)).to.deep.equal(['', 'S2', '1']);
});
});
});
6 changes: 4 additions & 2 deletions packages/x-charts/src/context/InteractionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ export type ItemInteractionData<T extends ChartSeriesType> = ChartItemIdentifier
export type AxisInteractionData = {
x: null | {
value: number | Date | string;
index?: number;
// Set to -1 if no index.
index: number;
};
y: null | {
value: number | Date | string;
index?: number;
// Set to -1 if no index.
index: number;
};
};

Expand Down
2 changes: 1 addition & 1 deletion packages/x-charts/src/hooks/useAxisEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const useAxisEvents = (disableAxisListener: boolean) => {
const value = scale.invert(mouseValue);

if (axisData === undefined) {
return { value };
return { value, index: -1 };
}

const valueAsNumber = getAsANumber(value);
Expand Down

0 comments on commit 89350ce

Please sign in to comment.