cancel
Showing results for 
Search instead for 
Did you mean: 

Easy way to visualize a process instance history?

gguimezanes
Champ in-the-making
Champ in-the-making
Hello,
I would like to draw the diagram of a process instance with the history highlighted. My ideal would be to highlight past activities and flows in one color, and current activities in another colors, but just being able to highlight the whole path "from start event to current state" would already be great.
I imagine that I should use
ProcessDiagramGenerator.generateDiagram(processDefinitionEntity, "png", highLightedActivities, highLightedFlows)

-> for the historical activities, I use
historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).finished().list();
-> for the current activities , I use :
runtimeService.getActiveActivityIds(processInstanceId);
-> but I have no idea on how to find the flows that I should get highlighted (I have several flows that end up to the same task so it is not absolutely obvious from the highlighted tasks which path led to them…)

Any idea?
16 REPLIES 16

frederikherema1
Star Contributor
Star Contributor
You could try to trace back, based on the activity-id's in the historic-activity instance and their respective start/end-time AND using the BPMN2.0 Pojo-model to figure out what sequence-flow was taken. When quick activiti-bursts are present (eg. gateway with some service-taks-that have the same start-end time, you can revert to the ID (which by default is numeric-incremental) to know which one came first.

iam
Champ in-the-making
Champ in-the-making
Hi!

Declare variables for passing thru methods

private List<String> historicActivityInstanceList = new ArrayList<String>();
private List<String> highLightedFlows = new ArrayList<String>();

What you need here is processDefinition and processInstanceId

List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstanceId);

And here you need in activiti-services
private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition,
String processInstanceId) {

List<HistoricActivityInstance> historicActivityInstances = historyService.
  createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).
  orderByHistoricActivityInstanceStartTime().asc().list();

for (HistoricActivityInstance hai : historicActivityInstances) {
  historicActivityInstanceList.add(hai.getActivityId());
}

// add current activities to list
List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
historicActivityInstanceList.addAll(highLightedActivities);

// activities and their sequence-flows
getHighLightedFlows(processDefinition.getActivities());

return highLightedFlows;
}

private void getHighLightedFlows (List<ActivityImpl> activityList) {
for (ActivityImpl activity : activityList) {
    if (activity.getProperty("type").equals("subProcess")) {
     // get flows for the subProcess
     getHighLightedFlows(activity.getActivities());
    }
  
    if (historicActivityInstanceList.contains(activity.getId())) {
     List<PvmTransition> pvmTransitionList = activity.getOutgoingTransitions();
     for (PvmTransition pvmTransition: pvmTransitionList) {
      String destinationFlowId = pvmTransition.getDestination().getId();
      if (historicActivityInstanceList.contains(destinationFlowId)) {
       highLightedFlows.add(pvmTransition.getId());
      }
     }
    }
  }
}

gguimezanes
Champ in-the-making
Champ in-the-making
Thanks for your answers.
They seem to mean I do have to recompute the flows from the activities, which is not what I intended to do as there are several paths that lead to the same activity… Perhaps I'd better place execution listeners on the sequenceFlows so as to register each flow taken…

iam
Champ in-the-making
Champ in-the-making
to register each flow taken…
Do you want to register and then store it on runtime? Or do you want to create additional table to store registered sequence flows?
Without that table it looks like storing in memory on runtime. And what about completed(ended) process instances?
The really easy way to visualize it is to parse outgoing transitions of the activities I think.

gguimezanes
Champ in-the-making
Champ in-the-making
Imagine I have one specific task, called check, to which I can go to from a all activities in my process according to conditional flows. Then I look at my history and see that I did task1, task2 and check. Now how do I know if I should highlight the flow from task1 to check or the flow from task2 to check?
Ok, it might sound obvious that I should look at the times of execution too, but with a complicated process that has tasks taking place in parallel and so on, it can become quite complicated.
That's why I wondered if there was a history of the sequenceFlows the same way as there is a history of executions. And if there's not, my idea to use listeners actually was to populate a custom history table for flows…

debarcar
Champ in-the-making
Champ in-the-making
How to get the BPMN2.0 Pojo-model? Any code sample?

Regards!

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi,

Here is one example how to do it :

You could find answer in the 5.15-SNAPSHOT jUnit test.
Regards
Martin


Hi Martin,

The latest activiti-crystalball maven build does not have the same code as the 5.15-SNAPSHOT JUnit link.  Do you know where it got moved to now that we are in the 5.19.x version?  Did it go to a different maven artifact/jar?

Jason

debarcar
Champ in-the-making
Champ in-the-making
I found what I want:

ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processInstance
    .getProcessDefinitionId());

and the repositoryService query processDefinition  will return empty tasks.

Regards!