React Flow 边的基础知识与示例:从基本属性到代码实例详解

news2025/5/19 19:58:24

本文为《React Agent:从零开始构建 AI 智能体》专栏系列文章。 专栏地址:https://blog.csdn.net/suiyingy/category_12933485.html。项目地址:https://gitee.com/fgai/react-agent(含完整代码示​例与实战源)。完整介绍:https://blog.csdn.net/suiyingy/article/details/146983582。

        节点和边是相互依存的关系。边的存在依赖于节点,因为边的起点(source)和终点(target)都是节点的 id。边用于定义节点之间的连接关系,这种关系可以表示流程流向、数据传递方向、依赖关系等。节点通过边与其他节点进行交互,形成一个有机的图表结构。例如,在一个流程图中,节点可能代表不同的任务步骤,边则表示任务之间的执行顺序。

        边与节点共同构成 React Flow 图表的核心内容,由 React Flow 容器统一管理。容器负责处理边的布局计算、渲染以及交互响应,确保边能够准确地连接节点,并在节点位置变动、图表缩放等操作下,依然保持正确的连接关系和视觉效果。边的存在使得原本独立的节点形成一个有机整体,赋予图表实际的业务意义和交互价值。

1 基本示例程序

        下面是边的基本示例程序。

import React, { useCallback } from 'react';
import {
  ReactFlow,
  useNodesState,
  useEdgesState,
  addEdge,
} from 'reactflow';

import 'reactflow/dist/style.css';

const initialNodes = [
  { id: '1', position: { x: 0, y: 0 }, data: { label: '1' } },
  { id: '2', position: { x: 0, y: 100 }, data: { label: '2' } },
];

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'default'
  }
];

