activiti5.17.0流程图及节点显示

2023-11-15

引用:activiti流程图上获取各节点的信息获取

这篇文章写得很好,揭示了图片点击出现信息的方法,于是我也做了,只不过有些改动,可能是activiti的版本不同的原因。

jsp页面,通过流程实例id进行操作

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ include file="/pages/common/common-js.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
        <title>Insert title here</title>  
        <style type="text/css">  
            .activity-attr{border-radius: 10px; border: 3px solid red; transition:ease-out 0.5s; box-shadow:0px 0px 9px red;}  
            #processKey{color: red;}  
            #flowImageAndRect{position: relative;overflow: scroll;height:300px; heibackground-image: url('grid_10.png')}  
            body,html{margin: 0px;padding:0px;}  
        </style>  
        <script type="text/javascript">  
            var baseURL = "<%=rootPath%>/pages/WorkTaskCon/";
            $(function(){  debugger;
                var pid = '${flowKey}'; // 流程定义的key  
                var $flowImageAndRect = $('#flowImageAndRect');  
                $('#processKey').html('流程定义的key --> ' + pid);  
                // 加载流程图片  
                loadProcessImage(pid,$flowImageAndRect);  
                // 加载各节点信息,最终实现,在点击图片上的各节点时,出现高亮  
                setTimeout(function(){  
                    loadProcessTrace(pid,$flowImageAndRect);  
                },200);  
                  
                var $revClickRect = null; // 上次点击的图形  
                // 绑定click事件,点击实现,只有点击的不是同一个时,才显示红色的边框(如果多次点击同一个,红色的边框只出现一次)  
                $('#flowImageAndRect').off('click').on('click','.activity-attr',function(e){  
                    var $this = $(this);  
                    var prevFlag = false; // 是上一个图形,避免多次点击同一个  
                    if($revClickRect){ // 说明不是第一次点击  
                        prevFlag = ($revClickRect.attr('actId')!=$this.attr('actId')) ? false : true;// 说明2次点击的不是同一个  
                        if(!prevFlag)  
                            $revClickRect.css('opacity','0');  
                    }  
                    if(!prevFlag){ // 此处可以请求后台,加载相关的数据(多次点击同一个,下方可确保只执行一次)  
                        $this.css('opacity','1'); // 显示当前的  
                        $revClickRect = $this; // 将当前设置为上次点击的  
                        $('#info').html('节点ID --> ' + $this.attr('actId') + "  |  " + "节点名称 --> " + $this.attr('name'));  
                    }  
                });  
            });  
               
            /** 
             * 加载图片 
             */  
            function loadProcessImage(pid,$flowImageAndRect){   debugger;
                var imageUrl =baseURL+ 'readResource.htm?pid=' + pid;  
                // 加载图片  
                $('<img />',{  
                    "src" : imageUrl,  
                    "alt" : ''  
                }).appendTo($flowImageAndRect);   
            }  
              
            /** 
             * 加载流程中各节点的信息  
             * @param pid : 流程定义的key 
             * @param $flowImageAndRect  
             */  
            function loadProcessTrace(pid,$flowImageAndRect){   debugger;
                var traceUrl = baseURL+'getProcessTrace.htm?pid='+pid;  
                $.getJSON(traceUrl,function(infos){  
                    var html = "";  
                    $.each(infos,function(i,v){  
                        // 矩形的div  
                        var $div = $('<div/>', {  
                                'class': 'activity-attr'  
                        }).css({  
                            position: 'absolute',  
                            left: v.x,  
                            top: v.y,  
                            width: v.width - 3,  
                            height:v.height - 3,  
                            opacity: 0,  
                            zIndex: 100,  
                   			cursor : 'pointer'  
                        }).attr({'actId':v.actId,'name':v.name});  
                        html += $div.prop("outerHTML");  
                    });  
                    $('<div />',{'id':'processRect'}).html(html).appendTo($flowImageAndRect);  
                });  
            }  
        </script>  
    </head>  
    <body>  
        <div id="main">  
            <div id="flowImageAndRect">  
                  
            </div>  
              
            <div id="processKey" style="font-size: 12px;text-align: center;margin-bottom: 50px;">  
              
            </div>  
              
            <div id="info" style="font-size: 12px;text-align: center;">  
                  
            </div>  
        </div>  
    </body>  
