Skip to content

Commit 86e568a

Browse files
authored
fix(charts): correctly apply React key with function accessors (#5775)
Fixes #5774
1 parent e47319a commit 86e568a

File tree

10 files changed

+66
-31
lines changed

10 files changed

+66
-31
lines changed

packages/charts/src/components/BarChart/BarChart.cy.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ const dimensions = [
88
interval: 0
99
}
1010
];
11+
1112
const measures = [
1213
{
13-
accessor: 'users',
14+
accessor: (data) => data.users,
1415
label: 'Users',
1516
formatter: (val: number) => val.toLocaleString('en')
1617
},
1718
{
18-
accessor: 'sessions',
19+
accessor: (data) => data.sessions,
1920
label: 'Active Sessions',
2021
formatter: (val) => `${val} sessions`,
2122
hideDataLabel: true
@@ -66,7 +67,16 @@ describe('BarChart', () => {
6667
'have.been.calledWith',
6768
Cypress.sinon.match({
6869
detail: Cypress.sinon.match({
69-
dataKey: 'users'
70+
value: 'Users'
71+
})
72+
})
73+
);
74+
cy.contains('Vol.').click();
75+
cy.get('@onLegendClick').should(
76+
'have.been.calledWith',
77+
Cypress.sinon.match({
78+
detail: Cypress.sinon.match({
79+
dataKey: 'volume'
7080
})
7181
})
7282
);

packages/charts/src/components/BarChart/BarChart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ const BarChart = forwardRef<HTMLDivElement, BarChartProps>((props, ref) => {
297297
<YAxis
298298
interval={dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
299299
type="category"
300-
key={dimension.accessor}
300+
key={dimension.reactKey}
301301
dataKey={dimension.accessor}
302302
tick={<YAxisTicks config={dimension} />}
303303
tickLine={index < 1}
@@ -316,7 +316,7 @@ const BarChart = forwardRef<HTMLDivElement, BarChartProps>((props, ref) => {
316316
<Bar
317317
stackId={element.stackId}
318318
fillOpacity={element.opacity}
319-
key={element.accessor}
319+
key={element.reactKey}
320320
name={element.label ?? element.accessor}
321321
strokeOpacity={element.opacity}
322322
type="monotone"

packages/charts/src/components/BulletChart/BulletChart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ const BulletChart = forwardRef<HTMLDivElement, BulletChartProps>((props, ref) =>
319319
axisProps.reversed = isRTL;
320320
}
321321

322-
return <AxisComponent key={dimension.accessor} {...axisProps} />;
322+
return <AxisComponent key={dimension.reactKey} {...axisProps} />;
323323
})}
324324
{layout === 'horizontal' && (
325325
<YAxis
@@ -473,7 +473,7 @@ const BulletChart = forwardRef<HTMLDivElement, BulletChartProps>((props, ref) =>
473473

474474
return (
475475
<Bar
476-
key={element.accessor}
476+
key={element.reactKey}
477477
name={element.label ?? element.accessor}
478478
label={
479479
isBigDataSet ? null : <ChartDataLabel config={element} chartType={'bar'} position={labelPosition} />

packages/charts/src/components/ColumnChart/ColumnChart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const ColumnChart = forwardRef<HTMLDivElement, ColumnChartProps>((props, ref) =>
253253
dimensions.map((dimension, index) => {
254254
return (
255255
<XAxis
256-
key={dimension.accessor}
256+
key={dimension.reactKey}
257257
dataKey={dimension.accessor}
258258
xAxisId={index}
259259
interval={dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
@@ -310,7 +310,7 @@ const ColumnChart = forwardRef<HTMLDivElement, ColumnChartProps>((props, ref) =>
310310
yAxisId={chartConfig.secondYAxis?.dataKey === element.accessor ? 'right' : 'left'}
311311
stackId={element.stackId}
312312
fillOpacity={element.opacity}
313-
key={element.accessor}
313+
key={element.reactKey}
314314
name={element.label ?? element.accessor}
315315
strokeOpacity={element.opacity}
316316
type="monotone"

packages/charts/src/components/ComposedChart/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ const ComposedChart = forwardRef<HTMLDivElement, ComposedChartProps>((props, ref
326326
axisProps.reversed = isRTL;
327327
}
328328

329-
return <AxisComponent key={dimension.accessor} {...axisProps} />;
329+
return <AxisComponent key={dimension.reactKey} {...axisProps} />;
330330
})}
331331
{layout === 'horizontal' && (
332332
<YAxis
@@ -487,7 +487,7 @@ const ComposedChart = forwardRef<HTMLDivElement, ComposedChartProps>((props, ref
487487
}
488488
return (
489489
<ChartElement
490-
key={element.accessor}
490+
key={element.reactKey}
491491
name={element.label ?? element.accessor}
492492
label={
493493
element.type === 'bar' || isBigDataSet ? undefined : (

packages/charts/src/components/LineChart/LineChart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ const LineChart = forwardRef<HTMLDivElement, LineChartProps>((props, ref) => {
237237
{dimensions.map((dimension, index) => {
238238
return (
239239
<XAxis
240-
key={dimension.accessor}
240+
key={dimension.reactKey}
241241
dataKey={dimension.accessor}
242242
xAxisId={index}
243243
interval={dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
@@ -294,7 +294,7 @@ const LineChart = forwardRef<HTMLDivElement, LineChartProps>((props, ref) => {
294294
<Line
295295
dot={element.showDot ?? !isBigDataSet}
296296
yAxisId={chartConfig.secondYAxis?.dataKey === element.accessor ? 'right' : 'left'}
297-
key={element.accessor}
297+
key={element.reactKey}
298298
name={element.label ?? element.accessor}
299299
strokeOpacity={element.opacity}
300300
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

packages/charts/src/components/RadarChart/RadarChart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ const RadarChart = forwardRef<HTMLDivElement, RadarChartProps>((props, ref) => {
187187
{measures.map((element, index) => {
188188
return (
189189
<Radar
190-
key={element.accessor}
190+
key={element.reactKey}
191191
activeDot={{ onClick: onDataPointClickInternal } as any}
192192
name={element.label ?? element.accessor}
193193
dataKey={element.accessor}

packages/charts/src/components/ScatterChart/ScatterChart.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ const ScatterChart = forwardRef<HTMLDivElement, ScatterChartProps>((props, ref)
237237
{chartConfig.xAxisVisible && (
238238
<XAxis
239239
type={'number'}
240-
key={xMeasure?.accessor}
240+
key={typeof xMeasure?.accessor !== 'function' ? xMeasure?.accessor : xMeasure?.label}
241241
name={xMeasure?.label}
242242
dataKey={xMeasure?.accessor}
243243
xAxisId={0}
@@ -263,7 +263,7 @@ const ScatterChart = forwardRef<HTMLDivElement, ScatterChartProps>((props, ref)
263263
name={yMeasure?.label}
264264
axisLine={chartConfig.yAxisVisible}
265265
tickLine={tickLineConfig}
266-
key={yMeasure?.accessor}
266+
key={typeof yMeasure?.accessor !== 'function' ? yMeasure?.accessor : yMeasure?.label}
267267
dataKey={yMeasure?.accessor}
268268
tickFormatter={yMeasure?.formatter}
269269
interval={0}
@@ -272,7 +272,12 @@ const ScatterChart = forwardRef<HTMLDivElement, ScatterChartProps>((props, ref)
272272
margin={yMeasure?.label ? { left: 200 } : 0}
273273
orientation={isRTL === true ? 'right' : 'left'}
274274
/>
275-
<ZAxis name={zMeasure?.label} dataKey={zMeasure?.accessor} range={[0, 5000]} key={zMeasure?.accessor} />
275+
<ZAxis
276+
name={zMeasure?.label}
277+
dataKey={zMeasure?.accessor}
278+
range={[0, 5000]}
279+
key={typeof zMeasure?.accessor !== 'function' ? zMeasure?.accessor : zMeasure?.label}
280+
/>
276281
{dataset?.map((dataSet, index) => {
277282
return (
278283
<Scatter

packages/charts/src/hooks/usePrepareDimensionsAndMeasures.cy.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ describe('useLabelFormatter', () => {
2727
cy.get('@result').should('have.been.calledWith', {
2828
dimensions: [
2929
{
30-
accessor: 'a'
30+
accessor: 'a',
31+
reactKey: 'a'
3132
}
3233
],
3334
measures: [
3435
{
35-
accessor: 'b'
36+
accessor: 'b',
37+
reactKey: 'b'
3638
}
3739
]
3840
});
@@ -52,13 +54,15 @@ describe('useLabelFormatter', () => {
5254
dimensions: [
5355
{
5456
accessor: 'a',
55-
dimensionDefault: true
57+
dimensionDefault: true,
58+
reactKey: 'a'
5659
}
5760
],
5861
measures: [
5962
{
6063
accessor: 'b',
61-
measureDefault: true
64+
measureDefault: true,
65+
reactKey: 'b'
6266
}
6367
]
6468
});
@@ -81,13 +85,15 @@ describe('useLabelFormatter', () => {
8185
dimensions: [
8286
{
8387
accessor: 'a',
84-
dimensionDefault: true
88+
dimensionDefault: true,
89+
reactKey: 'a'
8590
}
8691
],
8792
measures: [
8893
{
8994
accessor: 'b',
90-
measureDefault: true
95+
measureDefault: true,
96+
reactKey: 'b'
9197
}
9298
]
9399
});

packages/charts/src/hooks/usePrepareDimensionsAndMeasures.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import { useMemo } from 'react';
22

3+
function getAccessorReactKey(accessorObj: Record<string, any>) {
4+
let reactKey = accessorObj.accessor;
5+
if (typeof accessorObj.accessor === 'function') {
6+
reactKey = JSON.stringify(accessorObj);
7+
}
8+
return reactKey;
9+
}
10+
311
export const usePrepareDimensionsAndMeasures = <DimensionConfig = any, MeasureConfig = any>(
412
rawDimensions,
513
rawMeasures,
@@ -8,19 +16,25 @@ export const usePrepareDimensionsAndMeasures = <DimensionConfig = any, MeasureCo
816
) => {
917
const dimensions: DimensionConfig = useMemo(
1018
() =>
11-
rawDimensions.map((label) => ({
12-
...dimensionDefaults,
13-
...label
14-
})),
19+
rawDimensions.map((dimension) => {
20+
return {
21+
...dimensionDefaults,
22+
...dimension,
23+
reactKey: getAccessorReactKey(dimension)
24+
};
25+
}),
1526
[rawDimensions, dimensionDefaults]
1627
);
1728

1829
const measures: MeasureConfig = useMemo(
1930
() =>
20-
rawMeasures.map((value) => ({
21-
...measureDefaults,
22-
...value
23-
})),
31+
rawMeasures.map((measure) => {
32+
return {
33+
...measureDefaults,
34+
...measure,
35+
reactKey: getAccessorReactKey(measure)
36+
};
37+
}),
2438
[rawMeasures, measureDefaults]
2539
);
2640

0 commit comments

Comments
 (0)