AnsweredAssumed Answered

I modify some code and make ProcessInstance  Diagram better

Question asked by zxdlht on Jul 28, 2011
Latest reply on Aug 5, 2011 by jbarrez
I modify some code and make ProcessInstance  Diagram better
Zhe org.activiti.engine.impl.bpmn.diagram.ProcessDiagramGenerator class
modify like this:

package org.activiti.engine.impl.bpmn.diagram;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.imageio.ImageIO;

import org.activiti.engine.ProcessEngines;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;

public class ProcessDiagramGenerator
{
   
   public static InputStream generateDiagram(ProcessDefinitionEntity processDefinition, String imageType, List<String> highLightedActivities)
   {
       return generateDiagram(processDefinition, highLightedActivities).generateImage(imageType);
   }
   
   protected static ProcessDiagramCanvas generateDiagram(ProcessDefinitionEntity processDefinition, List<String> highLightedActivities)
   {
       ProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(processDefinition);
       drawProcessDiagram(processDiagramCanvas,processDefinition,highLightedActivities);
      
       return processDiagramCanvas;
   }
   
   protected static ProcessDiagramCanvas initProcessDiagramCanvas(ProcessDefinitionEntity processDefinition)
   {
       int minX = Integer.MAX_VALUE;
       int maxX = 0;
       int minY = Integer.MAX_VALUE;
       int maxY = 0;
       BufferedImage image=null;
       InputStream resource = ProcessEngines.getDefaultProcessEngine().getRepositoryService().getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
       try {
          image = ImageIO.read(resource);
          maxX =image.getWidth();
          maxY =image.getHeight();
       }
       catch(IOException ex)
       {
          ex.printStackTrace();
       }
       
      
       for (ActivityImpl activity : processDefinition.getActivities()) {
        
         // width
         if (activity.getX() + activity.getWidth() > maxX) {
           maxX = activity.getX() + activity.getWidth();
         }
         if (activity.getX() < minX) {
           minX = activity.getX();
         }
         // height
         if (activity.getY() + activity.getHeight() > maxY) {
           maxY = activity.getY() + activity.getHeight();
         }
         if (activity.getY() < minY) {
           minY = activity.getY();
         }
        
         for (PvmTransition sequenceFlow : activity.getOutgoingTransitions()) {
           List<Integer> waypoints = ((TransitionImpl) sequenceFlow).getWaypoints();
           for (int i=0; i < waypoints.size(); i+=2) {
             // width
             if (waypoints.get(i) > maxX) {
               maxX = waypoints.get(i);
             }
             if (waypoints.get(i) < minX) {
               minX = waypoints.get(i);
             }
             // height
             if (waypoints.get(i+1) > maxY) {
               maxY = waypoints.get(i+1);
             }
             if (waypoints.get(i+1) < minY) {
               minY = waypoints.get(i+1);
             }
           }
         }
       }
       ProcessDiagramCanvas processDiagramCanvas =new ProcessDiagramCanvas(maxX, maxY, minX, minY);
       processDiagramCanvas.drawProcessDiagramCanvas(image);
       return processDiagramCanvas;
   }
   
    protected static void drawProcessDiagram(ProcessDiagramCanvas processDiagramCanvas, ProcessDefinitionEntity process, List<String> highLightedActivities)
    {
       for(ActivityImpl activity : process.getActivities())
       {
          if(highLightedActivities.contains(activity.getId()))
             processDiagramCanvas.drawHighLight(activity.getX(), activity.getY(), activity.getWidth(), activity.getHeight()) ;
       }
    }
}

The org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas class modify like this:

package org.activiti.engine.impl.bpmn.diagram;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.util.IoUtil;

public class ProcessDiagramCanvas
{
   
   protected int canvasWidth = -1;
   protected int canvasHeight = -1;
   protected int minX = -1;
   protected int minY = -1;
   protected BufferedImage processDiagram;
   protected Graphics2D g;
   protected FontMetrics fontMetrics;
   protected boolean closed;
   
   protected static Color HIGHLIGHT_COLOR = Color.RED;
   protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(3.0f);
    
   public ProcessDiagramCanvas(int width, int height) {
      this.canvasWidth = width;
      this.canvasHeight = height;
      this.processDiagram = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_ARGB);
      this.g = (Graphics2D) processDiagram.createGraphics();
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g.setPaint(Color.black);
      Font font = new Font("Arial", Font.BOLD, 11);
      g.setFont(font);
      this.fontMetrics = g.getFontMetrics();
   }
   
   public ProcessDiagramCanvas(int width, int height, int minX, int minY) {
       this(width, height);
       this.minX = minX;
       this.minY = minY;
     }
   
   public InputStream generateImage(String imageType) {
      if (closed) {
            throw new ActivitiException("ProcessDiagramGenerator already closed");
          }
         
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          try {
            // Try to remove white space
            minX = (minX <= 5) ? 5 : minX;
            minY = (minY <= 5) ? 5 : minY;
            BufferedImage imageToSerialize = processDiagram;
            if (minX >= 0 && minY >= 0) {
              imageToSerialize = processDiagram.getSubimage(minX - 5, minY - 5,
                      canvasWidth - minX + 5 , canvasHeight - minY + 5);
            }
            ImageIO.write(imageToSerialize, imageType, out);
          } catch (IOException e) {
            throw new ActivitiException("Error while generating process image" , e);
          } finally {
            IoUtil.closeSilently(out);
          }
          return new ByteArrayInputStream(out.toByteArray());
   }
   
   public void drawProcessDiagramCanvas(Image processDiagram)
   {
      g.drawImage(processDiagram, 0, 0, canvasWidth, canvasHeight, null);
   }
   
    public void drawHighLight(int x, int y, int width, int height)
    {
          Paint originalPaint = g.getPaint();
          Stroke originalStroke = g.getStroke();

          g.setPaint(HIGHLIGHT_COLOR);
          g.setStroke(THICK_TASK_BORDER_STROKE);

          RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
          g.draw(rect);

          g.setPaint(originalPaint);
          g.setStroke(originalStroke);
        }

}

Outcomes