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

Flowable实战:自定义流程图生成器与高亮渲染进阶

1. 为什么需要自定义流程图生成器

在业务系统开发中,流程图的可视化展示往往需要满足特定的业务需求。比如在审批流程监控场景中,我们可能需要用不同颜色区分"已审批"、"当前处理中"和"被驳回"的节点;在运维流程中,可能需要用特殊图标标记存在风险的环节。Flowable自带的流程图生成器虽然功能完善,但在这些定制化需求面前就显得力不从心了。

我去年参与开发的一个电商风控系统就遇到了这个问题。系统需要实时展示订单审核流程,但默认的流程图生成器只能简单高亮当前节点,无法直观展示各个审核环节的状态(如"初审通过"、"复审拒绝"等)。这给运营人员带来了很大困扰,经常需要反复点击查看每个节点的详情。

2. 核心定制化方案

2.1 继承DefaultProcessDiagramCanvas

Flowable的图形渲染最终都是由DefaultProcessDiagramCanvas完成的。要自定义渲染效果,首先需要继承这个类:

public class CustomProcessDiagramCanvas extends DefaultProcessDiagramCanvas { // 自定义高亮当前活动节点的方法 public void drawActiveHighLight(int x, int y, int width, int height) { // 使用绿色填充当前节点 this.drawHighLight(x, y, width, height, Color.GREEN); } // 自定义挂起节点渲染 public void drawSuspendedActivity(int x, int y, int width, int height) { // 使用黄色填充并添加斜线标记 this.drawHighLight(x, y, width, height, Color.YELLOW); this.drawLine(x, y, x+width, y+height, Color.RED); } }

这里我添加了两个典型场景的渲染方法:

