当前位置: 首页 > article >正文

Springboot +Flowable,通过代码绘制流程图并设置高亮

一.简介

通过代码绘制一张流程图,并设置成高亮。

首先先来看一下绘制出来的效果图,截图如下:
在这里插入图片描述

已经执行的节点和连线用红色标记出来,大致上就是这么一个效果。

二.怎么实现

将一个流程图绘制成图片,相关的 API 在 flowable 中其实都是有提供的,流程图片的绘制,是根据流程的定义来绘制的,所以只需要提供一个流程定义的 ID 即可,代码如下:

ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("ExclusiveGatewayDemo01").latestVersion().singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
InputStream inputStream = generator.generatePngDiagram(bpmnModel, 1.0, true);
FileUtils.copyInputStreamToFile(inputStream, new File("/Users/hx/Downloads/test.png"));

来看下这段代码的释义:

  1. 查找到流程定义对象。
  2. 根据流程定义对象,获取到一个 BpmnModel 对象。
  3. 创建一个图片生成器对象 DefaultProcessDiagramGenerator。
  4. 调用 generatePngDiagram 方法生成这个流程定义所对应的图片,参数有三个,分别是:前面查询到的 bpmnModel 对象;缩放因子以及是否在绘制流程图的时候,在连线上加上描述文字,generatePngDiagram 方法的返回值则是一个输入流。
  5. 将这个输入流打印出来,就是一张图片了。

根据上面这段代码,执行结果如下:
在这里插入图片描述
可以看到,这就是普通的流程图,没有高亮。
如果希望已经执行的节点变成高亮的,那么可以使用如下方法:

在这里插入图片描述来看下这段代码的释义:

  1. 流程的 bpmnModel 对象。
  2. 生成的图片类型。
  3. 高亮的活动节点。
  4. 高亮的连线。
  5. 缩放因子。
  6. 是否在绘制连线的时候添加文字描述。

这里的关键就是第三个和第四个参数。这个流程图中哪些节点哪些连线需要高亮,我们将之列出来即可。

三.扩展

根据之前文章中的介绍,一个流程在执行过程中的活动信息,都是保存在 ACT_RU_ACTINST 表中,所以只需要根据流程实例的 ID 在ACT_RU_ACTINST 表中查询到即可,代码如下:

@Test
void test01() throws IOException {
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("ExclusiveGatewayDemo01").latestVersion().singleResult();
    BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
    ProcessInstance pi = runtimeService.createProcessInstanceQuery().singleResult();
    List<String> highLightedActivities = new ArrayList<>();
    List<String> hightLightedFlows = new ArrayList<>();
    double scaleFactor = 1.0;
    boolean drawSqquenceFlowNameWithNoLabelDI = true;
    if (pi == null) {
        return;
    }
    List<ActivityInstance> list = runtimeService.createActivityInstanceQuery().list();
    for (ActivityInstance ai : list) {
        if (ai.getActivityType().equals("sequenceFlow")) {
            hightLightedFlows.add(ai.getActivityId());
        } else {
            highLightedActivities.add(ai.getActivityId());
        }
    }
    DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
    InputStream inputStream = generator.generateDiagram(bpmnModel, "PNG", highLightedActivities, hightLightedFlows, scaleFactor, drawSqquenceFlowNameWithNoLabelDI);
    FileUtils.copyInputStreamToFile(inputStream, new File("/Users/sang/Downloads/1.png"));
}

这里使用 highLightedActivitieshightLightedFlows 两个集合,分别存一个流程已经执行的活动 ID 和连线的 ID。

通过 runtimeService.createActivityInstanceQuery().list(); 来查询到所有已经执行的活动,然后遍历,遍历的时候注意区分是不是 sequenceFlow,如果是 sequenceFlow 则将之添加到 hightLightedFlows 集合中,否则将之添加到 highLightedActivities 结合中。

最终,执行生成的图片就是本文最开始大家看到的图片。
在这里插入图片描述

但是呢。按照上面这种方式,对于一个已经执行完毕的流程来说,就画不出来流程图了,因为当一个流程执行完毕之后,ACT_RU_ACTINST 表中的数据就会自动清空。

不过根据前面文章的介绍,执行完毕的活动信息还可以去 ACT_HI_ACTINST 表中进行查询,因此,这个流程图还可以这样画,代码如下:

