Skip to content

Commit 895a29f

Browse files
committed
fix(ComponsedChart): use scale band where possible
1 parent 7a3119d commit 895a29f

File tree

2 files changed

+66
-1526
lines changed

2 files changed

+66
-1526
lines changed

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

Lines changed: 58 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { XAxisTicks } from '@ui5/webcomponents-react-charts/lib/components/XAxis
77
import { YAxisTicks } from '@ui5/webcomponents-react-charts/lib/components/YAxisTicks';
88
import { ChartContainer } from '@ui5/webcomponents-react-charts/lib/next/ChartContainer';
99
import { useLegendItemClick } from '@ui5/webcomponents-react-charts/lib/useLegendItemClick';
10-
import debounce from 'lodash.debounce';
11-
import React, { FC, forwardRef, Ref, useCallback, useMemo, useState } from 'react';
10+
import React, { FC, forwardRef, Ref, useCallback, useMemo } from 'react';
1211
import {
1312
Area,
1413
Bar,
@@ -31,7 +30,7 @@ import { IChartDimension } from '../../interfaces/IChartDimension';
3130
import { IChartMeasure } from '../../interfaces/IChartMeasure';
3231
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
3332
import { defaultFormatter } from '../../internal/defaults';
34-
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity, xAxisPadding } from '../../internal/staticProps';
33+
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
3534

