使用camunda+bpmn.js 绘制流程实例的执行高亮节点
获取高亮节点信息
public ActivitiHighLineDTO getHighlightNode(String processInsId) {
HistoricProcessInstance hisProIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInsId).singleResult();
//System.out.println(hisProIns.getProcessDefinitionName()+" "+hisProIns.getProcessDefinitionKey());
//===================已完成节点
List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInsId)
.finished()
.orderByHistoricActivityInstanceStartTime().asc()
.list();
Set<String> highPoint = new HashSet<>();
finished.forEach(t -> highPoint.add(t.getActivityId()));
//=================待完成节点
List<HistoricActivityInstance> unfinished = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInsId).unfinished().list();
Set<String> waitingToDo = new HashSet<>();
unfinished.forEach(t -> waitingToDo.add(t.getActivityId()));
//=================iDo 我执行过的
Set<String> iDo = new HashSet<>(); //存放 高亮 我的办理节点
List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery().taskAssignee(SecurityUtils.getUsername()).finished().processInstanceId(processInsId).list();
taskInstanceList.forEach(a -> iDo.add(a.getTaskDefinitionKey()));
//===========高亮线
Set<String> highLine2 = new HashSet<>(); //保存高亮的连线
//获取流程定义的bpmn模型
BpmnModelInstance bpmn = repositoryService.getBpmnModelInstance(hisProIns.getProcessDefinitionId());
//已完成任务列表 可直接使用上面写过的
List<HistoricActivityInstance> finishedList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInsId)
.finished()
.orderByHistoricActivityInstanceStartTime().asc()
.list();
int finishedNum = finishedList.size();
//循环 已完成的节点
for (int i = 0; i < finishedNum; i++) {
HistoricActivityInstance finItem = finishedList.get(i);
//根据 任务key 获取 bpmn元素
ModelElementInstance domElement = bpmn.getModelElementById(finItem.getActivityId());
//转换成 flowNode流程节点 才能获取到 输出线 和输入线
FlowNode act = (FlowNode)domElement;
Collection<SequenceFlow> outgoing = act.getOutgoing();
//循环当前节点的 向下分支
outgoing.forEach(v->{
String tarId = v.getTarget().getId();
//已完成
for (int j = 0; j < finishedNum; j++) {
//循环历史完成节点 和当前完成节点的向下分支比对
//如果当前完成任务 的结束时间 等于 下个任务的开始时间
HistoricActivityInstance setpFinish = finishedList.get(j);
String finxId = setpFinish.getActivityId();
if(tarId.equals(finxId)){
if(finItem.getEndTime().equals(setpFinish.getStartTime())){
highLine2.add(v.getId());
}
}
}
//待完成
for (int j = 0; j < unfinished.size(); j++) {
//循环待节点 和当前完成节点的向下分支比对
HistoricActivityInstance setpUnFinish = unfinished.get(j);
String finxId = setpUnFinish.getActivityId();
if(tarId.equals(finxId)){
if(finItem.getEndTime().equals(setpUnFinish.getStartTime())){
highLine2.add(v.getId());
}
}
}
});
}
//返回结果
ActivitiHighLineDTO activitiHighLineDTO =new ActivitiHighLineDTO();
activitiHighLineDTO.setHighPoint(highPoint);
activitiHighLineDTO.setHighLine(highLine2);
activitiHighLineDTO.setWaitingToDo(waitingToDo);
activitiHighLineDTO.setiDo(iDo);
return activitiHighLineDTO;
}
bpmn.js 渲染
setColor() {
if(!this.processInstanceId) return;
let canvas = this.bpmnViewer.get("canvas");
//给节点id 添加css样式
//canvas.addMarker("Activity_1jefsxq", "highlight");
line({ processInsId: this.processInstanceId }).then(
(res) => {
//高亮线
res.highLine.forEach((e) => {
if (e) {
canvas.addMarker(e, "highlightFlow");
}
});
//高亮任务
res.highPoint.forEach((e) => {
if (e) {
canvas.addMarker(e, "highlight");
}
});
//高亮我执行过的任务
res.iDo.forEach((e) => {
if (e) {
canvas.addMarker(e, "highlightIDO");
}
});
//高亮下一个任务
res.waitingToDo.forEach((e) => {
if (e) {
canvas.addMarker(e, "highlightTODO");
}
});
}
);
},
css样式
.highlight .djs-visual > :nth-child(1) {
stroke: green !important;
fill: rgba(0, 80, 0, 0.4) !important;
}
.highlightFlow .djs-visual > :nth-child(1) {
stroke: green !important;
}
.highlightIDO .djs-visual > :nth-child(1) {
stroke: rgb(255, 196, 0) !important;
fill: rgba(255, 196, 0, 0.4) !important;
}
.highlightTODO .djs-visual > :nth-child(1) {
stroke: rgb(255, 0, 0) !important;
fill: rgba(255, 255, 255, 0.4) !important;
}
最终效果如图: