Skip to content

Commit db3a5b7

Browse files
authored
fix(Charts-New): fix labels of donut chart and yAxis width calculation of bar chart (#498)
1 parent 2c73460 commit db3a5b7

File tree

13 files changed

+78
-91
lines changed

13 files changed

+78
-91
lines changed

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
YAxis
2121
} from 'recharts';
2222
import { useChartMargin } from '../../hooks/useChartMargin';
23-
import { useLongestYAxisLabel } from '../../hooks/useLongestYAxisLabel';
2423
import { useObserveXAxisHeights } from '../../hooks/useObserveXAxisHeights';
2524
import { usePrepareDimensionsAndMeasures } from '../../hooks/usePrepareDimensionsAndMeasures';
2625
import { useTooltipFormatter } from '../../hooks/useTooltipFormatter';
@@ -29,6 +28,7 @@ import { IChartMeasure } from '../../interfaces/IChartMeasure';
2928
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
3029
import { defaultFormatter } from '../../internal/defaults';
3130
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
31+
import { useLongestYAxisLabelBar } from '../../hooks/useLongestYAxisLabelBar';
3232

3333
const dimensionDefaults = {
3434
formatter: defaultFormatter
@@ -159,10 +159,8 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
159159
const isBigDataSet = dataset?.length > 30;
160160
const primaryDimensionAccessor = primaryDimension?.accessor;
161161

162-
const [width, legendPosition] = useLongestYAxisLabel(dataset, dimensions);
163-
162+
const [width, legendPosition] = useLongestYAxisLabelBar(dataset, dimensions);
164163
const marginChart = useChartMargin(chartConfig.margin, chartConfig.zoomingTool);
165-
166164
const [xAxisHeight] = useObserveXAxisHeights(chartRef, 1);
167165

168166
return (
@@ -202,11 +200,12 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
202200
key={dimension.accessor}
203201
dataKey={dimension.accessor}
204202
xAxisId={index}
205-
tick={<YAxisTicks config={dimension} level={index} />}
203+
tick={<YAxisTicks config={dimension} />}
206204
tickLine={index < 1}
207205
axisLine={index < 1}
208206
yAxisId={index}
209-
width={width}
207+
width={width[index]}
208+
allowDuplicatedCategory={index === 0}
210209
/>
211210
);
212211
})}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { action } from '@storybook/addon-actions';
22
import { boolean } from '@storybook/addon-knobs';
33
import { BarChart } from '@ui5/webcomponents-react-charts/lib/next/BarChart';
44
import React from 'react';
5-
import { bigDataSet, complexDataSet, secondaryDimensionDataSet, simpleDataSet } from '../../resources/DemoProps';
5+
import { complexDataSet, secondaryDimensionDataSet, simpleDataSet } from '../../resources/DemoProps';
66

77
export default {
88
title: 'Charts - Unstable / BarChart',

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,11 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
193193
dataKey={dimension.accessor}
194194
xAxisId={index}
195195
interval={dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
196-
tick={<XAxisTicks config={dimension} level={index} />}
196+
tick={<XAxisTicks config={dimension} />}
197197
tickLine={index < 1}
198198
axisLine={index < 1}
199199
height={xAxisHeights[index]}
200+
allowDuplicatedCategory={index === 0}
200201
/>
201202
);
202203
})}

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { IChartDimension } from '../../interfaces/IChartDimension';
3131
import { IChartMeasure } from '../../interfaces/IChartMeasure';
3232
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
3333
import { defaultFormatter } from '../../internal/defaults';
34-
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
34+
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity, xAxisPadding } from '../../internal/staticProps';
3535

3636
const dimensionDefaults = {
3737
formatter: defaultFormatter
@@ -238,6 +238,8 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
238238
[chartRef, setCurrentBarWidth, layout, props.dimensions]
239239
);
240240

241+
const chartDoesNotContainAnyBars = !props.measures.some((measure) => measure.type === 'bar');
242+
241243
return (
242244
<ChartContainer
243245
ref={chartRef}
@@ -263,21 +265,27 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
263265
dataKey: dimension.accessor,
264266
interval: dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0),
265267
tickLine: index < 1,
266-
axisLine: index < 1
268+
axisLine: index < 1,
269+
allowDuplicatedCategory: index === 0
267270
};
268271