</html>  
java代码,通过反射调用源码中的节点x、y以及信息

 /** 
    * 根据流程的key生成图片 
    *  
    * @param request 
    * @param response 
    * @param wfKey 流程定义的key 
    */  
    @RequestMapping(value="readResource.htm")
	public void readResource(HttpServletRequest request,HttpServletResponse response) {  
		try {
			IMap params = new IMap(request);
			String processDefinitionId = ProcessEngines.getDefaultProcessEngine().getHistoryService()
					.createHistoricProcessInstanceQuery()
					.processInstanceId(params.getString("pid")).singleResult()
					.getProcessDefinitionId();
			RepositoryService repositoryService =  ProcessEngines.getDefaultProcessEngine().getRepositoryService();  
			ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
					.getDeployedProcessDefinition(processDefinitionId);
			
			InputStream imageStream = iActivitiUtilSvc.getFlowImageByKey(processDefinition.getKey());

			// 输出资源内容到相应对象
			byte[] b = new byte[1024];
			int len;
			while ((len = imageStream.read(b, 0, 1024)) != -1) {
				response.getOutputStream().write(b, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    /** 
     * 获取各个节点的具体的信息 
     * @param wfKey 
     *      流程定义的key 
     * @return 
     */  
    @RequestMapping("getProcessTrace.htm")  
    @ResponseBody  
    public List<Map<String, Object>> getProcessTrace(String pid) throws Exception {  
        List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();  
        String processDefinitionId = ProcessEngines.getDefaultProcessEngine().getHistoryService()
				.createHistoricProcessInstanceQuery()
				.processInstanceId(pid).singleResult()
				.getProcessDefinitionId();
        RepositoryService repositoryService =  ProcessEngines.getDefaultProcessEngine().getRepositoryService();  
		ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
				.getDeployedProcessDefinition(processDefinitionId);
        List<ActivityImpl> activitiList = processDefinition.getActivities();  
        InputStream xmlIs = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());  
        BpmnModel bm = new BpmnXMLConverter().convertToBpmnModel(new InputStreamSource(xmlIs), false, true);  
        // 下方使用反射获取最小的x和y,仔细看就会发现调用的是上方2.1节的方法 
        Class<?> clazz = Class.forName("org.activiti.image.impl.DefaultProcessDiagramGenerator");  
        Method method = clazz.getDeclaredMethod("initProcessDiagramCanvas", BpmnModel.class, String.class,
        	      String.class, String.class, ClassLoader.class);  
        method.setAccessible(true);   
        DefaultProcessDiagramCanvas pdc = (DefaultProcessDiagramCanvas) method.invoke(clazz.newInstance(), bm,"png", "宋体", "宋体",  null); // 调用方法  
  
        clazz = Class.forName("org.activiti.image.impl.DefaultProcessDiagramCanvas");  
        Field minXField = clazz.getDeclaredField("minX"); // 得到minX字段  
        Field minYField = clazz.getDeclaredField("minY");  
        minXField.setAccessible(true);  
        minYField.setAccessible(true);  
        int minX = minXField.getInt(pdc);// 最小的x值    
        int minY = minYField.getInt(pdc); // 最小的y的值  
  

        minX = minX > 0 ? minX - 5 : 0;   // 此处为什么需要减5,上方2.2中activiti源码中有</span>  
        minY = minY > 0 ? minY - 5 : 0;  
        for (ActivityImpl activity : activitiList) {  
            Map<String, Object> activityInfo = new HashMap<String, Object>();  
            activityInfo.put("width", activity.getWidth());  
            activityInfo.put("height", activity.getHeight());  
            activityInfo.put("x", activity.getX() - minX);  
            activityInfo.put("y", activity.getY() - minY);  
            activityInfo.put("actId", activity.getId());  
            activityInfo.put("name", activity.getProperty("name")); // </strong>ActivityImpl 中没有getName方法,所以此处需要这样获取。</span>  
            activityInfos.add(activityInfo);  
        }  
       
        
        return activityInfos;  
    }  

public InputStream getFlowImageByKey(String flowKey){
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(flowKey).latestVersion()
				.singleResult();
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
		// 不使用spring请使用下面的两行代码
		ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines.getDefaultProcessEngine();
		Context.setProcessEngineConfiguration(defaultProcessEngine.getProcessEngineConfiguration());

		// 使用spring注入引擎请使用下面的这行代码
		// Context.setProcessEngineConfiguration(processEngine.getProcessEngineConfiguration());
		ProcessDiagramGenerator a = defaultProcessEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
		return a.generateDiagram(bpmnModel, "png", "宋体", "宋体", null, 1.0);
	}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

activiti5.17.0流程图及节点显示 的相关文章

随机推荐

  • QT--emit

    本文为学习记录 若有错误 请联系作者 谦虚受教 文章目录 前言 一 emit 二 相关代码 1 h文件 2 cpp文件 总结 前言 要努力 但是不要急 繁花锦簇 硕果累累都需要过程 一 emit emit是不同窗口 类间的触发信号 当对象改
  • 主线科技拿下数亿元新融资,自动驾驶卡车迎来拐点

    自图森未来敲响了自动驾驶公司上市的第一钟后 自动驾驶卡车赛道似乎迎来了非常不错的拐点 一批科技公司在产品落地 商业模式上也形成了独特的竞争优势 比如主线科技 其不仅率先实现了超百台港口无人驾驶集卡的交付 港口无人驾驶 去安全员 的常态化运营
  • 想用好虚幻4引擎做游戏,你需要避免这些扰人的坑(备忘)

    在手游品质越发上扬的如今 已经有不少厂商开始使用一些性能更好的引擎 去尝试游戏制作了 而虚幻4引擎 以下简称UE4 就是其中之一 在这款引擎中已经诞生了诸如 铁拳7 地狱之刃 帕拉贡 等一系列大作 对玩家而言 这些作品都是不折不扣的视觉盛宴
  • gitlab修改密码后无法pull的解决方法

    在登录gitlab的时候发现密码忘记了 在重新设置了密码之后 git无法pull代码 需要改windows下的凭据管理器中对应gitlab地址的凭据密码 把密码修改成你的新密码 个人建的交流群1125844267 欢迎大家加入 如果内容对大
  • OpenGL文字渲染的实例(C/C++)

    OpenGL文字渲染的实例 C C 在计算机图形学中 文字渲染是一个常见的任务 它涉及将字符或文本字符串呈现在屏幕上 OpenGL是一个广泛使用的图形库 它提供了强大的功能来渲染2D和3D图形 并且也支持文字渲染 本文将介绍如何使用Open
  • springboot 没有找到service_Spring Boot 应用程序五种部署方式

    翻译自 Deploying Spring Boot Applications 1 原作者 Murat Artim 2 可以使用各种方法将 Spring Boot 应用程序部署到生产系统中 在本文中 我们将通过以下 5 种方法来部署 Spri
  • 卡尔曼滤波之线性滤波,标量滤波

    卡尔曼滤波器由一系列递归数学公式描述 它们提供了一种高效可 计算的方法来估计过程的状态 并使估计均方误差最小 卡尔曼滤波 器应用广泛且功能强大 它可以估计信号的过去和当前状态 甚至能 估计将来的状态 即使并不知道模型的确切性质 对于Kalm
  • JAVA 快速排序算法(详细实现过程介绍)

    快速排序采用了一种分治的策略 通常称其为分治法 Divide and ConquerMethod 空间复杂度 快速排序是一种原地排序 只需要一个很小的栈作为辅助空间 空间复杂度为O log2n 所以适合在数据集比较大的时候使用 时间复杂度
  • 右腿驱动电路

    转自 http www 360doc com content 18 0312 15 1751130 736374982 shtml 1 使用目的 人和外界环境 尤其是电力线会形成容性耦合 这个耦合到的能量通过人体流入大地 而人体是带电阻的
  • 最全的目标检测与跟踪发展文献综述

    实时目标检测技术作为计算机视觉领域的重要研究方向之一 他在军事侦察 视频监控 智能战斗等领域有着重要的应用场景 随着深度学习的发展和硬件水平的提升 各种深度学习的算法对于航空影响的自动化起到了巨大的推动作用 基于深度神经网络的视觉算法通过自
  • 装饰者模式---装饰者模式和桥接模式的区别

    装饰者模式 什么是装饰者模式 动态将职责附加到对象上 若要扩展功能 装饰者提供了比继承更具弹性的代替方案 装饰者模式又称为包装模式 它主要是为了扩展对象的功能 包装类通过持有对象的引用 将对象传到包装类里面 聚合 把对象包装起来 可以在调用
  • 【数学建模】灰度预测之关联度求解

    灰度预测适用范围 在实际中 若得到的是离散的 规律性不强的数据 此时线性回归就不适用了 我们需要采用灰度预测的方法 灰度预测法则是一种对含有不确定因素的系统进行预测的方法 白色系统 黑色系统 灰色系统 白色系统 指一个系统的内部特征是完全已
  • TP6关于hasOne的用法

    TP6关于hasOne的用法 实际操作中看如下案例 文章分类表 CREATE TABLE case category id bigint 20 unsigned NOT NULL AUTO INCREMENT COMMENT 主键id na
  • GO语言网络编程(并发编程)Channel

    GO语言网络编程 并发编程 Channel 1 Channel 1 1 1 Channel 单纯地将函数并发执行是没有意义的 函数与函数间需要交换数据才能体现并发执行函数的意义 虽然可以使用共享内存进行数据交换 但是共享内存在不同的goro
  • hmcl启动器安装游戏版本失败_有关HMCL的个人粗糙介绍

    简单介绍关于HMCL Hello Minecraft Launcher 受欢迎的 Minecraft 启动器的使用 github https github com huanghongxun HMCL releases 1 使用前的一些调试
  • 「问题记录|VirtualBox」OSX系统启动就异常退出的问题

    背景说明 需要一个OSX系统进行软件打包 原本想在docker中进行 奈何电脑配置不够格 所以还是回归VirtualBox的怀抱 这里记录一个小操作 问题描述 虚拟机启动后加载完毕后闪退 快到甚至有可能没看到窗口 然后就看到侧边列表的虚拟机
  • Python USB通讯

    1 下载libusb 地址 Releases libusb libusb GitHub 下载7z压缩包文件到本地 解压后将32位版本的dll文件拷贝到C Windows System32 64位的dll文件拷贝到C Windows SysW
  • pytorch中的二分类及多分类交叉熵损失函数

    本文主要记录一下pytorch里面的二分类及多分类交叉熵损失函数的使用 import torch import torch nn as nn import torch nn functional as F torch manual seed
  • bin目录下存放的是什么文件?

    bin文件夹通常里面都是什么文件 经常使用电脑系统安装程序的朋友可能会发现 很多软件在安装后都会产生一个bin文件夹 那么bin文件夹是什么 里面大多放着什么文件呢 下面我们来学习一下 避免一些错误的认知导致程序损坏等误操作 软件的安装后文
  • activiti5.17.0流程图及节点显示

    引用 activiti流程图上获取各节点的信息获取 这篇文章写得很好 揭示了图片点击出现信息的方法 于是我也做了 只不过有些改动 可能是activiti的版本不同的原因 jsp页面 通过流程实例id进行操作