两个图表的弹性框溢出屏幕
Flex box of two charts is overflowing screen
我的页面上有两个图表。它们一起通过 Flex
(一个 css flexbox)占据了整个屏幕高度。第一个图表可通过 Accordion
.
折叠
我们如何才能让第一个图表占满屏幕高度的 30%,而第二个图表占满剩余的 ~70%?
当这两个图表是页面上 唯一 的东西时,我能够成功地做到这一点:
// This works well.
<Flex direction="column" height="100vh">
<Accordion allowToggle>
<AccordionItem>
<h2>
<AccordionButton
h={0}
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<Box flex="1">
<ThreeDataPoint />
</Box>
</Flex>
但是,如果我将行和列弹性框组合在一起,它就不起作用了。第二个图表溢出屏幕的高度。
这是截图:
图表高度是在页面呈现时计算的,因此切换顶部图表后不会重新计算底部图表高度。您需要采取变通办法来触发事件以重新计算第二个图表的高度。您可以使用 <Accordion>
的 onChange
事件来切换状态,并根据状态变化将您的第二个图表包装成高度 100vh
或 70vh
的 <Box>
。
import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
import { ChakraProvider } from "@chakra-ui/react";
import BasicLineSeries from "./BasicLineSeries";
import {
Box,
Accordion,
AccordionButton,
AccordionItem,
AccordionIcon,
AccordionPanel,
Flex,
Text
} from "@chakra-ui/react";
const ThreeDataPoint = () => (
<BasicLineSeries
data={[
{
close: 120,
open: 120,
high: 140,
low: 100,
date: new Date(2020, 7, 8, 10, 0, 0, 0),
volume: 1_000_000
},
{
close: 140,
open: 120,
high: 150,
low: 100,
date: new Date(2020, 7, 8, 10, 1, 0, 0),
volume: 1_000_000
},
{
close: 120,
open: 120,
high: 140,
low: 100,
date: new Date(2020, 7, 8, 10, 2, 0, 0),
volume: 1_000_000
}
]}
/>
);
const Test = () => {
const [expended, onExpend] = React.useState(false);
return (
<ChakraProvider>
<>
<Flex direction="column" height="100vh">
<Flex flex="1" direction="row">
<div>123456789010</div>
<Flex flex="1" direction="column">
<Accordion
allowToggle
onChange={(e) => {
if (e === 0) {
onExpend(true);
} else {
onExpend(false);
}
}}
>
<AccordionItem>
<h2>
<AccordionButton
h={0}
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<Box flex={expended ? 2 : 3}>
<ThreeDataPoint />
</Box>
</Flex>
</Flex>
</Flex>
</>
</ChakraProvider>
);
};
const rootElement = document.getElementById("root");
render(<Test />, rootElement);
我对您的代码进行了一些更改,试图获得令人满意的结果,使两个图表保持在 100vh
最大高度并避免滚动。
第二个图表的高度将自动调整,根据第一个图表是否折叠,尽可能多地填充space。
下面是我在您的 styles.css 文件中添加的一些样式(就在您的 .test
class 下方):
.flex-wrapper {
display: grid !important;
grid-auto-flow: column;
grid-auto-columns: max-content auto;
gap: 15px;
padding: 15px;
max-height: 100%;
width: 100%;
}
.accordion-box-container {
display: grid !important;
grid-template-rows: min-content auto;
gap: 15px;
overflow-y: hidden;
width: 100%;
}
.accordion-wrapper {
height: 100%;
}
.accordion-title {
display: flex;
align-items: center;
padding: 5px 0;
height: auto;
}
.accordion-button {
width: min-content !important;
margin-left: 5px;
}
.graph-wrapper {
height: 100%;
}
.graph-wrapper div {
height: 100% !important;
}
与此同时,我从 index.tsx
中的 jsx 中删除了一些 bootstrap classes 并将上面的 css classes 添加到适当的组件:
render(
<ChakraProvider>
<>
<Flex direction="column" height="100vh" className="flex-wrapper">
<div>123456789010</div>
<Flex>
<Box className="accordion-box-container">
<Accordion className="accordion-wrapper" allowToggle>
<AccordionItem>
<h2 className="accordion-title">
<AccordionButton
className="accordion-button"
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<div className="graph-wrapper">
<ThreeDataPoint />
</div>
</Box>
</Flex>
</Flex>
</>
</ChakraProvider>,
rootElement
);
最后,我不得不在 BasicLineSeries.tsx
中删除您对尺寸的限制,这将对两个图表强制执行最小高度,从而无法在渲染后调整它们的高度(仅更改了导出语句):
export default withSize()(
withDeviceRatio()(BasicLineSeries)
);
请尝试自行测试,如果这能满足您的要求,请告诉我。如果需要其他内容,请对其进行评论,我会尽力相应地调整我的解决方案。
我的页面上有两个图表。它们一起通过 Flex
(一个 css flexbox)占据了整个屏幕高度。第一个图表可通过 Accordion
.
我们如何才能让第一个图表占满屏幕高度的 30%,而第二个图表占满剩余的 ~70%?
当这两个图表是页面上 唯一 的东西时,我能够成功地做到这一点:
// This works well.
<Flex direction="column" height="100vh">
<Accordion allowToggle>
<AccordionItem>
<h2>
<AccordionButton
h={0}
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<Box flex="1">
<ThreeDataPoint />
</Box>
</Flex>
但是,如果我将行和列弹性框组合在一起,它就不起作用了。第二个图表溢出屏幕的高度。
这是截图:
图表高度是在页面呈现时计算的,因此切换顶部图表后不会重新计算底部图表高度。您需要采取变通办法来触发事件以重新计算第二个图表的高度。您可以使用 <Accordion>
的 onChange
事件来切换状态,并根据状态变化将您的第二个图表包装成高度 100vh
或 70vh
的 <Box>
。
import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
import { ChakraProvider } from "@chakra-ui/react";
import BasicLineSeries from "./BasicLineSeries";
import {
Box,
Accordion,
AccordionButton,
AccordionItem,
AccordionIcon,
AccordionPanel,
Flex,
Text
} from "@chakra-ui/react";
const ThreeDataPoint = () => (
<BasicLineSeries
data={[
{
close: 120,
open: 120,
high: 140,
low: 100,
date: new Date(2020, 7, 8, 10, 0, 0, 0),
volume: 1_000_000
},
{
close: 140,
open: 120,
high: 150,
low: 100,
date: new Date(2020, 7, 8, 10, 1, 0, 0),
volume: 1_000_000
},
{
close: 120,
open: 120,
high: 140,
low: 100,
date: new Date(2020, 7, 8, 10, 2, 0, 0),
volume: 1_000_000
}
]}
/>
);
const Test = () => {
const [expended, onExpend] = React.useState(false);
return (
<ChakraProvider>
<>
<Flex direction="column" height="100vh">
<Flex flex="1" direction="row">
<div>123456789010</div>
<Flex flex="1" direction="column">
<Accordion
allowToggle
onChange={(e) => {
if (e === 0) {
onExpend(true);
} else {
onExpend(false);
}
}}
>
<AccordionItem>
<h2>
<AccordionButton
h={0}
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<Box flex={expended ? 2 : 3}>
<ThreeDataPoint />
</Box>
</Flex>
</Flex>
</Flex>
</>
</ChakraProvider>
);
};
const rootElement = document.getElementById("root");
render(<Test />, rootElement);
我对您的代码进行了一些更改,试图获得令人满意的结果,使两个图表保持在 100vh
最大高度并避免滚动。
第二个图表的高度将自动调整,根据第一个图表是否折叠,尽可能多地填充space。
下面是我在您的 styles.css 文件中添加的一些样式(就在您的 .test
class 下方):
.flex-wrapper {
display: grid !important;
grid-auto-flow: column;
grid-auto-columns: max-content auto;
gap: 15px;
padding: 15px;
max-height: 100%;
width: 100%;
}
.accordion-box-container {
display: grid !important;
grid-template-rows: min-content auto;
gap: 15px;
overflow-y: hidden;
width: 100%;
}
.accordion-wrapper {
height: 100%;
}
.accordion-title {
display: flex;
align-items: center;
padding: 5px 0;
height: auto;
}
.accordion-button {
width: min-content !important;
margin-left: 5px;
}
.graph-wrapper {
height: 100%;
}
.graph-wrapper div {
height: 100% !important;
}
与此同时,我从 index.tsx
中的 jsx 中删除了一些 bootstrap classes 并将上面的 css classes 添加到适当的组件:
render(
<ChakraProvider>
<>
<Flex direction="column" height="100vh" className="flex-wrapper">
<div>123456789010</div>
<Flex>
<Box className="accordion-box-container">
<Accordion className="accordion-wrapper" allowToggle>
<AccordionItem>
<h2 className="accordion-title">
<AccordionButton
className="accordion-button"
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<div className="graph-wrapper">
<ThreeDataPoint />
</div>
</Box>
</Flex>
</Flex>
</>
</ChakraProvider>,
rootElement
);
最后,我不得不在 BasicLineSeries.tsx
中删除您对尺寸的限制,这将对两个图表强制执行最小高度,从而无法在渲染后调整它们的高度(仅更改了导出语句):
export default withSize()(
withDeviceRatio()(BasicLineSeries)
);
请尝试自行测试,如果这能满足您的要求,请告诉我。如果需要其他内容,请对其进行评论,我会尽力相应地调整我的解决方案。