-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Is your feature request related to a problem? Please describe.
Yes. We recently tried updating/upgrading from v2 to v3.
A long standing bug that we'd experienced and made a fix for, was the way in which the charts rounded bar graphs, especially stacked bar graphs.
It was only on a per "cell" basis, and did not take neighboring bar charts into account.
Our solution on v2:
A clipping mask, that perfectly fits the bars, and rounds the corners of all bars at once.
{stacked ? <Customized component={BarClippingMask} id={id} /> : null}const BarClippingMask = (props) => {
const { formattedGraphicalItems } = props;
const barProps: any[] = formattedGraphicalItems.filter(item => item.props.key.startsWith('bar-')).map(item => item.props);
var individualBars: any[] = [];
const dataLength = max(barProps.map(bar => bar?.data?.length ?? 0));
for (let i = 0; i < dataLength; i++)
individualBars[i] = barProps.filter(bar => !!bar.data).map(bar => bar.data[i]);
return (
<defs>
<clipPath id={`clip-all-bars-${props.id}`}>
{
individualBars.map((bar, i) => {
const minY = min(bar.map(d => d.y));
const minX = min(bar.map(d => d.x));
const posH = sum(bar.map(d => d.height >= 0 ? d.height : 0));
const negH = sum(bar.map(d => d.height < 0 ? d.height : 0));
const maxW: number = max(bar.map(d => d.width))!;
const topRadius = calculateRadius(posH, maxW);
const botRadius = calculateRadius(negH, maxW);
if (posH > 0) {
return (
<path key={i} style={{ transform: `translate(${minX}px, ${minY}px)` }} d={getRoundedRectanglePath(maxW, Math.abs(negH) + posH, topRadius, topRadius, botRadius, botRadius)} />
);
} else {
return (
<path key={i} style={{ transform: `translate(${minX}px, ${minY}px)` }} d={getRoundedRectanglePath(maxW, negH, botRadius, botRadius, topRadius, topRadius)} />
);
}
})
}
</clipPath>
</defs>
);
};
export default BarClippingMask;Describe the solution you'd like
Either:
a: Provide access to the graphical information on final bar outputs. Maybe through a useFormattedGraphicalItems or useComputedGraphicalItems hook?
b: Add a setting to round the corners of all bars in stack.
Describe alternatives you've considered
"Why not simply round the top bar?"
We tried that, but we have several entries, sometimes 5 or more, that can be only a few pixels high. So this causes other issues/complaints.
Using the values from useAppSelector to get the current graphical items:
const isPanorama = useIsPanorama();
const chartState = useAppSelector((state: any) => {
// Attempt One:
const bars = state.graphicalItems.cartesianItems.filter(item => item.type === 'bar').map(item => selectBarRectangles(state, props.xAxisId, props.yAxisId, isPanorama, item.id, []));
// Attempt Two:
return selectAllVisibleBars(state, props.xAxisId, props.yAxisId, isPanorama);
});
console.log('chartState', chartState);Two Major Issues here,
- This code doesn't work. The entries inside of graphical items do not actually contain the data it's supposed to. All the props on
graphicalItems.cartesianItems[0]are props that I was providing and already had access to, - It's a hack. Clearly this was not even remotely the intended way. The fact that props on these entries are incomplete or missing confirms it...
