使用react-flow制作流程图

Posted qing1224

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用react-flow制作流程图相关的知识,希望对你有一定的参考价值。

1.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制作流程图的主要内容,如果未能解决你的问题,请参考以下文章

关于网页制作的规划与流程图的使用

html怎么制作流程图

CorelDRAW教程:怎样绘制制作箭头流程图?

免费的流程图制作软件

免费流程图在线制作

如何使用ProcessOn制作“组织结构图”