  • drawActiveHighLight用绿色填充当前正在处理的节点
  • drawSuspendedActivity用黄色标记被挂起的节点,并添加红色斜线

2.2 重写DefaultProcessDiagramGenerator

有了自定义的画布后,还需要重写生成器来控制何时使用这些特殊渲染:

public class CustomProcessDiagramGenerator extends DefaultProcessDiagramGenerator { @Override protected void drawActivity(ProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode, List<String> highLightedActivities) { // 先调用父类方法绘制基础图形 super.drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities); // 自定义渲染逻辑 if (highLightedActivities.contains(flowNode.getId())) { GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); // 判断节点状态并调用对应的渲染方法 if(isSuspended(flowNode.getId())) { ((CustomProcessDiagramCanvas)processDiagramCanvas) .drawSuspendedActivity((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight()); } else if(isActive(flowNode.getId())) { ((CustomProcessDiagramCanvas)processDiagramCanvas) .drawActiveHighLight((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight()); } } } }

3. 完整实现案例

3.1 后端控制器实现

在Spring Boot中,我们可以这样暴露流程图生成接口:

@GetMapping("/process/diagram") public void generateDiagram(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException { // 获取流程定义和实例信息 ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult(); // 收集高亮节点 List<String> highLightedActivities = new ArrayList<>(); List<String> highLightedFlows = new ArrayList<>(); // 查询历史活动记录 List<HistoricActivityInstance> activities = historyService .createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId) .list(); // 区分节点类型 for (HistoricActivityInstance activity : activities) { if ("sequenceFlow".equals(activity.getActivityType())) { highLightedFlows.add(activity.getActivityId()); } else { highLightedActivities.add(activity.getActivityId()); } } // 使用自定义生成器 BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); ProcessDiagramGenerator generator = new CustomProcessDiagramGenerator(); try (InputStream is = generator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows, "宋体", "宋体", "宋体", 1.0, true); OutputStream os = response.getOutputStream()) { // 将图像写入响应流 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } } }

3.2 前端交互增强

为了让流程图更具交互性,可以在前端添加鼠标悬停显示节点详情的功能:

// 假设流程图以<img>标签展示 $('#processDiagram').on('mousemove', function(e) { const x = e.offsetX; const y = e.offsetY; // 遍历所有节点信息 nodes.forEach(node => { if (x > node.x && x < node.x + node.width && y > node.y && y < node.y + node.height) { // 显示节点详情弹窗 showNodeTooltip(node, x, y); } }); }); function showNodeTooltip(node, x, y) { // 动态创建tooltip元素 const tooltip = $('<div class="node-tooltip"></div>') .html(` <h4>${node.name}</h4> <p>状态: ${node.status}</p> <p>处理人: ${node.assignee}</p> <p>耗时: ${node.duration}</p> `) .css({ position: 'absolute', left: x + 'px', top: y + 'px' }); $('#diagramContainer').append(tooltip); }

4. 进阶优化技巧

4.1 性能优化方案

当流程实例很多时,频繁生成流程图可能导致性能问题。我们可以采用以下优化策略:

  1. 缓存机制:对已生成的流程图进行缓存
@Cacheable(value = "processDiagrams", key = "#processInstanceId + '_' + #highlightType") public byte[] generateDiagram(String processInstanceId, String highlightType) { // 生成逻辑 }
  1. 异步生成:使用Spring的@Async实现异步生成
@Async public Future<byte[]> asyncGenerateDiagram(String processInstanceId) { // 生成逻辑 return new AsyncResult<>(diagramBytes); }
  1. 预生成策略:在流程关键节点触发预生成

4.2 动态样式配置

为了更灵活地控制渲染样式,可以引入样式配置:

# application.yml flowable: diagram: colors: active: "#4CAF50" suspended: "#FFC107" completed: "#9E9E9E" fonts: default: "Microsoft YaHei" label: "Microsoft YaHei, 12px"

然后在生成器中使用这些配置:

@Value("${flowable.diagram.colors.active}") private String activeColor; protected void drawActiveNode(ProcessDiagramCanvas canvas, GraphicInfo graphicInfo) { Color color = Color.decode(activeColor); // 使用配置的颜色进行绘制 }

5. 常见问题排查

在实际项目中,可能会遇到以下典型问题:

  1. 中文乱码问题
  • 确保系统安装了中文字体
  • 在生成器配置中明确指定中文字体
generateDiagram(bpmnModel, "png", activities, flows, "Microsoft YaHei", "Microsoft YaHei", "Microsoft YaHei", 1.0, true);
  1. 节点坐标偏移
  • 检查BPMN文件中是否正确定义了graphicInfo
  • 确保没有在自定义渲染时错误修改了坐标计算
  1. 渲染性能低下
  • 避免在draw方法中执行复杂计算
  • 考虑使用缓冲图像技术
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); // 绘制操作 g2d.dispose();
  1. 高亮效果不明显
  • 增加边框宽度
  • 使用更醒目的颜色组合
  • 添加动画效果(前端实现)

通过继承Flowable的核心渲染类,我们可以实现高度定制化的流程图展示效果。这种方案不仅能够满足各种业务场景的可视化需求,还能保持与Flowable引擎的无缝集成。在实际项目中,建议先明确业务对流程图的具体要求,再针对性地设计渲染方案,避免过度设计。

http://www.jsqmd.com/news/1190930/

相关文章:

  • AI镜像站实用测试指南:从功能验证到稳定落地
  • MPC轨迹跟踪算法:从双移线仿真到工程实践的关键调试与验证
  • AI求职系统:从简历生成到数据驱动的求职流程优化
  • 贪心算法实战:多机调度问题的核心策略与性能评估
  • C++物联网网关交互协议设计:从ctGateway看异步IO与插件化架构
  • 汇编语言实验进阶:从DOS功能调用到交互式密码验证程序的设计与实现
  • 从裸机到事件驱动:QP框架如何重塑单片机编程思维
  • 工业级遗传算法实战:解决局部最优与约束失效的工程方案
  • 开源组件攻击激增650%,Gitee CodePecker SCA如何用三道防线守住软件供应链
  • 多类别逻辑回归:OvR与Multinomial原理、选型与实操避坑指南
  • 2026年池州酒店推拉移门供应商实力盘点选购指南 - 热点品牌推荐
  • Medium文章精准转Markdown:DOM语义提取实战指南
  • # 串行输出与并行输出详解:原理、时序、优缺点及应用场景
  • OpenRefine数据清洗:从入门到精通,解锁高效数据预处理
  • 中国大模型API调用量超美国6倍:成本优势与开发实战指南
  • 从TTL到LVDS:逻辑电平的演进与选型实战指南
  • 一个月系统掌握AI开发:从PyTorch入门到项目实战
  • 5.实战案例 基于74LS148与74LS138的病房呼叫系统设计与Multisim仿真
  • KKManager终极指南:如何快速成为Illusion游戏模组管理专家?
  • AI炒股实战指南:从信息处理到风险控制的完整使用流程
  • 基于STM32的智能风扇多模态交互系统设计
  • Medium文章流行度评估:为什么没有单一最佳指标
  • 深入解析uni-app软键盘模式:从adjustPan到adjustResize的适配策略
  • 小程序图片上传进阶:从基础API到企业级封装实践
  • DRA7xx处理器DPI与GPMC接口时序配置实战指南
  • 沃锐智能:常州市全自动打包机选型与可靠性评估方案,常州市全自动打包机推荐 - 品牌推荐师
  • 微信小程序开发核心概念与实战应用解析
  • MetaMask 进阶功能与安全实践指南
  • 大模型三层路由降本方案:60%成本优化与工程实践
  • Python测试框架pytest入门:从基础概念到实战应用