@Test
void test05() throws IOException {
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("ExclusiveGatewayDemo01").latestVersion().singleResult();
    BpmnModel bpmnModel = repositoryService.getBpmnModel(pd.getId());
    HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().singleResult();
    if (hpi == null) {
        return;
    }
    List<String> highLightedActivities = new ArrayList<>();
    List<String> hightLightedFlows = new ArrayList<>();
    double scaleFactor = 1.0;
    boolean drawSqquenceFlowNameWithNoLabelDI = true;
    List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(hpi.getId()).list();
    for (HistoricActivityInstance hai : list) {
        if (hai.getActivityType().equals("sequenceFlow")) {
            hightLightedFlows.add(hai.getActivityId());
        } else {
            highLightedActivities.add(hai.getActivityId());
        }
    }
    DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
    InputStream inputStream = generator.generateDiagram(bpmnModel, "PNG", highLightedActivities, hightLightedFlows, scaleFactor, drawSqquenceFlowNameWithNoLabelDI);
    FileUtils.copyInputStreamToFile(inputStream, new File("/Users/sang/Downloads/1.png"));
}

可以看到,当一个流程实例执行完毕的时候,我们可以去历史表中查询这个流程实例,同时也去历史表中查询这个流程实例所执行过的活动 ID,找到之后,还是按照之前的办法,填充给 hightLightedFlowshighLightedActivities 两个变量。最终绘制出来的流程图如下图:
在这里插入图片描述

《肖申克的救赎》

生命可以归结为一种简单的选择:要么忙于生存,要么赶着去死。

懦怯囚禁人的灵魂,希望可以感受自由。强者自救,圣者渡人。

希望是件美丽的东西,也许是最好的东西。美好的东西是永远不会死的。

每个人都是自己的上帝。如果你自己都放弃自己了,还有谁会救你?

《熔炉》

我们一路奋战,不是为了能改变世界,而是为了不让世界改变我们。

现实如水母,看似美好无害实质总是致命伤人。

我们来到世界上,都是孤独的旅行,即使身边有人相伴,最终也会各奔东西!

世界上最美丽最珍贵的,反而是听不见且看不清的,只有用心才能感受得到。

《教父》

人可以不断犯错,但绝不能犯要命的错。

不要憎恨你的敌人,那会影响你的判断力。

人并非生来就伟大,而是越活越伟大。

《活着》

人是为了活着本身而活着,而不是为了活着之外的任何事物而活着。

以笑的方式哭,在死亡的伴随下活着。

没有什么比时间更具有说服力了,因为时间无需通知我们就可以改变一切。

你的命是爹娘给的,你不要命了也得先去问问他们。

《我不是药神》

世界上只有一种病,穷病,这种病你没法治,你也治不过来。

人间最高贵的是善良,是对生命的致敬。

《指环王》

把手握紧,里面什么也没有;把手放开,你得到的是一切。

我宁愿和你共度凡人短暂的一生,也不愿一个人看尽这世界的沧海桑田。

20.幸福的家庭都是相似的,不幸的家庭各有各的不幸。

或许有一天,人类变得萎缩懦弱,舍弃朋友,断绝友谊,但今天决不会这样。
《饮食男女》

22.人生不能像做菜,把所有的材料都准备好了才下锅。

什么叫做“可惜”啊,要心中有个“惜”字儿,才知道可惜。

其实一家人,住在一个屋檐下,照样可以各过各的日子,可是从心里产生的那种顾忌,才是一个家之所以为家的意义。

《让子弹飞》

世界上本没有路,有了腿便有了路。

如果你活着,早晚都会死;如果你死了,你就永远活着。

赚钱嘛,不寒碜


http://www.kler.cn/a/14979.html

相关文章:

  • 车联网OTA安全实践
  • 2023年全国最新保安员精选真题及答案62
  • 计算机专业VB系统,有论文,源代码
  • 【Linux常见指令以及权限理解】基本指令(2)
  • Python自动化测试框架之unittest使用详解
  • 如何使用python网络爬虫批量获取公共资源数据
  • 用梯度下降的方式来拟合曲线
  • 使用virsh远程连接主机遇到的问题
  • Java版本+企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势
  • 矢量、栅格、瓦片地图傻傻分不清
  • 封装了一个echarts图全屏放大的功能
  • NetApp ONTAP: 企业级数据管理软件,为无缝混合云奠定基础
  • 大学生用什么蓝牙耳机好?2023好用的蓝牙耳机推荐
  • 单片机常见问题分析调试办法
  • 前后端分离常见跨域问题及解决方法
  • 论文阅读:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
  • 毕业四年换了3份软件测试工作,我为何仍焦虑?
  • CVE漏洞复现-CVE-2016-10033-远程命令执行
  • Scala中使用Typesafe Config 库
  • Java 中的多态是什么,如何实现多态?(六)