我正在尝试为我的数据可视化应用程序创建自定义可折叠图例。它使用反应和重新绘制图表。该组件第一次渲染得很好。但是,当我折叠图例并重新打开它时,响应式容器不会缩小以适应。如果我知道父容器的大小(以像素为单位),但我没有有关渲染的信息,这会更容易。这是重新图表或弹性框的错误还是我做错了?
代码如下:https://codesandbox.io/s/8krz9qjk52
澄清:问题是,当我关闭然后打开图例时,图例组件被推出查看区域,并且图表不会缩小回原来的较小尺寸。
这看起来相当老套,但一个可行的解决方案是将宽度设置为 99%,并设置高度或纵横比。
<ResponsiveContainer width="99%" aspect={3}>
看到这个问题:
我知道这是一个非常老的问题,但我在这里发帖以防万一其他人通过 Google 登陆这里。
我不知道为什么这有效,但是将
position: absolute
设置为.recharts-wrapper
将完全解决这个问题。到目前为止,我还没有发现这有什么缺点,但 YRMV 除外。
尝试这个,它解决了宽度和高度的响应能力(调整大小)
<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>
最好的选择是给它 100% 的宽度,然后调整纵横比,直到您满意为止。我这样做是为了适应不同的屏幕尺寸
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
现在,
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}
请注意,此模式仅在原始函数绑定到父函数时才有效,因为它会改变父函数的状态。现在是 CSS 网格容器。chart-container
它呈现一个内联样式,根据状态处理列宽。
<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
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 个月内没有提交)。
将以下内容添加到您的
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
的高度......嗯,反应灵敏。
在 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>
希望这对某人有帮助。需要解决的问题很痛苦。