export default function App() {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

  const onConnect = useCallback(
    (params) => setEdges((eds) => addEdge(params, eds)),
    [setEdges],
  );

  return (
    <div style={{ height: '500px' }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        fitView
      />
    </div>
  );
}

        运行程序后结果如下图所示。

图1 直线边

2 基本属性

2.1 id

        id:边的唯一标识符,用于在 React Flow 中识别和管理边。在复杂图表中,通过 id 可以方便地获取、更新或删除特定边。

const edgeWithId = {
    id: 'unique-edge-id-1',
    source: 'node-a',
    target: 'node-b',
    type:'default'
};

2.2 source 和 target

        source 和 target:分别指定边的起点和终点节点的 id,是边存在的基础,决定边连接的节点对象。source 是提供输入的节点,target 则是接收输出的节点。

const specificConnectionEdge = {
    id: 'edge-2',
    source: 'node-3',
    target: 'node-4',
    type: 'straight'
};

2.3 sourceHandle 和targetHandle

        sourceHandle 和targetHandle:分别指定边的起点和终点节点的连接端点 id。sourceHandle 是提供输入的端点,targetHandle 则是接收输出的端点。

import React, { useCallback } from 'react';
import {
  ReactFlow,
  useNodesState,
  useEdgesState,
  addEdge,
  Handle,
} from 'reactflow';
import 'reactflow/dist/style.css';

const CustomNode = ({ data }) => {
  return (
    <div style={{
      padding: 20,
      border: '1px solid #ddd',
      borderRadius: 5,
      background: '#fff',
    }}>
      <div>{data.label}</div>
      {/* 左侧两个输入句柄 */}
      <Handle
        type="target"
        position="left"
        id="input-1"
        style={{ top: '30%' }}
      />
      <Handle
        type="target"
        position="left"
        id="input-2"
        style={{ top: '70%' }}
      />
      {/* 右侧两个输出句柄 */}
      <Handle
        type="source"
        position="right"
        id="output-1"
        style={{ top: '30%' }}
      />
      <Handle
        type="source"
        position="right"
        id="output-2"
        style={{ top: '70%' }}
      />
    </div>
  );
};

const initialNodes = [
  { 
    id: '1', 
    position: { x: 0, y: 0 }, 
    data: { label: '1' },
    type: 'custom',
  },
  { 
    id: '2', 
    position: { x: 200, y: 100 }, 
    data: { label: '2' },
    type: 'custom',
  },
];

const initialEdges = [
  { 
    id: 'e1-2a', 
    source: '1', 
    sourceHandle: 'output-1',
    target: '2', 
    targetHandle: 'input-2',
  },
  { 
    id: 'e1-2b', 
    source: '1', 
    sourceHandle: 'output-2',
    target: '2', 
    targetHandle: 'input-1',
  }
];

const nodeTypes = {
  custom: CustomNode,
};

export default function App() {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

  const onConnect = useCallback(
    (params) => setEdges((eds) => addEdge({
      ...params,
      type: 'default',
    }, eds)),
    [setEdges]
  );

  return (
    <div style={{ height: '500px' }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        nodeTypes={nodeTypes}
        fitView
      />
    </div>
  );
}

        运行程序后结果如下图所示。

图2 指定连接点

2.4 type

        type:指定边的类型,既可以是内置类型,也可以是自定义类型,影响边的渲染方式和默认行为。边的类型丰富多样,默认包含 default、straight、step、smoothstep 等,每一种类型都赋予边独特的形状与视觉呈现,满足不同场景的设计需求。default 类型的边通常会根据节点的相对位置,以自然流畅的曲线形态连接节点,这种曲线过渡柔和,能够在复杂的节点布局中营造出一种和谐、美观的视觉效果,让整个流程图看起来更具艺术感;straight 类型如其名,边呈现为笔直的线条,简洁明了地连接两个节点,这种形状在追求简洁、直观表达连接关系的场景下极为适用,能够快速引导用户理解节点之间的直接关联;step 类型的边则是通过直角转折的方式连接节点,它会以阶梯状的折线形态出现,适合用于表示具有明确步骤、层级关系的连接,为流程图增添清晰的逻辑层次感;smoothstep 类型的边在 step 类型的基础上进行了优化,它同样有转折,但转折处采用了平滑的曲线过渡,在保留逻辑分层感的同时避免了过于生硬的直角,使边的形态更加优雅流畅,在复杂且注重美观与逻辑兼具的流程图中发挥重要作用。

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'smoothstep'
  }
];

        运行程序后结果如下图所示。

图3 smoothstep 类型

2.5 style

        style:用于设置边的内联样式,包括线条颜色、宽度、线型(实线、虚线等)、箭头样式等。例如,将边设置为红色虚线:

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'smoothstep',
    style: {
      stroke:'red',
      strokeWidth: 3,
      strokeDasharray: '5, 5',
    }
  }
]

        运行程序后结果如下图所示。

图4  边样式

2.6 animated

        animated:设置为true时,边可以启用动画效果,如淡入淡出、路径变化动画等,增强图表的动态展示效果。

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'smoothstep',
    animated: true,
    style: {
      stroke:'red',
      strokeWidth: 3,
      strokeDasharray: '5, 5',
    }
  }
];

2.7 selectable

        selectable:控制边是否可以被用户选中。选中边后,可以对其进行编辑、删除等操作,或展示相关信息。

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'smoothstep',
    animated: true,
    selectable: true,
    style: {
      stroke:'red',
      strokeWidth: 3,
      strokeDasharray: '5, 5',
    }
  }
];

2.8 事件属性

        onClick、onMouseEnter等事件属性:与节点类似,边也可以绑定各种事件处理函数,响应用户操作。例如,当用户点击边时,显示边的详细信息:

const initialEdges = [
  { id: 'e1-2', 
    source: '1', 
    target: '2',
    type: 'smoothstep',
    animated: true,
    selectable: true,
    style: {
      stroke:'red',
      strokeWidth: 3,
      strokeDasharray: '5, 5',
    },
    onClick: () => {
      alert('You clicked the edge!');
    }
  }
];

立即关注获取最新动态

