New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot wrap Line
with customized component
#412
Comments
@huozhi |
I just ran into this issue. I'm trying to do the following:
No lines render (although the tooltip does work). thoughts? btw there's no Surface component in recharts as far as I can see. |
I found a workaround to customize original import { LineChart, Line as ReLine } from 'recharts';
// Extends the Line component to overwrite its default props
class Line extends ReLine {
static defaultProps = {
...ReLine.defaultProps,
// Customized props
strokeWidth: 2,
dot: false,
};
}
// In real use case
<LineChart data={data}>
<Line dataKey="example" />
</LineChart> |
I think this should be reopened as it still is an issue. The workaround from @cjies works but that's certainly not how it should be. |
@xile611 Yes I agree I think this is still an issue. I think that workaround is just adding more code and over declaration for wrapping components. I have encountered the same issue. I am currently using Recharts v1.0.0 and was trying to write a wrapped component that had too much prop settings on style that hindered readability for a bar chart.
|
Facing same issue.
|
If you set the statics, defaultProps, and displayName of the returned component from the HOF then you can wrap the components. Let's say I had a HOF that provided me a theme (from a ThemeProvider) as an example. Below is an example of wrapping the Line component:
I also tried this with react-redux's connect and it works fine. Hope this helps. |
Here's another workaround: Use the same approach that @sscaff1 is using only on the top-level chart components (BarChart, LineChart, etc), then map the children if the displayName is EDIT: The below example doesn't work without properly subtracting the component's Example: export const fixWrapperFC = <P extends BP, BP = {}>(b: React.ComponentType<BP>, wrapperFC: React.FC<P>, defaultProps?: Partial<P>): React.FC<P> => {
Object.assign(wrapperFC, b);
if (defaultProps) {
if (!wrapperFC.defaultProps) {
wrapperFC.defaultProps = {};
}
Object.assign(wrapperFC.defaultProps, defaultProps);
}
return wrapperFC;
};
const BarChart: React.FC<BarChartProps> = fixWrapperFC(BarChartBase, (props) => {
const { children, ...rest } = props;
// use context hook to provide defaults (themes, etc)
const ctx = React.useContext(MyThemeContext);
return (
<RCBarChart {...rest}>
{React.Children.map(children, (c: any) => {
if (!c || !c.type || !c.type.displayName) {
return c;
}
const displayName = c.type.displayName;
if (displayName === "XAxis") {
return React.cloneElement(c, {
...YOUR_DEFAULT_PROPS_HERE,
...c.props,
});
} else if (displayName === "YAxis") {
return React.cloneElement(c, {
...YOUR_DEFAULT_PROPS_HERE,
...c.props,
});
}
return c;
})}
</RCBarChart>
);
}, { <your bar chart default prop overrides here> }); |
Why is this closed? Wrapping still does not work on anything. @sscaff1 where does your @tibudiyanto's solution does not work if you use hooks in the out-sourced component. |
I also want to vote for this to be reopened, we have used Recharts to build a distinct visual style for our charts but the code for each element is complex. Having to copy and paste it to new charts rather than build our own building blocks on top is bad practice and not how React is meant to be used.
Even just wrapping a reference area in a functional component prevents it from working. I'm aware I'm probably doing something wrong, but this is a common pattern in React and it is not documented how to use the Recharts components in this way. |
The issue still persist and @sscaff1's workaround doesn't work for me. I get the line with the sizes of 0x0 rendered for some reason. This is such a react-y thing composing of components, and with this lib, you can't just simply do This thing should be definitely mentioned in the README and at the API docs page at the very top with bold and uppercase: WE DON'T SUPPORT WRAPPING COMPONENTS. UPD: workaround still works, but you need to pass |
+1 |
+1, why was this closed??? |
+1 |
+1 |
recharts sux +1 |
Did you find a better alternative for your use case? |
This would be nice to fix |
I am still facing the same issue, how come this has been closed? |
Yep, I use a |
This should be reopened since is breaking the base pattern to compose react applications @xile611 |
@xile611 Please, reopen this. This is a serious issue that collides with basic React approach to composition. |
+1 |
1 similar comment
+1 |
+1 |
4 similar comments
+1 |
+1 |
+1 |
+1 |
Re-opened this (unsure why it was closed like a lot of other issues). Unfortunately, recharts items such as Line, Area, etc. rely on their parent because their parent calls the (very complex and bloated) generator function that does almost all of the logic for recharts charts. Without that function Line, etc. have basically no functionally. This is an unfortunate design flaw that hasn't aged well as React has matured. Recharts needs a refactor of huge proportions in order to be able to support standard composition. It essentially created its own rules for what can be composed and what cannot. |
@sscaff1's solution didn't work for me for some props (e.g. |
this worked for me: import { Bar } from 'recharts';
import type { BarProps } from 'recharts/types/cartesian/Bar';
...
export const CustomBar = ({ className, ...props }: BarProps) => {
return (
<Bar
{...props}
{...barChartDefaultProps}
className={cn(barChartDefaultProps.className, className)} // clsx
/>
);
};
CustomBar.displayName = Bar.displayName;
CustomBar.getComposedData = Bar.getComposedData;
CustomBar.defaultProps = Bar.defaultProps; referenced @tibudiyanto turned out |
Following @tibudiyanto's approach, it seems like the most straightforward option is to return your wrapped
rather than
I personally stuck it in a hook as there's a bunch of React specific things I need to do before returning the JSX. |
this should be addressed once 3.x comes out |
I was trying to wrap
<Line />
with my customized component. Likebut the Line didn't render in the chart. Is there some way to do it correctly ? : )
The text was updated successfully, but these errors were encountered: