以下是代码: https://codesandbox.io/s/8krz9qjk52 澄清一下:问题在于当我关闭并重新打开图例时,图例组件被推出了视觉区域,而图表也没有缩回到原来较小的尺寸。
看起来有些不正规,但可行的解决方法是将宽度设置为99%,并具有高度或纵横比。
<ResponsiveContainer width="99%" aspect={3}>
参见此问题:
.recharts-wrapper
上设置 position: absolute
将完全解决此问题。到目前为止,我尚未发现任何缺点,但您可能会有所不同。试一下这个,它可以解决宽度和高度的响应性(调整大小)问题。
<div style={{position: 'relative', width: '100%', paddingBottom: '250px'}}>
<div
style={{
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
top: 0,
}}
>
<ResponsiveContainer>
<YourChartGoesHere />
</ResponsiveContainer>
</div>
</div>
const theme = useTheme(); //this is from mui
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
<ResponsiveContainer width="100%" aspect={isMobile?1.5:1.8}>
非常好用
由于我在我的项目中遇到了类似的问题,所以我决定坚持这个问题。最终我成功找到了解决方案!
我将所做的更改从大到小列出:
我将状态从
CustomLegend
提升到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.
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.
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
只有一个render
方法。
renderVisible
和 renderHidden
,现在只有一个方法,根据 props(依赖于 CustomChart
的状态)有条件地渲染 legend-list
。legend-container
现在始终渲染(它是一个网格项)。其他小改动:
SampleChart
中:<ResponsiveContainer width="100%" height="100%" className={props.className}>
已更改,因为<SampleChart className="chart-area" data={data} />
实际上会将className
作为一个属性发送。请注意!您需要直接在SampleChart
返回的层次结构上(在这种情况下是ResponsiveContainer
)设置className
。尝试返回原始codesandbox并更改styles.css
中chart-area
的background-color
(什么也不会发生!)。styles.css
中所有实例的overflow:scroll
都已删除,因为我们不再需要它。fr
单位或在 chart-container
上使用任何 flex 布局来进行网格布局,则图表不会正确地调整大小。不幸的是,Recharts 的 ResponsiveContainer
与 Grid 或 Flexbox 不兼容(该项目的主要贡献者正在逐渐减少支持 - 截至目前为止已经3个月没有提交了)。styles.css
文件中:html, body, #root {
width: 100%;
height: 100%;
}
.chart-container
也不会占据整个视口。然后在SampleChart.jsx
中更改此内容:<ResponsiveContainer width="100%" height={400}>
转换为:
<ResponsiveContainer width="100%" height="100%">
让你的ResponsiveContainer
的高度...响应式。