使用react-flow制作流程图
Posted qing1224
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用react-flow制作流程图相关的知识,希望对你有一定的参考价值。
react-flow是一个用于构建基于节点的应用程序的库。这些可以是简单的静态图或复杂的基于节点的编辑器。同时react-flow支持自定义节点类型和边线类型,并且它附带一些组件,可以查看缩略图的Mini Map和悬浮控制器Controls.
2.react-flow安装
npm install react-flow-renderer # npm yarn add react-flow-renderer # Yarn
3.react-flow基本使用
1、每个节点固定格式 里面添加内容
代码
index.tsx
import React from \'react\'; import ReactFlow, addEdge, MiniMap, Controls, Background, useNodesState, useEdgesState, from \'react-flow-renderer\'; import nodes as initialNodes, edges as initialEdges from \'./initial-elements\'; const OverviewFlow = () => const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const onConnect = (params) => setEdges((eds) => addEdge(params, eds)); return ( <ReactFlow nodes=nodes // 节点 edges=edges // 连接线 onNodesChange=onNodesChange // 节点拖拽等改变 onEdgesChange=onEdgesChange // 连接线拖拽等改变 onConnect=onConnect // 节点直接连接 fitView // 渲染节点数据 attributionPosition="top-right" // react-flow的位置,类似水印,可以通过css隐藏 > // 背景图 可以配置颜色 方格宽度 <Background color="#aaa" gap=16 /> </ReactFlow> ); ; export default OverviewFlow;
initial-elements.ts节点与连接线数据
import MarkerType from \'react-flow-renderer\'; export const nodes = [ id: \'1\', // id必须 type: \'input\', // 类型: input开始 default默认 output结束 区别在于连接点不一样 data: // 额外的数据 label: ( // 节点名称 <> Welcome to <strong>React Flow!</strong> </> ), // value: 5, .... // 可以将其他数据放入 , position: x: 250, y: 0 , // 节点位置 , id: \'2\', data: label: ( <> This is a <strong>default node</strong> </> ), , position: x: 100, y: 100 , , id: \'3\', data: label: ( <> This one has a <strong>custom style</strong> </> ), , position: x: 400, y: 100 , style: background: \'#D6D5E6\', color: \'#333\', border: \'1px solid #222138\', width: 180, , , id: \'4\', position: x: 250, y: 200 , data: label: \'Another default node\', , , id: \'5\', data: label: \'Node id: 5\', , position: x: 250, y: 325 , , id: \'6\', type: \'output\', data: label: ( <> An <strong>output node</strong> </> ), , position: x: 100, y: 480 , , id: \'7\', type: \'output\', data: label: \'Another output node\' , position: x: 400, y: 450 , , ]; export const edges = [ id: \'e1-2\', source: \'1\', target: \'2\', label: \'this is an edge label\' , id: \'e1-3\', source: \'1\', target: \'3\' , id: \'e3-4\', // id必须 source: \'3\', // 连接线起始节点id target: \'4\', // 连接线结束节点id animated: true, // 连接线是否有动画 label: \'animated edge\', // 连接线名称 , id: \'e4-5\', source: \'4\', target: \'5\', label: \'edge with arrow head\', markerEnd: // 连接线尾部的箭头 type: MarkerType.ArrowClosed, , , id: \'e5-6\', source: \'5\', target: \'6\', type: \'smoothstep\', // 连接线类型 default straight step smoothstep label: \'smooth step edge\', , id: \'e5-7\', source: \'5\', target: \'7\', type: \'step\', style: stroke: \'#f6ab6c\' , // 连接线颜色 label: \'a step edge\', animated: true, labelStyle: fill: \'#f6ab6c\', fontWeight: 700 , // 连接线名称样式 , ];
效果图
2、自定义每个节点中的内容和样式 以及连接点
这个是静态的 展示流程图 想拖动节点 加上1里面的 onNodesChange... 的参数即可
index.tsx
import React, useEffect from \'react\'; import ReactFlow, useNodesState, useEdgesState, from \'react-flow-renderer\'; import nodes as initialNodes, edges as initialEdges from \'./initial-elements\'; import CustomNode from \'./ResizableNode\'; //自定义的渲染每个节点的代码 const nodeTypes = custom: CustomNode, //自定义的内容 ; const OverviewFlow = (resizeFlag: any) => const [nodes, setNodes] = useNodesState(initialNodes); const [edges] = useEdgesState(initialEdges); useEffect(() => setNodes([]); setTimeout(() => setNodes(initialNodes); , 50); , [resizeFlag]); if (!nodes?.length) return null; return ( <ReactFlow nodes=nodes // 节点 edges=edges // 连接线 panOnDrag=false zoomOnDoubleClick=false zoomOnPinch=false zoomOnScroll=false panOnScroll=false fitView // 渲染节点数据 nodeTypes=nodeTypes attributionPosition="top-left" // react-flow的位置,类似水印,可以通过css隐藏 =》 .react-flow__attribution.left display: none;
> /* <Background color="#aaa" gap=16 /> */ </ReactFlow> ); ; export default OverviewFlow;
initial-elements.ts
import MarkerType, Position from \'react-flow-renderer\'; const styles = color: \'#333\', border: \'1px solid #4E8FF0\', borderRadius: \'5px\', background: \'white\', ;
//因为数据太多删除了几个 不过格式都是这样写 export const nodes = [ id: \'0\', type: \'custom\',//有input,output,default三种,input只有一个输出,output只有一个输入,default输入输出各有一个 或者自定义的 data: label: \'\', , position: x: -20, y: 40, // 节点位置 style: width: 1550, height: 500, border: \'1px solid #91caff\', borderRadius: \'15px\', color: \'#4585F2\', background: \'#E2E6F3\', zIndex: -2, , , id: \'1\', // id必须 type: \'custom\', // 类型: input开始 default默认 output结束 区别在于连接点不一样 data: // 额外的数据 label: \'任务1\', // value: 1 // .... // 可以将其他数据放入 , position: x: 200, y: 70, // 节点位置 style: width: 200, height: 150, ...styles, , , id: \'2\', type: \'custom\', data: label: \'任务2\', , position: x: 450, y: 70, style: width: 200, height: 150, , , id: \'3\', type: \'custom\', data: label: ( \'任务3\' ), , position: x: 700, y: 70, style: width: 200, height: 150, ...styles, , ]; export const edges = [ id: \'1-2\', source: \'1\', target: \'2\', markerEnd: // 连接线尾部的箭头 type: MarkerType.ArrowClosed, color: \'#4E8FF0\', , style: stroke: \'#4E8FF0\', // 连接线颜色 labelStyle: fill: \'#4E8FF0\', fontWeight: 700, // 连接线名称样式 , id: \'2-3\', // id必须 source: \'2\', // 连接线起始节点id target: \'3\', // 连接线结束节点id markerEnd: // 连接线尾部的箭头 type: MarkerType.ArrowClosed, color: \'#4E8FF0\', , style: stroke: \'#4E8FF0\', // 连接线颜色 labelStyle: fill: \'#4E8FF0\', fontWeight: 700, // 连接线名称样式 , id: \'3-4\', source: \'3\', target: \'4\', style: stroke: \'#4E8FF0\', // 连接线颜色 labelStyle: fill: \'#4E8FF0\', fontWeight: 700, // 连接线名称样式 markerEnd: // 连接线尾部的箭头 type: MarkerType.ArrowClosed, color: \'#4E8FF0\', , ];
ResizableNode.tsx
import React, memo from \'react\'; import Handle, Position from \'react-flow-renderer\'; import className from \'./home.module.scss\'; import newTask from \'@/static/newTask.png\'; import Operator from \'@/static/OperatorConfig.png\'; import DeployTask from \'@/static/DeploymentTask.png\'; import TaskReview from \'@/static/TaskReview.png\'; import TaskLaunch from \'@/static/TaskLaunch.png\'; import Button from \'antd\'; const datadevelopment = [ id: \'0\', , src: newTask, id: \'1\', button: \'快速开始\', url: \'\', width: \'50px\', height: \'50px\', , src: Operator, id: \'11\', button: \'配置说明\', link: \'\', width: \'45px\', height: \'45px\', , src: DeployTask, id: \'3\', title: \'任务基本信息\', width: \'55px\', height: \'55px\', , ]; export default memo((data, id, isConnectable: any) => // console.log(1, data); const position = (sum: any) => switch (sum) case \'6\': return Position.Right; case \'9\': return Position.Top; default: return Position.Left; ; const pageButton = (item: any) => if (item.link) return ( <Button target=\'_blank\' type=\'link\' htmlType=\'button\' href=item.link > item.button </Button> ); else return ( <Button style= background: \'linear-gradient(90deg,#2468E8,#2C61E4,#4148D0,#5127B8)\', border: \'none\', onClick=e => e.stopPropagation(); window.location.hash = item.url; type=\'primary\' > item.button </Button> ); ; return ( <div className=className.ResicabelNode> <Handle style=visibility: \'hidden\' type="target" position=position(id) isConnectable=isConnectable /> datadevelopment.filter((item: any) => return item.id === id; ).map((item: any) => return ( +item.id < 12 ? <div key=item.id className=className.nodeContent style=data.style > item.src ? <img style=width: item.width, height: item.height src=item.src /> : null <div className=className.nodeRightbox> <p className=className.nodelabel>data.label</p> item.button ? pageButton(item) : <span className=className.nodelabelTitle>item.title</span> </div> </div> : <div key=item.id className=className.dataDistribution style=data.style > item.order ? <p className=className.circle> item.order </p> : null <p className=className.nodelabel>data.label</p> item.button ? pageButton(item) : null </div> ); ) <Handle style=visibility: \'hidden\' type=\'source\' position=id === \'11\' || id === \'5\' ? Position.Bottom : Position.Right id=\'a\' className=\'my_handle\' isConnectable=isConnectable /> </div> ); );
效果图
收集的一些关于 react-flow 参数讲解链接以及官网地址
https://www.5axxw.com/wiki/content/obkffc
https://reactflow.dev/
CorelDRAW教程:怎样绘制制作箭头流程图?
箭头流程图主要由矢量图和连接符组成,通过图形之间的顺序阐述的一个过程,应用也是非常广泛,有些软件中会自带流程图,对于CDR这款矢量绘图软件来说,手动制作流程图是简单且高效的。首先CorelDRAW中就为用户提供了多种箭头形状,使用这些箭头形状能够快速制作出各种自己想要的效果,本文,小编就使用CDR中自带的箭头形状,制作矢量箭头流程图,效果也是很不错的。
CDR软件下载:http://wm.makeding.com/iclk/?zoneid=20126
步骤1:鼠标左键单击并悬停三秒“多边形工具”,在展开的多种形状工具中选择“箭头形状”,属性栏中会显示相关选项,单击“完美形状”挑选器按钮,然后从列表中选择第一个箭头形状。
步骤2:在页面中按下鼠标左键并拖动,松开鼠标后可绘制出选择的形状。移动“轮廓沟槽的菱形手柄”的位置,可以改变箭头的外形,这个根据需要自行调整。
步骤3:选择箭头形状,Ctrl+Q转曲,按下F10,使用“形状工具”结合属性栏“转换为曲线”功能改变曲线形状,如下图所示。
步骤4:填充任意颜色并去除轮廓,然后按住Shift从右向左复制(因为图层顺序的原因),也可以从左向右复制,但之后要调整顺序(调整顺序快捷键:从左到右可以依次按下Ctrl+End)。
步骤5:先复制出一个,然后按下Ctrl+R等距复制多个,如下图所示。
步骤6:用贝塞尔工具绘制小三角形,放在流程图左侧,保持完整性,然后添加阴影效果,并调整参数。
步骤7:分别复制第一箭头的阴影效果,复制方法:先选择要添加阴影的对象,然后点击阴影工具,在属性栏中点击“复制阴影效果属性”按钮,出现黑色箭头时,单击要复制的带有阴影效果的图形即可,以后的每一个图形重复此操作就好了。
如果觉得这么做麻烦,也可以在一开始就应用阴影效果,全选图形和阴影,然后再Ctrl+R等距复制,小编之所以这么做,是想让大家学习复制阴影的方法哦。
最后,添加文字,以同样的方法等距复制,箭头流程图制作完成。
原文转自www.coreldrawchina.com,更多有关CDR矢量绘图的基础信息可关注CDR中文官网。
以上是关于使用react-flow制作流程图的主要内容,如果未能解决你的问题,请参考以下文章