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

基于jsplumb构建的流程设计器

项目背景

最近在准备开发工作流引擎相关模块,完成表结构设计后开始着手流程设计器的技术选型,调研了众多开源项目后决定基于jsplumb.js开源库进行自研开发,保证定制化的便捷性,相关效果图及项目地址如下

项目地址:https://gitee.com/code2roc/fast-flow-desgion

在这里插入图片描述

需求概述

流程设计器中最基础的两个元素为活动(节点)和变迁(连接),我们需要以下基础功能来配合相关接口进行工作流相关设计数据的保存/修改

  • 活动的添加/删除/移动
  • 变迁的添加/删除
  • 活动/变迁数据的全部读取
  • 根据json渲染活动与变迁

相关引入依赖如下表所示

名称功能
jsplumb.js设计器主要依赖,用于绘制相关图形与动态操作实现
jquery.jsjsplumb依赖的库
jquery-ui.jsjsplumb依赖的库,进行拖拽绑定
contextMenu.js实现右击菜单
mustache.js模板引擎渲染活动,避免字符串拼接

实现思路

活动添加

通过mustache的render方法渲染添加到html后,需要调用draggable方法让活动能够进行自由拖动,其中grid参数作用是固定每次拖拽移动最小距离,便于不同节点经过移动后对齐

<script type="text/x-mustache" id="jnode-template"><div class="jnode-panel" id="{{id}}" jnode="{{jnode}}" style="top:{{top}}px;left:{{left}}px"><div class="jnode-box {{jnodeClass}}">{{{jnodeHtml}}}</div></div>
</script>jsPlumb.draggable(id, {containment: 'parent',grid: [8, 8]
})

活动删除

通过jsPlumb.remove方法删除,会删除相关活动与连接的变迁,参数是活动id,通过右键菜单的点击事件获取属性

 callback: function(itemKey, opt, rootMenu, originalEvent) {var id = $($(opt.$trigger[0]).parent()).attr("id");jsPlumb.remove(id)
}

活动移动

在活动拖动的过程中位置进行变化,我们需要进行事件监听获取实时位置保存到数据库,通过jsPlumb.draggable方法的stop方法注册实现

    jsPlumb.draggable(id, {containment: 'parent',grid: [8, 8],stop: function(event, ui) {var nodeID = $(ui.helper.context).attr("id");moveActivity(nodeID, ui.position.left, ui.position.top);}});

变迁添加

jsplumb节点可以添加相关锚点,连接不同锚点会自动绘制连线,在实际操作时连线要求锚点对准操作精度较高不便捷,所以我们通过设置节点整体对象为连接对象,可实现鼠标放置在活动div范围内进行拖拽连线,需要注意makeSource和makeTarget需要同时执行,节点才能作为起点与终点

function registAutoConnect(id) {jsPlumb.makeSource(id, {endpoint: "Dot",anchor: "Continuous"})jsPlumb.makeTarget(id, {endpoint: "Dot",anchor: "Continuous"})
}

以上方法是手动在流程设计器中进行操作连接,如果我们通过接口获取已有数据,需要通过connect方法进行代码渲染变迁

需要注意jsplumb中connection的id为自动生成,我们需要通过setAttribute方法对canvas进行id赋值操作,才能绑定我要自己的id数据

function addConnect(id, sourceID, targetID) {var connection = jsPlumb.connect({source: sourceID,target: targetID});connection.id = idjsPlumb.setAttribute(connection.canvas, "id", connection.id)
}

通过监听connection事件我们可以知道连接添加完成,进行相关接口调用,但我们需要区分是我们通过设计器操作还是代码渲染,只要判断originalEvent是否存在,存在则是通过鼠标操作的

    jsPlumb.bind("connection", function(connInfo, originalEvent) {if (originalEvent) {}});

变迁删除

通过jsPlumb.detach方法进行变迁的删除,默认只删除变迁不删除连接的活动

function deleteConnect(id) {var connects = jsPlumb.getAllConnections();for (var i = 0; i < connects.length; i++) {var connect = connects[i];if (connect.id == id) {jsPlumb.detach(connect)}}
}

