使用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;
}
最終效果如圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0EkeNBTWq5UMNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5EDO1AzNwATMyAjMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)