Documentation Index Fetch the complete documentation index at: https://mintlify.com/recharts/recharts/llms.txt
Use this file to discover all available pages before exploring further.
Recharts provides powerful tools for creating responsive visualizations that adapt to different screen sizes and container dimensions. The ResponsiveContainer component is the foundation of responsive chart design.
ResponsiveContainer
The ResponsiveContainer component automatically adjusts chart dimensions based on its parent container size.
Basic usage
import { ResponsiveContainer , LineChart , Line , XAxis , YAxis } from 'recharts' ;
function ResponsiveChart () {
return (
< div style = { { width: '100%' , height: 400 } } >
< ResponsiveContainer >
< LineChart data = { data } >
< XAxis dataKey = "name" />
< YAxis />
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
</ div >
);
}
The parent container of ResponsiveContainer must have a defined width and height. ResponsiveContainer fills 100% of its parent by default.
How it works
The ResponsiveContainer component:
Observes its parent container using the ResizeObserver API
Calculates appropriate dimensions based on container size
Provides these dimensions to child charts via React context
Re-renders charts when container size changes
// From src/component/ResponsiveContainer.tsx:170-199
useEffect (() => {
if ( containerRef . current == null || typeof ResizeObserver === 'undefined' ) {
return noop ;
}
let callback = ( entries : ResizeObserverEntry []) => {
const entry = entries [ 0 ];
if ( entry == null ) {
return ;
}
const { width : containerWidth , height : containerHeight } = entry . contentRect ;
setContainerSize ( containerWidth , containerHeight );
onResizeRef . current ?.( containerWidth , containerHeight );
};
if ( debounce > 0 ) {
callback = throttle ( callback , debounce , {
trailing: true ,
leading: false ,
});
}
const observer = new ResizeObserver ( callback );
const { width : containerWidth , height : containerHeight } = containerRef . current . getBoundingClientRect ();
setContainerSize ( containerWidth , containerHeight );
observer . observe ( containerRef . current );
return () => {
observer . disconnect ();
};
}, [ setContainerSize , debounce ]);
Container dimensions
Percentage dimensions
Use percentage values for fluid layouts:
< ResponsiveContainer width = "100%" height = "100%" >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
Fixed dimensions
Use pixel values for fixed-size charts:
< ResponsiveContainer width = { 600 } height = { 300 } >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
Mixed dimensions
Combine percentage and fixed values:
< ResponsiveContainer width = "100%" height = { 400 } >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
Aspect ratio
Maintain a specific width-to-height ratio:
< ResponsiveContainer width = "100%" aspect = { 16 / 9 } >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
16:9 (Widescreen)
4:3 (Standard)
1:1 (Square)
< ResponsiveContainer width = "100%" aspect = { 16 / 9 } >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
< ResponsiveContainer width = "100%" aspect = { 4 / 3 } >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
< ResponsiveContainer width = "100%" aspect = { 1 } >
< PieChart data = { data } >
< Pie dataKey = "value" />
</ PieChart >
</ ResponsiveContainer >
When using aspect, the height is calculated as width / aspect. This is useful for maintaining visual consistency across different screen sizes.
Minimum and maximum dimensions
Set constraints on chart size:
< ResponsiveContainer
width = "100%"
height = "100%"
minWidth = { 300 }
minHeight = { 200 }
maxHeight = { 600 }
>
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
Debouncing resize events
Optimize performance during rapid resize events:
< ResponsiveContainer
width = "100%"
height = { 400 }
debounce = { 200 } // Wait 200ms after resize before re-rendering
>
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
Debouncing is useful when charts contain large datasets or complex rendering. It prevents excessive re-renders during window resizing.
Resize callback
Execute code when chart size changes:
import { useState } from 'react' ;
import { ResponsiveContainer , LineChart , Line } from 'recharts' ;
function ChartWithResizeTracking () {
const [ dimensions , setDimensions ] = useState ({ width: 0 , height: 0 });
return (
< div >
< p > Chart size: { dimensions . width } px × { dimensions . height } px </ p >
< ResponsiveContainer
width = "100%"
height = { 400 }
onResize = { ( width , height ) => {
setDimensions ({ width , height });
console . log ( 'Chart resized to:' , width , height );
} }
>
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
</ div >
);
}
Responsive patterns
Full-width charts
function FullWidthChart () {
return (
< div style = { { width: '100%' , height: 400 } } >
< ResponsiveContainer >
< LineChart data = { data } >
< XAxis dataKey = "name" />
< YAxis />
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
</ div >
);
}
Dashboard grid
function DashboardGrid () {
return (
< div style = { {
display: 'grid' ,
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))' ,
gap: 20 ,
} } >
< div style = { { height: 300 } } >
< ResponsiveContainer >
< LineChart data = { data1 } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
</ div >
< div style = { { height: 300 } } >
< ResponsiveContainer >
< BarChart data = { data2 } >
< Bar dataKey = "value" fill = "#82ca9d" />
</ BarChart >
</ ResponsiveContainer >
</ div >
< div style = { { height: 300 } } >
< ResponsiveContainer >
< PieChart >
< Pie data = { data3 } dataKey = "value" />
</ PieChart >
</ ResponsiveContainer >
</ div >
</ div >
);
}
Mobile-first design
import { useState , useEffect } from 'react' ;
import { ResponsiveContainer , LineChart , Line , XAxis , YAxis } from 'recharts' ;
function MobileFirstChart () {
const [ isMobile , setIsMobile ] = useState ( false );
useEffect (() => {
const checkMobile = () => setIsMobile ( window . innerWidth < 768 );
checkMobile ();
window . addEventListener ( 'resize' , checkMobile );
return () => window . removeEventListener ( 'resize' , checkMobile );
}, []);
return (
< div style = { { width: '100%' , height: isMobile ? 250 : 400 } } >
< ResponsiveContainer >
< LineChart
data = { data }
margin = { isMobile
? { top: 5 , right: 5 , left: 0 , bottom: 5 }
: { top: 20 , right: 30 , left: 20 , bottom: 5 }
}
>
< XAxis
dataKey = "name"
tick = { { fontSize: isMobile ? 10 : 12 } }
angle = { isMobile ? - 45 : 0 }
textAnchor = { isMobile ? 'end' : 'middle' }
/>
< YAxis tick = { { fontSize: isMobile ? 10 : 12 } } />
< Line dataKey = "value" stroke = "#8884d8" strokeWidth = { isMobile ? 1 : 2 } />
</ LineChart >
</ ResponsiveContainer >
</ div >
);
}
Breakpoint-based configuration
import { useState , useEffect } from 'react' ;
import { ResponsiveContainer , BarChart , Bar , XAxis , YAxis , Legend , Tooltip } from 'recharts' ;
function BreakpointChart () {
const [ breakpoint , setBreakpoint ] = useState ( 'large' );
useEffect (() => {
const updateBreakpoint = () => {
const width = window . innerWidth ;
if ( width < 640 ) setBreakpoint ( 'small' );
else if ( width < 1024 ) setBreakpoint ( 'medium' );
else setBreakpoint ( 'large' );
};
updateBreakpoint ();
window . addEventListener ( 'resize' , updateBreakpoint );
return () => window . removeEventListener ( 'resize' , updateBreakpoint );
}, []);
const config = {
small: {
height: 200 ,
layout: 'vertical' ,
margin: { top: 5 , right: 5 , left: 40 , bottom: 5 },
showLegend: false ,
},
medium: {
height: 300 ,
layout: 'horizontal' ,
margin: { top: 20 , right: 20 , left: 20 , bottom: 20 },
showLegend: true ,
},
large: {
height: 400 ,
layout: 'horizontal' ,
margin: { top: 20 , right: 30 , left: 20 , bottom: 5 },
showLegend: true ,
},
}[ breakpoint ];
return (
< div style = { { width: '100%' , height: config . height } } >
< ResponsiveContainer >
< BarChart
data = { data }
layout = { config . layout }
margin = { config . margin }
>
{ config . layout === 'horizontal' ? (
<>
< XAxis dataKey = "name" />
< YAxis />
</>
) : (
<>
< XAxis type = "number" />
< YAxis dataKey = "name" type = "category" />
</>
) }
< Tooltip />
{ config . showLegend && < Legend /> }
< Bar dataKey = "value" fill = "#8884d8" />
</ BarChart >
</ ResponsiveContainer >
</ div >
);
}
Container queries (CSS)
Leverage modern CSS container queries with ResponsiveContainer:
// styles.css
. chart - container {
container - type : size ;
width : 100 % ;
height : 400 px ;
}
@ container ( max - width : 600 px ) {
. chart - wrapper {
height : 250 px ;
}
}
@ container ( min - width : 601 px ) {
. chart - wrapper {
height : 400 px ;
}
}
// Component
function ContainerQueryChart () {
return (
< div className = "chart-container" >
< div className = "chart-wrapper" >
< ResponsiveContainer >
< LineChart data = { data } >
< Line dataKey = "value" stroke = "#8884d8" />
</ LineChart >
</ ResponsiveContainer >
</ div >
</ div >
);
}
Optimize large datasets
import { useMemo } from 'react' ;
import { ResponsiveContainer , LineChart , Line } from 'recharts' ;
function OptimizedChart ({ rawData }) {
// Downsample data on large screens, more aggressive on mobile
const processedData = useMemo (() => {
const isMobile = window . innerWidth < 768 ;
const sampleRate = isMobile ? 10 : 5 ;
return rawData . filter (( _ , index ) => index % sampleRate === 0 );
}, [ rawData ]);
return (
< ResponsiveContainer width = "100%" height = { 400 } >
< LineChart data = { processedData } >
< Line
dataKey = "value"
stroke = "#8884d8"
isAnimationActive = { false } // Disable animation for better performance
dot = { false } // Hide dots on mobile for performance
/>
</ LineChart >
</ ResponsiveContainer >
);
}
Lazy loading charts
import { lazy , Suspense } from 'react' ;
const Chart = lazy (() => import ( './Chart' ));
function LazyChart () {
return (
< Suspense fallback = { < div > Loading chart... </ div > } >
< Chart data = { data } />
</ Suspense >
);
}
Common issues
Ensure the parent container has explicit dimensions: // Wrong - no height defined
< div >
< ResponsiveContainer >
< LineChart data = { data } />
</ ResponsiveContainer >
</ div >
// Correct - explicit height
< div style = { { height: 400 } } >
< ResponsiveContainer >
< LineChart data = { data } />
</ ResponsiveContainer >
</ div >
Add debounce to reduce re-renders: < ResponsiveContainer debounce = { 100 } >
< LineChart data = { data } />
</ ResponsiveContainer >
Chart too small on mobile
Set minimum dimensions: < ResponsiveContainer
width = "100%"
height = { 400 }
minHeight = { 250 }
>
< LineChart data = { data } />
</ ResponsiveContainer >
Adjust chart margins based on legend position: < LineChart
margin = { { top: 5 , right: 20 , bottom: 40 , left: 20 } }
>
< Legend verticalAlign = "bottom" height = { 36 } />
</ LineChart >