Recharts 响应式容器在 flexbox 中无法正确调整大小

Posted

技术标签:

【中文标题】Recharts 响应式容器在 flexbox 中无法正确调整大小【英文标题】:Recharts Responsive Container does not resize correctly in flexbox 【发布时间】:2018-11-26 05:52:02 【问题描述】:

我正在尝试为我的数据可视化应用创建自定义可折叠图例。它使用反应和图表。该组件第一次渲染得很好。但是当我折叠图例并重新打开它时,响应容器不会缩小以适应。如果我知道父容器的大小(以像素为单位),这会更容易,但我没有关于渲染的信息。这是 recharts 或 flex box 的错误还是我做错了?

这是代码:https://codesandbox.io/s/8krz9qjk52

澄清:问题是当我关闭然后打开图例时,图例组件被推出查看区域并且图表不会收缩回原来的较小尺寸。

【问题讨论】:

【参考方案1】:

这似乎很老套,但一个可行的解决方法是将宽度设置为 99%,并设置高度或纵横比。

<ResponsiveContainer width="99%" aspect=3>

看到这个问题:

https://github.com/recharts/recharts/issues/172

【讨论】:

这对我有用。我不知道为什么会这样。如果有人能阐明这个问题,我们将不胜感激。 怎么样?因为这个正在工作:D 打字稿说它需要一个数字 ts 还说方面不存在【参考方案2】:

我知道这是一个非常古老的问题,但我在这里发帖以防其他人通过 Google 登陆这里。

我不知道为什么这可行,但将position: absolute 设置为.recharts-wrapper 将完全解决此问题。到目前为止,我没有发现任何缺点,但 YRMV。

【讨论】:

【参考方案3】:

由于我在我的项目中遇到了类似的问题,所以我决定坚持这个问题。我终于能够得到一个可行的解决方案!

codesandbox

我会从大到小列出我所做的更改:

我lifted state up 从CustomLegendCustomChart

现在,CustomChart 负责发生的事情。它将可见性信息作为道具传递给CustomLegendCustomChart 如何知道何时更改状态?

CustomChart 有一个名为handleButtonClick 的成员函数来设置其状态。 handleButtonClick 作为道具发送到CustomLegend。所以CustomChart 会像这样渲染CustomLegend

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

现在在 CustomLegend 中,我们可以将其包含在 button 定义中:onClick=this.props.onClick 请注意,此模式仅在原始函数绑定到父函数时才有效,因为它改变了父函数的状态。

chart-container 现在是 CSS Grid 容器。

它呈现一个基于状态处理列宽的内联样式。

<div
    className="chart-container"
    style=
      gridTemplateColumns: this.state.legendVisible
        ? "80% 1fr"
        : "1fr min-content"
    
>

请注意,1fr 是一个小数单位,在这种情况下,用于填充剩余空间。

styles.css 中,grid-auto-flow 设置为column,这允许将事物作为列放置在网格中。我们放入网格的东西是SampleChartCustomLegend,所以SampleChart 是左列,CustomLegend 是右列。 gridTemplateColumns: 80% 1fr:当图例可见时,我们希望左列占据 80% 的宽度,右列填充其余部分。 gridTemplateColumns: 1fr min-content:当图例不可见时,我们希望右列占用其元素填充的最小空间,左列填充剩余空间。

CustomLegend 只有一个 render 方法。

除了renderVisiblerenderHidden,还有一种方法可以根据道具有条件地渲染legend-list(取决于CustomChart 的状态)。 legend-container 现在总是呈现(它是一个网格项)。

其他小改动:

SampleChart: &lt;ResponsiveContainer width="100%" height="100%" className=props.className&gt; 这已被更改,因为&lt;SampleChart className="chart-area" data=data /&gt; 实际上将className 作为道具发送。小心这个!您需要直接在SampleChart 返回的层次结构中的父标记上设置className(在本例中为ResponsiveContainer)。尝试回到您的 original codesandbox 并更改 chart-area 上的 background-color styles.css(没有任何反应!)。 overflow: scroll 在所有情况下都来自 styles.css,因为我们不再需要它。

您会注意到,如果您尝试仅使用fr 单位的网格布局或chart-container 上的任何弹性布局,图表将无法正确调整大小。不幸的是,Recharts 的 ResponsiveContainers 不能很好地与 Grid 或 Flexbox 配合使用(该项目的主要贡献者正在逐渐减少对 no commits 的支持 - 截至目前的 3 个月内)。

【讨论】:

【参考方案4】:

将以下内容添加到您的styles.css

html, body, #root 
  width: 100%;
  height: 100%;

否则.chart-container,即使它的宽度和高度设置为100%,也不会占据整个视口。然后在SampleChart.jsx,改成这样:

<ResponsiveContainer  height=400>

到这里:

<ResponsiveContainer  >

让您的ResponsiveContainer 的高度...嗯,响应迅速。

【讨论】:

那没有帮助。当我关闭然后打开图例时,图例组件被推出查看区域并且图表不会缩回到原来的较小尺寸 对不起,我误解了这个问题。看看我的第二个答案!

以上是关于Recharts 响应式容器在 flexbox 中无法正确调整大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有固定高度的 flex 容器中缩小响应式图像

具有左右容器的 Flex 框响应式布局

如何居中对齐 flexbox 容器? [复制]

使用 flexbox 的响应式投资组合/联系人

响应式 flexbox 和重新排序子子项

带有 css 邻接选择器的响应式 flexbox 设计