其它

代码还包含很多其他细节,如下所示,就不详细赘述了,大家可以仔细阅读,项目中包含了详细的注释

  • 连接添加控制,例如开始节点不能为连接终点,结束节点不能为起点
  • 导入默认配置控制连线样式
  • 各种操作模式指针变换及交互模式
  • 流程图整体移动
  • 活动/变迁的选中效果及点击空白处取消

相关文章:

基于jsplumb构建的流程设计器

项目背景 最近在准备开发工作流引擎相关模块&#xff0c;完成表结构设计后开始着手流程设计器的技术选型&#xff0c;调研了众多开源项目后决定基于jsplumb.js开源库进行自研开发&#xff0c;保证定制化的便捷性&#xff0c;相关效果图及项目地址如下 项目地址&#xff1a;ht…...

解析从Linux零拷贝深入了解Linux-I/O(下)

接上文解析从Linux零拷贝深入了解Linux-I/O&#xff08;上&#xff09; 大文件传输场景 零拷贝还是最优选吗 在大文件传输的场景下&#xff0c;零拷贝技术并不是最优选择&#xff1b;因为在零拷贝的任何一种实现中&#xff0c;都会有「DMA 将数据从磁盘拷贝到内核缓存区——P…...

【学习笔记2.19】动态规划、MySQL、Linux、Redis(框架)

