Advertisement
bodry

Untitled

Sep 6th, 2022
2,334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, {useCallback} from 'react';
  2. import ReactFlow, {addEdge, ConnectionLineType, useNodesState, useEdgesState} from 'react-flow-renderer';
  3. import dagre from 'dagre';
  4. import DataConstructor from './DataConstructor'
  5. import {Box} from "@mui/material";
  6.  
  7.  
  8. const dagreGraph = new dagre.graphlib.Graph();
  9. dagreGraph.setDefaultEdgeLabel(() => ({}));
  10.  
  11. const nodeWidth = 172;
  12. const nodeHeight = 36;
  13.  
  14. const getLayoutedElements = (nodes, edges, direction = 'TB') => {
  15.     const isHorizontal = direction === 'LR';
  16.     dagreGraph.setGraph({rankdir: direction});
  17.  
  18.     nodes.forEach((node) => {
  19.         dagreGraph.setNode(node.id, {width: nodeWidth, height: nodeHeight});
  20.     });
  21.  
  22.     edges.forEach((edge) => {
  23.         dagreGraph.setEdge(edge.source, edge.target);
  24.     });
  25.  
  26.     dagre.layout(dagreGraph);
  27.  
  28.     nodes.forEach((node) => {
  29.         const nodeWithPosition = dagreGraph.node(node.id);
  30.         node.targetPosition = isHorizontal ? 'left' : 'top';
  31.         node.sourcePosition = isHorizontal ? 'right' : 'bottom';
  32.  
  33.         // We are shifting the dagre node position (anchor=center center) to the top left
  34.         // so it matches the React Flow node anchor point (top left).
  35.         node.position = {
  36.             x: nodeWithPosition.x - nodeWidth / 2,
  37.             y: nodeWithPosition.y - nodeHeight / 2,
  38.         };
  39.  
  40.         return node;
  41.     });
  42.  
  43.     return {nodes, edges};
  44. };
  45.  
  46. const LayoutFlow = (props) => {
  47.     const {_nodes, _edges} = DataConstructor(props)
  48.     const {nodes: layoutedNodes, edges: layoutedEdges} = getLayoutedElements(
  49.         _nodes,
  50.         _edges
  51.     );
  52.  
  53.     const [nodes, setNodes, onNodesChange] = useNodesState(layoutedNodes);
  54.     const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges);
  55.     const onConnect = useCallback(
  56.         (params) => setEdges((eds) => addEdge({...params, type: ConnectionLineType.SmoothStep, animated: true}, eds)),
  57.         []
  58.     );
  59.     const onLayout = useCallback(
  60.         (direction) => {
  61.             const {nodes: layoutedNodes, edges: layoutedEdges} = getLayoutedElements(
  62.                 nodes,
  63.                 edges,
  64.                 direction
  65.             );
  66.  
  67.             setNodes([...layoutedNodes]);
  68.             setEdges([...layoutedEdges]);
  69.         },
  70.         [nodes, edges]
  71.     );
  72.  
  73.  
  74.     return (
  75.         <Box sx={{border: 1}} className="layoutflow" style={{width: 1200, height: 560}}>
  76.             <ReactFlow
  77.                 nodes={nodes}
  78.                 edges={edges}
  79.                 onNodesChange={onNodesChange}
  80.                 onEdgesChange={onEdgesChange}
  81.                 onConnect={onConnect}
  82.                 connectionLineType={ConnectionLineType.SmoothStep}
  83.                 fitView
  84.             />
  85.             <div className="controls">
  86.                 <button onClick={() => onLayout('TB')}>vertical layout</button>
  87.                 <button onClick={() => onLayout('LR')}>horizontal layout</button>
  88.             </div>
  89.         </Box>
  90.     );
  91. };
  92.  
  93. export default LayoutFlow;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement