使用jsPlumb插件实现动态连线功能
这周去看了两天的羽毛球亚锦赛,工作有提前晚上加班做一些,但是技术文章却拉下了。
这段时间一直在寻找可以实现前端元素动态连线的功能,找了好几个库,考虑过用d3或者原生svg和canvas来实现,最后和同项目的同事商量后决定使用jsPlumb插件库来做。
jsPlumb是一个强大的JavaScript连线库,它可以将html中的元素用箭头、曲线、直线等连接起来,适用于开发Web上的图表、建模工具等,其实jsPlumb可能主要是用来做流程图的,它在实现这方面的功能上非常强大,我在项目中只使用了它少部分功能,来实现项目中连线的效果。
initJSPlumb = () => {
this.jsp = jsPlumb.getInstance({
//锚点位置;对任何没有声明描点的Endpoint设置锚点,用于source及target节点
Anchor: ["Right", "Left"],
Anchors: ["Right", "Left"], //连线的source和target Anchor
ConnectionsDetachable: false, //连线是否可用鼠标分离
ConnectionOverlays: [ //连线的叠加组件,如箭头、标签
["Arrow", { //箭头参数设置
location: 1,
visible: true,
width: 11,
length: 11,
id: "ARROW",
events: {
click: function () {
}
}
}],
["Label", { //标签参数设置
location: 0.1,
id: "label",
cssClass: "aLabel", //hover时label的样式名
events: {
tap: function () {
}
},
visible: true
}]
],
Connector: "Bezier", //连线的类型,流程图(Flowchart)、贝塞尔曲线等
//父级元素id;假如页面元素所在上层不同,最外层父级一定要设置
Container: "module",
//如果请求不存在的Anchor、Endpoint或Connector,是否抛异常
DoNotThrowErrors: false,
//通过jsPlumb.draggable拖拽元素时的默认参数设置
DragOptions: {cursor: 'pointer', zIndex: 2000},
DropOptions: {}, //target Endpoint放置时的默认参数设置
Endpoint: "Dot", //端点(锚点)的样式声明
//用jsPlumb.connect创建连接时,source端点和target端点的样式设置
Endpoints: [null, null],
EndpointOverlays: [], //端点的叠加物
//端点的默认样式
EndpointStyle: {fill: 'transparent', stroke: '#1565C0', radius: 4,
strokeWidth: 1},
EndpointStyles: [null, null], //连线的source和target端点的样式
//端点hover时的样式
EndpointHoverStyle: {fill: '#1565C0', stroke: '#1565C0', radius: 4,
strokeWidth: 1},
//连线的source和target端点hover时的样式
EndpointHoverStyles: [null, null],
//连线hover时的样式
HoverPaintStyle: {stroke: '#1565C0', strokeWidth: 3},
LabelStyle: {color: "black"}, //标签的默认样式,用css写法。
LogEnabled: false, //是否开启jsPlumb内部日志
Overlays: [], //连线和端点的叠加物
MaxConnections: 10, //端点支持的最大连接数
//连线样式
PaintStyle: {stroke: '#1565C0', strokeWidth: 1, joinstyle: 'round'},
ReattachConnections: true, //是否重新连接使用鼠标分离的线?
RenderMode: "svg", //默认渲染模式
Scope: "jsPlumb_DefaultScope", //范围,具有相同scope的点才可连接
reattach: true,
})
this.jsp.bind('beforeDrop', this.jspBeforeDrop)
}
以上是初始化jsPlumb对象的函数。
接下来获取数据,加载页面的系统和编制模块。
fetchDataForLeft(data) {
var jsonString_left = '[{"module_name":"crm系统","module_id":"A","nodes":[{"id":"A-1","text":"开始","position":"left"},{"id":"A-2","text":"过程","position":"left"},{"id":"A-3","text":"过程ing","position":"left"}]},{"module_name":"财务系统","module_id":"B","nodes":[{"id":"B-1","text":"开始","position":"left"}]}]';
var jsonString_right = '[{"module_name":"年度预算编制","module_id":"C","nodes":[{"id":"C-1","text":"结束","position":"right"}]},{"module_name":"营收编制","module_id":"D","nodes":[{"id":"D-1","text":"结束","position":"right"}]}]';
// var nodeData_left = JSON.parse(jsonString_left);
//[{"entity":null,"id":"934D62BD0F8249B09F29EC9FA051E390","code":"1","name":"CRM????","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"81ABCD2890E2460B90A9B8A0ACE3FABD","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"9AE1B07886E54F3DB0082D46392DE774","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"E6D29376AC86455DBC3518D12F28C5B0","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null}]
var nodeData_left = data;
this.setState({
nodes_left: nodeData_left,
})
//绘制左边点
nodeData_left.map((node, index) => {
this.setState({datas: node, nodes: node.fromModelList}, () => {
this.initNodes(this.refs.nodes_left[index], 'left');
// this.initEdges(nodeData.edges);
});
})
//绘制右边点
// nodeData_right.map((node, index) => {
// this.setState({data_right: node, node_right: node.toModelList}, () => {
// this.initNodes(this.refs.nodes_right[index], 'right');
// // this.initEdges(nodeData.edges);
// });
// })
}
fetchDataForRight(data){
var jsonString_left = '[{"module_name":"crm系统","module_id":"A","nodes":[{"id":"A-1","text":"开始","position":"left"},{"id":"A-2","text":"过程","position":"left"},{"id":"A-3","text":"过程ing","position":"left"}]},{"module_name":"财务系统","module_id":"B","nodes":[{"id":"B-1","text":"开始","position":"left"}]}]';
var jsonString_right = '[{"module_name":"年度预算编制","module_id":"C","nodes":[{"id":"C-1","text":"结束","position":"right"}]},{"module_name":"营收编制","module_id":"D","nodes":[{"id":"D-1","text":"结束","position":"right"}]}]';
// var nodeData_left = JSON.parse(jsonString_left);
//[{"entity":null,"id":"934D62BD0F8249B09F29EC9FA051E390","code":"1","name":"CRM????","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"81ABCD2890E2460B90A9B8A0ACE3FABD","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"9AE1B07886E54F3DB0082D46392DE774","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"E6D29376AC86455DBC3518D12F28C5B0","code":null,"name":"CRM系统","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null}]
var nodeData_right = data;
this.setState({
nodes_right: nodeData_right
})
//绘制右边点
nodeData_right.map((node, index) => {
this.setState({data_right: node, node_right: node.toModelList}, () => {
this.initNodes(this.refs.nodes_right[index], 'right');
// this.initEdges(nodeData.edges);
});
})
}
初始化连接锚点
initNodes = (node, position) => {
this.jsp.setSuspendDrawing(true);
if (position === "left") {
DynamicAnchors.map(anchor => this.rjsp.addEndpoint(node, anEndpoint, {anchor: "Right"}));
} else {
DynamicAnchors_Right.map(anchor => this.rjsp.addEndpoint(node, anEndpoint, {anchor: "Left"}));
}
this.rjsp.setSuspendDrawing(false, true);
}
//自动连线
initEdges = (edges) => {
this.rjsp.setSuspendDrawing(true);
edges.map(edge => {
this.jsp.connect(edge, Common);
})
this.jsp.setSuspendDrawing(false, true);
}
使用jsPlumb插件实现动态连线功能的更多相关文章
- Android 插件化 动态升级
最新内容请见原文:Android 插件化 动态升级 不少朋友私信以及 Android开源交流几个 QQ 群 中都问到这个问题,这里简单介绍下 1.作用 大多数朋友开始接触这个问题是因为 App 爆棚了 ...
- 传统方式和插件方式 分别实现 分页 功能 pageHelper 插件
实现分页 这里提供两种方式 一种是传统的分页方式 一种是基于pageHelper插件 实现的分类 推荐使用后者 前者是一般开发的方式 思路 先手动创建一个 pageUtil 工具 ...
- 【大话QT之十二】基于CTK Plugin Framework的插件版本号动态升级
应用需求: 某些场景下我们可能面临这种问题,在执行着的应用程序不能终止的情况下,升级某个功能(或添,或减.或改动).在不採用CTK Plugin Framework插件系统架构的情况下这将是非常困难的 ...
- C#实现插件的“动态替换”
如果某个"功能"需要动态更新?这种动态更新,可能是需求驱动的,也可能是为了修改 BUG,面对这种场景,如何实现“热插拔”呢?先解释一下“热插拔”:在系统运行过程动态替换某些功能,不 ...
- 基于jsplumb插件制作可拖拽、保存流程图、重绘保存后的流程图总结
1.重点参考博文 https://blog.csdn.net/j_bean/article/details/78092647 2.关键点总结 1)实现可视区域图形画满后,拖动整个画布的效果 a.最好不 ...
- MFC画线功能总结
本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6216464.html MFC画线功能要点有二:其一,鼠标按下时记录初始位置为线的起始 ...
- MFC消息映射机制以及画线功能实现
---此仅供用于学习交流,切勿用于商业用途,转载请注明http://www.cnblogs.com/mxbs/p/6213404.html. 利用VS2010创建一个单文档标准MFC工程,工程名为Dr ...
- jQuery.YesShow - 图片轮播插件(带图片放大功能)
jQuery.YesShow - 图片轮播插件(带图片放大功能) 使用简单,原文件只要这样就可以了:<div id="yes"> <ul> ...
- Qt编写自定义控件插件开放动态库dll使用(永久免费)
这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...
随机推荐
- SpringBoot 初始化流程以及各种常见第三方配置的源码实现
带着这几个问题去分析SpringBoot 初始化以及扩展机制实现 1.容器何时被创建,并默认配置了什么? 2.Spring 容器依赖于哪个后置处理器进行bean 容器的装配? 3.Spring 如何进 ...
- Acwing P274 移动服务 题解
每日一题 day21 打卡 Analysis DP的状态为已经完成的请求数量,通过指派一位服务员可以把”完成i - 1个请求的状态”转移到”完成i个请求的状态”那么我们可以知道转移从dp[i - 1] ...
- bash: cd: too many arguments 报错
路径名或者变量有空格时候,会造成参数太多的错误提示 解决方法:把空格的地方用引号包括起来
- Python学习之--字符串的使用
一.大小写转换 1. 首字母大写:title(); 如下: 2. 大写转换:upper(),如 3.小写转换:lower(),如 二.合并(拼接)字符串:”+“ 1. 2. 三.制表符.换行 制表符 ...
- ZOJ 1608 Two Circles and a Rectangle
Give you two circles and a rectangle, your task is to judge wheather the two circles can be put into ...
- codevs 1729 单词查找树
二次联通门 : codevs 1729 单词查找树 /* codevs 1729 单词查找树 Trie树 统计节点个数 建一棵Trie树 插入单词时每新开一个节点就计数器加1 */ #include ...
- 【一起来烧脑】一步学会Vue.js系统
Vuejs是一个构建数据驱动的web界面的库,通过api实现响应的数据绑定和组合的视图组件,Vue.js的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单,一旦创建了绑定,DOM 将与数 ...
- cs 与 bs 架构
C/S和B/S各有优势,C/S在图形的表现能力上以及运行的速度上肯定是强于B/S模式的,不过缺点就是他需要运行专门的客户端,而且更重要的是它不能跨平台,用c++在windows下写的程序肯定是不能在l ...
- 从过狗到编写tamper【转载】
原作者:我会啊D 原文出处:https://www.t00ls.net/articles-52894.html 0x0 前言 在sql注入的时候,很可能会碰到各种厂商的waf,bypass之后,以后每 ...
- [MYSQL手工注入](3)基于报错的SQL注入实战
0x03 MYSQL 手工注入实战--基于错误的 SQL 注入 今天如愿以偿的找到了基于错误的SQL注入环境了:是一个国外卖音响的小网站,还在建设中: 看一下报错信息: (1)确定闭合语句:从上面的报 ...