Skip to content

Commit 4a47e1d

Browse files
fix(Charts - New): layouting fixes (#488)
- Legend Position is always bottom, modifiable via `chartConfig.legendPosition` - Legend Horizontal Align is always Start (Center for Polar Charts), modifiable with `chartConfig.legendHorizontalAlign` - Calculation of longest y-axis-label, limited to 200px - adjust legend position based on needed axis size
1 parent c318ca2 commit 4a47e1d

File tree

16 files changed

+283
-164
lines changed

16 files changed

+283
-164
lines changed

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

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,22 @@ import {
2020
YAxis
2121
} from 'recharts';
2222
import { useChartMargin } from '../../hooks/useChartMargin';
23+
import { useLongestYAxisLabel } from '../../hooks/useLongestYAxisLabel';
24+
import { useObserveXAxisHeights } from '../../hooks/useObserveXAxisHeights';
2325
import { usePrepareDimensionsAndMeasures } from '../../hooks/usePrepareDimensionsAndMeasures';
2426
import { useTooltipFormatter } from '../../hooks/useTooltipFormatter';
2527
import { IChartDimension } from '../../interfaces/IChartDimension';
2628
import { IChartMeasure } from '../../interfaces/IChartMeasure';
2729
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
30+
import { defaultFormatter } from '../../internal/defaults';
2831
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
2932

30-
const formatYAxisTicks = (tick = '') => {
31-
const splitTick = tick.split(' ');
32-
return splitTick.length > 3
33-
? `${splitTick.slice(0, 3).join(' ')}...`
34-
: tick.length > 11
35-
? `${tick.slice(0, 12)}...`
36-
: tick;
37-
};
38-
3933
const dimensionDefaults = {
40-
formatter: formatYAxisTicks
34+
formatter: defaultFormatter
4135
};
4236

4337
const measureDefaults = {
44-
formatter: (d) => d,
38+
formatter: defaultFormatter,
4539
opacity: 1
4640
};
4741

@@ -120,7 +114,8 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
120114
gridStroke: ThemingParameters.sapList_BorderColor,
121115
gridHorizontal: true,
122116
gridVertical: false,
123-
legendPosition: 'top',
117+
legendPosition: 'bottom',
118+
legendHorizontalAlign: 'left',
124119
barGap: 3,
125120
zoomingTool: false,
126121
...props.chartConfig
@@ -164,14 +159,11 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
164159
const isBigDataSet = dataset?.length > 30;
165160
const primaryDimensionAccessor = primaryDimension?.accessor;
166161

167-
const marginChart = useChartMargin(
168-
dataset,
169-
dimensions,
170-
chartConfig.margin,
171-
true,
172-
dimensions.length > 1,
173-
chartConfig.zoomingTool
174-
);
162+
const [width, legendPosition] = useLongestYAxisLabel(dataset, dimensions);
163+
164+
const marginChart = useChartMargin(chartConfig.margin, chartConfig.zoomingTool);
165+
166+
const [xAxisHeight] = useObserveXAxisHeights(chartRef, 1);
175167

176168
return (
177169
<ChartContainer
@@ -194,13 +186,14 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
194186
<XAxis
195187
interval={0}
196188
type="number"
197-
tick={<XAxisTicks config={primaryMeasure} chartRef={chartRef} />}
189+
tick={<XAxisTicks config={primaryMeasure} />}
198190
axisLine={chartConfig.xAxisVisible}
199191
tickLine={tickLineConfig}
200192
tickFormatter={primaryMeasure?.formatter}
193+
height={xAxisHeight}
201194
/>
202195
)}
203-
{(chartConfig.yAxisVisible) &&
196+
{chartConfig.yAxisVisible &&
204197
dimensions.map((dimension, index) => {
205198
return (
206199
<YAxis
@@ -213,6 +206,7 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
213206
tickLine={index < 1}
214207
axisLine={index < 1}
215208
yAxisId={index}
209+
width={width}
216210
/>
217211
);
218212
})}
@@ -234,7 +228,14 @@ const BarChart: FC<BarChartProps> = forwardRef((props: BarChartProps, ref: Ref<a
234228
/>
235229
);
236230
})}
237-
{!noLegend && <Legend verticalAlign={chartConfig.legendPosition} onClick={onItemLegendClick} />}
231+
{!noLegend && (
232+
<Legend
233+
verticalAlign={chartConfig.legendPosition}
234+
align={chartConfig.legendHorizontalAlign}
235+
onClick={onItemLegendClick}
236+
wrapperStyle={legendPosition}
237+
/>
238+
)}
238239
{chartConfig.referenceLine && (
239240
<ReferenceLine
240241
stroke={chartConfig.referenceLine.color}

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ import {
2020
YAxis
2121
} from 'recharts';
2222
import { useChartMargin } from '../../hooks/useChartMargin';
23+
import { useLongestYAxisLabel } from '../../hooks/useLongestYAxisLabel';
24+
import { useObserveXAxisHeights } from '../../hooks/useObserveXAxisHeights';
2325
import { usePrepareDimensionsAndMeasures } from '../../hooks/usePrepareDimensionsAndMeasures';
2426
import { useTooltipFormatter } from '../../hooks/useTooltipFormatter';
2527
import { IChartDimension } from '../../interfaces/IChartDimension';
2628
import { IChartMeasure } from '../../interfaces/IChartMeasure';
2729
import { RechartBaseProps } from '../../interfaces/RechartBaseProps';
30+
import { defaultFormatter } from '../../internal/defaults';
2831
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity } from '../../internal/staticProps';
2932

3033
interface MeasureConfig extends IChartMeasure {
@@ -76,11 +79,11 @@ export interface ColumnChartProps extends RechartBaseProps {
7679
}
7780

7881
const dimensionDefaults = {
79-
formatter: (d) => d
82+
formatter: defaultFormatter
8083
};
8184

8285
const measureDefaults = {
83-
formatter: (d) => d,
86+
formatter: defaultFormatter,
8487
opacity: 1
8588
};
8689

@@ -108,7 +111,8 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
108111
gridStroke: ThemingParameters.sapList_BorderColor,
109112
gridHorizontal: true,
110113
gridVertical: false,
111-
legendPosition: 'top',
114+
legendPosition: 'bottom',
115+
legendHorizontalAlign: 'left',
112116
barGap: 3,
113117
zoomingTool: false,
114118
...props.chartConfig
@@ -124,6 +128,8 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
124128

125129
const tooltipValueFormatter = useTooltipFormatter(measures);
126130

131+
const [yAxisWidth, legendPosition] = useLongestYAxisLabel(dataset, measures);
132+
127133
const primaryDimension = dimensions[0];
128134
const primaryMeasure = measures[0];
129135

@@ -159,14 +165,8 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
159165
const isBigDataSet = dataset?.length > 30 ?? false;
160166
const primaryDimensionAccessor = primaryDimension?.accessor;
161167

162-
const marginChart = useChartMargin(
163-
dataset,
164-
measures,
165-
chartConfig.margin,
166-
false,
167-
dimensions.length > 1,
168-
chartConfig.zoomingTool
169-
);
168+
const marginChart = useChartMargin(chartConfig.margin, chartConfig.zoomingTool);
169+
const xAxisHeights = useObserveXAxisHeights(chartRef, props.dimensions.length);
170170

171171
return (
172172
<ChartContainer
@@ -193,9 +193,10 @@ 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} chartRef={chartRef} level={index} />}
196+
tick={<XAxisTicks config={dimension} level={index} />}
197197
tickLine={index < 1}
198198
axisLine={index < 1}
199+
height={xAxisHeights[index]}
199200
/>
200201
);
201202
})}
@@ -205,6 +206,7 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
205206
yAxisId="left"
206207
interval={0}
207208
tick={<YAxisTicks config={primaryMeasure} />}
209+
width={yAxisWidth}
208210
/>
209211
{chartConfig.secondYAxis?.dataKey && (
210212
<YAxis
@@ -235,7 +237,14 @@ const ColumnChart: FC<ColumnChartProps> = forwardRef((props: ColumnChartProps, r
235237
/>
236238
);
237239
})}
238-
{!noLegend && <Legend verticalAlign={chartConfig.legendPosition} onClick={onItemLegendClick} />}
240+
{!noLegend && (
241+
<Legend
242+
verticalAlign={chartConfig.legendPosition}
243+
align={chartConfig.legendHorizontalAlign}
244+
onClick={onItemLegendClick}
245+
wrapperStyle={legendPosition}
246+
/>
247+
)}
239248
{chartConfig.referenceLine && (
240249
<ReferenceLine
241250
stroke={chartConfig.referenceLine.color}

0 commit comments

Comments
 (0)