Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Remove redundant default axis #16734

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions packages/x-charts-pro/src/Heatmap/Heatmap.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,55 @@ describe('<Heatmap /> - License', () => {

expect(await screen.findAllByText('MUI X Missing license key')).not.to.equal(null);
});

it('should render "No data to display" when axes are empty arrays', () => {
render(<Heatmap series={[]} width={100} height={100} xAxis={[]} yAxis={[]} />);

expect(screen.getByText('No data to display')).toBeVisible();
});

describe('axis defaults', () => {
const series = [
{
data: [
[0, 3, 7],
[1, 5, 8],
],
},
] as const;

it('should render default axes when axes are empty arrays and series contain data', () => {
render(<Heatmap series={series} width={100} height={100} xAxis={[]} yAxis={[]} />);

const xAxisTickLabels = screen.getAllByTestId('ChartsXAxisTickLabel');
expect(xAxisTickLabels.map((t) => t.textContent)).to.deep.equal(['0', '1']);

const yAxisTickLabels = screen.getAllByTestId('ChartsYAxisTickLabel');
expect(yAxisTickLabels.map((t) => t.textContent)).to.deep.equal([
'0',
'1',
'2',
'3',
'4',
'5',
]);
});

it('should render default axes when axes are an array of an empty object and series contain data', () => {
render(<Heatmap series={series} width={100} height={100} xAxis={[{}]} yAxis={[{}]} />);

const xAxisTickLabels = screen.getAllByTestId('ChartsXAxisTickLabel');
expect(xAxisTickLabels.map((t) => t.textContent)).to.deep.equal(['0', '1']);

const yAxisTickLabels = screen.getAllByTestId('ChartsYAxisTickLabel');
expect(yAxisTickLabels.map((t) => t.textContent)).to.deep.equal([
'0',
'1',
'2',
'3',
'4',
'5',
]);
});
});
});
34 changes: 30 additions & 4 deletions packages/x-charts-pro/src/Heatmap/Heatmap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ChartsOverlaySlotProps,
ChartsOverlaySlots,
} from '@mui/x-charts/ChartsOverlay';
import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '@mui/x-charts/constants';
import { ChartContainerPro, ChartContainerProProps } from '../ChartContainerPro';
import { HeatmapSeriesType } from '../models/seriesType/heatmap';
import { HeatmapPlot } from './HeatmapPlot';
Expand Down Expand Up @@ -100,6 +101,19 @@ const defaultColorMap = interpolateRgbBasis([

const seriesConfig: ChartSeriesConfig<'heatmap'> = { heatmap: heatmapSeriesConfig };

function getDefaultDataForAxis(series: HeatmapProps['series'], dimension: number) {
if (series?.[0]?.data === undefined || series[0].data.length === 0) {
return [];
}

return Array.from(
{ length: Math.max(...series[0].data.map((dataPoint) => dataPoint[dimension])) + 1 },
(_, index) => index,
);
}
const getDefaultDataForXAxis = (series: HeatmapProps['series']) => getDefaultDataForAxis(series, 0);
const getDefaultDataForYAxis = (series: HeatmapProps['series']) => getDefaultDataForAxis(series, 1);

const Heatmap = React.forwardRef(function Heatmap(
inProps: HeatmapProps,
ref: React.Ref<SVGSVGElement>,
Expand Down Expand Up @@ -129,13 +143,25 @@ const Heatmap = React.forwardRef(function Heatmap(
const clipPathId = `${id}-clip-path`;

const defaultizedXAxis = React.useMemo(
() => xAxis.map((axis) => ({ scaleType: 'band' as const, categoryGapRatio: 0, ...axis })),
[xAxis],
() =>
(xAxis && xAxis.length > 0 ? xAxis : [{ id: DEFAULT_X_AXIS_KEY }]).map((axis) => ({
scaleType: 'band' as const,
categoryGapRatio: 0,
...axis,
data: axis.data ?? getDefaultDataForXAxis(series),
})),
[series, xAxis],
);

const defaultizedYAxis = React.useMemo(
() => yAxis.map((axis) => ({ scaleType: 'band' as const, categoryGapRatio: 0, ...axis })),
[yAxis],
() =>
(yAxis && yAxis.length > 0 ? yAxis : [{ id: DEFAULT_Y_AXIS_KEY }]).map((axis) => ({
scaleType: 'band' as const,
categoryGapRatio: 0,
...axis,
data: axis.data ?? getDefaultDataForYAxis(series),
})),
[series, yAxis],
);

const defaultizedZAxis = React.useMemo(
Expand Down
8 changes: 8 additions & 0 deletions packages/x-charts/src/BarChart/BarChart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import { createRenderer } from '@mui/internal-test-utils/createRenderer';
import { describeConformance } from 'test/utils/describeConformance';
import { BarChart } from '@mui/x-charts/BarChart';
import { expect } from 'chai';
import { screen } from '@mui/internal-test-utils';

describe('<BarChart />', () => {
const { render } = createRenderer();
Expand All @@ -28,4 +30,10 @@ describe('<BarChart />', () => {
],
}),
);

it('should render "No data to display" when axes are empty arrays', () => {
render(<BarChart series={[]} width={100} height={100} xAxis={[]} yAxis={[]} />);

expect(screen.getByText('No data to display')).toBeVisible();
});
});
1 change: 1 addition & 0 deletions packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ function ChartsXAxis(inProps: ChartsXAxisProps) {
<TickLabel
x={xTickLabel}
y={yTickLabel}
data-testid="ChartsXAxisTickLabel"
{...axisTickLabelProps}
text={formattedValue.toString()}
/>
Expand Down
1 change: 1 addition & 0 deletions packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ function ChartsYAxis(inProps: ChartsYAxisProps) {
<TickLabel
x={xTickLabel}
y={yTickLabel}
data-testid="ChartsYAxisTickLabel"
text={formattedValue.toString()}
{...axisTickLabelProps}
/>
Expand Down
8 changes: 8 additions & 0 deletions packages/x-charts/src/LineChart/LineChart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import { createRenderer } from '@mui/internal-test-utils/createRenderer';
import { describeConformance } from 'test/utils/describeConformance';
import { LineChart } from '@mui/x-charts/LineChart';
import { expect } from 'chai';
import { screen } from '@mui/internal-test-utils';

describe('<LineChart />', () => {
const { render } = createRenderer();
Expand All @@ -27,4 +29,10 @@ describe('<LineChart />', () => {
],
}),
);

it('should render "No data to display" when axes are empty arrays', () => {
render(<LineChart series={[]} width={100} height={100} xAxis={[]} yAxis={[]} />);

expect(screen.getByText('No data to display')).toBeVisible();
});
});
6 changes: 6 additions & 0 deletions packages/x-charts/src/ScatterChart/ScatterChart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,10 @@ describe('<ScatterChart />', () => {
const labelY = await screen.findByText('600');
expect(labelY).toBeVisible();
});

it('should render "No data to display" when axes are empty arrays', () => {
render(<ScatterChart series={[]} width={100} height={100} xAxis={[]} yAxis={[]} />);

expect(screen.getByText('No data to display')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ export function defaultizeAxis(
): AxisConfig[] {
const DEFAULT_AXIS_KEY = axisName === 'x' ? DEFAULT_X_AXIS_KEY : DEFAULT_Y_AXIS_KEY;

const hasNoDefaultAxis =
inAxis === undefined || inAxis.findIndex(({ id }) => id === DEFAULT_AXIS_KEY) === -1;

const offsets = {
top: 0,
right: 0,
Expand All @@ -37,10 +34,10 @@ export function defaultizeAxis(
none: 0,
};

const parsedAxes = [
...(inAxis ?? []),
...(hasNoDefaultAxis ? [{ id: DEFAULT_AXIS_KEY, scaleType: 'linear' as const }] : []),
].map((axisConfig, index) => {
const inputAxes =
inAxis && inAxis.length > 0 ? inAxis : [{ id: DEFAULT_AXIS_KEY, scaleType: 'linear' as const }];

const parsedAxes = inputAxes.map((axisConfig, index) => {
const dataKey = axisConfig.dataKey;
const defaultPosition = axisName === 'x' ? ('bottom' as const) : ('left' as const);

Expand Down