当前位置: 首页 > article >正文

LogicFlow 进阶实战:自定义节点连线规则与动态样式控制

1. LogicFlow自定义节点连线规则实战LogicFlow作为一款专业的流程图编辑框架最强大的特性之一就是可以精确控制节点间的连接规则。在实际业务流程建模中我们经常需要限制某些节点的连接方式比如开始节点不能被其他节点连接结束节点不能连接其他节点审批节点后面必须接分支节点特定业务节点只能与指定类型的节点相连这些业务规则都可以通过sourceRules和targetRules两个关键属性来实现。我最近在开发一个OA审批流系统时就遇到了这样的需求报销申请节点后面只能连接财务审批节点而财务审批节点后面只能连接出纳付款节点。下面分享我的实现方法。首先我们来看基础实现。假设我们需要创建一个正方形节点要求它只能连接到圆形节点import { RectNode, RectNodeModel } from logicflow/core; class SquareModel extends RectNodeModel { initNodeData(data) { super.initNodeData(data); const circleOnlyAsTarget { message: 正方形节点下一个节点只能是圆形节点, validate: (sourceNode, targetNode) { return targetNode.type circle; }, }; this.sourceRules.push(circleOnlyAsTarget); } }这段代码的关键点在于validate函数它接收三个参数sourceNode连线起始节点targetNode连线目标节点sourceAnchor/targetAnchor连接的锚点信息进阶用法当我们在画布上拖动连线时LogicFlow会自动执行这些校验规则。如果校验不通过会触发connection:not-allowed事件我们可以监听这个事件给出友好提示lf.on(connection:not-allowed, (error) { alert(error.message); // 显示正方形节点下一个节点只能是圆形节点 });2. 动态样式反馈与状态管理单纯的校验提示还不够直观好的用户体验应该提供实时视觉反馈。LogicFlow的节点model中有个state属性专门用于这种场景 - 当连接规则校验不通过时state会被设为5。我们可以利用这个特性实现动态样式变化。下面是一个六边形节点的实现示例当连接不合法时会变成红色class CustomHexagonModel extends PolygonNodeModel { getNodeStyle() { const style super.getNodeStyle(); // 连接不合法时显示红色 if (this.state 5) { style.fill red; } // 悬停状态 if (this.isHovered) { style.stroke blue; } // 选中状态 if (this.properties.isSelected) { style.strokeWidth 3; } return style; } }在实际项目中我推荐使用CSS类名而不是直接修改样式这样更易于维护getNodeStyle() { const style super.getNodeStyle(); if (this.state 5) { this.addClassName(connection-error); } else { this.removeClassName(connection-error); } return style; }对应的CSS可以这样定义.lf-node.connection-error { fill: #ffebee; stroke: #f44336; animation: pulse 0.5s infinite alternate; } keyframes pulse { from { opacity: 0.8; } to { opacity: 1; } }3. 锚点的高级控制技巧很多复杂场景需要更精细的连线控制比如只允许从节点右侧锚点连出只允许连接到节点左侧锚点不同业务字段使用不同颜色的锚点这需要我们自定义锚点逻辑。下面是一个SQL表节点的实现它要求只能从右侧锚点连出线只能连接到左侧锚点每个表字段都有独立的锚点class SqlNodeModel extends HtmlNodeModel { setAttributes() { // 从右侧锚点连出的规则 this.sourceRules.push({ message: 只允许从右边的锚点连出, validate: (sourceNode, targetNode, sourceAnchor) { return sourceAnchor.type right; } }); // 连接到左侧锚点的规则 this.targetRules.push({ message: 只允许连接左边的锚点, validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) { return targetAnchor.type left; } }); } getDefaultAnchor() { return this.properties.fields.map((field, index) { return [ // 左侧输入锚点 { x: this.x - this.width/2 10, y: this.y - this.height/2 60 index * 24, id: ${this.id}_${field.key}_left, type: left }, // 右侧输出锚点 { x: this.x this.width/2 - 10, y: this.y - this.height/2 60 index * 24, id: ${this.id}_${field.key}_right, type: right } ]; }).flat(); } }锚点的样式也可以完全自定义比如在view中重写getAnchorShapeclass SqlNode extends HtmlNode { getAnchorShape(anchorData) { const { x, y, type } anchorData; // 左侧锚点显示为红色矩形 if(type left) { return h(rect, { x: x-5, y: y-5, width: 10, height: 10, fill: #ff0000 }); } // 右侧锚点显示为绿色圆形 return h(circle, { cx: x, cy: y, r: 5, fill: #00ff00 }); } }4. 复杂业务规则的综合应用在实际ERP系统开发中我遇到过这样一个需求采购订单需要依次经过部门审批→财务审批→总经理审批三个环节每个环节的审批人不同且不能跳过任何环节。这种复杂业务流程可以通过组合多种规则来实现。首先定义三种审批节点模型// 部门审批节点 class DeptApprovalModel extends RectNodeModel { initNodeData(data) { super.initNodeData(data); // 只能连接到财务审批节点 this.sourceRules.push({ validate: (source, target) target.type finance-approval }); // 必须从采购订单节点连接过来 this.targetRules.push({ validate: (source) source.type purchase-order }); } } // 财务审批节点 class FinanceApprovalModel extends RectNodeModel { initNodeData(data) { super.initNodeData(data); // 只能连接到总经理审批 this.sourceRules.push({ validate: (source, target) target.type ceo-approval }); // 必须从部门审批连接过来 this.targetRules.push({ validate: (source) source.type dept-approval }); } } // 总经理审批节点 class CEOApprovalModel extends RectNodeModel { initNodeData(data) { super.initNodeData(data); // 不能连接其他节点终审节点 this.sourceRules.push({ validate: () false }); // 必须从财务审批连接过来 this.targetRules.push({ validate: (source) source.type finance-approval }); } }然后我们可以添加全局校验逻辑确保流程完整性lf.on(connection:add, ({sourceNode, targetNode}) { // 检查是否跳过环节 const validPaths { purchase-order: [dept-approval], dept-approval: [finance-approval], finance-approval: [ceo-approval] }; if(!validPaths[sourceNode.type]?.includes(targetNode.type)) { lf.graphModel.removeEdge(edge.id); alert(流程环节不完整请按照规范连接节点); return false; } });为了让规则配置更灵活我通常会把这些校验规则提取到业务配置文件中// workflow-rules.js export const APPROVAL_RULES { purchase-order: { nextSteps: [dept-approval], color: #FF9800 }, dept-approval: { nextSteps: [finance-approval], requiredPrev: [purchase-order], color: #2196F3 }, // ...其他规则 }; // 在节点模型中动态应用 class DynamicApprovalModel extends RectNodeModel { initNodeData(data) { const rules APPROVAL_RULES[this.type]; this.sourceRules.push({ validate: (_, target) rules.nextSteps.includes(target.type) }); if(rules.requiredPrev) { this.targetRules.push({ validate: (source) rules.requiredPrev.includes(source.type) }); } this.fill rules.color; } }

相关文章:

LogicFlow 进阶实战:自定义节点连线规则与动态样式控制

1. LogicFlow自定义节点连线规则实战 LogicFlow作为一款专业的流程图编辑框架,最强大的特性之一就是可以精确控制节点间的连接规则。在实际业务流程建模中,我们经常需要限制某些节点的连接方式,比如: 开始节点不能被其他节点连接结…...

华为交换机MSTP+VRRP实战:从零配置到故障排查,手把手教你搞定企业双机热备

华为交换机MSTPVRRP企业级部署全指南:从规划到排障的深度实践 在中小型企业网络架构中,业务连续性和链路可靠性是核心诉求。当核心交换机单点故障可能导致整个园区网络瘫痪时,如何设计既具备冗余能力又能智能管理流量的解决方案?这…...

Keyence VT5 HMI嵌入式通信库:RS232协议栈实现

1. KeyenceHMI_Lib 库深度解析:面向工业现场的 RS232 HMI 通信协议栈实现1.1 工程定位与核心价值KeyenceHMI_Lib 是一个专为嵌入式平台(特别是 Arduino 生态)设计的轻量级通信库,其核心目标是在资源受限的微控制器上,可…...

【R 4.5大数据处理性能跃迁指南】:20年实战验证的7大底层优化策略(含benchmark实测提升3.8×)

第一章:R 4.5大数据处理性能跃迁的核心动因与基准定位R 4.5 版本在底层内存管理、向量化执行引擎及并行调度机制上实现了结构性升级,显著提升了大规模数据集(GB级及以上)的加载、聚合与建模效率。其核心动因并非单一优化&#xff…...

做了一个网页天气可视化路

基础示例:单工作表 Excel 转 TXT 以下是将一个 Excel 文件中的第一个工作表转换为 TXT 的完整步骤: 1. 加载并读取Excel文件 from spire.xls import * from spire.xls.common import * workbook Workbook() workbook.LoadFromFile("示例.xlsx"…...

Java项目Loom改造倒计时:JDK 23正式弃用传统线程池API,你还在用ExecutorService吗?

第一章:Java项目Loom响应式编程转型指南Project Loom 为 Java 带来了轻量级虚拟线程(Virtual Threads)和结构化并发(Structured Concurrency),极大简化了高并发 I/O 密集型场景下的响应式编程模型。与传统基…...

5个你不知道的TTS应用场景:除了语音合成还能这样玩

5个你不知道的TTS应用场景:除了语音合成还能这样玩 当大多数人听到"文本转语音"(TTS)时,首先想到的可能是语音助手或无障碍阅读工具。但这项技术的潜力远不止于此——它正在悄然改变我们与数字世界互动的方式。从智能家…...

深入解析嵌入式通信协议:UART、SPI、IIC、CAN的实战对比

1. 嵌入式通信协议基础概念 当你拆开一个智能家居设备或者汽车电子模块时,总会发现几根细如发丝的导线连接着不同芯片。这些看似简单的导线背后,隐藏着电子设备之间交流的秘密语言——通信协议。作为嵌入式开发者,理解UART、SPI、IIC、CAN这四…...

Linux 文本处理三剑客(日志 / 配置分析)

前言 在 Linux 服务器工作中,90% 的问题都要靠看日志、改配置解决。面对动辄几万行的日志文件,手动翻阅效率极低,而 grep、sed、awk 这三个工具,就是 Linux 下处理文本的 “终极三剑客”。掌握它们,你就能实现快速过滤…...

为什么你的AI应用总在上线后崩塌?SITS2026披露3类被忽视的“非功能性AI缺陷”及防御性工程实践

第一章:SITS2026专家解读:AI原生研发的核心挑战 2026奇点智能技术大会(https://ml-summit.org) AI原生研发并非简单地将大模型API嵌入传统系统,而是重构整个软件生命周期——从需求建模、架构设计、代码生成到验证运维,均需以“模…...

MIT Cheetah机器人刚体模型详解:从DH参数到足端位置计算的保姆级推导

MIT Cheetah机器人刚体建模实战:从坐标系定义到足端轨迹计算的完整推导 在四足机器人研究领域,MIT Cheetah系列机器人以其卓越的运动性能和创新设计闻名。对于想要深入理解其运动控制原理的工程师和学生来说,掌握其刚体建模方法是必经之路。本…...

ESP32以太网异步DNS服务器库:LwIP事件驱动与PHY硬件抽象

1. 项目概述AsyncDNSServer_ESP32_Ethernet是一款专为 ESP32 系列微控制器(含 ESP32-S2/S3/C3)设计的全异步 DNS 服务器库,面向基于 LwIP 协议栈、搭载 W5500、W6100 或 ENC28J60 以太网物理层芯片的嵌入式系统。该库并非从零构建&#xff0c…...

MPU9150 DMP库深度解析:嵌入式运动协处理器工程实践

1. MPU9150_DMP库深度解析:嵌入式系统中DMP运动协处理器的工程化应用MPU9150是InvenSense公司于2012年推出的集成六轴惯性测量单元(6-DoF IMU)与三轴电子罗盘(3-DoF Magnetometer)的高精度MEMS传感器。其核心价值不仅在…...

PCA9505/06工业级I²C IO扩展驱动设计与实战

1. PCA9505/06 库概述:面向工业级IC端口扩展的底层驱动设计PCA9505与PCA9506是NXP推出的40位IC总线IO扩展器,专为资源受限但需高密度数字信号管理的嵌入式系统设计。该库并非简单封装Arduino Wire接口的轻量级适配层,而是一套具备完整寄存器映…...

OpenClaw学习总结_IV_认证与安全_4:Multi-Account Patterns详解

OpenClaw IV. 认证与安全(4)Multi-Account Patterns本篇目标:把“一个人/一个团队同时拥有多个账号(或多个 Bot / 多个 Workspace / 多个 Provider credentials)”时,OpenClaw 侧应该怎么建模、怎么隔离、怎…...

ESP32 RMT硬件实现双向DShot协议驱动

1. 项目概述DShotRMT 是一款专为 ESP32 微控制器设计的高性能 DShot 协议驱动库,基于 ESP-IDF v5.5.x 的 RMT(Remote Control)外设全新 API(rmt_tx.h/rmt_rx.h)构建。该库并非简单封装,而是深度耦合硬件时序…...

OpenClaw学习总结_IV_认证与安全_3:Authorization与Policies详解

IV. 认证与安全 - 3. Authorization 与 Policies 📍 课程位置 阶段:IV. 认证与安全 课序:第 3 课 前置知识:IV-2. Authentication 后续课程:IV-4. Multi-Account Patterns🎯 本课核心问题(你不懂…...

告别AD转Cadence的迷茫:OrCAD Capture CIS 16.6新建工程与环境设置保姆级指南

告别AD转Cadence的迷茫:OrCAD Capture CIS 16.6新建工程与环境设置保姆级指南 从Altium Designer切换到Cadence OrCAD,就像从自动挡汽车换到手动挡——虽然最终目的地相同,但操作方式截然不同。我至今记得第一次打开OrCAD时那种无处下手的窘迫…...

如何处理phpMyAdmin提示配置文件读取失败_文件属组与读写权限调整

根本原因是PHP进程无法读取config.inc.php文件,主因是系统级权限问题:Web服务器用户(如www-data)无读取权限,或文件权限为666/660等不安全组合,或SELinux/AppArmor拦截,或符号链接目标权限错误。…...

CEA-Leti 和 CEA-List 已宣布与 Powerchip 半导体制造公司 (PSMC) 合作

合作将利用 PSMC 的 3D 堆叠和中介层技术来集成下一代 AI 设备两家法国旗舰研究机构 CEA-Leti 和 CEA-List 已宣布与台湾代工厂 Powerchip 半导体制造公司 (PSMC) 建立合作关系。该合作将利用 CEA-List 的 RISC-V 设计专业知识和 CEA-Leti 的硅光子学专业知识(包括微…...

“三合一”光电二极管被中国科研团队发明

这项研究解决了一个长期存在的硬件瓶颈:传统相机需要把“感光”、“存储”和“计算”分开做,导致体积大、耗电多。中国科学技术大学孙海定教授团队开发了一种“三合一”光电二极管,它能在一个器件里同时完成这三项任务,就像人眼和…...

告别“看图说话”:Qwen3-VL如何用平方根重加权与时间戳文本,搞定长视频与图文交错文档?

Qwen3-VL技术解析:平方根重加权与时间戳文本如何重塑多模态理解 当一段长达两小时的监控视频需要快速定位关键帧,或是一份百页技术文档中的图表需要即时解读时,传统多模态模型往往陷入"视觉失焦"或"文本过载"的困境。Qwe…...

Spirent TestCenter实战:手把手教你用SAPEE回放MySQL流量做性能压测(附完整配置截图)

Spirent TestCenter深度实战:基于SAPEE的MySQL流量回放与极限性能压测方法论 在当今高并发数据库应用场景中,准确评估MySQL服务器的真实处理能力已成为架构设计的关键环节。传统基准测试工具往往难以模拟真实业务流量特征,而基于Spirent Test…...

FastRGB嵌入式LED库:AVR平台纳秒级RGB控制框架

1. FastRGB库深度解析:面向嵌入式系统的高性能可寻址RGB LED控制框架FastRGB是一个专为资源受限嵌入式平台设计的现代、面向对象、轻量级可寻址RGB LED控制库。其核心目标并非追求通用性,而是针对特定MCU架构(尤其是8位AVR平台)进…...

FastTimer嵌入式时间切片调度框架解析

1. FastTimer 库深度解析:嵌入式时间管理的工程化实践在嵌入式系统开发中,时间管理是底层驱动、状态机调度、周期性采样与事件分发的核心基础设施。传统millis()或micros()轮询方式虽简单,但存在精度漂移、逻辑耦合度高、多级周期嵌套困难等工…...

实战解析:基于unidbg的APP逆向与关键算法模拟执行

1. 为什么需要unidbg进行APP逆向分析 当你尝试分析一个移动应用的核心算法时,最头疼的问题是什么?我猜90%的开发者都会说:无法直接运行和调试so文件中的native代码。传统的逆向方法要么需要真机环境,要么要处理复杂的交叉编译问题…...

Vue3 解决表格切换闪烁的问题

表格切换闪烁的原因:el-table-column 没有固定宽度,导致切换标签页时表格重新计算列宽产生视觉变化(闪烁形象)表格实际需求的分析:需要实现自动适应视窗宽度,表格至终不会有横向滚动条最佳解决方案&#xf…...

从零开始:手把手教你搭建与操作主流向量数据库

1. 为什么你需要一个向量数据库? 想象一下你正在开发一个智能相册应用。当用户上传一张猫咪照片时,系统需要从数百万张图片中快速找到所有相似的猫咪照片。传统数据库只能做精确匹配(比如"文件名cat001.jpg")&#xff0…...

ADXL335模拟加速度计Arduino驱动库详解

1. 项目概述7Semi ADXL335 Accelerometer 是一款面向嵌入式平台的轻量级模拟加速度传感器驱动库,专为 ADXL335 这一经典三轴模拟输出 MEMS 加速度计设计。该库并非直接操作数字总线(如 IC 或 SPI),而是通过标准 ArduinoanalogRead…...

Arduino多平台临界区封装库:轻量级中断屏蔽RAII实现

1. 项目概述107-Arduino-CriticalSection是一个面向多平台 Arduino 生态的轻量级临界区(Critical Section)封装库。其核心目标并非实现全新的同步原语,而是在异构硬件抽象层(HAL)之上提供统一、可移植、零依赖的中断屏…...