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

问题描述 投票:0回答:7

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

代码如下:https://codesandbox.io/s/8krz9qjk52

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

css reactjs user-interface flexbox recharts
7个回答
44
投票

这看起来相当老套,但一个可行的解决方案是将宽度设置为 99%,并设置高度或纵横比。

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

看到这个问题:

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


11
投票

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

我不知道为什么这有效,但是将

position: absolute
设置为
.recharts-wrapper
将完全解决这个问题。到目前为止,我还没有发现这有什么缺点,但 YRMV 除外。


6
投票

尝试这个,它解决了宽度和高度的响应能力(调整大小)

<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>


3
投票

最好的选择是给它 100% 的宽度,然后调整纵横比,直到您满意为止。我这样做是为了适应不同的屏幕尺寸

const theme = useTheme(); //this is from mui
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));

<ResponsiveContainer width="100%" aspect={isMobile?1.5:1.8}>

像魅力一样工作


1
投票

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

代码沙箱

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

提升状态

CustomLegend
CustomChart

  • 现在,

    CustomChart
    负责发生的事情。它将可见性信息作为 prop 传递给
    CustomLegend
    CustomChart
    如何知道何时改变状态?

  • 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 网格容器。

  • 它呈现一个内联样式,根据状态处理列宽。

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

    请注意,

    1fr
    是一个分数单位,在本例中,用于填充剩余空间。

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

CustomLegend
只有一个
render
方法。

  • 有一种方法可以根据 props 有条件地渲染
    renderVisible
    (取决于
    renderHidden
    的状态),而不是
    legend-list
    CustomChart
  • legend-container
    现在总是渲染(它是一个网格项)。

其他小改动:

  • SampleChart
    中:
    <ResponsiveContainer width="100%" height="100%" className={props.className}>
    这已更改,因为
    <SampleChart className="chart-area" data={data} />
    实际上将
    className
    作为道具发送。小心这个!您需要直接在
    className
    返回的层次结构中的父标签上设置
    SampleChart
    (在本例中为
    ResponsiveContainer
    )。尝试返回到您的 原始代码和框 并更改
    background-color
    chart-area
    上的
    styles.css
    (什么也没有发生!)。
  • overflow: scroll
    在所有情况下都来自
    styles.css
    ,因为我们不再需要它。

您会注意到,如果您尝试仅使用

fr
单位或
chart-container
上的任何弹性布局进行网格布局,图表将无法正确调整大小。不幸的是,Recharts 的
ResponsiveContainer
无法与 Grid 或 Flexbox 很好地配合(该项目的主要贡献者正在逐渐减少支持 - 截至目前的 3 个月内没有提交)。


0
投票

将以下内容添加到您的

styles.css

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

否则

.chart-container
,即使其宽度和高度设置为100%,也不会占据整个视口。然后在
SampleChart.jsx
中,更改此:

<ResponsiveContainer width="100%" height={400}>

对此:

<ResponsiveContainer width="100%" height="100%">

让你的

ResponsiveContainer
的高度......嗯,反应灵敏。


0
投票

在 2 列网格布局中也有同样的问题,即桑基图表无响应。必须切换到 Flex 并专门将宽度放在 Flex 行中的每个子项上。默认情况下,Flex 列似乎工作正常,但不放置宽度的 Flex 行破坏了图表的响应行为。

// example based on Charka UI 2.x components in flex row.

<Flex direction="row">
  <Box w="50%"> Something </Box>
  <Box w="50%">
    <ResponsiveContainer width="100%" height={CHART_HEIGHT}>
      <SankeyChart {...props} />
    </ResponsiveContainer>
  </Box> 
<Flex>

希望这对某人有帮助。需要解决的问题很痛苦。

© www.soinside.com 2019 - 2024. All rights reserved.