#javascript #reactjs
Вопрос:
Редактировать
Я пока оставляю этот вопрос открытым, но вот как я его решил.
Вы можете изменить значение numberOfBoxes
, чтобы увидеть изменения.
import * as React from "react";
import styled from "@emotion/styled";
const numberOfBoxes = 20;
const totalMarginPerBox = 2;
const containerHeight = window.innerHeight - 100;
const Component = React.memo(() => {
const boxHeight = (containerHeight - 2 * numberOfBoxes) / numberOfBoxes;
return (
<Container>
{boxHeight}px
{Array.from({ length: numberOfBoxes }, (_, index) => (
<Box height={boxHeight}>box {index 1}</Box>
))}
</Container>
);
});
export default Component;
const Container = styled.div`
width: 100%;
height: ${containerHeight}px;
display: flex;
flex-direction: column;
align-items: center;
`;
const Box = styled.div<{ height: number }>`
${({ height }) => `
width: 10rem;
height: ${height}px;
border: 1px solid black;
margin: ${
totalMarginPerBox /
// top margin = 1px ; bottom margin = 1px
2
}px 0;
max-height: ${height}px;
overflow: hidden;
amp;:first-child {
background-color: lightgreen;
}
amp;:last-child {
background-color: tomato;
}
`}
`;
Я использую react-xarrows для рисования диаграммы и react-zoom-pan-pinch, чтобы иметь дополнительную функциональность для увеличения и уменьшения масштаба диаграммы.
Проблема, с которой я сталкиваюсь, заключается в том, что если на диаграмме много содержимого, то оно переполняет страницу, и пользователь вынужден прокручивать ее, чтобы увидеть.
Diagram
Компонент выглядит так:
import React from "react";
import Xarrow, { Xwrapper } from "react-xarrows";
import styled from "@emotion/styled";
const BOX_WIDTH = 362;
const QuestionAndOptionContainer = styled.div`
display: flex;
align-items: center;
flex-direction: column;
justify-content: flex-start;
z-index: 10000;
`;
const Node = styled.div`
amp;amp;amp; {
background: "#e3e";
border: 1px solid #dcdcdc;
box-sizing: border-box;
border-radius: 8px;
padding: 20px 24px;
width: ${BOX_WIDTH}px;
display: flex;
margin: 1rem;
}
`;
const diagram = {
nodes: [
{
id: "1",
questionNumber: "1",
title: "This is node number 1",
connectionsConfig: [
{
id: "2"
}
]
},
{
id: "2",
questionNumber: "2",
title: "This is node number 2",
connectionsConfig: [
{
id: "3"
}
]
},
{
id: "3",
questionNumber: "3",
title: "This is node number 3",
connectionsConfig: [
{
id: "4"
}
]
},
{
id: "4",
questionNumber: "4",
title: "This is node number 4",
connectionsConfig: [
{
id: "5"
}
]
},
{
id: "5",
questionNumber: "5",
title: "This is node number 5"
}
]
};
const Diagram = React.memo(() => {
const handleRenderQuestionsTree = React.useCallback(
({ id, title, connectionsConfig }) => {
return (
<QuestionAndOptionContainer>
<Node id={id}>
<div>{title}</div>
</Node>
{!!connectionsConfig?.length amp;amp; (
<>
{connectionsConfig.map(({ id: nextNodeId }) => (
<Xarrow
color={"#000000"}
headSize={7}
tailSize={2}
strokeWidth={1}
lineColor={"#000000"}
start={id}
end={nextNodeId}
/>
))}
</>
)}
</QuestionAndOptionContainer>
);
},
[]
);
return <Xwrapper>{diagram.nodes.map(handleRenderQuestionsTree)}</Xwrapper>;
});
export default Diagram;
Now imagine, that diagram.nodes
is much larger:
const diagram = {
nodes: [
{
id: "1",
questionNumber: "1",
title: "This is node number 1",
connectionsConfig: [
{
id: "2"
}
]
},
{
id: "2",
questionNumber: "2",
title: "This is node number 2",
connectionsConfig: [
{
id: "3"
}
]
},
{
id: "3",
questionNumber: "3",
title: "This is node number 3",
connectionsConfig: [
{
id: "4"
}
]
},
{
id: "4",
questionNumber: "4",
title: "This is node number 4",
connectionsConfig: [
{
id: "5"
}
]
},
{
id: "5",
questionNumber: "5",
title: "This is node number 5",
connectionsConfig: [
{
id: "6"
}
]
},
{
id: "6",
questionNumber: "6",
title: "This is node number 6",
connectionsConfig: [
{
id: "7"
}
]
},
{
id: "7",
questionNumber: "7",
title: "This is node number 7",
connectionsConfig: [
{
id: "8"
}
]
},
{
id: "8",
questionNumber: "8",
title: "This is node number 8",
connectionsConfig: [
{
id: "9"
}
]
},
{
id: "9",
questionNumber: "9",
title: "This is node number 9",
connectionsConfig: [
{
id: "10"
}
]
},
{
id: "10",
questionNumber: "10",
title: "This is node number 10",
connectionsConfig: [
{
id: "11"
}
]
},
{
id: "11",
questionNumber: "11",
title: "This is node number 11"
}
]
};
The content overflows off the page and I’m unable to see it all.
I’m looking for a dynamic way to make sure that the content fits the page, and, if the user wants, they can zoom into it all they want.
The only thing that came to mind was calculating the BOX_WIDTH
(and height) of all elements in a useEffect
, which would count the number of nodes available and compare it to the windows size, something like height: window.innerHeight / diagram.nodes.length}px;
, but that didn’t work out too well.
What can I do here?