3635
const dimensionDefaults = {
3736
formatter: defaultFormatter
@@ -103,8 +102,6 @@ enum ChartTypes {
103102
area = Area
104103
}
105104

106-
const BAR_DEFAULT_PADDING = 20;
107-
108105
type AvailableChartTypes = 'line' | 'bar' | 'area' | string;
109106

110107
/**
@@ -127,9 +124,6 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
127124
} = props;
128125

129126
const chartRef = useConsolidatedRef<any>(ref);
130-
const [currentBarWidth, setCurrentBarWidth] = useState(
131-
dataset.some(({ type }) => type === 'bar') ? BAR_DEFAULT_PADDING : 0
132-
);
133127

134128
const chartConfig = useMemo(() => {
135129
return {
@@ -166,34 +160,34 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
166160
(payload, eventOrIndex, event) => {
167161
if (payload.name) {
168162
typeof onDataPointClick === 'function' &&
169-
onDataPointClick(
170-
enrichEventWithDetails(event ?? eventOrIndex, {
171-
value: payload.value.length ? payload.value[1] - payload.value[0] : payload.value,
172-
dataIndex: payload.index ?? eventOrIndex,
173-
dataKey: payload.value.length
174-
? Object.keys(payload).filter((key) =>
175-
payload.value.length
176-
? payload[key] === payload.value[1] - payload.value[0]
177-
: payload[key] === payload.value && key !== 'value'
178-
)[0]
179-
: payload.dataKey ??
180-
Object.keys(payload).find((key) => payload[key] === payload.value && key !== 'value'),
181-
payload: payload.payload
182-
})
183-
);
163+
onDataPointClick(
164+
enrichEventWithDetails(event ?? eventOrIndex, {
165+
value: payload.value.length ? payload.value[1] - payload.value[0] : payload.value,
166+
dataIndex: payload.index ?? eventOrIndex,
167+
dataKey: payload.value.length
168+
? Object.keys(payload).filter((key) =>
169+
payload.value.length
170+
? payload[key] === payload.value[1] - payload.value[0]
171+
: payload[key] === payload.value && key !== 'value'
172+
)[0]
173+
: payload.dataKey ??
174+
Object.keys(payload).find((key) => payload[key] === payload.value && key !== 'value'),
175+
payload: payload.payload
176+
})
177+
);
184178
} else {
185179
typeof onDataPointClick === 'function' &&
186-
onDataPointClick(
187-
enrichEventWithDetails(
188-
{},
189-
{
190-
value: eventOrIndex.value,
191-
dataKey: eventOrIndex.dataKey,
192-
dataIndex: eventOrIndex.index,
193-
payload: eventOrIndex.payload
194-
}
195-
)
196-
);
180+
onDataPointClick(
181+
enrichEventWithDetails(
182+
{},
183+
{
184+
value: eventOrIndex.value,
185+
dataKey: eventOrIndex.dataKey,
186+
dataIndex: eventOrIndex.index,
187+
payload: eventOrIndex.payload
188+
}
189+
)
190+
);
197191
}
198192
},
199193
[onDataPointClick]
@@ -217,30 +211,8 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
217211
};
218212

219213
const Placeholder = useCallback(() => {
220-
return <ComposedChartPlaceholder layout={layout} measures={measures} />;
214+
return <ComposedChartPlaceholder layout={layout} measures={measures}/>;
221215
}, [layout, measures]);
222-
223-
const updateChartPadding = useCallback(
224-
debounce(() => {
225-
if (chartRef.current) {
226-
const bars = chartRef.current.querySelectorAll(
227-
'.recharts-bar-rectangles .recharts-bar-rectangle:first-child path'
228-
);
229-
if (bars.length) {
230-
let totalBarWidth = 0;
231-
bars.forEach((bar) => {
232-
const bBox = bar.getBBox();
233-
totalBarWidth += layout === 'vertical' ? bBox.height : bBox.width;
234-
});
235-
setCurrentBarWidth(totalBarWidth);
236-
}
237-
}
238-
}, 50),
239-
[chartRef, setCurrentBarWidth, layout, props.dimensions]
240-
);
241-
242-
const chartDoesNotContainAnyBars = !props.measures.some((measure) => measure.type === 'bar');
243-
244216
return (
245217
<ChartContainer
246218
ref={chartRef}
@@ -259,51 +231,43 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
259231
stroke={chartConfig.gridStroke}
260232
/>
261233
{chartConfig.xAxisVisible &&
262-
dimensions.map((dimension, index) => {
263-
let AxisComponent;
264-
const axisProps = {
265-
key: dimension.accessor,
266-
dataKey: dimension.accessor,
267-
interval: dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0),
268-
tickLine: index < 1,
269-
axisLine: index < 1,
270-
allowDuplicatedCategory: index === 0
271-
};
272-
273-
if (layout === 'vertical') {
274-
axisProps.type = 'category';
275-
axisProps.tick = <YAxisTicks config={dimension} />;
276-
axisProps.yAxisId = index;
277-
axisProps.padding = { top: currentBarWidth, bottom: currentBarWidth };
278-
axisProps.width = yAxisWidth;
279-
AxisComponent = YAxis;
280-
} else {
281-
axisProps.dataKey = dimension.accessor;
282-
axisProps.tick = <XAxisTicks config={dimension} />;
283-
axisProps.xAxisId = index;
284-
if (chartDoesNotContainAnyBars) {
285-
axisProps.padding = xAxisPadding;
286-
} else {
287-
axisProps.padding = { left: currentBarWidth, right: currentBarWidth };
288-
}
234+
dimensions.map((dimension, index) => {
235+
let AxisComponent;
236+
const axisProps: any = {
237+
dataKey: dimension.accessor,
238+
interval: dimension?.interval ?? (isBigDataSet ? 'preserveStart' : 0),
239+
tickLine: index < 1,
240+
axisLine: index < 1,
241+
allowDuplicatedCategory: index === 0,
242+
scale: dimensions.length === 1 ? 'band' : 'auto'
243+
};
289244

290-
axisProps.height = xAxisHeights[index];
291-
// axisProps.height = 100
292-
AxisComponent = XAxis;
293-
}
245+
if (layout === 'vertical') {
246+
axisProps.type = 'category';
247+
axisProps.tick = <YAxisTicks config={dimension}/>;
248+
axisProps.yAxisId = index;
249+
axisProps.width = yAxisWidth;
250+
AxisComponent = YAxis;
251+
} else {
252+
axisProps.dataKey = dimension.accessor;
253+
axisProps.tick = <XAxisTicks config={dimension}/>;
254+
axisProps.xAxisId = index;
255+
axisProps.height = xAxisHeights[index];
256+
AxisComponent = XAxis;
257+
}
294258

295-
return <AxisComponent {...axisProps} />;
296-
})}
259+
return <AxisComponent key={dimension.accessor} {...axisProps} />;
260+
})}
297261
{layout === 'horizontal' && (
298262
<YAxis
299263
{...measureAxisProps}
300264
yAxisId="primary"
301265
width={yAxisWidth}
302-
tick={<YAxisTicks config={primaryMeasure} />}
266+
tick={<YAxisTicks config={primaryMeasure}/>}
303267
/>
304268
)}
305269
{layout === 'vertical' && (
306-
<XAxis {...measureAxisProps} xAxisId="primary" type="number" tick={<XAxisTicks config={primaryMeasure} />} />
270+
<XAxis {...measureAxisProps} xAxisId="primary" type="number" tick={<XAxisTicks config={primaryMeasure}/>}/>
307271
)}
308272

309273
{chartConfig.secondYAxis?.dataKey && layout === 'horizontal' && (
@@ -337,7 +301,7 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
337301
xAxisId={layout === 'vertical' ? 'primary' : undefined}
338302
/>
339303
)}
340-
<Tooltip cursor={tooltipFillOpacity} formatter={tooltipValueFormatter} contentStyle={tooltipContentStyle} />
304+
<Tooltip cursor={tooltipFillOpacity} formatter={tooltipValueFormatter} contentStyle={tooltipContentStyle}/>
341305
{!noLegend && (
342306
<Legend
343307
verticalAlign={chartConfig.legendPosition}
@@ -350,7 +314,6 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
350314
const ChartElement = (ChartTypes[element.type] as any) as FC<any>;
351315

352316
const chartElementProps: any = {
353-
onAnimationEnd: updateChartPadding,
354317
isAnimationActive: noAnimation === false
355318
};
356319
let labelPosition = 'top';
@@ -376,7 +339,6 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
376339
} else {
377340
labelPosition = 'insideTop';
378341
}
379-
chartElementProps.maxBarSize = 40;
380342
break;
381343
case 'area':
382344
chartElementProps.dot = !isBigDataSet;
@@ -398,7 +360,7 @@ const ComposedChart: FC<ComposedChartProps> = forwardRef((props: ComposedChartPr
398360
name={element.label ?? element.accessor}
399361
label={
400362
isBigDataSet ? null : (
401-
<ChartDataLabel config={element} chartType={element.type} position={labelPosition} />
363+
<ChartDataLabel config={element} chartType={element.type} position={labelPosition}/>
402364
)
403365
}
404366
stroke={element.color ?? `var(--sapChart_OrderedColor_${(index % 11) + 1})`}

0 commit comments

Comments
 (0)