点击订阅《React Agent 开发专栏》,每周获取智能体开发深度教程。项目代码持续更新至React Agent 开源仓库,欢迎 Star 获取实时更新通知!FGAI 人工智能平台:FGAI 人工智能平台

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oracle 资源管理器的使用

14.8.2资源管理器的使用 资源管理器控制CPU资源使用说明&#xff1a;  第一种分配方法&#xff1a;EMPHASIS CPU 分配方法确定在资源计划中对不同使用者组中的会话的重视程度。CPU占用率的分配级别为从1 到8&#xff0c;级别1 的优先级最高。百分比指定如何将CPU 资源分配给每…

贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现

贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现 目录 贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现效果一览基本介绍程序设计参考资料…

Docker配置SRS服务器 ,ffmpeg使用rtmp协议推流+vlc拉流

目录 演示视频 前期配置 Docker配置 ffmpeg配置 vlc配置 下载并运行 SRS 服务 推拉流流程实现 演示视频 2025-05-18 21-48-01 前期配置 Docker配置 运行 SRS 建议使用 Docker 配置 Docker 请移步&#xff1a; 一篇就够&#xff01;Windows上Docker Desktop安装 汉化完整指…

一个stm32工程从底层上都需要由哪些文件构成

原文链接&#xff1a;https://kashima19960.github.io/2025/05/17/stm32/一个stm32工程从底层上都需要由哪些文件构成/ 前言 我最近因为做课设要用到stm32&#xff0c;所以去找了一些开源的stm32工程来看看&#xff0c;然后发现现在新版的keil mdk对于环境的配置跟以前 相比发…

[Mac] 开发环境部署工具ServBay 1.12.2

[Mac] 开发环境部署工具ServBay 链接&#xff1a;https://pan.xunlei.com/s/VOQS0LDsC_J6XU4p-R6voF6YA1?pwdnbyg# 非常给力的本地 Web 开发/测试环境工具&#xff1a;ServBay。之前我们本地搭个 PHP MySQL Nginx 环境&#xff0c;或者搞个 PHP web 环境啥的&#xff0c;不…

商城小程序源码介绍

今天要为大家介绍一款基于ThinkPHP、FastAdmin以及UniApp开发的商城小程序源码&#xff0c;这款源码在设计和功能上都有不俗的表现&#xff0c;非常适合想要搭建线上商城的开发者。 该源码采用了ThinkPHP作为后端框架&#xff0c;利用其强大的性能和灵活性&#xff0c;保障了系…

科技项目验收测试对软件产品和企业分别有哪些好处?

科技项目验收测试是指在项目的开发周期结束后&#xff0c;针对项目成果进行的一系列验证和确认活动。其目的是确保终交付的产品或系统符合预先设定的需求和标准。验收测试通常包括功能测试、性能测试、安全测试等多个方面&#xff0c;帮助企业评估软件在实际应用中的表现。 科…

汽车零部件冲压车间MES一体机解决方案

在当前制造业升级的大背景下&#xff0c;提升生产效率、实现精细化管理已成为企业竞争力的关键。特别是在汽车零部件制造领域&#xff0c;冲压车间作为生产流程中的重要一环&#xff0c;其生产数据的实时采集与分析对于确保产品质量、优化生产节拍、降低运营成本至关重要。今天…

hysAnalyser 从MPEG-TS导出ES功能说明

摘要 hysAnalyser 是一款特色的 MPEG-TS 数据分析工具。本文主要介绍了 hysAnalyser 从MPEG-TS 中导出选定的 ES 或 PES 功能(版本v1.0.003)&#xff0c;以便用户知悉和掌握这些功能&#xff0c;帮助分析和解决各种遇到ES或PES相关的实际问题。hysAnalyser 支持主流的MP1/MP2/…

家里wifi不能上网或莫名跳转到赌博及色情网站就是域名被劫持、DNS被污染了

