Recharts Responsive Container does not resize correctly in flexbox
Solution 1
It seems rather hacky but a viable fix is to set width to 99% with a height or aspect ratio.
<ResponsiveContainer width="99%" aspect={3}>
See this issue:
https://github.com/recharts/recharts/issues/172
Solution 2
I know this is a really old issue, but I'm posting here just in case somebody else lands here via Google.
I don't know why this works, but setting position: absolute
on .recharts-wrapper
will fix this issue entirely. So far I have found no downsides to this, but YRMV.
Solution 3
Since I'm having similar problems in my project, I decided to stick with this question. I was finally able to get a working solution!
I'll list the changes I made from biggest to smallest:
I lifted state up from
CustomLegend
toCustomChart
.
Now,
CustomChart
is in charge of what happens. It passes visibility information toCustomLegend
as a prop. How doesCustomChart
know when to change state?-
CustomChart
has a member function calledhandleButtonClick
that sets its state.handleButtonClick
is sent toCustomLegend
as a prop. SoCustomChart
rendersCustomLegend
like this:<CustomLegend items={legendData} onClick={this.handleButtonClick} legendVisible={this.state.legendVisible} />
Now in
CustomLegend
, we can include this in thebutton
definition:onClick={this.props.onClick}
Note that this pattern only works if the original function is bound to the parent since it alters the parent's state.
chart-container
is now a CSS Grid container.
-
It renders an inline style handling the column width based on state.
<div className="chart-container" style={{ gridTemplateColumns: this.state.legendVisible ? "80% 1fr" : "1fr min-content" }} >
Note that
1fr
is a fractional unit which, in this case, serves to fill the remaining space. - In
styles.css
,grid-auto-flow
is set tocolumn
which allows things to be placed in the grid as columns. The things we place into the grid areSampleChart
andCustomLegend
, soSampleChart
is the left column andCustomLegend
is the right column. -
gridTemplateColumns: 80% 1fr
: When the legend is visible, we want the left column to take up 80% of the width and the right column to fill the rest. -
gridTemplateColumns: 1fr min-content
: When the legend is invisible, we want the right column to take up the minimum amount of space which its elements fill and the left column to fill the remaining space.
CustomLegend
has only a singlerender
method.
- Instead of
renderVisible
andrenderHidden
, there is one method which conditionally renders thelegend-list
based on props (dependent onCustomChart
's state). - The
legend-container
always renders now (it is a grid item).
Other small changes:
- In
SampleChart
:<ResponsiveContainer width="100%" height="100%" className={props.className}>
This has been changed because<SampleChart className="chart-area" data={data} />
actually sendsclassName
as a prop. Be careful with this! You need to setclassName
directly on the parent tag inSampleChart
's returned hierarchy (in this case theResponsiveContainer
). Try going back to your original codesandbox and changing thebackground-color
onchart-area
instyles.css
(nothing happens!). -
overflow: scroll
in all instances fromstyles.css
because we no longer need it.
You'll notice that if you attempt a grid layout using only fr
units or any flex layout on chart-container
, that the chart doesn't resize properly. Unfortunately, Recharts' ResponsiveContainer
s just don't play nicely with Grid or Flexbox (the project's main contributors are gradually tapering off support – no commits in 3 months as of now).
Lucas D
Updated on September 16, 2021Comments
-
Lucas D over 2 years
I'm trying to create a custom collapsable legend for my data visualization app. It uses react and recharts. the component renders nicely the first time. But when I collapse the legend and reopen it, the responsive container doesn't shrink to fit. This would be easier if I knew the size of the parent container in pixels but I don't have that information on render. Is this a bug with recharts or flex box or am I doing it wrong?
Heres the code: https://codesandbox.io/s/8krz9qjk52
Clarification: The problem is that when I close and then open the legend, the legend component gets pushed out of the viewing area and the chart does not shrink back to the original smaller size.
-
Lucas D almost 6 yearsthat doest help. When I close and then open the legend, the legend component get pushed out of the viewing area and the chart does not shrink back to the original smaller size
-
Parabolord almost 6 yearsSorry, I misinterpreted the question. Check out my second answer!
-
Ryxle over 4 yearsThis worked for me. I don't know why this works. Appreciate it if someone can shed the light on this issue.
-
rufatZZ over 2 yearsHOW? Because this one is working :D
-
A.com over 2 yearstypescript says it needs a number
-
A.com over 2 yearsts also says aspect doesn't exist