天天看點

camunda 流程圖高亮

使用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;
}
           

最終效果如圖:

camunda 流程圖高亮