文章目录 定义上网过程域名被劫持可能阶段案例排查工具 解决方法清除系统DNS缓存查看DNS缓存清除DNS缓存 登录路由器&#xff0c;设置DNS可用的DNS地址&#xff1a; 找网络运营商报警 定义 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;劫持&#xff0c…

基于SSM实现的健身房系统功能实现十六

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升&#xff0c;健身行业也在迅速扩展。越来越多的人加入到健身行列&#xff0c;健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂&#xff0c;传统的手工或部分自动化的管…

【Java微服务组件】分布式协调P1-数据共享中心简单设计与实现

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 目录 引言设计一个共享数据中心选择数据模型键值对设计 数据可靠性设计持久化快照 &#xff08…

cursor/vscode启动项目connect ETIMEDOUT 127.0.0.1:xx

现象&#xff1a; 上午正常使用cursor/vscode&#xff0c;因为需要写前端安装了nodejs16.20和vue2&#xff0c;结果下午启动前端服务无法访问&#xff0c;浏览器一直转圈。接着测试运行最简单的flask服务&#xff0c;vscode报错connect ETIMEDOUT 127.0.0.1:xx&#xff0c;要么…

兼顾长、短视频任务的无人机具身理解!AirVista-II:面向动态场景语义理解的无人机具身智能体系统

作者&#xff1a;Fei Lin 1 ^{1} 1, Yonglin Tian 2 ^{2} 2, Tengchao Zhang 1 ^{1} 1, Jun Huang 1 ^{1} 1, Sangtian Guan 1 ^{1} 1, and Fei-Yue Wang 2 , 1 ^{2,1} 2,1单位&#xff1a; 1 ^{1} 1澳门科技大学创新工程学院工程科学系&#xff0c; 2 ^{2} 2中科院自动化研究所…

20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤

20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤 2025/5/15 19:55 百度&#xff1a;intel 集成显卡 NVIDIA 配置成为 总是用独立显卡 百度为您找到以下结果 ?要将Intel集成显卡和NVIDIA独立显卡配置为总是使用独立显卡&#xff0c;可以通过以下步骤实现?&#xff…

sparkSQL读入csv文件写入mysql

思路 示例 &#xff08;年龄>18改成>20) mysql的字符集问题 把user改成person “让字符集认识中文”

大涡模拟实战:从区域尺度到街区尺度的大气环境模拟

前言&#xff1a; 随着低空经济的蓬勃发展&#xff0c;无人机、空中出租车等新型交通工具正在重塑我们的城市空间。这场静默的革命不仅带来了经济机遇&#xff0c;更对城市大气环境提出了全新挑战。在距离地面200米以下的城市冠层中&#xff0c;建筑物与大气的复杂相互作用、人…

单目测距和双目测距 bev 3D车道线

单目视觉测距原理 单目视觉测距有两种方式。 第一种&#xff0c;是通过深度神经网络来预测深度&#xff0c;这需要大量的训练数据。训练后的单目视觉摄像头可以认识道路上最典型的参与者——人、汽车、卡车、摩托车&#xff0c;或是其他障碍物&#xff08;雪糕桶之类&#xf…

Web开发-JavaEE应用SpringBoot栈SnakeYaml反序列化链JARWAR构建打包

知识点&#xff1a; 1、安全开发-JavaEE-WAR&JAR打包&反编译 2、安全开发-JavaEE-SnakeYaml反序列化&链 一、演示案例-WEB开发-JavaEE-项目-SnakeYaml序列化 常见的创建的序列化和反序列化协议 • &#xff08;已讲&#xff09;JAVA内置的writeObject()/readObje…

项目复习(2)

第四天 高并发优化 前端每隔15秒就发起一次请求&#xff0c;将播放记录写入数据库。 但问题是&#xff0c;提交播放记录的业务太复杂了&#xff0c;其中涉及到大量的数据库操作&#xff1a;在并发较高的情况下&#xff0c;会给数据库带来非常大的压力 使用Redis合并写请求 一…