`
┿┅мīSS
  • 浏览: 95160 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Activiti 5.6 流程实例图实现历史节点高亮

 
阅读更多

我们先来看效果图,高亮的红色部分代表正在处理中的任务,已经完成的任务我用高亮的绿色来表示:

 

Activiti提供了画流程图的实现,当我们部署一个流程文件的时候,相应的流程图就会自动部署到数据库里面。我们可以通过Activiti 提供的 API检索出来。

 

翻阅Activiti的source code,我们看到在org.activiti.engine.impl.bpmn.deployer.BpmnDeployer的deploy() 方法有那么一段:

 

 ............
 for (ProcessDefinitionEntity processDefinition: bpmnParse.getProcessDefinitions()) {
          processDefinition.setResourceName(resourceName);
          
          String diagramResourceName = getDiagramResourceForProcess(resourceName, processDefinition.getKey(), resources);
          if (diagramResourceName==null && processDefinition.isGraphicalNotationDefined()) {
            try {
              byte[] diagramBytes = IoUtil.readInputStream(ProcessDiagramGenerator.generatePngDiagram(processDefinition), null);
              diagramResourceName = getProcessImageResourceName(resourceName, processDefinition.getKey(), "png");
              createResource(diagramResourceName, diagramBytes, deployment);
            } catch (Exception e) { // if anything goes wrong, we don't store the image (the process will still be executable).
              LOG.log(Level.WARNING, "Error while generating process diagram, image will not be stored in repository", e);
            }
          } 
.........
 

 

 byte[] diagramBytes = IoUtil.readInputStream(ProcessDiagramGenerator.generatePngDiagram(processDefinition), null); 表明了当流程图的DI信息存在时,就会去调用 ProcessDiagramGenerator.generatePngDiagram() 生成相应的流程图,并部署到数据库中.

 

ProcessDiagramGenerator.generatePngDiagram()生成流程图的流程大概是以下几步:

 

1.根据解析出来的流程DI信息,计算出画布的大小,即如果最靠右的组件x坐标是300,最靠底部的组件y坐标是400,那么就生成一个310*410的画布,保证了画布能够容纳整幅流程图的组件。

 

2.根据流程DI信息各个组件的类型,调用相应的渲染方法,在画布上画图。

 

3.此时,流程图画完了,但是左上部分可能会有很多空白的位置,所以根据流程DI信息,计算出最近左边的组件的x坐标和顶部的组件的y坐标,然后做一个裁剪,使输出的流程图大小刚刚好。

 

了解了Activiti画图的过程,我们在流程图上加工画高亮就容易多了,步骤如下,

 

1.检索出流程图原图。

 

2.解析流程DI信息。

 

3.由于上面画图的第三步做了个裁剪的操作,DI的坐标信息已经不对了,实际的x,y坐标会比DI上的要小了,但我们可以根据DI计算出minX,和minY,从而相减计算出真实的坐标。

 

4.加载流程的历史数据

 

5.根据历史数据和相应的DI坐标信息,利用java 2D画图。

 

在实际应用中,相同的流程,前3步只需要操作一次就够了,第二次就可以直接共享了,没必要浪费系统资源。

所以可以用一个很简单的LRU Map (least recently used Map)来缓存流程图的信息,每次只需要在图上加工就可以了。

 

 

public class LRUMap<K, V> extends LinkedHashMap<K, V> {

	private static final long serialVersionUID = -348656573172586525L;

	private final int maxCapacity;

	private static final float DEFAULT_LOAD_FACTOR = 0.75f;

	private Entry<K, V> eldestEntry;

	public LRUMap(int maxCapacity) {
		super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
		this.maxCapacity = maxCapacity;
	}

	@Override
	protected boolean removeEldestEntry(Entry<K, V> eldest) {
		boolean remove = size() > maxCapacity;
		if (remove) {
			this.eldestEntry = eldest;
		}
		return remove;
	}

	public Entry<K, V> getEldestEntry() {
		return eldestEntry;
	}

}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics