fix performance

This commit is contained in:
AykutSarac 2022-08-13 19:15:20 +03:00
parent 129096f25b
commit 440f0f78ff
2 changed files with 96 additions and 69 deletions

View File

@ -19,15 +19,13 @@ import useConfig from "src/hooks/store/useConfig";
import styled from "styled-components";
import shallow from "zustand/shallow";
interface GraphProps {
interface LayoutProps {
json: string;
isWidget?: boolean;
isWidget: boolean;
openModal: () => void;
setSelectedNode: (node: object) => void;
}
const wheelOptions = {
step: 0.05,
};
const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
position: absolute;
width: 100%;
@ -43,23 +41,12 @@ const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
}
`;
export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
const MemoizedGraph = React.memo(function Layout({
json,
isWidget = false,
...props
}) => {
const [isModalVisible, setModalVisible] = React.useState(false);
const updateSetting = useConfig((state) => state.updateSetting);
const [expand, layout] = useConfig(
(state) => [state.settings.expand, state.settings.layout],
shallow
);
const onInit = (ref: ReactZoomPanPinchRef) => {
updateSetting("zoomPanPinch", ref);
};
const [selectedNode, setSelectedNode] = React.useState<NodeData | null>(null);
isWidget,
openModal,
setSelectedNode,
}: LayoutProps) {
const [nodes, setNodes] = React.useState<NodeData[]>([]);
const [edges, setEdges] = React.useState<EdgeData[]>([]);
const [size, setSize] = React.useState({
@ -67,6 +54,12 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
height: 2000,
});
const updateSetting = useConfig((state) => state.updateSetting);
const [expand, layout] = useConfig(
(state) => [state.settings.expand, state.settings.layout],
shallow
);
React.useEffect(() => {
const { nodes, edges } = getEdgeNodes(json, expand);
@ -74,6 +67,10 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
setEdges(edges);
}, [json, expand]);
const onInit = (ref: ReactZoomPanPinchRef) => {
updateSetting("zoomPanPinch", ref);
};
const onCanvasClick = () => {
const input = document.querySelector("input:focus") as HTMLInputElement;
if (input) input.blur();
@ -88,54 +85,74 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
e: React.MouseEvent<SVGElement>,
props: NodeProps
) => {
setSelectedNode(props.properties);
setModalVisible(true);
setSelectedNode(props.properties.text);
openModal();
};
return (
<>
<StyledEditorWrapper isWidget={isWidget}>
<TransformWrapper
maxScale={1.8}
minScale={0.4}
initialScale={0.7}
wheel={wheelOptions}
onInit={onInit}
<StyledEditorWrapper isWidget={isWidget}>
<TransformWrapper
onInit={onInit}
maxScale={1.8}
minScale={0.4}
initialScale={0.7}
wheel={{
step: 0.05,
}}
>
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%",
overflow: "hidden",
}}
>
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%",
overflow: "hidden",
}}
>
<Canvas
nodes={nodes}
edges={edges}
maxWidth={size.width + 100}
maxHeight={size.height + 100}
direction={layout}
key={layout}
onCanvasClick={onCanvasClick}
onLayoutChange={onLayoutChange}
node={(props) => (
<CustomNode
onClick={(e) => handleNodeClick(e, props)}
{...props}
/>
)}
zoomable={false}
readonly
{...props}
/>
</TransformComponent>
</TransformWrapper>
</StyledEditorWrapper>
{!isWidget && selectedNode && (
<Canvas
nodes={nodes}
edges={edges}
maxWidth={size.width + 100}
maxHeight={size.height + 100}
direction={layout}
key={layout}
onCanvasClick={onCanvasClick}
onLayoutChange={onLayoutChange}
node={(props) => (
<CustomNode
onClick={(e) => handleNodeClick(e, props)}
{...props}
/>
)}
zoomable={false}
readonly
/>
</TransformComponent>
</TransformWrapper>
</StyledEditorWrapper>
);
});
export const Graph: React.FC<{ json: string; isWidget?: boolean }> = ({
json,
isWidget = false,
}) => {
const [isModalVisible, setModalVisible] = React.useState(false);
const [selectedNode, setSelectedNode] = React.useState<object>({});
const openModal = React.useCallback(() => setModalVisible(true), []);
return (
<>
<MemoizedGraph
json={json}
openModal={openModal}
setSelectedNode={setSelectedNode}
isWidget={isWidget}
/>
{!isWidget && (
<NodeModal
selectedNode={selectedNode.text}
selectedNode={selectedNode}
visible={isModalVisible}
setVisible={setModalVisible}
closeModal={() => setModalVisible(false)}
/>
)}
</>

View File

@ -1,10 +1,17 @@
import React from "react";
import toast from "react-hot-toast";
import { FiCopy } from "react-icons/fi";
import { NodeData } from "reaflow";
import { Button } from "src/components/Button";
import { Modal } from "src/components/Modal";
import styled from "styled-components";
interface NodeModalProps {
selectedNode: object;
visible: boolean;
closeModal: () => void;
}
const StyledTextarea = styled.textarea`
resize: none;
width: 100%;
@ -19,16 +26,19 @@ const StyledTextarea = styled.textarea`
border: none;
`;
export const NodeModal = ({ selectedNode, visible = true, setVisible }) => {
export const NodeModal = ({
selectedNode,
visible,
closeModal,
}: NodeModalProps) => {
const handleClipboard = () => {
toast("Content copied to clipboard!");
navigator.clipboard.writeText(JSON.stringify(selectedNode));
setVisible(false);
closeModal();
};
return (
<Modal visible={visible} setVisible={setVisible}>
<Modal visible={visible} setVisible={closeModal}>
<Modal.Header>Node Content</Modal.Header>
<Modal.Content>
<StyledTextarea
@ -42,7 +52,7 @@ export const NodeModal = ({ selectedNode, visible = true, setVisible }) => {
)}
/>
</Modal.Content>
<Modal.Controls setVisible={setVisible}>
<Modal.Controls setVisible={closeModal}>
<Button status="SECONDARY" onClick={handleClipboard}>
<FiCopy size={18} /> Clipboard
</Button>