用Js实现工作流设计器图形绘制
- 格式:pdf
- 大小:1.67 MB
- 文档页数:5
转:超级好⽤的流程图js框架⽀叫(Graph Theroy)。
利⽤图我们可以做很多⼯具,⽐如思维导图,流程图,状态机,组织架构图,等等。
今天我要做的是⽤开源的HTML5⼯具来快速构造⼀个做图的⼯具。
⼯具选择预先善其事,必先利其器。
第⼀件事是选择⼀件合适的⼯具,开源时代,程序员还是很幸福的,选择很多。
最终,我选择了jsPlumb,因为它完全开源,使⽤很简单,⽤D3的话可能会多花很多功夫。
joint.js也不错。
⼤家可以根据⾃⼰的需要选择。
构建静态应⽤下⾯我们⼀步⼀步的来使⽤jsPlumb来创建我们的流程图⼯具。
第⼀步是等待DOM和jsPlumb初始化完毕,类似document.ready()和jquery.ready(), 要使⽤jsPlumb, 需要把代码放在这个函数⾥:1 2 3jsPlumb.ready(function() {// ... your code goes here ... }创建⼀个jsPlumb的实例,并初始化jsPlumb的配置参数:1 2 3 4 5 6 7 8 9 10 11 12 13//Initialize JsPlumbvar color = "#E8C870";var instance = jsPlumb.getInstance({// notice the 'curviness' argument to this Bezier curve. the curves on this page are far smoother // than the curves on the first demo, which use the default curviness value.Connector : [ "Bezier", { curviness:50 } ],DragOptions : { cursor: "pointer", zIndex:2000 },PaintStyle : { strokeStyle:color, lineWidth:2 },EndpointStyle : { radius:5, fillStyle:color },HoverPaintStyle : {strokeStyle:"#7073EB"},EndpointHoverStyle : {fillStyle:"#7073EB"},Container:"container-id"});这⾥给给出了⼀些配置包括,连接线(这⾥配置了⼀个贝塞尔曲线),线的风格,连接点得风格。
bpmnjs教程设计流程BPMN-JS是一个基于浏览器的JavaScript库,用于绘制、编辑和渲染BPMN 图。
BPMN 是一种标准化的图形语言,用于表示业务流程模型和流程定义。
以下是使用bpmn-js库进行流程设计的简单教程:第一步:安装bpmn-js库如果你使用npm,可以通过以下命令安装bpmn-js库:```shellnpm install bpmn-js```第二步:创建流程设计器在你的HTML文件中,你需要引入bpmn-js库,然后创建一个BPMN设计器实例:```html<!DOCTYPE html><html><head><title>BPMN Designer</title></head><body><div id="canvas"></div><script src="node_modules/bpmn-js/dist/"></script> <script>var bpmnModeler = new BpmnModeler({container: 'canvas',propertiesPanel: { parent: 'properties-panel' },// 更多的配置项...});</script></body></html>```第三步:加载流程定义你可以使用bpmn-js库的API来加载和编辑BPMN流程定义。
以下是一个简单的示例,展示了如何加载一个流程定义并使其可见:```javascriptvar reader = new BpmnXMLReader({ bpmnElementFactory: }); (bpmnModeler, 'path/to/your/').then(function(result) {var canvas = ('canvas');('fit-viewport'); // 自动缩放以适应视口大小});```在这个例子中,我们首先创建了一个新的BPMN XML阅读器实例,然后使用`importXML`方法加载BPMN流程定义。
JointJS流程图的绘制⽅法最近项⽬上需要⽤流程图来做问题定界分析,之前有同事⽤jsPlumb做过,但是阅读代码后觉得⽐较⿇烦,所以⾃⼰⼜找了⼀圈,找到⼀个叫Dagre-D3的开源类库,画出来的效果如下图,Dagre-D3最⼤的优点就是可以实现⾃动布局,你只需要put数据就可以了,但是缺点就是⾃动布局后的连线会⽐较乱,⽽且连线不是横平竖直的,对于流程图不复杂的还好,稍微复杂点画出来的连线就没法看。
最后还是被pass了。
后⾯经过⼀番百度,最终决定⽤JointJS,官⽹:,相⽐Dagre-D3和jsPlumb,JointJS的API很详细,代码量少,连接线有多种选择,封装了多种常⽤的形状,⽽且能画的图很多,官⽅也给了⼀些demo可以参考。
下⾯是我⽤JointJS画出来的流程图:依赖:在官⽹的下载页⾯都能找到<link rel="stylesheet" type="text/css" href="joint.css" /><script src="jquery.min.js"></script><script src="lodash.min.js"></script><script src="backbone-min.js"></script><script src="joint.js"></script>我的demo⾥还引⽤了bootstrap的依赖⽤来显⽰模态框html代码<body><div id="paper" class="paper"></div><div class="modal fade searchpanel" id="detailModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button><h4 class="modal-title" id="modalTitle">详细信息</h4></div><div class="modal-body"></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button></div></div></div></div></body>js代码⾸先是定义画板和画布,这⾥重写了ElementView和LinkView,⽬的是为了让画出来的流程图不能被删除和编辑var graph = new joint.dia.Graph();var ElementView = joint.dia.ElementView.extend({pointerdown: function () {this._click = true;joint.dia.ElementView.prototype.pointerdown.apply(this, arguments);},pointermove: function(evt, x, y) {this._click = false;joint.dia.ElementView.prototype.pointermove.apply(this, arguments);},pointerup: function (evt, x, y) {if (this._click) {// triggers an event on the paper and the element itselfthis.notify('cell:click', evt, x, y);} else {joint.dia.ElementView.prototype.pointerup.apply(this, arguments);}}});var LinkView = joint.dia.LinkView.extend({addVertex: function(evt, x, y) {},removeVertex: function(endType) {},pointerdown:function(evt, x, y) {}});//定义画布var paper = new joint.dia.Paper({el: $('#paper'),width: 1200,height: 600,gridSize: 1,model: graph,elementView: ElementView,linkView:LinkView});//paper.$el.css('pointer-events', 'none')//去除默认样式,使所有事件不可⽤然后我写了两个函数分别⽤来创建形状和连线,这样写可以减少代码量,官⽅的demo也⼤都是这样写的//定义形状var state = function(x, y, shape, background, text){var cell;if(shape==="rect"){cell = new joint.shapes.basic.Rect({position: { x: x, y: y },//坐标size: { width: 140, height: 40 },//宽⾼attrs: {rect: {fill: {type: 'linearGradient',stops: [{ offset: '0%', color: background },//渐变开始{ offset: '100%', color: '#fe8550' }//渐变结束],attrs: { x1: '0%', y1: '0%', x2: '0%', y2: '100%' }},stroke: background,//边框颜⾊'stroke-width': 1//边框⼤⼩},text: { text: text } //显⽰⽂字}});} else if(shape==="ellipse"){cell = new joint.shapes.basic.Ellipse({position: { x: x, y: y },//坐标size: { width: 140, height: 40 },//宽⾼attrs: {ellipse: {fill: {type: 'linearGradient',stops: [{ offset: '0%', color: background },//渐变开始{ offset: '100%', color: '#FFFFFF' }//渐变结束],attrs: { x1: '0%', y1: '0%', x2: '0%', y2: '100%' }},stroke: background,//边框颜⾊'stroke-width': 1//边框⼤⼩},text: { text: text } //显⽰⽂字}});}graph.addCell(cell);return cell;};//定义连线function link(source, target, label){var cell = new joint.dia.Link({source: { id: source.id },target: { id: target.id },labels: [{ position: 0.5, attrs: { text: { text: label || '', 'font-weight': 'bold' } } }],router: { name: 'manhattan' },//设置连线弯曲样式 manhattan直⾓attrs: {'.connection': {stroke: '#333333',//连线颜⾊'stroke-width': 2//连线粗细},'.marker-target': {fill: '#333333',//箭头颜⾊d: 'M 10 0 L 0 5 L 10 10 z'//箭头样式}}});graph.addCell(cell);return cell;}最后就是我们实际的业务代码了,这⾥我们可以整理⼀下数据结构,把数据定义成json格式,然后写⼀个函数通过json直接⽣成流程图,当然坐标需要寻找规律⾃⼰计算⼀下//创建元素var start = state(500,100,"ellipse","#00FFFF", "视频播放成功率");var state1 = state(500,200,"rect","#f7a07b", "GET响应成功率");var state2 = state(400,300,"rect","#f7a07b", "HTTP错误码分析");var state3 = state(600,300,"rect","#f7a07b", joint.util.breakText("TCP异常和其他原因",{width:80}));var state4 = state(400,400,"rect","#f7a07b", "4XX、5XX分析");var state5 = state(600,400,"rect","#f7a07b", "接⼝以上分析");var state6 = state(750,400,"rect","#f7a07b", "接⼝以下分析");//创建连线link(start, state1, "");link(state1, state2, "≥70%");link(state1, state3, "<70%");link(state2, state4, "");link(state3, state5, "是");link(state3, state6, "否");//给所有元素添加点击事件paper.on('cell:click', function (e) {$("#detailModal .modal-body").html("");var arr = $("#"+e.id+" tspan");if(arr.length===1){$("#detailModal .modal-body").append($(arr).html());$("#detailModal").modal();} else{var tmp="";$.each(arr, function(k,v){tmp+=$(v).html();});$("#detailModal .modal-body").append(tmp);$("#detailModal").modal();}});后⾯是给每个元素(不包含连线)添加了⼀个点击事件,弹出⼀个模态框,显⽰当前点击的内容。
BPMN(Business Process Model and Notation,业务流程建模和标注)是一种用于描述业务流程的图形化标注语言,它能够帮助企业清晰地了解、定义、执行和管理各种业务流程。
而bpmn.js是一个基于JavaScript的工作流引擎,可以用于在Web应用中绘制和执行BPMN工作流。
下面通过一个实际的案例来展示如何使用bpmn.js来绘制和执行BPMN工作流。
1. 理解业务流程需求我们需要理解具体的业务流程需求,比如一个简单的请假申请流程。
该流程包括申请人提交请假申请、主管审核请假申请、人力资源审核请假申请、审批结果通知申请人等步骤。
这些需求将成为我们绘制BPMN工作流的基础。
2. 使用bpmn.js绘制BPMN工作流接下来,我们可以使用bpmn.js来绘制上述的请假申请流程。
我们需要准备一个空白的BPMN图形化界面,并在其中添加各类BPMN元素,比如任务、网关、流程线等,以及相应的流程名称和描述。
在绘制过程中,我们需要根据业务流程需求,合理地安排和连接各个流程步骤,确保流程图的逻辑清晰且符合实际情况。
3. 配置BPMN工作流执行环境完成流程图的绘制后,我们需要配置BPMN工作流的执行环境,包括引入必要的JavaScript依赖库以及定义执行流程时所需的各类参数和事件。
这些工作将确保BPMN工作流能够在Web应用中正常执行,并与实际业务系统进行有效的交互。
4. 集成BPMN工作流到业务系统一旦BPMN工作流的执行环境准备妥当,我们就可以将其集成到实际的业务系统中。
这可能涉及到前端页面的引入和布局、与后端接口的对接以及与数据库的交互等工作。
通过这些工作,我们可以使BPMN 工作流成为业务系统的一部分,为实际的业务流程提供支持。
5. 测试和调试BPMN工作流集成完成后,我们需要进行测试和调试,以确保BPMN工作流在业务系统中的正常运行。
在测试过程中,我们需要模拟各种业务场景,验证流程图的逻辑正确性和执行结果的准确性,并及时排查和修复可能存在的问题。
js 流程图插件JavaScript(简称JS)是一种高级的、解释型的编程语言,它主要用于在网页上实现动态效果和交互功能。
在Web开发中,流程图是一个常见的需求,它可以清晰地展示流程和逻辑关系,帮助用户更好地理解和分析信息。
为了简化流程图的创建过程,提高效率,我们可以使用JS流程图插件来实现。
JS流程图插件是一种可以在网页上嵌入的工具,它可以帮助用户轻松地创建和展示流程图。
在使用JS流程图插件之前,我们需要先了解一些基本概念和使用方法。
首先,我们需要引入JS流程图插件的相关文件。
通常情况下,我们可以通过在HTML文件中使用`<script>`标签来引入插件的JS文件,或者通过npm安装插件的包。
接着,我们需要在HTML文件中创建一个容器,用于展示流程图。
我们可以使用`<div>`标签来创建这样一个容器,并为其指定一个唯一的ID,以便在JS代码中进行操作。
接下来,我们可以编写JS代码来初始化和配置流程图插件。
在初始化插件之前,我们需要先准备好流程图的数据,通常是一个包含节点和连接关系的数据结构。
一般来说,我们可以使用JSON格式来表示这样的数据结构。
在初始化插件时,我们可以将这样的数据传递给插件,从而让插件根据数据来生成流程图。
除此之外,我们还可以通过配置选项来定制流程图的样式、布局和交互行为,以满足特定的需求。
一旦插件初始化完成,我们就可以在网页上看到一个美观且功能强大的流程图了。
通过鼠标操作,我们可以对流程图进行缩放、拖拽和选择等操作,以便更好地查看和分析流程图。
此外,插件还提供了丰富的API,可以让我们通过编程的方式来操作流程图,比如增加节点、删除节点、修改连接等操作。
总的来说,JS流程图插件是一个非常实用的工具,它可以帮助我们快速地创建和展示流程图,提高工作效率。
通过合理的配置和定制,我们可以使用插件来满足各种复杂的需求,比如展示业务流程、设计系统架构、分析数据流程等。
如何使用JavaScript实现Canvas绘图和动画使用JavaScript来实现Canvas绘图和动画是一种常见的技术,它可以实现各种各样的图形效果和动态交互,非常适合用于创建各种类型的网页动画和游戏。
在本文中,我将详细介绍如何使用JavaScript来绘制图形、实现动画以及一些常用的绘图和动画效果。
一、构建Canvas元素为了开始绘制和动画,我们首先需要在HTML文档中创建一个Canvas元素。
Canvas是HTML5中新增的元素,它提供了一个绘制2D 图形的区域,我们可以通过JavaScript来操纵它。
在HTML文档的body标签中添加以下代码:```<canvas id="myCanvas" width="500" height="300"></canvas> ```上面的代码创建了一个id为myCanvas的Canvas元素,宽度为500像素,高度为300像素。
二、获取Canvas上下文要绘制图形或进行动画,我们需要获取Canvas的上下文对象。
在JavaScript中,我们可以使用`getContext()`方法来获取上下文对象。
在JavaScript中,使用以下代码获取Canvas上下文对象:```const canvas = document.getElementById('myCanvas');const ctx = canvas.getContext('2d');```上面的代码通过`getElementById`方法获取了id为myCanvas的Canvas元素,然后通过`getContext`方法获取了2D上下文对象ctx。
三、绘制基本图形下面介绍如何使用JavaScript在Canvas上绘制一些基本图形,例如矩形、圆形和直线。
Canvas提供了一系列的API可以用于绘制图形。
js 流程图JavaScript(简称JS)是一种高级的、解释型的编程语言,用于创建动态内容,比如网页上的交互效果。
在网页开发中,流程图是一种非常常见的图形化展示方式,用于展示程序的流程和逻辑。
在本文中,我们将讨论如何使用JavaScript来创建流程图。
首先,我们需要了解一下流程图的基本结构。
流程图通常由各种不同的形状组成,比如矩形、圆角矩形、菱形等。
这些形状代表了不同的操作或决策点。
在JavaScript中,我们可以使用HTML5的Canvas元素来创建这些形状,并通过JavaScript来控制它们的位置和样式。
接下来,我们需要考虑如何在流程图中表示不同的操作和决策。
在JavaScript中,我们可以使用条件语句(比如if语句)来表示决策点,使用循环语句(比如for循环)来表示重复的操作。
我们可以通过在Canvas上绘制不同的形状来表示这些操作和决策点,并使用JavaScript来监听用户的输入,从而改变流程图的显示。
除了基本的形状和操作外,流程图还需要能够展示不同操作之间的关系。
在JavaScript中,我们可以使用线条来连接不同的形状,从而表示它们之间的关系。
通过在Canvas上绘制线条,并使用JavaScript来计算线条的起点和终点,我们可以很容易地实现这一点。
另外,流程图还需要能够展示不同操作之间的数据流动。
在JavaScript中,我们可以使用变量来存储和传递数据。
我们可以在Canvas上绘制箭头或其他符号来表示数据的流动,并使用JavaScript来更新这些符号的位置和样式。
最后,我们还需要考虑如何使流程图具有交互性。
在JavaScript中,我们可以使用事件监听器来监听用户的输入,比如鼠标点击或键盘输入。
通过在Canvas上绘制可交互的元素,并使用JavaScript来响应用户的输入,我们可以实现流程图的交互效果,比如拖动形状、改变形状的样式等。
综上所述,使用JavaScript创建流程图并不难,只需要了解Canvas元素的基本用法,以及如何使用JavaScript来控制它。
js流程图JavaScript流程图是一种以图形方式表示程序运行过程的工具。
它使用各种符号和连线来表示程序中的各个步骤和决策,帮助开发者更清晰地理解和分析程序的逻辑。
下面是一个关于JavaScript流程图的详细介绍。
1. 流程图基本符号:- 开始/结束符号:用来表示程序的开始和结束。
- 输入/输出符号:用来表示程序与用户之间的输入和输出。
- 处理符号:用来表示程序的处理操作。
- 条件判断符号:用来表示程序的条件判断。
- 连线:用来连接各个符号,并表示程序运行的流向。
2. 流程图的绘制:绘制JavaScript流程图需要按照以下步骤进行:- 首先,确定程序的开始和结束,使用开始/结束符号标记。
- 然后,根据程序中的输入和输出,使用输入/输出符号标记用户与程序之间的交互。
- 接下来,根据程序中的处理操作,使用处理符号标记各个处理步骤。
处理步骤可以是赋值操作、运算操作、函数调用等。
- 在处理步骤之间,使用连线将各个步骤连接起来,表示程序的运行流向。
- 然后,在需要进行条件判断的地方,使用条件判断符号标记。
条件判断符号通常包括一个条件表达式和两条连线,表示根据条件判断程序运行的不同路径。
- 最后,根据程序的逻辑结构和用户交互,完善流程图的细节。
3. JavaScript流程图的优势和应用:- JavaScript流程图能够直观地展示程序的逻辑结构和运行过程,帮助开发者更清晰地理解和分析程序。
- JavaScript流程图具有可读性强的特点,可以方便地与他人进行沟通和交流。
- JavaScript流程图可以用于代码编写的规划和设计,帮助开发者更好地组织代码结构和逻辑。
- JavaScript流程图常用于软件开发过程中,包括需求分析、程序设计、代码调试等阶段。
总结:JavaScript流程图是一种以图形方式表示程序运行过程的工具。
它使用各种符号和连线来表示程序中的各个步骤和决策,帮助开发者更清晰地理解和分析程序的逻辑。
使用JavaScript进行图表绘制教程第一章:引言随着互联网的迅速发展,数据可视化已成为现代社会中重要的需求,图表作为一种直观、易于理解的数据呈现形式,被广泛应用于数据分析、报告展示等领域。
本文将介绍使用JavaScript进行图表绘制的基本知识和技巧。
第二章:准备工作在开始绘制图表之前,我们需要准备一些基础工作,包括引入相关的JavaScript库和创建绘制图表所需的HTML结构。
常用的JavaScript图表库包括D3.js、Chart.js和Echarts等,我们选择其中的一款来进行讲解。
以Chart.js为例,我们需要在HTML文件中引入相关的库文件,并创建一个用于显示图表的图表容器。
第三章:绘制基础图表在使用JavaScript绘制图表之前,我们首先需要了解一些基础概念和API。
以Chart.js为例,该库提供了丰富的图表类型和配置选项,我们可以根据数据的不同特点选择合适的图表类型,并通过配置选项进行样式和交互效果的定制。
我们可以使用简单的示例代码来绘制柱状图、折线图和饼图等基础图表,并通过修改配置选项来实现不同的效果。
第四章:数据处理与绑定在真实的数据可视化应用中,我们不仅需要绘制静态的图表,还需要实时更新数据和交互操作。
为了实现这一点,我们可以使用JavaScript对数据进行处理和绑定。
通过从服务器获取数据或用户输入数据,我们可以将数据进行预处理、筛选和排序,然后将处理后的数据与图表进行绑定,实现动态的数据更新和交互效果。
第五章:图表效果与动画为了提高图表的可视化效果和用户体验,我们可以使用JavaScript库提供的各种效果和动画功能。
以Chart.js为例,该库提供了丰富的动画选项和效果插件,我们可以根据需求选择合适的动画效果,并通过配置选项进行定制。
通过添加渐变效果、缩放效果和平滑过渡效果等,我们可以使图表更加生动、美观,并增强用户的视觉体验。
第六章:图表交互与事件处理在数据可视化应用中,用户通常需要与图表进行交互,如点击图表查看详细信息、拖动图表进行数据筛选等。
基于Extjs可视工作流设计器的实现基于Extjs可视工作流设计器的实现一、说明可视化工作流设计管理器是工作流系统的一部分。
实现工作流活动,转移的可视化配置。
通常工作流系统会涉及以下几方面的内容。
1.工作流定义2.组织机构实现3.工作流授权实现4.动态表单实现5.工作流引擎实现6.工作流可视化定义维护本文只说明工作流设计器的实现。
设计器有很多实现的方法,本文只说明用Extjs实现需要处理的问题。
二、工作流设计器的功能主体功能1.增加、删除活动2.增加、删除转移3.修改活动、转移属性设计器界面效果1.活动节点定位2.橡皮筋拖动,重叠检测与反弹3.自动、手动选择线型4.线型的偏移和圆色修饰5.网格定位(snap)6.流程执行路径展示。
三、基本功能实现设计器要解决的首要问题是节点定位,拖动,画线。
节点定位:活动结点,以Div来表示,其内部为图标区和文字说明区。
节点定位通过样式postion来实现节点拖动:通过Extjs 的DragDrop相关类来实现。
画线:使用canvas标记。
IE中,通过Google提供的库来实现。
1.最简单的场景:页面中两个可以移动的节点。
相关的代码只有两句:Ext.onReady(function(){node1 = new Ext.dd.DD( 'IconManual','g2');node2 = new Ext.dd.DD( 'IconAuto','g2' );});2.拖动画线对上面的例子做一个扩充。
定义一个节点类,封装相关的功能。
定义一个画布,用于画线。
下面是源代码:TestGraph00.apsx<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestGraph01.aspx.cs"Inherits="Common_Workflow_TestGraph01" %><!DO CTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""/TR/xhtml1/DTD/xhtml1-transitional.dtd" ><html xmlns="/1999/xhtml"><head runat="server"><title>无标题页</title><!-- ExtJS --><link rel="stylesheet" type="text/css"href="/resources/css/ext-all.css" /><script type="text/javascript"src="/bootstrap.js"></script><script type="text/javascript"src="Script/excanvas.js"></script><link href="Css/TestGraph01.css" rel="stylesheet" type="text/css" /><script type="text/javascript"src="Script/excanvas.js"></script><script src="Script/Graph01.js"type="text/javascript"></script></head><body><form id="form1" runat="server"><div id="canvas" class="canvas"><canvas id="mainGraph" width="800"height="500" class="mainGraph"></canvas><canvas id="markGraph" width="800"height="500" class="markGraph"></canvas><div align="center" class="iconZone"id="IconManual"><div class="iconActManual"></div><div id='NodeNameDiv'>人工结点</div></div><div align="center" class="iconZone" id="IconAuto"><div class="iconActAuto"></div><div id="NodeNameDiv">自动节点</div></div></div></form></body></html>注意:markGraph暂时没有使用。
JavaScript+SVG实现Web前端WorkFlow⼯作流DAG有向⽆环图⼀、效果图展⽰及说明(图⼀)(图⼆)附注说明:1. 图例都是DAG有向⽆环图的展现效果。
两张图的区别为第⼆张图包含了多个分段关系。
放置展⽰图⽚效果主要是为了说明该例⼦⽀持多段关系的展现(当前也包括单独的节点展现,图例没有展⽰)2.图例中的圆形和曲线均使⽤的是SVG绘制。
之前考虑了三种⽅式,⼀种是html5的canvas,⼀种是原始的html DOM,再有就是SVG。
不过canvas对事件的⽀持不是很好(记得之前看过⼀篇⽂章主要是通过计算⿏标定位是否在canvas上的某个区域来触发事件机制,⽐较不适⽤⼯作流节点上的各种事件触发机制),另外原始的 DOM虽然对事件的处理⽐canvas要⽅便,但是从编码和绘制dom上则会过度的耗费资源,尤其是曲线的绘制,毕竟过多的dom操作都会影响性能拖慢响应速度,所以综合考虑使⽤SVG,它提供了绘制圆形,多边形,路径等操作,尤其是path的使⽤对于我们这种不会画曲线的⼈太⽅便了。
并且svg的dom对事件的⽀持和处理也很好。
⼆、有向⽆环图分析Okay,了解了⽀持的展现效果和使⽤的技术,下⾯开始分析开发workflow的dag有向⽆环图吧(透露⼀下,有向⽆环图最重要的是计算每个节点的最⼤步长了,最⼤步长也就是该节点在这⼀段关系中,距离根节点的最远距离,⽹上有⼀些计算的算法什么的,不过本⼈不会,搞不通算法)。
本例的核⼼技术其实是递归。
就是⽤递归就算每个节点的最⼤步长。
还不了解递归是什么的童鞋们先了解⼀下递归。
1. 梳理dag关系,剥离不存关系的节点和存在关系的节点,并找到每段关系的根节点(图三)附注说明:上图是⼀个DAG有向⽆环图的关系链展⽰。
(不要认为dag有向⽆环图单单指的是上图的中间部分,我们完全可以将上图理解为⼀个完整的dag关系。
因为考虑问题要全⾯嘛!不是所有的节点只存在⼀段关系中,也不是所有的节点就⼀定和其它节点有关系。
基于jsplumb绘制流程图效果图需要⽤到以下四个⽂件包jQuery.jsjquery-ui.min.cssjquery-ui.min.jsjquery.jsPlumb-1.6.2-min.js<script src="js/jquery-ui-1.11.4.custom/external/jquery/jquery.js" type="text/javascript"></script><link rel="stylesheet" href="js/jquery-ui-1.11.4.custom/jquery-ui.min.css"><script src="js/jquery-ui-1.11.4.custom/jquery-ui.min.js" type="text/javascript"></script><script src="js/jquery.jsPlumb-1.6.2-min.js"></script>css样式代码<style>body{text-align: center;}#root{width:100%;height:100vh;display: flex;justify-content: space-between;}#left{width:243px;height:50vh;padding:32px;border:2px solid darkgray;box-sizing: border-box;display: flex;flex-flow: column;justify-content: space-between;}.node {box-shadow: 2px 2px 19px #aaa;border-radius:6px;opacity: 0.8;filter: alpha(opacity=80);border: 1px solid #346789;width: 150px;text-align: center;z-index: 20;background-color: #eeeeef;color: black;padding: 10px;font-size: 9pt;cursor: pointer;height: 50px;/*line-height: 50px;*/background: lightskyblue;}.node:hover {box-shadow: 2px 2px 19px #444;opacity: 0.8;filter: alpha(opacity=80);}.node2css{background:orange;}.node3css{background: indianred;}.node4css{background: greenyellow;}#right{width:calc(100% - 260px);height:100vh;border:2px solid olivedrab;box-sizing: border-box;}.content{border-top: 1px solid darkgrey;}#myDropDown{width:80px;height:30px;border:2px solid blue;}#main{width:100%;height:calc(100% - 75px);border:1px solid red;}</style>HTML页⾯代码<div id="root"><div id="left"><div class="node" id="node1">流程1</div><div class="node node2css" id="node2">流程2</div><div class="node node3css" id="node3">流程3</div><div class="node node4css" id="node4">流程4</div></div><div id="right"><h2>下⽅区域绘制流程图</h2><div class="content" id="main"></div></div></div>js⾏为代码<script>//设置左侧为可复制的$("#left").children().draggable({helper: "clone",scope: "zlg",});//设置右侧为拖拽存放区var i=0;$("#main").droppable({scope:"zlg",drop:function (event , ui) {var left = parseInt(ui.offset.left - $(this).offset().left)+268.78;var top = parseInt(ui.offset.top - $(this).offset().top)+81;var name = ui.draggable[0].id;switch (name) {case "node1":i++;var id = "state_start" + i;$(this).append('<div class="node" style="position: absolute" id="' + id + '" >' + $(ui.helper).html() + '</div>');$("#" + id).css("left", left).css("top", top);jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);jsPlumb.draggable(id);$("#" + id).draggable({ containment: "parent" });doubleclick("#" + id);break;case "node2":i++;id = "state_flow" + i;$(this).append("<div class='node node2css' style='position: absolute' id='" + id + "'>" + $(ui.helper).html() + "</div>"); $("#" + id).css("left", left).css("top", top);jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, hollowCircle);jsPlumb.draggable(id);$("#" + id).draggable({ containment: "parent" });doubleclick("#" + id);break;case "node3":i++;id = "state_decide" + i;$(this).append("<div class='node node3css' style='position: absolute' id='" + id + "'>" + $(ui.helper).html() + "</div>"); $("#" + id).css("left", left).css("top", top);jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, hollowCircle);jsPlumb.draggable(id);$("#" + id).draggable({ containment: "parent" });doubleclick("#" + id);break;case "node4":i++;id = "state_end" + i;$(this).append('<div class="node node4css" style=\'position: absolute\' id="' + id + '" >' + $(ui.helper).html() + '</div>'); $("#" + id).css("left", left).css("top", top);jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);jsPlumb.draggable(id);$("#" + id).draggable({ containment: "parent" });doubleclick("#" + id);break;}}});//基本连接线样式var connectorPaintStyle = {lineWidth: 4,strokeStyle: "#61B7CF",joinstyle: "round",outlineColor: "white",outlineWidth: 2};// ⿏标悬浮在连接线上的样式var connectorHoverStyle = {lineWidth: 4,strokeStyle: "green",outlineWidth: 2,outlineColor: "white"};//端点的颜⾊样式var paintStyle = {strokeStyle: "#1e8151",fillStyle: "transparent",radius: 3,lineWidth:6 ,}// ⿏标悬浮在端点上的样式var hoverPaintStyle = {outlineStroke: 'lightblue'}//设置连接端点和连接线var hollowCircle = {endpoint: ["Dot", { radius: 8 }], //端点的形状connectorStyle: connectorPaintStyle,connectorHoverStyle: connectorHoverStyle,paintStyle: paintStyle,hoverPaintStyle: hoverPaintStyle ,isSource: true, //是否可以拖动(作为连线起点)connector: ["Flowchart", { stub: [40, 60], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }], //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ] isTarget: true, //是否可以放置(连线终点)maxConnections: -1, // 设置连接点最多可以连接⼏条线connectorOverlays:[ "Arrow",["Custom", {create:function(component) {return $("<select id='myDropDown'>" +"<option value='one'>暂未审理</option>" +"<option value='two'>通过</option>" +"<option value='three'>驳回</option>" +"</select>");},location:0.7,id:"customOverlay",}]]};//⿏标进⼊增加⼀个删除的⼩图标$("#main").on("mouseenter", ".node", function () {$(this).append('<img src="images/close2.png" style="position: absolute;" />');var widthnum = $(this).css("width").substr(0,5);if (widthnum < 60) {$("img").css("left", 67).css("top", -13);} else {$("img").css("left", 167).css("top", -12);}});//⿏标离开⼩图标消失$("#main").on("mouseleave", ".node", function () {$("img").remove();});//节点⼩图标的单击事件$("#main").on("click", "img",function () {if (confirm("确定要删除此节点吗?")) {jsPlumb.removeAllEndpoints($(this).parent().attr("id"));$(this).parent().remove();}});//连接线的双击事件jsPlumb.bind("dblclick", function (conn, originalEvent) {if (confirm("确定删除此连线吗?"))jsPlumb.detach(conn);});//双击节点内容区域时的事件function doubleclick(id) {$(id).dblclick(function () {var text = $(this).text();$(this).html("");$(this).append("<input style='width: 130px' type='text' value='" + text + "' />");$(this).mouseleave(function () {$(this).html($("input[type='text']").val());});});}</script>。
JointJSJavaScript流程图绘制框架解析JointJS:JavaScript 流程图绘制框架最近调研了js画流程图的框架,最后选择了Joint。
配合上 dagre 可以画出像模像样的流程图。
JointJS 简介是⼀个开源前端框架,⽀持绘制各种各样的流程图、⼯作流图等。
Rappid 是 Joint 的商业版,提供了⼀些更强的插件。
JointJS 的特点有下⾯⼏条,摘⾃官⽹:能够实时地渲染上百(或者上千)个元素和连接⽀持多种形状(矩形、圆、⽂本、图像、路径等)⾼度事件驱动,⽤户可⾃定义任何发⽣在 paper 下的事件响应元素间连接简单可定制的连接和关系图连接平滑(基于贝塞尔插值 bezier interpolation)& 智能路径选择基于 SVG 的可定制、可编程的图形渲染NodeJS ⽀持通过 JSON 进⾏序列化和反序列化总之 JoingJS 是⼀款很强的流程图制作框架,开源版本已经⾜够⽇常使⽤了。
⼀些常⽤地址:JointJS Hello world<!DOCTYPE html><html><head><link rel="stylesheet" type="text/css" href="https:///ajax/libs/jointjs/2.1.0/joint.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" /> </head><body><!-- content --><div id="myholder"></div><!-- dependencies 通过CDN加载依赖--><script src="https:///ajax/libs/jquery/3.1.1/jquery.js"></script><script src="https:///ajax/libs/lodash.js/3.10.1/lodash.js"></script><script src="https:///ajax/libs/backbone.js/1.3.3/backbone.js"></script><script src="https:///ajax/libs/jointjs/2.1.0/joint.js"></script><!-- code --><script type="text/javascript">var graph = new joint.dia.Graph;var paper = new joint.dia.Paper({el: document.getElementById('myholder'),model: graph,width: 600,height: 100,gridSize: 1});var rect = new joint.shapes.standard.Rectangle();rect.position(100, 30);rect.resize(100, 40);rect.attr({body: {fill: 'blue'},label: {text: 'Hello',fill: 'white'}});rect.addTo(graph);var rect2 = rect.clone();rect2.translate(300, 0);rect2.attr('label/text', 'World!');rect2.addTo(graph);var link = new joint.shapes.standard.Link();link.source(rect);link.target(rect2);link.addTo(graph);</script></body></html>hello world 代码没什么好说的。
如何使用JavaScript在网页上实现画图板随着互联网的发展,越来越多的人开始关注网页的交互性和用户体验。
在网页中添加一些小游戏和工具,可以吸引用户停留,增强网站的吸引力。
在这个过程中,画图板是一个很有意思的工具,它可以让用户在网页上自由绘制图形。
本文将介绍如何使用JavaScript在网页上实现画图板。
一、HTML页面准备在实现画图板之前,需要准备一个HTML页面。
在该页面中,需要添加一些基本的元素,如canvas元素和按钮元素。
具体代码如下:```html<!DOCTYPE html><html><head><title>画图板</title></head><body><canvas id="canvas" width="600" height="400"></canvas><div><button id="pencil">铅笔</button><button id="eraser">橡皮</button><button id="clear">清空</button></div><script src="draw.js"></script></body></html>```在这个HTML页面中,首先定义了一个canvas元素,它的宽度是600,高度是400。
canvas元素是实现画图板的核心元素,它提供了一种在网页上进行绘图的方式。
接下来是三个按钮元素,分别是“铅笔”、“橡皮”和“清空”。
这些按钮是用来操作画图板的,用户可以通过它们来选择画笔和清空画布。
js 流程可视化简易代码
当涉及到 JavaScript 流程可视化时,有一个名为 js2flowchart 的开源库可以将JavaScript 代码转化为可视化流程图。
js2flowchart 是一个接受任何 JS 代码并从中生成SVG 流程图的库,适用于客户端和服务器端,且支持 ES6。
js2flowchart 的主要特点如下:- 支持定义抽象级别,以仅渲染导入/导出、类/函数名称、函数依赖性,从而逐步学习/解释代码。
- 支持创建自己的抽象级别。
- 表示生成器,以生成 SVG 列表,从而达到不同的抽象级别。
- 定义流树修饰符,以映射众所周知的 API,例如 `.map`、`.forEach`、`.filter` 到方案上的循环结构等。
- 销毁修饰符,用于在方案上用一个形状替换代码块。
- 支持自定义流树修改器。
- 支持过滤器,忽略一些代码节点,即日志行。
- 焦点节点或整个代码逻辑分支,以突出方案中的重要部分。
- 模糊节点或整个代码逻辑分支,以隐藏不太重要的东西。
- 支持定义样式主题。
- 支持创建自己的主题,更适合开发者自己的上下文颜色。
- 自定义颜色和样式,支持提供方便的 API 来更改特定样式,而无需样板。
js2flowchart 的典型用例包括通过流程图解释/记录代码、通过视觉理解学习别人的代码、为由有效的 JS 语法简单描述的任何过程创建流程图。
用JS实现工作流设计器图形绘制
王玉贵
【期刊名称】《电脑编程技巧与维护》
【年(卷),期】2012(000)015
【摘要】通过使用JS (JavaScript)实现一个能够跨浏览器绘制工作流图形的工具,简单、实用,具有很高的应用价值.
【总页数】5页(P31-35)
【作者】王玉贵
【作者单位】
【正文语种】中文
【相关文献】
1.基于WFMC规范的工作流系统——工作表管理器模块的设计与实现 [J], 张晖;林坚
2.企业公文工作流中报表和流程设计器的设计与实现 [J], 闵孝忠;朱巧明
3.基于关系数据库的工作流服务器设计与实现 [J], 刘惠义;吴中华
4.一个基于Web的工作流监控器的设计与实现 [J], 潘华
5.基于SVG的产品测试工作流编辑器的设计与实现 [J], 张泽江;郭志卓;刘青因版权原因,仅展示原文概要,查看原文内容请购买。
JS组件系列——JsPlumb流程图及相关效果详解(⼆:附源码)前⾔:上篇介绍了下JsPlumb在浏览器⾥⾯画流程图的效果展⽰,以及简单的JsPlumb代码⽰例。
这篇还是接着来看看各个效果的代码说明。
⼀、设置连线的样式和颜⾊效果代码⽰例⼤概的效果如图:这些效果看着很简单,那么,我们如何⽤代码去实现它呢。
上章我们说过,JsPlumb的连线样式是由点的某些属性决定的,既然如此,我们就通过设置点的样式来动态改变连线的样式即可。
来看代码:⾸先来看看连线类型的那个select<div id="btn_linetype" class="divMenuBtn btn-default btn">连线类型: <select id="sel_linetype" style="width:80px;height:20px"> <option value="2">直线</option> <option value="1">折线</option> <option value="3">曲线</option> </select></div>在页⾯初始化的时候注册select的change事件//全局的空⼼圆端点样式设置var hollowCircle = {DragOptions: { cursor: 'pointer', zIndex: 2000 },endpoint: ["Dot", { radius: 7 }], //端点的形状connectorStyle: connectorPaintStyle,//连接线的颜⾊,⼤⼩样式connectorHoverStyle: connectorHoverStyle,paintStyle: {strokeStyle: "#1e8151",fillStyle: "transparent",radius: 5,lineWidth: 2}, //端点的颜⾊样式//anchor: "AutoDefault",isSource: true, //是否可以拖动(作为连线起点)connector: ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }], //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]isTarget: true, //是否可以放置(连线终点)maxConnections: -1, // 设置连接点最多可以连接⼏条线connectorOverlays: [["Arrow", { width: 10, length: 10, location: 1 }]]};//页⾯初始化完成之后$(function () {//连线样式下拉框的change事件$("#sel_linetype").change(function () {var strlinetype = "";var strlinecolor = "";//设置新添加元素的节点的连线样式//直线的样式和样⾊if ($(this).val() == "1") {strlinetype = "Flowchart";strlinecolor = "red";hollowCircle.connector = ["Flowchart", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];}//折线的样式和颜⾊else if ($(this).val() == "2") {strlinetype = "Straight";strlinecolor = "green";hollowCircle.connector = ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];}//曲线的样式和颜⾊else if ($(this).val() == "3") {strlinetype = "Bezier";strlinecolor = "orange";hollowCircle.connector = ["Bezier", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];}//设置已经存在的所有的连接点的连线样式var arrnode = $("#divCenter").find(".node");for (var i = 0; i < arrnode.length; i++) {var arrendpoints = jsPlumb.getEndpoints($(arrnode[i]).attr("id"));if (arrendpoints == undefined || arrendpoints == null) {return;}var oconnector = arrendpoints[0].connector;if (oconnector == null || oconnector == undefined) {return;}oconnector[0] = strlinetype;var oconnectstyle = arrendpoints[0].connectorStyle;if (oconnectstyle == null || oconnectstyle == undefined) {return;}oconnectstyle.strokeStyle = strlinecolor;}});});其实也就⼏⾏代码,设置已经存在和将要拖动到界⾯上⾯的端点的连线样式。