activiti5.21 + SVG 绘制流程图 高亮显示已完成节点
本功能实现是结合actitivi5.21的数据结构来获取相关数据,并通过AJAX调用进行SVG图形的绘制。
1、SpringBoot 接口及相关实体
/** * 读取组装绘制流程图的数据 */ @RequestMapping(value = "/getDrawingFlowChart/{processInstanceId}") @ResponseBody public ImgJSON getDrawingFlowChart(HttpServletResponse response,@PathVariable String processInstanceId){//获取历史流程实例 HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); //获取流程图 BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); List<BmpNodeInfo> bmpNodeInfos=new ArrayList<BmpNodeInfo>(); if(bpmnModel!=null){List<FlowElement> flowElements= (List<FlowElement>) bpmnModel.getProcesses().get(0).getFlowElements(); for(int i=0;i<flowElements.size();i++){BmpNodeInfo bmpNodeInfo=new BmpNodeInfo(); bmpNodeInfo.setClassType(flowElements.get(i).getClass().getName()); bmpNodeInfo.setId(flowElements.get(i).getId()); bmpNodeInfo.setName(flowElements.get(i).getName()); bmpNodeInfos.add(bmpNodeInfo); }}ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); processEngineConfiguration = processEngine.getProcessEngineConfiguration(); Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration); ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator(); ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId()); List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list(); //高亮环节id集合 List<String> highLightedActivitis = new ArrayList<String>(); //高亮线路id集合 List<String> highLightedFlows = DrawingFlowChartUtil.getHighLightedFlows(definitionEntity, highLightedActivitList); for (HistoricActivityInstance tempActivity : highLightedActivitList) {String activityId = tempActivity.getActivityId(); highLightedActivitis.add(activityId); }ImgJSON imgJSON=new ImgJSON(); imgJSON.setBpmnModel(bpmnModel); imgJSON.setHighLightedActivitList(highLightedActivitList); imgJSON.setHighLightedActivitis(highLightedActivitis); imgJSON.setHighLightedFlows(highLightedFlows); imgJSON.setList(bmpNodeInfos); return imgJSON; }
public class BmpNodeInfo {private String classType; private String id; private String name; public String getClassType() {return classType; }public void setClassType(String classType) {this.classType = classType; }public String getId() {return id; }public void setId(String id) {this.id = id; }public String getName() {return name; }public void setName(String name) {this.name = name; } }
import org.activiti.bpmn.model.BpmnModel; import org.activiti.engine.history.HistoricActivityInstance; import java.io.Serializable; import java.util.List; public class ImgJSON implements Serializable {private BpmnModel bpmnModel; private List<HistoricActivityInstance> highLightedActivitList; private List<String> highLightedActivitis; private List<String> highLightedFlows; private List<BmpNodeInfo> list; public BpmnModel getBpmnModel() {return bpmnModel; }public void setBpmnModel(BpmnModel bpmnModel) {this.bpmnModel = bpmnModel; }public List<HistoricActivityInstance> getHighLightedActivitList() {return highLightedActivitList; }public void setHighLightedActivitList(List<HistoricActivityInstance> highLightedActivitList) {this.highLightedActivitList = highLightedActivitList; }public List<String> getHighLightedActivitis() {return highLightedActivitis; }public void setHighLightedActivitis(List<String> highLightedActivitis) {this.highLightedActivitis = highLightedActivitis; }public List<String> getHighLightedFlows() {return highLightedFlows; }public void setHighLightedFlows(List<String> highLightedFlows) {this.highLightedFlows = highLightedFlows; }public List<BmpNodeInfo> getList() {return list; }public void setList(List<BmpNodeInfo> list) {this.list = list; } }
2、JS文件
function createRects(rects,list,hights,draw) {$.each(rects,function (key,values) {var nodeType=getNodeType(key,list); if(nodeType!=null && nodeType!=""){if(nodeType[0]=="StartEvent" || nodeType[0]=="EndEvent"){draw.appendChild(createCircle(values.x+values.width/2,values.y+values.width/2,values.width/2,getNodeHightLighte(key,hights),nodeType[1],nodeType[0])); }else if(nodeType[0]=="InclusiveGateway" ||nodeType[0]==" ExclusvieGateway" ||nodeType[0]=="EventGateway" ||nodeType[0]=="ParallelGateway"){draw.appendChild(createDoublePolygon(values.x,values.y,values.width,values.height,getNodeHightLighte(key,hights),nodeType[1])); }else{draw.appendChild(createRect(values.x,values.y,values.width,values.height,getNodeHightLighte(key,hights),nodeType[1])); }}}); } //判断节点是否需要高亮显示 function getNodeHightLighte(key,hights) {var boo=false; $.each(hights,function (index,item) {if(key==item){boo=true; }}); return boo; } //查找节点的类型 function getNodeType(key,list) {var name={}; var re=new Array(); $.each(list,function (index,item) {if(key==item.id){name= item.classType.split("."); re[1]=item.name; }}); if(name!=null && name.length>0){re[0]=name[name.length-1]; }return re; } function createDoublePolygon(x,y,width,height,hl) {var g=document.createElementNS("http://www.w3.org/2000/svg","g"); g.appendChild(createPolygon(x,y,width,height,hl)); g.appendChild(createPolygon(x+width/4,y+height/4,width/2,height/2,hl)); return g; } //画一个棱形 function createPolygon (x,y,width,height,hl) {var node; node=document.createElementNS("http://www.w3.org/2000/svg","polygon"); var point=(x+width/2)+","+y; point=point+" "+(x+width)+","+(y+height/2); point=point+" "+(x+width/2)+","+(y+height); point=point+" "+x+","+(y+height/2); node.setAttribute("points",point); node.setAttribute("fill","#FFFFFF"); if(hl==true){node.setAttribute("stroke","#1ccb6f"); }else{node.setAttribute("stroke","#000000"); }node.setAttribute("stroke-width","2"); return node; } //画一个圆 function createCircle(x,y,r,hl,text_str,nodetype) {var node; var g=document.createElementNS("http://www.w3.org/2000/svg","g"); node=document.createElementNS("http://www.w3.org/2000/svg","circle"); var text=document.createElementNS("http://www.w3.org/2000/svg","text"); node.setAttribute("cx",x); node.setAttribute("cy",y); node.setAttribute("r",r); if(hl==true){node.setAttribute("stroke","#1ccb6f"); }else{node.setAttribute("stroke","#000000"); }node.setAttribute("stroke-width","2"); node.setAttribute("fill","#FFFFFF"); text.setAttribute("text-anchor","middle"); text.style.fontSize="0.5em"; text.textContent=text_str; text.setAttribute("startOffset","1"); text.setAttribute("x",x); if(nodetype=="StartEvent"){text.setAttribute("y",y-r-10); }else{text.setAttribute("y",y+r+10); }text.setAttribute("fill","black"); g.appendChild(node); g.appendChild(text); return g; } // 画一个矩形 function createRect(x,y,width,height,hl,text_str) {var node; var g=document.createElementNS("http://www.w3.org/2000/svg","g"); var text=document.createElementNS("http://www.w3.org/2000/svg","text"); // <foreignObject width="120" height="50"> // <body xmlns="http://www.w3.org/1999/xhtml"> // <p style="font-size:12px;margin:0;">一段需要word wrap的文字。</p> // </body> // </foreignObject> g.setAttribute("type","userTask"); // g.setAttribute("id","id_"+v.id); node=document.createElementNS("http://www.w3.org/2000/svg","rect"); node.setAttribute("x",x);//矩形的左侧位置 node.setAttribute("y",y);//矩形的顶部位置 node.setAttribute("rx","5");//圆角 node.setAttribute("ry","5");//圆角 node.setAttribute("height",height);//矩形的高度 node.setAttribute("width",width);//矩形的宽度 if(hl==true){node.setAttribute("stroke","#1ccb6f"); }else{node.setAttribute("stroke","#000000"); }node.setAttribute("stroke-width","2"); node.setAttribute("fill","#FFFFFF"); text.setAttribute("text-anchor","middle"); text.setAttribute("height",height);//矩形的高度 text.setAttribute("width",width);//矩形的宽度 // var body=document.createElementNS("http://www.w3.org/2000/svg","body"); // body.setAttribute("xmlns","http://www.w3.org/1999/xhtml"); // var p=document.createElementNS("http://www.w3.org/2000/svg","p"); // // p.css({"font-size":"12px","margin":"0"}); // p.textContent=text_str; // body.appendChild(p); // text.appendChild(body); text.style.fontSize="0.7em"; text.textContent=text_str; text.setAttribute("startOffset","1"); text.setAttribute("x",x+width/2); text.setAttribute("y",y+height-10); // // node.appendChild(text); g.appendChild(node); g.appendChild(text); return g; } function createLines(lines,hight,drwa) {$.each(lines,function (key,item) {if(item.length>2){var points=new Array(); var j=0; for(var i=0;i<item.length;i++){var pp=new Array(); pp[0]=item[i].x; pp[1]=item[i].y; points[j++]=pp; }draw.appendChild( createBrokenLine(points,getNodeHightLighte(key,hight))); }else{draw.appendChild( createLine(item[0].x,item[0].y,item[1].x,item[1].y,getNodeHightLighte(key,hight))); }}); } function createLine(x1,y1,x2,y2,hl) {var node; var g=document.createElementNS("http://www.w3.org/2000/svg","g"); // var text=document.createElementNS("http://www.w3.org/2000/svg","text"); g.setAttribute("type","userTask"); // g.setAttribute("id","id_"+v.id); node=document.createElementNS("http://www.w3.org/2000/svg","path"); node.setAttribute("fill","none"); if(hl==true){node.setAttribute("stroke","#1ccb6f"); }else{node.setAttribute("stroke","#000000");//线颜色 }// text.setAttribute("startOffset","1"); // text.setAttribute("x",parseInt(node.getAttribute("x"))+parseInt(node.getAttribute("width"))/2); // text.setAttribute("y",parseInt(node.getAttribute("y"))+parseInt(node.getAttribute("height"))/2); // text.setAttribute("fill","black"); node.setAttribute("d",drawLineArrow(x1,y1,x2,y2)); g.appendChild(node); // g.appendChild(text); return g; } function createBrokenLine(points,hl) {var node; var g=document.createElementNS("http://www.w3.org/2000/svg","g"); // var text=document.createElementNS("http://www.w3.org/2000/svg","text"); g.setAttribute("type","userTask"); // g.setAttribute("id","id_"+v.id); node=document.createElementNS("http://www.w3.org/2000/svg","path"); node.setAttribute("fill","none"); if(hl==true){node.setAttribute("stroke","#1ccb6f"); }else{node.setAttribute("stroke","#000000");//线颜色 }// text.setAttribute("startOffset","1"); // text.setAttribute("x",parseInt(node.getAttribute("x"))+parseInt(node.getAttribute("width"))/2); // text.setAttribute("y",parseInt(node.getAttribute("y"))+parseInt(node.getAttribute("height"))/2); // text.setAttribute("fill","black"); node.setAttribute("d",drawBrokenLineArrow(points)); g.appendChild(node); // g.appendChild(text); return g; } // 画折线和箭头 function drawBrokenLineArrow(points) {var path = ""; for (var i = 0; i <= points.length - 2; i++) {var p = points[i]; var p2 = points[i + 1]; if (i == points.length - 2) {path += drawLineArrow(p[0], p[1], p2[0], p2[1]); } else {path += "M" + p[0] + "," + p[1] + " L" + p2[0] + "," + p2[1]; }}console.log("BrokenLine, path=" + path); return path; } // 画直线和箭头 function drawLineArrow(x1, y1, x2, y2) {var path; var slopy, cosy, siny; var Par = 10.0; var x3, y3; slopy = Math.atan2((y1 - y2), (x1 - x2)); cosy = Math.cos(slopy); siny = Math.sin(slopy); path = "M" + x1 + "," + y1 + " L" + x2 + "," + y2; x3 = x2; y3 = y2; path += " M" + x3 + "," + y3; path += " L" + (Number(x3) + Number(Par * cosy - (Par / 2.0 * siny))) + "," + (Number(y3) + Number(Par * siny + (Par / 2.0 * cosy))); path += " M" + (Number(x3) + Number(Par * cosy + Par / 2.0 * siny) + "," + (Number(y3) - Number(Par / 2.0 * cosy - Par * siny))); path += " L" + x3 + "," + y3; console.log("path=" + path); return path; } function moveMouse(even) {var rects=document.getElementsByTagName("rect"); $.each(rects,function (index,item) {$(item).on('click',function (event) {alert("Ss"); }); })}
3、HTML调用
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>Title</title> <script type="application/javascript" th:src="@{/my_js/jquery2.1.4.js}"></script> <script type="application/javascript" th:src="@{/bootstrap-3.3.7-dist/js/bootstrap.js}"></script> <script type="application/javascript" th:src="@{/my_js/activiti_svg.js}"></script> <script type="application/javascript"> /*<![CDATA[*/ var draw_width=800//$(window).width();//初始画布大小为浏览器可视区域大小 var draw_height=500//$(window).height();//初始画布大小为浏览器可视区域大小 var draw = document.createElementNS("http://www.w3.org/2000/svg","svg"); $(draw).css({"width":draw_width+"px","height":draw_height+"px","border":"1px sold #000000"}); $(function () {getImgJson(); }); function getImgJson() {$.ajax({url:'/getDrawingFlowChart/122663', type:'GET', //GET async : true, data:{}, timeout:10000, //超时时间 dataType:'json', //返回的数据格式: success:function(json){createRects(json.bpmnModel.locationMap,json.list,json.highLightedActivitis,draw); createLines(json.bpmnModel.flowLocationMap,json.highLightedFlows); $('#svg_c').html(draw); console.log(json); }, error:function(xhr,textStatus){console.log('错误')console.log(xhr)console.log(textStatus)}}); }/*]]>*/ </script> </head> <body > <div id="svg_c"> </div> </body> </html>
4、示例(任意拖拉流程) bpm文件效果
html 绘制效果
大家有时间可以将折线绘制了好看点,对点进行计算形成四个点的折线会更加好看
activiti5.21 + SVG 绘制流程图 高亮显示已完成节点相关推荐
- VUE+bpmn.js+iview 页面绘制流程图
前言:业务需求需要在页面绘制流程图,之前后台的同事都是在eclipse画的流程图,为了方便点希望能在页面上画. 我用的是iview的ui框架,用原生的话记得把按钮等标签改改. 如果用的是element ...
- activiti绘制流程图,线上显示文字,审批过的节点添加审批人的名字
最有时间优化了一下activiti的绘制图片工具类,主要用于在领导审批的时候展示的漂亮,直接上代码吧, /** 放在我们的业务代码中,穿个流程实例id进来,返回一个字符数组,然后该怎么处理你们应该知道 ...
- 1过程流程图 3 apqp_如何绘制流程图?这里有3种绘制方法,既简单又高效!1分钟可学会...
工作中,很多小伙伴需要绘制流程图,那么如何绘制流程图呢?其实并不难,今天小编就来给大家分享流程图的3种绘制方法,大家可以根据自己的想法选择最适合自己的那一种哦~ 一.Word制作 1.借助SmartA ...
- 在线绘制流程图网站、思维导图网站总结
本篇博客总结了在线绘制流程图.思维导图的几个网站,欢迎留言补充 1.processsOn 免费在线作图.实时协作 支持流程图.思维导图.原型图.UML.网络拓扑图.组织结构图等 2.爱莫流程图 爱莫流 ...
- Raphael绘制流程图箭头的方法
原项目使用的Raphael绘制流程图,要求能自定义箭头的样式和颜色,结合从网上找到的一些资料进行修改. 1.使用Raphael自带的箭头样式,代码与箭头的样式对应如下: var c = r.path( ...
- MATLAB轻松绘制地图路线——已知及未知坐标下的处理方法(1)
文章目录 已知坐标的情况 未知坐标的情况 完整工程文件下载链接: 要想绘制地图路线, 最基本的要素就是 各点的坐标,有了坐标,还要知道哪个点和哪个点相连,最后将各点相连即可: 但有时候我们有的往往只是 ...
- word2003流程图变成图片_转:Word2003 绘制流程图(2)
转:Word2003 绘制流程图(2) (2010-07-26 21:56:28) 标签: 杂谈 制作过程中应把握以下三大规律: 1. 先难后易 流程图一般最下面的部分比较复杂,做起来困难一些,那就 ...
- 一文读懂:程序员为什么要学会画流程图 11种流程图的绘制工具:processon,wps,draw.io, 迅捷画图等 详细说明使用processon绘制流程图 详细说明绘制流程图
这里写目录标题 为什么要学会画流程图 11种画流程图的工具 processon wps draw.io Zen Flowchart xGraph lucidchart boardmix plantum ...
- 【高效工具】《三》Typora直接使用MarkDown语法绘制流程图、时序图、甘特图
平常使用Typora撰写内容的时候,偶尔会用到流程图,原来一直使用Word来作图,在插入到文档中,昨天偶然间了解到Typora支持使用mermaid来绘制流程图,才发现自己差点Out了.此处整理一下如 ...
最新文章
- 最新调查,48%的美国人表示不会乘坐自动驾驶汽车
- 关于Jsoup解析https网页的问题
- IIC软件模拟-读写EEPROM
- java查询线程状态命令_JAVA 线程死锁,以及linux 命令和jstack 命令 查看线程死锁状态信息...
- android.graphics.drawable.Drawable.Callback回调接口
- Redis 4.0深入持久化
- idea java代码格式化_IDEA java 代码格式化统一
- 云计算与大数据——云计算的特点
- ORA-00932: 数据类型不一致: 应为 CHAR, 但却获得 NUMBER
- DNS解析错误的问题,域名解析错误导致输入域名不访问而直接输入网站IP却可以正常访问
- 关于 该设备或资源(127.0.0.1)未设置为接受端口 的解决办法
- 干货 | 什么是ABCDE轮融资?
- 基于ETest的发动机ECU硬件在环测试平台的研究与开发
- knex.js中文文档
- 实验四 进程同步与通信(一)进程同步与互斥1
- matlab同轴电缆能量密度,导体电介质和磁介质之同轴电缆的能量密度.ppt
- 1月31日 解决问题的方法( 麦肯锡七步成诗法 )
- 《嵌入式系统原理与接口技术》——嵌入式系统接口应用基础
- 联发科MT7682芯片资料MT6762原理图资料
- JedisSentinelPool 连接 master
热门文章
- DYMO/Mimio推出最新互动教育软件linux操作系统培训
- html中图像标记的属性,HTML中的图象标签属性
- 基于Springboot的学生信息管理系统
- oracle查询dictionary,Oracle的DICTIONARY/DICT视图。
- 老友记第一季台词打印_老友记第一季第一集台词
- 启动MyEclipse时报错,An error has occurred see the log file 出现此类错误提示
- tms320vc5416c语言编程,TMS320VC5416与CAN总线的接口设计及软件编程
- 操作系统实验一到实验九合集(哈工大李治军)
- Hazel引擎学习(六)
- DBeaver(其他可视化工具一样的逻辑)连接IoTDBDriver教程