十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Reflex Enterprise React Flow 核心概念全解:节点、连接线与视口机制

Reflex Enterprise React Flow 核心概念全解:节点、连接线与视口机制 Reflex Enterprise React Flow 核心概念全解节点、连接线与视口机制【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflex节点Node、句柄Handle、边Edge、连接线Connection Line与视口Viewport构成了 Reflex Enterprise 中rxe.flow交互式流程图的五大核心概念。本文以 docs/enterprise/react_flow/overview.md 为主线结合该目录下的 nodes.md、edges.md、components.md 等系列文档系统讲解这些基础构件的数据结构、配置方式与交互原理帮助你从零理解并搭建一个可拖拽、可连接、可缩放的流程图应用。从整体理解一个 Flow 的组成在 Reflex Enterprise 中一个流程图Flow本质上是由节点Nodes和连接节点的边Edges组成的交互式图interactive graph。所有视觉元素最终都渲染在 React Flow 的画布之上而 Reflex 通过reflex_enterprise简称rxe下的rxe.flow组件树把这一整套能力封装成纯 Python 的组件体系。理解 Flow 需要抓住以下五个基本构件构件作用节点Node流程图的构建单元承载内容与功能句柄Handle节点上供边连接的锚点边Edge连接两个节点的连线连接线Connection Line拖拽新建连接时出现的占位边视口Viewport包含整个流程的可视区域负责缩放与平移下文逐一展开每个概念并给出可直接复用的配置示例。Nodes流程图的构建单元节点是流程的积木。除了少数内置节点类型真正的能力来自自定义节点你可以让节点包含交互元素、展示动态数据、支持多个连接点。框架提供基础样式与功能由你定义。节点的数据形态一个 Python 字典在 Reflex Enterprise 中节点被表示为带有固定字段的 Python 字典核心字段如下idstr—— 节点的唯一标识符positiondict—— 节点的位置含x、y坐标datadict—— 传递给节点组件的任意数据typestr—— 在node_types中定义的节点类型sourcePosition/targetPositionstr—— 控制源句柄/目标句柄的位置top、right、bottom、lefthidden、selected、draggable、selectable、connectable、deletablebool—— 控制节点的可见性、选中状态与各项交互能力width、heightfloat—— 节点尺寸parentIdstr—— 父节点 ID用于创建子流程sub-flowsstyledict—— 节点自定义样式classNamestr—— 节点的 CSS 类名。三种内置节点类型Reflex Flow 提供了三种开箱即用的内置节点类型详见 nodes.mdnodes: list[Node] [ { id: 1, type: input, position: {x: 100, y: 100}, data: {label: Start}, }, { id: 2, type: default, position: {x: 300, y: 100}, data: {label: Process}, }, { id: 3, type: output, position: {x: 500, y: 100}, data: {label: End}, }, ]input—— 流程入口点只带源句柄source handlesdefault—— 标准节点同时具备源句柄与目标句柄output—— 流程出口点只带目标句柄target handles。节点定位、样式与句柄配置定位、样式与句柄都是节点上可以独立配置的属性# 节点定位通过 position 的 x/y 决定节点在画布上的坐标 node { id: positioned-node, type: default, position: {x: 250, y: 150}, data: {label: Positioned Node}, } # 节点样式通过 style 直接传入 CSS 属性 styled_node { id: styled-node, type: default, position: {x: 100, y: 200}, data: {label: Custom Style}, style: { background: #ff6b6b, color: white, border: 2px solid #ff5252, borderRadius: 8px, padding: 10px, }, } # 句柄位置sourcePosition / targetPosition 决定边的出入方向 node_with_handles { id: handle-node, type: default, position: {x: 300, y: 300}, data: {label: Custom Handles}, sourcePosition: right, targetPosition: left, }Handles边与节点的连接锚点句柄是节点上边所依附的点。它们通常出现在节点的上、下、左、右侧但可以自由定位与定制样式。一个节点可以拥有多个句柄从而支持复杂的连接布局。在自定义节点中句柄通过rxe.flow.handle组件显式声明。以 nodes.md 中的颜色选择器自定义节点为例import reflex as rx import reflex_enterprise as rxe rx.memo def color_selector_node( data: rx.Var[dict], isConnectable: rx.Var[bool] ) - rx.Component: data data.to(dict) return rx.el.div( rxe.flow.handle( typetarget, positionleft, is_connectableisConnectable, ), rx.el.div( Custom Color Picker Node: , rx.el.strong(data[color]), ), rx.el.input( class_namenodrag, typecolor, on_changeCustomNodeState.on_change_color, default_valuedata[color], ), rxe.flow.handle( typesource, positionright, is_connectableisConnectable, ), )该示例展示了句柄的两个关键属性type——target接收连接或source发出连接position—— 句柄在节点上的方位is_connectable—— 是否允许建立连接可结合业务逻辑动态控制例如连接数上限见 examples.md 中的 Connection Limit 示例。另外注意class_namenodrag给节点内部的可交互元素加上nodrag类可以避免拖拽节点时误触发输入控件。自定义节点的挂载方式自定义节点本质上是标准的 Reflex 组件通过node_types字典映射到type字符串上rxe.flow( ..., node_types{selectorNode: color_selector_node}, )因为是标准组件你可以在节点内渲染任意内容、实现任意功能并通过data字段把动态数据注入节点。Edges节点之间的连接边是连接两个节点的连线。每条边都需要一个源节点source与一个目标节点target。边可以被定制样式多句柄节点也能挂载多条边自定义边可以包含交互元素、专门的路径算法或超越简单线条的独特视觉样式。边的数据形态边同样以 Python 字典表示详见 edges.mdidstr—— 边的唯一标识符source/targetstr—— 源节点与目标节点的 IDtypestr—— 在edge_types中定义的边类型sourceHandle/targetHandlestr | None—— 可选的源/目标句柄 IDanimatedbool—— 是否启用动画hidden、deletable、selectablebool—— 可见性与交互开关datadict—— 任意元数据labelAny—— 沿边渲染的标签文本styledict、classNamestr—— 边的样式控制。五种内置边类型edges: list[Edge] [ {id: e1, source: 1, target: 2, type: default}, {id: e2, source: 2, target: 3, type: straight}, {id: e3, source: 3, target: 4, type: step}, {id: e4, source: 4, target: 5, type: smoothstep}, {id: e5, source: 5, target: 6, type: bezier}, ]default—— 标准曲线边straight—— 节点间的直线step—— 直角折线路径smoothstep—— 平滑的直角折线路径bezier—— 贝塞尔曲线路径。边样式、动画与标签# 样式通过 style 控制描边颜色与粗细 edges: list[Edge] [ { id: styled-edge, source: 1, target: 2, style: { stroke: #ff6b6b, strokeWidth: 3, }, } ] # 动画animatedTrue 让流动的点沿边运动 edges: list[Edge] [ { id: animated-edge, source: 1, target: 2, animated: True, style: {stroke: #4dabf7}, } ] # 标签label 在边的中间位置渲染文本 edges: list[Edge] [ { id: labeled-edge, source: 1, target: 2, label: Connection, style: {stroke: #51cf66}, } ]自定义边当默认直线或贝塞尔连接器无法满足需求时可以通过edge_types定义自定义边类型。例如在 edges.md 的带删除按钮的边示例中自定义边组合了rxe.flow.base_edge渲染路径与rxe.flow.edge_label_renderer渲染中点处的交互按钮rx.memo def button_edge( id: rx.Var[str], sourceX: rx.Var[float], sourceY: rx.Var[float], targetX: rx.Var[float], targetY: rx.Var[float], sourcePosition: rx.Var[Position], targetPosition: rx.Var[Position], markerEnd: rx.Var[str], ) - rx.Fragment: bezier_path rxe.components.flow.util.get_bezier_path( source_xsourceX, source_ysourceY, target_xtargetX, target_ytargetY, source_positionsourcePosition, target_positiontargetPosition, ) return rx.fragment( rxe.flow.base_edge(pathbezier_path.path, markerEndmarkerEnd), rxe.flow.edge_label_renderer( rx.el.div( rx.el.button( ×, on_clickrx.run_script(...), # 通过 api.set_edges 删除当前边 style{position: absolute, left: f{bezier_path.label_x}px, ...}, ), ) ), )其中get_bezier_path返回的label_x/label_y用于把按钮精确定位到边的中点。自定义边通过edge_types{button: button_edge}挂载到 Flow 上。Connection Line拖拽连接时的占位边当用户从一个句柄点击并拖向另一个句柄来创建新边时拖拽过程中出现的占位边被称为连接线Connection Line。连接线的行为与普通边一致其外观与行为同样可以被定制。连接线的生命周期由 Flow 的事件驱动on_connect—— 用户完成一次有效连接从一个句柄拖到另一个句柄时触发配合rxe.flow.util.add_edge把新边写入状态on_connect_end—— 连接交互结束时触发无论是否有效。可结合rxe.flow.api.screen_to_flow_position把鼠标屏幕坐标转换为画布坐标实现在画布空白处松手即新建节点等高级交互见 examples.md 的 Add Node on Edge Drop 示例。一个典型的连接接线方式如下完整示例见 interactivity.mdrxe.flow( ..., on_connectlambda connection: FlowState.set_edges( rxe.flow.util.add_edge(connection, FlowState.edges) ), )Viewport视口与画布坐标体系视口是包含整个流程的可视区域。每个节点都有 x、y 坐标表示其位置移动视口会改变这些坐标放大或缩小则调整缩放级别zoom。视口保证了图表始终可导航、可交互。rxe.flow提供了若干与视口相关的配置fit_view: bool—— 为True时Flow 会自动缩放并平移使所有初始节点完整适配视口基础示例见 basic_flow.mdfit_view_options: FitViewOptions—— 定制 fitView 行为如{padding: 2}default_viewport—— 设置初始视口例如{x: 0, y: 0, zoom: 1.5}snap_to_grid/snap_grid—— 是否启用网格吸附及网格间距如snap_grid(20, 20)。视口相关的程序化能力由rxe.flow.api提供详见 hooks.mdscreen_to_flow_position(x, y, snap_to_gridFalse)—— 把屏幕像素坐标转换为 Flow 画布坐标flow_to_screen_position(x, y)—— 把画布内坐标转换为屏幕像素坐标。例如把用户松开连接的鼠标位置转换为画布坐标rxe.flow( ..., on_connect_endlambda connection_status, event: FlowState.handle_connect_end( connection_status, rxe.flow.api.screen_to_flow_position( xevent.client_x, yevent.client_y, ), ), )让五大概念协作一个完整的交互式 Flow把上述概念串起来就是一个完整的交互式流程图。以下代码取自 basic_flow.md包含输入/默认/输出三种节点、一条动画边与一条普通边并挂载了控件、背景网格与迷你地图import reflex as rx import reflex_enterprise as rxe from reflex_enterprise.components.flow.types import Node, Edge # 所有节点共用的样式 node_style { backgroundColor: #ffcc00, color: #000000, padding: 10px, borderRadius: 5px, } class FlowState(rx.State): nodes: list[Node] [ {id: 1, type: input, position: {x: 100, y: 100}, data: {label: Input Node}, style: node_style}, {id: 2, type: default, position: {x: 300, y: 200}, data: {label: Default Node}, style: node_style}, {id: 3, type: output, position: {x: 500, y: 100}, data: {label: Output Node}, style: node_style}, ] edges: list[Edge] [ {id: e1-2, source: 1, target: 2, animated: True}, {id: e2-3, source: 2, target: 3}, ] def flow_example(): return rx.box( rxe.flow( rxe.flow.controls(), rxe.flow.background(), rxe.flow.mini_map(), default_nodesFlowState.nodes, default_edgesFlowState.edges, nodesFlowState.nodes, edgesFlowState.edges, fit_viewTrue, attribution_positionbottom-right, ), height100vh, width100vw, )要点节点可移动、边会随节点动态更新用户可从句柄拖出新连接缩放、平移与迷你地图开箱即用Flow 自动适配视口fit_viewTrue并支持浅色/深色模式务必给外层容器设置显式height与width——Flow 填满父容器没有尺寸则不可见。状态驱动的交互controlled 与 uncontrolled在 interactivity.md 中Reflex Flow 明确区分了两种工作模式受控controlled传入nodes/edges你的 State 是唯一数据源画布渲染状态中的确切内容。此时必须接线on_nodes_change/on_edges_change否则拖拽、选择、删除等交互结果会被丢弃非受控uncontrolled只传default_nodes/default_edges组件内部自行管理变更但你的 State 不会感知这些变化。受控模式的完整事件接线def interactive_flow(): return rx.box( rxe.flow( rxe.flow.controls(), rxe.flow.background(), rxe.flow.mini_map(), nodesFlowState.nodes, edgesFlowState.edges, on_nodes_changelambda node_changes: FlowState.set_nodes( rxe.flow.util.apply_node_changes(FlowState.nodes, node_changes) ), on_edges_changelambda edge_changes: FlowState.set_edges( rxe.flow.util.apply_edge_changes(FlowState.edges, edge_changes) ), on_connectlambda connection: FlowState.set_edges( rxe.flow.util.add_edge(connection, FlowState.edges) ), fit_viewTrue, attribution_positionbottom-right, ), height100vh, width100vw, )on_nodes_change—— 节点被拖拽、选择、缩放或删除时触发on_edges_change—— 边被选择或删除时触发on_connect—— 用户完成一次句柄连接时触发rxe.flow.util.add_edge根据连接信息构建新边列表。重要约束apply_node_changes/apply_edge_changes这类工具函数必须在组件代码即接线到on_nodes_change/on_edges_change的 lambda中使用在客户端求值并产出更新后的列表再交给普通的 setter 事件处理器绝不能在rx.event处理器内部调用它们——State 一侧只负责接收并保存结果列表。常用组件与主题定制四大辅助组件rxe.flow组件体系详见 components.md还包含四个高频辅助组件组件作用关键 Propsrxe.flow.provider上下文 Provider让 Flow 的内部状态可在ReactFlow /之外访问多数 API hooks 依赖它initial_nodes、default_edges、initial_width、initial_height、fit_view、initial_fit_view_options、initial_min_zoom、initial_max_zoom、node_origin、node_extentrxe.flow.background渲染背景图案线条、圆点或十字color、bg_color、variantlines\|dots\|cross、gap、sizerxe.flow.controls缩放/适配视图/锁定视口的控制面板show_zoom、show_fit_view、show_interactive、positionrxe.flow.mini_map流程总览小地图node_color、node_stroke_color、pannable、zoomable、position注意rxe.flow.provider不接受任何事件处理器所有事件on_nodes_change、on_edges_change、on_connect等必须设置在内部的rxe.flow上。典型用法rxe.flow.provider( rxe.flow( rxe.flow.background(), nodesFlowState.nodes, edgesFlowState.edges, on_nodes_changelambda changes: FlowState.set_nodes( rxe.flow.util.apply_node_changes(FlowState.nodes, changes) ), fit_viewTrue, ) )Provider 的initial_width/initial_height是服务端使用fit_view所必需的尺寸参数node_extent用来限定节点可移动的边界。API Hooks 一览rxe.flow.api模块封装了 React Flow 的useReactFlowhook须配合rxe.flow.provider使用详见 hooks.md节点get_nodes()、set_nodes(nodes)、add_nodes(nodes)、get_node(id)、update_node(id, node_update, replaceFalse)、update_node_data(id, data_update, replaceFalse)边get_edges()、set_edges(edges)、add_edges(edges)、get_edge(id)、update_edge(id, edge_update, replaceFalse)、update_edge_data(id, data_update, replaceFalse)视口screen_to_flow_position/flow_to_screen_position见上文其他to_object()导出 Flow 状态为 JSON、get_intersecting_nodes(node, partiallyTrue, nodesNone)碰撞检测、get_node_connections(id, handle_type, handle_id)查询节点连接、get_connection()获取进行中的连接状态。主题定制Flow 组件自带默认主题可通过 CSS 变量覆盖详见 theming.md.react-flow { --xy-background-color: #f7f9fb; --xy-node-border-default: 1px solid #ededed; --xy-node-boxshadow-default: 0px 3.54px 4.55px 0px #00000005; --xy-node-border-radius-default: 8px; --xy-handle-background-color-default: #ffffff; --xy-handle-border-color-default: #aaaaaa; --xy-edge-label-color-default: #505050; }通过rxe.App或rx.App的stylesheets参数引入自定义样式表app rxe.App( stylesheets[ /css/my-custom-styles.css, ], )然后在项目assets/css/my-custom-styles.css中编写覆盖样式。除此之外单个节点与边也可以直接用style字典或className类名做精细化定制。小结把握住节点承载内容、句柄决定连接锚点、边表达关系、连接线呈现拖拽过程、视口管理导航这五条主线就能顺畅地阅读 nodes.md 与 edges.md 中完整的数据结构字段表并在此基础上阅读 components.md、hooks.md 与 utils.md 理解组件、API 与工具函数最终参考 interactivity.md 与 examples.md 构建出真正可用的交互式流程图应用。【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表