269272
if (layout === 'vertical') {
270273
axisProps.type = 'category';
271-
axisProps.tick = <YAxisTicks config={dimension} level={index} />;
274+
axisProps.tick = <YAxisTicks config={dimension} />;
272275
axisProps.yAxisId = index;
273276
axisProps.padding = { top: currentBarWidth, bottom: currentBarWidth };
274277
axisProps.width = yAxisWidth;
275278
AxisComponent = YAxis;
276279
} else {
277280
axisProps.dataKey = dimension.accessor;
278-
axisProps.tick = <XAxisTicks config={dimension} level={index} />;
281+
axisProps.tick = <XAxisTicks config={dimension} />;
279282
axisProps.xAxisId = index;
280-
axisProps.padding = { left: currentBarWidth, right: currentBarWidth };
283+
if (chartDoesNotContainAnyBars) {
284+
axisProps.padding = xAxisPadding;
285+
} else {
286+
axisProps.padding = { left: currentBarWidth, right: currentBarWidth };
287+
}
288+
281289
axisProps.height = xAxisHeights[index];
282290
// axisProps.height = 100
283291
AxisComponent = XAxis;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { IChartDimension } from '../../interfaces/IChartDimension';
2828
import { IChartMeasure } from '../../interfaces/IChartMeasure';
2929
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
3030
import { defaultFormatter } from '../../internal/defaults';
31-
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
31+
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity, xAxisPadding } from '../../internal/staticProps';
3232

