Skip to content

Commit a811f92

Browse files
[charts] Warn if axis data don't have enough elements (#16830)
1 parent 03c32eb commit a811f92

File tree

4 files changed

+74
-23
lines changed

4 files changed

+74
-23
lines changed

packages/x-charts/src/BarChart/BarPlot.tsx

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const useAggregatedData = (): {
119119

120120
const verticalLayout = series[seriesId].layout === 'vertical';
121121

122-
checkScaleErrors(verticalLayout, seriesId, xAxisId, xAxis, yAxisId, yAxis);
122+
checkScaleErrors(verticalLayout, seriesId, series[seriesId], xAxisId, xAxis, yAxisId, yAxis);
123123

124124
const baseScaleConfig = (
125125
verticalLayout ? xAxisConfig : yAxisConfig
@@ -138,10 +138,11 @@ const useAggregatedData = (): {
138138
});
139139
const barOffset = groupIndex * (barWidth + offset);
140140

141-
const { stackedData } = series[seriesId];
141+
const { stackedData, data: currentSeriesData, layout } = series[seriesId];
142142

143-
return stackedData
144-
.map((values, dataIndex: number) => {
143+
return baseScaleConfig
144+
.data!.map((baseValue, dataIndex: number) => {
145+
const values = stackedData[dataIndex];
145146
const valueCoordinates = values.map((v) => (verticalLayout ? yScale(v)! : xScale(v)!));
146147

147148
const minValueCoord = Math.round(Math.min(...valueCoordinates));
@@ -152,19 +153,15 @@ const useAggregatedData = (): {
152153
const result = {
153154
seriesId,
154155
dataIndex,
155-
layout: series[seriesId].layout,
156-
x: verticalLayout
157-
? xScale(xAxis[xAxisId].data?.[dataIndex])! + barOffset
158-
: minValueCoord,
159-
y: verticalLayout
160-
? minValueCoord
161-
: yScale(yAxis[yAxisId].data?.[dataIndex])! + barOffset,
156+
layout,
157+
x: verticalLayout ? xScale(baseValue)! + barOffset : minValueCoord,
158+
y: verticalLayout ? minValueCoord : yScale(baseValue)! + barOffset,
162159
xOrigin: xScale(0)!,
163160
yOrigin: yScale(0)!,
164161
height: verticalLayout ? maxValueCoord - minValueCoord : barWidth,
165162
width: verticalLayout ? barWidth : maxValueCoord - minValueCoord,
166163
color: colorGetter(dataIndex),
167-
value: series[seriesId].data[dataIndex],
164+
value: currentSeriesData[dataIndex],
168165
maskId: `${chartId}_${stackId || seriesId}_${groupIndex}_${dataIndex}`,
169166
};
170167

packages/x-charts/src/BarChart/checkScaleErrors.test.ts

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ describe('BarChart - checkScaleErrors', () => {
1111
checkScaleErrors(
1212
true,
1313
'seriesId',
14+
// @ts-expect-error
15+
{ stackedData: [[0, 1]] },
1416
xKey,
1517
{
16-
// @ts-expect-error
1718
[xKey]: { id: xKey, scaleType: 'linear' },
1819
},
1920
yKey,
@@ -33,9 +34,10 @@ describe('BarChart - checkScaleErrors', () => {
3334
checkScaleErrors(
3435
true,
3536
'seriesId',
37+
// @ts-expect-error
38+
{ stackedData: [[0, 1]] },
3639
xKey,
3740
{
38-
// @ts-expect-error
3941
[xKey]: { id: xKey, scaleType: 'band' },
4042
},
4143
yKey,
@@ -46,16 +48,45 @@ describe('BarChart - checkScaleErrors', () => {
4648
}).throws('MUI X: The first `xAxis` should have data property.');
4749
});
4850

51+
it('should throw an error when the x-axis data property is smaller than the series data.', () => {
52+
expect(() => {
53+
const xKey = DEFAULT_X_AXIS_KEY;
54+
const yKey = DEFAULT_Y_AXIS_KEY;
55+
checkScaleErrors(
56+
true,
57+
'seriesId',
58+
// @ts-expect-error
59+
{
60+
stackedData: [
61+
[0, 1],
62+
[0, 1],
63+
],
64+
},
65+
xKey,
66+
{
67+
[xKey]: { id: xKey, scaleType: 'band', data: [1] },
68+
},
69+
yKey,
70+
{
71+
[yKey]: { id: yKey, scaleType: 'linear' },
72+
},
73+
);
74+
}).toErrorDev(
75+
'MUI X: The first `xAxis` has less data (1 values) than the bar series of id "seriesId" (2 values)',
76+
);
77+
});
78+
4979
it('should throw an error when the y-axis is not a continuous scale', () => {
5080
expect(() => {
5181
const xKey = DEFAULT_X_AXIS_KEY;
5282
const yKey = DEFAULT_Y_AXIS_KEY;
5383
checkScaleErrors(
5484
true,
5585
'seriesId',
86+
// @ts-expect-error
87+
{ stackedData: [[0, 1]] },
5688
xKey,
5789
{
58-
// @ts-expect-error
5990
[xKey]: { id: xKey, scaleType: 'band', data: [] },
6091
},
6192
yKey,
@@ -75,9 +106,10 @@ describe('BarChart - checkScaleErrors', () => {
75106
checkScaleErrors(
76107
true,
77108
'seriesId',
109+
// @ts-expect-error
110+
{ stackedData: [] },
78111
xKey,
79112
{
80-
// @ts-expect-error
81113
[xKey]: { id: xKey, scaleType: 'band', data: [] },
82114
},
83115
yKey,
@@ -97,9 +129,10 @@ describe('BarChart - checkScaleErrors', () => {
97129
checkScaleErrors(
98130
false,
99131
'seriesId',
132+
// @ts-expect-error
133+
{ stackedData: [[0, 1]] },
100134
xKey,
101135
{
102-
// @ts-expect-error
103136
[xKey]: { id: xKey, scaleType: 'linear' },
104137
},
105138
yKey,
@@ -119,9 +152,10 @@ describe('BarChart - checkScaleErrors', () => {
119152
checkScaleErrors(
120153
false,
121154
'seriesId',
155+
// @ts-expect-error
156+
{ stackedData: [[0, 1]] },
122157
xKey,
123158
{
124-
// @ts-expect-error
125159
[xKey]: { id: xKey, scaleType: 'linear' },
126160
},
127161
yKey,
@@ -139,9 +173,10 @@ describe('BarChart - checkScaleErrors', () => {
139173
checkScaleErrors(
140174
false,
141175
'seriesId',
176+
// @ts-expect-error
177+
{ stackedData: [[0, 1]] },
142178
xKey,
143179
{
144-
// @ts-expect-error
145180
[xKey]: { id: xKey, scaleType: 'band' },
146181
},
147182
yKey,
@@ -161,9 +196,10 @@ describe('BarChart - checkScaleErrors', () => {
161196
checkScaleErrors(
162197
false,
163198
'seriesId',
199+
// @ts-expect-error
200+
{ stackedData: [] },
164201
xKey,
165202
{
166-
// @ts-expect-error
167203
[xKey]: { id: xKey, scaleType: 'linear' },
168204
},
169205
yKey,
@@ -182,9 +218,10 @@ describe('BarChart - checkScaleErrors', () => {
182218
checkScaleErrors(
183219
true,
184220
'seriesId',
221+
// @ts-expect-error
222+
{ stackedData: [[0, 1]] },
185223
xKey,
186224
{
187-
// @ts-expect-error
188225
[xKey]: { id: xKey, scaleType: 'linear' },
189226
},
190227
yKey,
@@ -204,9 +241,10 @@ describe('BarChart - checkScaleErrors', () => {
204241
checkScaleErrors(
205242
false,
206243
'seriesId',
244+
// @ts-expect-error
245+
{ stackedData: [[0, 1]] },
207246
xKey,
208247
{
209-
// @ts-expect-error
210248
[xKey]: { id: xKey, scaleType: 'band' },
211249
},
212250
yKey,

packages/x-charts/src/BarChart/checkScaleErrors.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { warnOnce } from '@mui/x-internals/warning';
12
import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
23
import { AxisDefaultized, AxisId, isBandScaleConfig, isPointScaleConfig } from '../models/axis';
4+
import { DefaultizedBarSeriesType } from '../models/seriesType/bar';
35
import { SeriesId } from '../models/seriesType/common';
46

57
const getAxisMessage = (axisDirection: 'x' | 'y', axisId: AxisId) => {
@@ -14,6 +16,7 @@ const getAxisMessage = (axisDirection: 'x' | 'y', axisId: AxisId) => {
1416
export function checkScaleErrors(
1517
verticalLayout: boolean,
1618
seriesId: SeriesId,
19+
series: DefaultizedBarSeriesType & { stackedData: [number, number][] },
1720
xAxisId: AxisId,
1821
xAxis: { [axisId: AxisId]: AxisDefaultized },
1922
yAxisId: AxisId,
@@ -46,4 +49,15 @@ export function checkScaleErrors(
4649
`MUI X: ${getAxisMessage(continuousAxisDirection, continuousAxisId)} should be a continuous type to display the bar series of id "${seriesId}".`,
4750
);
4851
}
52+
if (process.env.NODE_ENV !== 'production') {
53+
if (discreteAxisConfig.data.length < series.stackedData.length) {
54+
warnOnce(
55+
[
56+
`MUI X: ${getAxisMessage(discreteAxisDirection, discreteAxisId)} has less data (${discreteAxisConfig.data.length} values) than the bar series of id "${seriesId}" (${series.stackedData.length} values).`,
57+
'The axis data should have at least the same length than the series using it.',
58+
],
59+
'error',
60+
);
61+
}
62+
}
4963
}

packages/x-charts/src/LineChart/LinePlot.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import * as React from 'react';
33
import PropTypes from 'prop-types';
44
import { styled } from '@mui/material/styles';
5+
import { warnOnce } from '@mui/x-internals/warning';
56
import { line as d3Line } from '@mui/x-charts-vendor/d3-shape';
67
import {
78
LineElement,
@@ -98,8 +99,9 @@ const useAggregatedData = () => {
9899
);
99100
}
100101
if (xData.length < stackedData.length) {
101-
throw new Error(
102+
warnOnce(
102103
`MUI X: The data length of the x axis (${xData.length} items) is lower than the length of series (${stackedData.length} items).`,
104+
'error',
103105
);
104106
}
105107
}

0 commit comments

Comments
 (0)