Recharts Responsive Container does not resize correctly in flexbox Recharts Responsive Container does not resize correctly in flexbox reactjs reactjs

Recharts Responsive Container does not resize correctly in flexbox


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


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!

codesandbox

I'll list the changes I made from biggest to smallest:

I lifted state up from CustomLegend to CustomChart.

  • Now, CustomChart is in charge of what happens. It passes visibility information to CustomLegend as a prop. How does CustomChart know when to change state?

  • CustomChart has a member function called handleButtonClick that sets its state. handleButtonClick is sent to CustomLegend as a prop. So CustomChart renders CustomLegend like this:

    <CustomLegend    items={legendData}    onClick={this.handleButtonClick}    legendVisible={this.state.legendVisible}/>

    Now in CustomLegend, we can include this in the button 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 to column which allows things to be placed in the grid as columns. The things we place into the grid are SampleChart and CustomLegend, so SampleChart is the left column and CustomLegend 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 single render method.

  • Instead of renderVisible and renderHidden, there is one method which conditionally renders the legend-list based on props (dependent on CustomChart'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 sends className as a prop. Be careful with this! You need to set className directly on the parent tag in SampleChart's returned hierarchy (in this case the ResponsiveContainer). Try going back to your original codesandbox and changing the background-color on chart-area in styles.css (nothing happens!).
  • overflow: scroll in all instances from styles.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' ResponsiveContainers 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).


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.