本功能实现是结合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 绘制流程图 高亮显示已完成节点相关推荐

  1. VUE+bpmn.js+iview 页面绘制流程图

    前言:业务需求需要在页面绘制流程图,之前后台的同事都是在eclipse画的流程图,为了方便点希望能在页面上画. 我用的是iview的ui框架,用原生的话记得把按钮等标签改改. 如果用的是element ...

  2. activiti绘制流程图,线上显示文字,审批过的节点添加审批人的名字

    最有时间优化了一下activiti的绘制图片工具类,主要用于在领导审批的时候展示的漂亮,直接上代码吧, /** 放在我们的业务代码中,穿个流程实例id进来,返回一个字符数组,然后该怎么处理你们应该知道 ...

  3. 1过程流程图 3 apqp_如何绘制流程图?这里有3种绘制方法,既简单又高效!1分钟可学会...

    工作中,很多小伙伴需要绘制流程图,那么如何绘制流程图呢?其实并不难,今天小编就来给大家分享流程图的3种绘制方法,大家可以根据自己的想法选择最适合自己的那一种哦~ 一.Word制作 1.借助SmartA ...

  4. 在线绘制流程图网站、思维导图网站总结

    本篇博客总结了在线绘制流程图.思维导图的几个网站,欢迎留言补充 1.processsOn 免费在线作图.实时协作 支持流程图.思维导图.原型图.UML.网络拓扑图.组织结构图等 2.爱莫流程图 爱莫流 ...

  5. Raphael绘制流程图箭头的方法

    原项目使用的Raphael绘制流程图,要求能自定义箭头的样式和颜色,结合从网上找到的一些资料进行修改. 1.使用Raphael自带的箭头样式,代码与箭头的样式对应如下: var c = r.path( ...

  6. MATLAB轻松绘制地图路线——已知及未知坐标下的处理方法(1)

    文章目录 已知坐标的情况 未知坐标的情况 完整工程文件下载链接: 要想绘制地图路线, 最基本的要素就是 各点的坐标,有了坐标,还要知道哪个点和哪个点相连,最后将各点相连即可: 但有时候我们有的往往只是 ...

  7. word2003流程图变成图片_转:Word2003  绘制流程图(2)

    转:Word2003  绘制流程图(2) (2010-07-26 21:56:28) 标签: 杂谈 制作过程中应把握以下三大规律: 1. 先难后易 流程图一般最下面的部分比较复杂,做起来困难一些,那就 ...

  8. 一文读懂:程序员为什么要学会画流程图 11种流程图的绘制工具:processon,wps,draw.io, 迅捷画图等 详细说明使用processon绘制流程图 详细说明绘制流程图

    这里写目录标题 为什么要学会画流程图 11种画流程图的工具 processon wps draw.io Zen Flowchart xGraph lucidchart boardmix plantum ...

  9. 【高效工具】《三》Typora直接使用MarkDown语法绘制流程图、时序图、甘特图

    平常使用Typora撰写内容的时候,偶尔会用到流程图,原来一直使用Word来作图,在插入到文档中,昨天偶然间了解到Typora支持使用mermaid来绘制流程图,才发现自己差点Out了.此处整理一下如 ...

最新文章

  1. 最新调查,48%的美国人表示不会乘坐自动驾驶汽车
  2. 关于Jsoup解析https网页的问题
  3. IIC软件模拟-读写EEPROM
  4. java查询线程状态命令_JAVA 线程死锁,以及linux 命令和jstack 命令 查看线程死锁状态信息...
  5. android.graphics.drawable.Drawable.Callback回调接口
  6. Redis 4.0深入持久化
  7. idea java代码格式化_IDEA java 代码格式化统一
  8. 云计算与大数据——云计算的特点
  9. ORA-00932: 数据类型不一致: 应为 CHAR, 但却获得 NUMBER
  10. DNS解析错误的问题,域名解析错误导致输入域名不访问而直接输入网站IP却可以正常访问
  11. 关于 该设备或资源(127.0.0.1)未设置为接受端口 的解决办法
  12. 干货 | 什么是ABCDE轮融资?
  13. 基于ETest的发动机ECU硬件在环测试平台的研究与开发
  14. knex.js中文文档
  15. 实验四 进程同步与通信(一)进程同步与互斥1
  16. matlab同轴电缆能量密度,导体电介质和磁介质之同轴电缆的能量密度.ppt
  17. 1月31日 解决问题的方法( 麦肯锡七步成诗法 )
  18. 《嵌入式系统原理与接口技术》——嵌入式系统接口应用基础
  19. 联发科MT7682芯片资料MT6762原理图资料
  20. JedisSentinelPool 连接 master

热门文章

  1. DYMO/Mimio推出最新互动教育软件linux操作系统培训
  2. html中图像标记的属性,HTML中的图象标签属性
  3. 基于Springboot的学生信息管理系统
  4. oracle查询dictionary,Oracle的DICTIONARY/DICT视图。
  5. 老友记第一季台词打印_老友记第一季第一集台词
  6. 启动MyEclipse时报错,An error has occurred see the log file 出现此类错误提示
  7. tms320vc5416c语言编程,TMS320VC5416与CAN总线的接口设计及软件编程
  8. 操作系统实验一到实验九合集(哈工大李治军)
  9. Hazel引擎学习(六)
  10. DBeaver(其他可视化工具一样的逻辑)连接IoTDBDriver教程