动态规划 343整数拆分 class Solution {public int integerBreak(int n) {int dp [] new int [n 1];//dp[i]:正整数i拆分后的最大乘积dp[2] 1;for(int i 2;i < n ;i ){for(int j 1;j < i;j ){dp[i] Math.max(dp[i],Math.max(j * (i - j),j * dp[i - j]));} …...

String intern方法理解

1、原理 参考学习视频&#xff1a; https://www.bilibili.com/video/BV1WK4y1M77t/?spm_id_from333.337.search-card.all.click&vd_source4dc3f886f5ce1d43363b603935f02bd1 String s1 “hello”; String s1 "hello"; 代码原理解释如下图String s1 new Str…...

解决 cocosjs与安卓原生集成 崩溃问题

版本:cocos2dx3.16 背景&#xff1a;公司需要把游戏整合到一个APP里面。于是打算通过activity切换的方式实现。但是游戏退出重进之后总会出现fatal 11线程报错。于是有了以下修改。我是底层小白。折腾了好久总算鼓捣出一个能用的版本。优化的地方应该有很多。不过就没去好好优…...

spring注解方式整合Dubbo

系列文章目录 文章目录系列文章目录一、创建一个父工程项目二、创建子模块(dubbo-api模块)二、创建子模块(dubbo-provider模块)三、创建子模块(dubbo-consumer模块)总结一、创建一个父工程项目 这里我们通过Spring Initializer 来帮我们构建一个spring-dubbo这个父项目,点击nex…...

Git详解

Git1.Git简介1.1 Git是什么1.2 Git的作用1.3 Git的简介1.4 Git的下载和安装1.5 Git的安装目录结构如下2.Git代码托管服务2.1 常用的Git代码托管服务1.Git简介 1.1 Git是什么 Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件&#xff08;Java类、x…...

003__JAVA模板方法-设计模式

模板方法 定义&#xff1a;定义了一个算法的骨架&#xff0c;并允许子类为一个或多个步骤提供实现 举个例子&#xff0c;把大象放进冰箱分几步&#xff0c;第一打开冰箱&#xff0c;第二打大象放进冰箱&#xff0c;第三把冰箱关闭。这三个步骤就可以用模板方法的设计模式。 …...

Springboot项目集成Netty组件

系列文章目录 Springboot项目集成Netty组件 Netty新增解析数据包指定长度功能 文章目录系列文章目录前言一、Netty是什么&#xff1f;二、使用步骤1. 项目引入依赖1.1 项目基础版本信息&#xff1a;1.2 Netty依赖2. 项目配置2.1 在 yml 配置文件中配置以下&#xff1a;2.2 创建…...

python 中的import cfg问题

pip install cfg 报错: ERROR: Could not find a version that satisfies the requirement cfg (from versions: none) ERROR: No matching distribution found for cfg 要使用pip install cfg2才行...

[oeasy]python0088_字节_Byte_存储单位_KB_MB_GB_TB

编码进化 回忆上次内容 上次 回顾了 字符大战的结果 ibm 曾经的 EBCDIC 由于字符不连续的隐患 导致后续 出现 无数问题无法补救 7-bit 的 ASA X3.4-1963 字母序号连续 比较字符时 效率高判断字符 是否是字母 也很容易 获得了 IBM以外公司的 支持 为什么 ASA X3.4-1963 是 7…...

vue3.0 生命周期

目录前言&#xff1a;vue3.0生命周期图例1.beforeCreate2.created3.beforeMount/onBeforeMount4.mounted/onMounted5.beforeUpdate/onBeforeUpdate6.updated/onUpdated7.beforeUnmount/onBeforeUnmount8.unmounted/onUnmounted案例&#xff1a;总结前言&#xff1a; 每个Vue组…...

CGAL 数字类型

文章目录 一、简介二、内置数字类型三、CGAL中的数字类型参考资料一、简介 在CGAL汇总,数字类型必须满足特定的语法和语义要求,这样它们才能在CGAL代码中成功使用。一般来说,它们往往是代数结构概念的模型,如果它们对实数的子集模型,那么它们就也是RealEmbeddable模型。 二…...

如何将Python打包后的exe还原成.py?

将python打包好的exe解压为py文件&#xff0c;步骤如下&#xff1a;下载pyinstxtractor.py文件下载地址&#xff1a;https://nchc.dl.sourceforge.net/project/pyinstallerextractor/dist/pyinstxtractor.py并将pyinstxtractor.py放到和exe相同的目录文件下打开命令控制台cd 进…...

CJSON简单介绍

json简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集&#xff0c;最新的定义可以参考ECMA-404_2nd_ed…...

算法训练营 day49 动态规划 爬楼梯 (进阶)零钱兑换 完全平方数

算法训练营 day49 动态规划 爬楼梯 &#xff08;进阶&#xff09;零钱兑换 完全平方数 爬楼梯 &#xff08;进阶&#xff09; 70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同…...

Vue:extends继承组件复用性

提到extends继承&#xff0c;最先想到的可能是ES6中的class、TS中的interface、面向对象编程语言中中的类和接口概念等等&#xff0c;但是我们今天的关注点在于&#xff1a;如何在Vue中使用extends继承特性。 目录 Vue&#xff1a;创建Vue实例的方式 构造函数方式&#xff1…...

ChatGPT 的一些思考

最近 ChatGPT3.5 在全世界范围内掀起了一次 AI 的潮流&#xff0c;ChatGPT1.0/ChatGPT2.0 当时也是比较火爆&#xff0c;但是那个当时感觉还是比较初级的应用&#xff0c;相当于是一个进阶版的微软小冰&#xff0c;给人的感觉是有一点智能&#xff0c;但不多。其实从早期版本开…...

GEE学习笔记 六十九:【GEE之Python版教程三】Python基础编程一

环境配置完成后&#xff0c;那么可以开始正式讲解编程知识。之前我在文章中也讲过&#xff0c;GEE的python版接口它是依赖python语言的。目前很多小伙伴是刚开始学习GEE编程&#xff0c;之前或者没有编程基础&#xff0c;或者是没有学习过python。为了照顾这批小伙伴&#xff0…...

大数据全系安装

内容版本号CentOS7.6.1810ZooKeeper3.4.6Hadoop2.9.1HBase1.2.0MySQL5.6.51HIVE2.3.7Sqoop1.4.6flume1.9.0kafka2.8.1scala2.12davinci3.0.1spark2.4.8flink1.13.5 1. 下载CentOS 7镜像 CentOS官网 2. 安装CentOS 7系统——采用虚拟机方式 2.1 新建虚拟机 2.2.1 [依次选择]-&…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...