recharts
recharts copied to clipboard
Responsive Container it is very slow when resizing page
Do you want to request a feature or report a bug?
Seems like a bug.
What is the current behavior?
When I resize the page, the animation caused by ResponsiveContainer is very slow creating an horizontal overflow. This is propagated for all components in the page environment. I have a page with 4 charts like this:
<ResponsiveContainer width='99%' minHeight={ 275 }>
<BarChart
{ ...chartProps }
data={ props.values }>
<XAxis
{ ...axisProps }
hide
/>
<YAxis
{ ...axisProps }
interval={ 0 }
dataKey='date'
type='category'
tick={ {
...chartTextProps,
fontSize: 10
} }
/>
<Tooltip
separator={ '' }
formatter={ formatLabelTooltip }
labelFormatter={ formatDateTooltip }
/>
<Bar
dataKey='value'
fill={ GREEN_LABEL }
maxBarSize={ 12 }
fontSize={ 10 } >
<LabelList
dataKey='value'
position='right'
/>
</Bar>
</BarChart>
</ResponsiveContainer>
What is the expected behavior?
Resize more fast or not too slow.
Which versions of Recharts, and which browser / OS are affected by this issue? Did this work in previous versions of Recharts?
Recharts "1.6.2": Ubuntu - Chrome 73.0.3683.103 (have same behaviour on all the OSs and browsers)
I have the same problem. Please any feedback
I do experience this, for what it's worth it only seems to be an issue when decreasing in size, increase in size works as expected.
Same here
I have the same issue. When I resize the window. all animation is very slow not smoothly. any idea to fix it :(((
+1
Also facing this. EDIT: I can always reproduce it if at the element containing the ResponsiveContainer shrinks due to another element growing in size (ex. one flex item in a single-row flex container changing width)
+1 I'm also experiencing the same issue. Appreciate if someone can help me.
I made a code sandbox that sort of highlights it: https://codesandbox.io/s/gifted-elion-x3ilm?fontsize=14 It might just be a general performance problem if there's more than a few charts on the page. When the chart space grows, it is smooth. When it shrinks, it's not smooth unless there's only a couple charts. It happens even with a debounce value on the responsive containers. It would likely be noticeable on something like a dashboard.
+1
Any updates? Is there a way to only disable resize animations but keep the others?
+1
In my case, this was happening where there was a lot of data in the graphs. I'm representing the graphs in a flex box container, so I just added width: 0
property to the flex item and it solved the problem.
@stolaar can you please elaborate a bit on your solution? Perhaps share your code? Much appreciated!
Sorry for my unclear solution above. So this was the solution in my case. I have the following graphs:
JSX:
<div className="dashboard>
<div className="chart-container">
<ResponsiveContainer width="99%" aspect={2}>
{/* Graph components */ }
</ResponsiveContainer>
</div>
{ /* 5 more graphs here */ }
</div>
CSS:
.dashboard {
display: flex;
justify-content: space-evenly;
}
.chart-container {
flex: 0 1 500px;
width: 0;
}
width: 0
on the chart-container solves my problem.
Having the same issue: trying to have a drawer component that forces the graphs to stretch and shrink. @stolaar's solution doesn't fix it for me.
this happens because responsive container has width: 100%
, and its child, that is svg element, has fixed width, equal to containers width in px. that means the containers actual width is equal to its child width. so when you resize down, container doesn't change dimensions, and resize observer callback never gets called.
my workaround is to position absolute ResponsiveContainer
inside a 'responsive' div, and use that as a replacement.
import { ResponsiveContainer } from 'recharts';
function CustomResponsiveContainer(props) {
return (
<div style={{ width: '100%', height: '100%', position: 'relative' }}>
<div
style={{
width: '100%',
height: '100%',
position: 'absolute',
top: 0,
left: 0
}}
>
<ResponsiveContainer {...props} />
</div>
</div>
);
}
@VacaSan your fix made things slightly better but I'm still getting these laggy animations when resizing the window: https://share.getcloudapp.com/NQuD98GY
Any ideas on how to fix this? Is there a way to disable animations when resizing the window?
I had the same problem. I fixed it by adding "overflow-y: hidden;" to the ResponsiveContainer container.
My code is something similar to:
<div className="chart-wrapper">
<p className="chart-title">
Chart Title
</p>
<div className="recharts-container">
<ResponsiveContainer>
<AllOfRechartsCode />
</ResponsiveContainer>
</div>
</div>
With CSS:
.chart-wrapper {
display: flex;
flex-direction: column;
}
.recharts-container {
flex-grow: 1;
overflow-y: hidden;
}
I have a few similar components that use that same structure. Before I got to fix it, I had all of them with flex-wrap: wrap;
instead of flex-direction: column;
on .chart-wrapper
. None of them had the overflow-y
setting.
Then I changed flex-wrap
to flex-direction
, and just one of them started working properly. By comparing it to others, the only relevant difference was the overflow-y
setting. So I just tested on the others components and they all worked.
I don't quite understand why that worked, though. Based on VacaSan's response, saying that observer callback never gets called on down resizing, I'd guess that for every resize step overflow would get recalculated or something, thus delaying a proper resize.
But I'm not even sure if that makes much sense. I'm not a very experienced developer, it was quite a struck of luck.
Anyways... Hope this helps.
I see that this has been closed but I have yet to be able to remedy this issue in my app. I've tried every suggested css approach and nothing speeds up the size reduction animation. Where has this been conclusively resolved?
I see that this has been closed but I have yet to be able to remedy this issue in my app. I've tried every suggested css approach and nothing speeds up the size reduction animation. Where has this been conclusively resolved?
I've encountered this issue maybe using debounce props on ResponsiveContainer will resolve the lag transition on the charts
Hey all, I had been struggling with the same problem for ages. I used the '99%' width trick and it helped take maybe the edge off but with large data sets its still a very noticeable problem. I highly suggest using a hook similar to this one I made
import { useState, useEffect, useCallback } from 'react';
import lodash from 'lodash';
// A custom hook that detects if the window is currently being resized
// Returns a single value 'isBeingResized'
// the method is debounced to 200ms after which it returns to being false.
export const useIsResizing = () => {
const [isBeingResized, setIsBeingResized] = useState(false);
const reset = useCallback(
lodash.debounce(() => {
setIsBeingResized(false);
}, 200),
[],
);
useEffect(() => {
const handleResize = () => {
setIsBeingResized(true);
reset();
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, [setIsBeingResized]);
return isBeingResized;
};
Then where ever you are rendering the graph simply remove it from the DOM while isBeingResized is true or show some placeholder text / component. This allows the layout to still resize in real time then the graph kind of pops back in when resizing ends.
Hope this helps someone!
I see that this issue has been closed, even though it has not been fixed yet, and there are only workarounds stated. Currently in our application, I used AutoSizer instead of the responsive Container, but this should not be the solution for a highly used Framework like this, as its also not fixing the issue 100%
Using flex-basis instead of width will help solve the problem
Comments give me visibility into these closed issues, thanks. Reopening.
I was suffering from similar issue and found that there's "debounce" props in ResponsiveContainer.
Try using the debounce props.
I'm not really proud of that solution but there it is haha, i'm pausing with a spinner to give the impression that it's not a bug and the resizing is as fast as usual. (DashboardBox is the component that wraps all the responsive containers i'm using)
I hope this helps.
import { Box } from "@mui/material";
import { styled } from "@mui/system";
import Spinner from "./Spinner";
import { useEffect, useState } from "react";
const DashboardBox = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.background.light,
borderRadius: "1rem",
boxShadow: "0.15rem 0.2rem 0.15rem 0.1rem rgba(0, 0, 0, 0.8)",
}));
const ResizableBox = ({ children, gridArea }) => {
const [isResizing, setIsResizing] = useState(false);
let resizeTimeout;
const handleResizeStart = () => {
clearTimeout(resizeTimeout);
setIsResizing(!isResizing);
};
const handleResizeEnd = () => {
resizeTimeout = setTimeout(() => {
setIsResizing(false);
}, 150);
};
useEffect(() => {
window.addEventListener("resize", handleResizeStart);
window.addEventListener("resize", handleResizeEnd);
return () => {
window.removeEventListener("resize", handleResizeStart);
window.removeEventListener("resize", handleResizeEnd);
};
}, []);
return (
<DashboardBox gridArea={gridArea}>
{isResizing ? <Spinner /> : children}
</DashboardBox>
);
};
export default ResizableBox;
Hey everyone, so what's the ideal solution here? I've been trying to figure it out but no luck 🙏
We've refactored responsive container for the next version which is directly using resize detector. The debounce prop is there and maybe next release we'll add a sane default
@ckifer would you know what specific version has this update? I ask because I'm on version 2.0.6 and when I upgraded to 2.9.0, it throws me this error (something to do with the tsconfig.json)
So maybe if I update it to a specific version then hopefully I won't face this issue
@mamo-muj can you create a separate issue for this? (please include webpack/bundler config, package.json, etc.) victory-vendor
was added in 2.3 (but this issue we're in isn't fixed anywhere yet)