3333
interface MeasureConfig extends IChartMeasure {
3434
/**
@@ -183,10 +183,12 @@ const LineChart: FC<LineChartProps> = forwardRef((props: LineChartProps, ref: Re
183183
dataKey={dimension.accessor}
184184
xAxisId={index}
185185
interval={dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
186-
tick={<XAxisTicks config={dimension} level={index} />}
186+
tick={<XAxisTicks config={dimension} />}
187187
tickLine={index < 1}
188188
axisLine={index < 1}
189189
height={xAxisHeights[index]}
190+
padding={xAxisPadding}
191+
allowDuplicatedCategory={index === 0}
190192
/>
191193
);
192194
})}

packages/charts/src/components/PieChart/PieChart.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const PieChart: FC<PieChartProps> = forwardRef((props: PieChartProps, ref: Ref<a
8989
}),
9090
[props.dimension]
9191
);
92+
9293
const measure: MeasureConfig = useMemo(
9394
() => ({
9495
formatter: defaultFormatter,
@@ -97,37 +98,36 @@ const PieChart: FC<PieChartProps> = forwardRef((props: PieChartProps, ref: Ref<a
9798
[props.measure]
9899
);
99100

101+
const label = useMemo(() => {
102+
return {
103+
position: 'outside',
104+
content: measure.DataLabel,
105+
formatter: measure.formatter
106+
};
107+
}, [measure]);
108+
100109
const tooltipValueFormatter = useCallback((value) => measure.formatter(value), [measure.formatter]);
101110
const chartRef = useConsolidatedRef<any>(ref);
102111

103112
const onItemLegendClick = useLegendItemClick(onLegendClick, () => measure.accessor);
104113

105114
const onDataPointClickInternal = useCallback(
106-
(payload, index, event) => {
107-
if (payload && onDataPointClick && payload.value) {
115+
(payload, event) => {
116+
if (payload && payload?.activePayload && onDataPointClick) {
108117
onDataPointClick(
109118
enrichEventWithDetails(event, {
110-
value: payload.value,
111-
dataKey: measure.accessor,
112-
name: payload.name,
113-
payload: payload.payload,
114-
dataIndex: index
119+
value: payload.activePayload[0].value,
120+
dataKey: payload.activePayload[0].dataKey,
121+
name: payload.activePayload[0].payload.name,
122+
payload: payload.activePayload[0].payload,
123+
dataIndex: payload.activeTooltipIndex
115124
})
116125
);
117126
}
118127
},
119128
[onDataPointClick]
120129
);
121130

122-
const label = useMemo(() => {
123-
if(measure.hideDataLabel) return null;
124-
return {
125-
position: 'outside',
126-
content: measure.DataLabel,
127-
formatter: measure.formatter
128-
};
129-
}, [measure]);
130-
131131
return (
132132
<ChartContainer
133133
dataset={dataset}
@@ -139,15 +139,16 @@ const PieChart: FC<PieChartProps> = forwardRef((props: PieChartProps, ref: Ref<a
139139
tooltip={tooltip}
140140
slot={slot}
141141
>
142-
<PieChartLib margin={chartConfig.margin}>
142+
<PieChartLib onClick={onDataPointClickInternal} margin={chartConfig.margin}>
143143
<Pie
144144
innerRadius={chartConfig.innerRadius}
145145
paddingAngle={chartConfig.paddingAngle}
146146
nameKey={dimension.accessor}
147147
dataKey={measure.accessor}
148148
data={dataset}
149+
animationBegin={0}
150+
isAnimationActive={false}
149151
label={label}
150-
onClick={onDataPointClickInternal}
151152
>
152153
{centerLabel && <Label position={'center'}>{centerLabel}</Label>}
153154
{dataset &&

packages/charts/src/hooks/useLongestYAxisLabel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ export const useLongestYAxisLabel = (dataset: unknown[], elements): [number, obj
1919
}
2020

2121
labelLength = Math.min(labelLength, defaultMaxYAxisWidth);
22+
2223
return [labelLength, { marginLeft: labelLength, maxWidth: `calc(100% - ${labelLength + 10}px)` }];
2324
}, [dataset, elements]);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { getTextWidth } from '@ui5/webcomponents-react-charts/lib/Utils';
2+
import { useMemo } from 'react';
3+
import { getValueByDataKey } from 'recharts/lib/util/ChartUtils';
4+
import { defaultMaxYAxisWidth } from '../internal/defaults';
5+
6+
export const useLongestYAxisLabelBar = (dataset: unknown[], elements): [number[], object] =>
7+
useMemo(() => {
8+
let axisWidths = Array(elements.length).fill(0);
9+
let marginLeft = 0;
10+
11+
if (dataset instanceof Array && elements) {
12+
const resolveAllMeasureLabels = (item): string[] => {
13+
return elements.map((elementConfig) =>
14+
elementConfig.formatter(getValueByDataKey(item, elementConfig.accessor, ''))
15+
);
16+
};
17+
18+
const allFormattedDataLabels = dataset.map(resolveAllMeasureLabels);
19+
allFormattedDataLabels.forEach((dimensionLabels) => {
20+
dimensionLabels.forEach((label, dimensionIndex) => {
21+
axisWidths[dimensionIndex] = Math.max(getTextWidth(label), axisWidths[dimensionIndex]);
22+
});
23+
});
24+
25+
axisWidths = axisWidths.map((length) => Math.min(defaultMaxYAxisWidth, length));
26+
marginLeft = axisWidths.reduce((acc, val) => acc + val, 0);
27+
}
28+
29+
return [axisWidths, { marginLeft, maxWidth: `calc(100% - ${marginLeft + 8}px)` }];
30+
}, [dataset, elements]);

packages/charts/src/internal/SecondaryDimensionXAxisTick.tsx

Lines changed: 0 additions & 23 deletions
This file was deleted.

packages/charts/src/internal/SecondaryDimensionYAxisTick.tsx

Lines changed: 0 additions & 22 deletions
This file was deleted.

packages/charts/src/internal/XAxisTicks.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingPara
22
import { getTextWidth, truncateLongLabel } from '@ui5/webcomponents-react-charts/lib/Utils';
33
import React, { FC } from 'react';
44
import { IChartMeasure } from '../interfaces/IChartMeasure';
5-
import { SecondaryDimensionTicksXAxis } from './SecondaryDimensionXAxisTick';
65

76
interface XAxisTicksProps {
87
visibleTicksCount?: number;
@@ -11,19 +10,14 @@ interface XAxisTicksProps {
1110
y?: number;
1211
payload?: any;
1312
config: IChartMeasure;
14-
level?: number;
1513
}
1614

1715
export const XAxisTicks: FC<XAxisTicksProps> = (props: XAxisTicksProps) => {
18-
const { x, y, payload, config, level = 0, visibleTicksCount, width } = props;
16+
const { x, y, payload, config, visibleTicksCount, width } = props;
1917

2018
const bandWidth = width / visibleTicksCount;
2119
const shouldRotate = bandWidth <= 100;
2220

23-
if (level > 0) {
24-
return <SecondaryDimensionTicksXAxis {...props} />;
25-
}
26-
2721
const formattedValue = config.formatter(payload.value);
2822
let textToDisplay = formattedValue;
2923
if (shouldRotate) {

packages/charts/src/internal/YAxisTicks.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@ import { getTextWidth, truncateLongLabel } from '@ui5/webcomponents-react-charts
33
import React, { FC } from 'react';
44
import { IChartMeasure } from '../interfaces/IChartMeasure';
55
import { defaultMaxYAxisWidth } from './defaults';
6-
import { SecondaryDimensionTicksYAxis } from './SecondaryDimensionYAxisTick';
76

87
interface YAxisTicksProps {
98
x?: number;
109
y?: number;
1110
payload?: any;
1211
config: IChartMeasure;
13-
level?: number;
1412
}
1513

1614
export const YAxisTicks: FC<YAxisTicksProps> = (props: YAxisTicksProps) => {
17-
const { x, y, payload, config, level = 0 } = props;
15+
const { x, y, payload, config } = props;
1816

19-
if (level > 0) {
20-
return <SecondaryDimensionTicksYAxis {...props} />;
21-
}
2217
const formattedValue = config.formatter(payload.value);
2318
let textToDisplay = formattedValue;
2419
if (getTextWidth(formattedValue) > defaultMaxYAxisWidth) {

packages/charts/src/internal/staticProps.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingPara
33
export const tickLineConfig = { stroke: 'transparent' };
44
export const tooltipContentStyle = { backgroundColor: ThemingParameters.sapBackgroundColor };
55
export const tooltipFillOpacity = { fillOpacity: 0.3 };
6+
export const xAxisPadding = { left: 25, right: 25 };

0 commit comments

Comments
 (0)