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

需求概述
流程设计器中最基础的两个元素为活动(节点)和变迁(连接),我们需要以下基础功能来配合相关接口进行工作流相关设计数据的保存/修改
- 活动的添加/删除/移动
- 变迁的添加/删除
- 活动/变迁数据的全部读取
- 根据json渲染活动与变迁
相关引入依赖如下表所示
| 名称 | 功能 |
|---|---|
| jsplumb.js | 设计器主要依赖,用于绘制相关图形与动态操作实现 |
| jquery.js | jsplumb依赖的库 |
| jquery-ui.js | jsplumb依赖的库,进行拖拽绑定 |
| 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构建的流程设计器
项目背景 最近在准备开发工作流引擎相关模块,完成表结构设计后开始着手流程设计器的技术选型,调研了众多开源项目后决定基于jsplumb.js开源库进行自研开发,保证定制化的便捷性,相关效果图及项目地址如下 项目地址:ht…...
解析从Linux零拷贝深入了解Linux-I/O(下)
接上文解析从Linux零拷贝深入了解Linux-I/O(上) 大文件传输场景 零拷贝还是最优选吗 在大文件传输的场景下,零拷贝技术并不是最优选择;因为在零拷贝的任何一种实现中,都会有「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、原理 参考学习视频: 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 背景:公司需要把游戏整合到一个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是一个分布式版本控制工具,主要用于管理开发过程中的源代码文件(Java类、x…...
003__JAVA模板方法-设计模式
模板方法 定义:定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现 举个例子,把大象放进冰箱分几步,第一打开冰箱,第二打大象放进冰箱,第三把冰箱关闭。这三个步骤就可以用模板方法的设计模式。 …...
Springboot项目集成Netty组件
系列文章目录 Springboot项目集成Netty组件 Netty新增解析数据包指定长度功能 文章目录系列文章目录前言一、Netty是什么?二、使用步骤1. 项目引入依赖1.1 项目基础版本信息:1.2 Netty依赖2. 项目配置2.1 在 yml 配置文件中配置以下: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 生命周期
目录前言:vue3.0生命周期图例1.beforeCreate2.created3.beforeMount/onBeforeMount4.mounted/onMounted5.beforeUpdate/onBeforeUpdate6.updated/onUpdated7.beforeUnmount/onBeforeUnmount8.unmounted/onUnmounted案例:总结前言: 每个Vue组…...
CGAL 数字类型
文章目录 一、简介二、内置数字类型三、CGAL中的数字类型参考资料一、简介 在CGAL汇总,数字类型必须满足特定的语法和语义要求,这样它们才能在CGAL代码中成功使用。一般来说,它们往往是代数结构概念的模型,如果它们对实数的子集模型,那么它们就也是RealEmbeddable模型。 二…...
如何将Python打包后的exe还原成.py?
将python打包好的exe解压为py文件,步骤如下:下载pyinstxtractor.py文件下载地址: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的一个子集,最新的定义可以参考ECMA-404_2nd_ed…...
算法训练营 day49 动态规划 爬楼梯 (进阶)零钱兑换 完全平方数
算法训练营 day49 动态规划 爬楼梯 (进阶)零钱兑换 完全平方数 爬楼梯 (进阶) 70. 爬楼梯 - 力扣(LeetCode) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同…...
Vue:extends继承组件复用性
提到extends继承,最先想到的可能是ES6中的class、TS中的interface、面向对象编程语言中中的类和接口概念等等,但是我们今天的关注点在于:如何在Vue中使用extends继承特性。 目录 Vue:创建Vue实例的方式 构造函数方式࿱…...
ChatGPT 的一些思考
最近 ChatGPT3.5 在全世界范围内掀起了一次 AI 的潮流,ChatGPT1.0/ChatGPT2.0 当时也是比较火爆,但是那个当时感觉还是比较初级的应用,相当于是一个进阶版的微软小冰,给人的感觉是有一点智能,但不多。其实从早期版本开…...
GEE学习笔记 六十九:【GEE之Python版教程三】Python基础编程一
环境配置完成后,那么可以开始正式讲解编程知识。之前我在文章中也讲过,GEE的python版接口它是依赖python语言的。目前很多小伙伴是刚开始学习GEE编程,之前或者没有编程基础,或者是没有学习过python。为了照顾这批小伙伴࿰…...
大数据全系安装
内容版本号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 [依次选择]-&…...
RevokeMsgPatcher:微信QQ防撤回终极指南,轻松保留重要消息
RevokeMsgPatcher:微信QQ防撤回终极指南,轻松保留重要消息 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: htt…...
别再混淆了!JavaScript与Java的10个本质区别(附常见面试题解析)
别再混淆了!JavaScript与Java的10个本质区别(附常见面试题解析) 当面试官问"Java和JavaScript有什么区别"时,超过60%的初级开发者会给出"它们就像汽车和地毯的关系"这类玩笑式回答。但真正理解这两种语言的核…...
FastAPI类型提示:Self的终极指南:提升代码可读性与维护性的完整教程
FastAPI类型提示:Self的终极指南:提升代码可读性与维护性的完整教程 【免费下载链接】fastapi FastAPI framework, high performance, easy to learn, fast to code, ready for production 项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi …...
AI开源项目贡献指南:测试工程师从PR提交到核心维护者的专业路径
测试工程师在AI开源生态中的独特价值在AI开源项目的演进中,软件测试从业者具备不可替代的专业优势:质量敏感度:精准识别模型漂移、接口兼容性、数据异常等AI特有风险系统化思维:构建覆盖数据流水线、模型服务、API交互的端到端验证…...
别再让LVGL卡顿了!手把手教你用思澈SDK的menuconfig优化framebuffer配置,帧率翻倍
别再让LVGL卡顿了!手把手教你用思澈SDK的menuconfig优化framebuffer配置,帧率翻倍 嵌入式UI开发中,LVGL的流畅度直接影响用户体验。许多开发者在使用思澈SDK时,常遇到界面卡顿、帧率低的问题。本文将深入分析framebuffer配置对性能…...
5分钟掌握MPC Video Renderer:解锁专业级HDR视频渲染的完整解决方案
5分钟掌握MPC Video Renderer:解锁专业级HDR视频渲染的完整解决方案 【免费下载链接】VideoRenderer RTX HDR modded into MPC-VideoRenderer. 项目地址: https://gitcode.com/gh_mirrors/vid/VideoRenderer MPC Video Renderer是一款功能强大的开源DirectSh…...
【限时技术白皮书】:Istio 1.20正式版Java适配黄金72小时——我们已验证的6大兼容性断点及热修复方案
第一章:Istio 1.20正式版Java微服务适配全景概览Istio 1.20 正式版于2023年10月发布,针对Java生态的可观测性、安全通信与流量治理能力进行了系统性增强。该版本在Sidecar注入、Java应用兼容性、OpenTelemetry集成及JVM指标采集方面均实现关键演进&#…...
SQL Server数据库标记为SUSPECT的紧急修复指南:从单用户到多用户模式的完整恢复流程
1. 数据库被标记为SUSPECT的常见原因 数据库突然变成SUSPECT状态,就像电脑突然蓝屏一样让人措手不及。我遇到过最典型的情况是机房突然断电,导致SQL Server没来得及完成所有事务就强制关闭了。这种情况下,数据库引擎为了保护数据完整性&#…...
突破付费墙封锁:智能内容解锁工具完全指南
突破付费墙封锁:智能内容解锁工具完全指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 你是否曾为了一篇重要的付费文章而束手无策?在信息爆炸的时代&#…...
BGP路由优化实战:加速收敛,提升网络稳定性
BGP路由优化实战:加速收敛,提升网络稳定性在复杂的网络环境中,尤其是在大规模数据中心或跨区域互联的网络中,BGP(Border Gateway Protocol)路由协议的性能直接影响着网络的可用性和用户体验。BGP 作为互联网…...
