Graphics2D generates histogram

One of the requirements of the project is to display a horizontal histogram, and encapsulate a tool class for generating a histogram by yourself. The effect diagram is as follows:


The code above:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.wangyun.vo.Style;

/**
 * @ClassName: Histogram tool class   
 * @Description: Generate a histogram according to the parameters set
 * @author: wangyun
 * @date: 2018-5-4 3:00:20 PM
 */
public class PlotUtils {
	/**
	 * Generate pictures
	 * @param names city name
	 * @param dls corresponding value
	 * @param objList RGB value
	 * @param dl average
	 * @param cutValue the maximum value of the dividing line
	 * @throws FileNotFoundException
	 */
	public static String CreatePicture(String[] names,double[] dls,List<Style> objList ,double dl,double cutValue,String name,HttpServletRequest request ) throws FileNotFoundException{
		String proute = null;
		//image width
		int width = 1000;
		// left title bar width
	        int lwidth = 200;
		//image height
		int high =  (names.length+1)*40;
		// find the maximum negative value
		double dlss [] =new double[dls.length];
		//Explanation: mainly to prevent pointing to the same address
		for (int i = 0; i < dls.length; i++) {
			dlss[i]=dls[i];
		}
		Arrays.sort(dlss);//From small to large
		double fudl =0.00 ;
		if(dlss[0]<0){
			fudl =dlss[0];
			cutValue=-dlss[0]*5;
		}else{
			cutValue=dlss[dlss.length-1]+dl;
		}
		 // Get the image buffer width and height image category
        BufferedImage bi = new BufferedImage(width, high, BufferedImage.TYPE_INT_RGB);
        // get it's drawing environment (the pen of this image)
        Graphics2D g2 = (Graphics2D)bi.getGraphics();
        // Set the left canvas color
        g2.setColor(new Color(Integer.valueOf(objList.get(0).getR()), Integer.valueOf(objList.get(0).getG()), Integer.valueOf(objList.get(0).getB())));
        // Fill the entire image (actually set the background color) int x, int y, int width, int height
        g2.fillRect(0, 0, lwidth, high);
        //Set the left title box
        int k=0;
        for (int i = 0; i < names.length; i++) {
        	 // set font
            g2.setFont(new Font("宋体", Font.BOLD, 26));
            //Set the font color of the city name
            g2.setColor(new Color(Integer.valueOf(objList.get(1).getR()), Integer.valueOf(objList.get(1).getG()), Integer.valueOf(objList.get(1).getB())));
            // antialiasing
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    		g2.drawString(" "+sub_Str(names[i]), 30, 40+i*40);
    		if(k>=0&&k<5){
    			 g2.setColor(new Color(Integer.valueOf(objList.get(2).getR()), Integer.valueOf(objList.get(2).getG()), Integer.valueOf(objList.get(2).getB())));
    			k++;
    		}else{
    			 g2.setColor(new Color(Integer.valueOf(objList.get(3).getR()), Integer.valueOf(objList.get(3).getG()), Integer.valueOf(objList.get(3).getB())));
    			k++;
    			if(k>9){
    				k=0;
    			}
    		}
    		g2.fillRoundRect(5,20+i*40,26,26, 0, 0);  
    		// serial number color
    		g2.setColor(new Color(Integer.valueOf(objList.get(4).getR()), Integer.valueOf(objList.get(4).getG()), Integer.valueOf(objList.get(4).getB())));
    		g2.setFont(new Font("宋体", Font.BOLD, 26));
    		if(i>=0&&i<9){
    			g2.drawString(""+(i+1)+" ", 5, 40+i*40);
    		}else{
    			g2.drawString(i+1+" ", 5, 40+i*40);
    		}
		}
        

        //Set the right canvas color
        g2.setColor(new Color(Integer.valueOf(objList.get(5).getR()), Integer.valueOf(objList.get(5).getG()), Integer.valueOf(objList.get(5).getB())));
        // Fill the entire image (actually set the background color) int x, int y, int width, int height
        g2.fillRect(lwidth, 0, width, high);
        
        //Set the dividing line color
        g2.setColor(new Color(Integer.valueOf(objList.get(6).getR()), Integer.valueOf(objList.get(6).getG()), Integer.valueOf(objList.get(6).getB())));
        for (int i = 0; i <5; i++) {
        	g2.drawLine(lwidth+(width-lwidth)/5*i,0, lwidth+(width-lwidth)/5*i,high);
		}
      //Set the digital color of the dividing line
        g2.setFont(new Font("宋体", Font.BOLD, 20));
        g2.setColor(new Color(Integer.valueOf(objList.get(7).getR()), Integer.valueOf(objList.get(7).getG()), Integer.valueOf(objList.get(7).getB())));
        for (int i = 0; i <5; i++) {
             g2.drawString(""+new BigDecimal((cutValue/5)*i+fudl).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), lwidth+(width-lwidth)/5*i, 15);//设置分割线数值
        }
        
        //set the column
        int p = 0;
        for (int i = 0; i < dls.length; i++) {//int x, int y, int width, int height,  int arcWidth, int arcHeight
        	      //set the column color
        		  g2.setColor(new Color(Integer.valueOf(objList.get(8).getR()), Integer.valueOf(objList.get(8).getG()), Integer.valueOf(objList.get(8).getB())));
        		  if(dls[i]>0){
             		 if(dls[i]>cutValue){
             				if(dlss[0]<0){
             					g2.fillRoundRect(lwidth-(int)(fudl*(width-lwidth)/cutValue),20+i*40,(width-lwidth)*3/5,26, 0, 0);
             					g2.fillRoundRect(lwidth-(int)(fudl*(width-lwidth)/cutValue)+(width-lwidth)*3/5+10,20+i*40,90,26, 0, 0);
             				}else{
             					g2.fillRoundRect(lwidth-(int)(fudl*(width-lwidth)/cutValue),20+i*40,(width-lwidth)*4/5,26, 0, 0);  
             					g2.fillRoundRect(lwidth-(int)(fudl*(width-lwidth)/cutValue)+(width-lwidth)*4/5+10,20+i*40,90,26, 0, 0);
             				}
             		 }else{
                 		 g2.fillRoundRect(lwidth-(int)(fudl*(width-lwidth)/cutValue),20+i*40,(int)(dls[i]*(width-lwidth)/cutValue),26, 0, 0);  
             		 }
              	}else{
              		g2.fillRoundRect(lwidth-(int)((fudl-dls[i])*(width-lwidth)/cutValue),20+i*40,(int)(-dls[i]*(width-lwidth)/cutValue),26, 0, 0);
              	}
        		  if(p==0){
        			  if(dls[i]>dl&&dls[i+1]<dl){
           			   // draw the average line
           		        g2.setColor(new Color(Integer.valueOf(objList.get(9).getR()), Integer.valueOf(objList.get(9).getG()), Integer.valueOf(objList.get(9).getB())));  //int x1, int y1, int x2, int y2
           		        g2.drawLine( lwidth,53+i*40,  width,50+i*40);
           		        // draw the average line value
           		        g2.setColor(new Color(Integer.valueOf(objList.get(10).getR()), Integer.valueOf(objList.get(10).getG()), Integer.valueOf(objList.get(10).getB())));  //int x1, int y1, int x2, int y2
           		        g2.setFont(new Font("宋体", Font.BOLD, 20));
           		        g2.drawString(new BigDecimal(dl).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()+"", width-100, 80+i*40);
           		        p++;
           		  }
        		  } 		 
		}
        
        
        //set the column value
        for (int i = 0; i < dls.length; i++) {
        	 // set font
        	  g2.setColor(new Color(Integer.valueOf(objList.get(11).getR()), Integer.valueOf(objList.get(11).getG()), Integer.valueOf(objList.get(11).getB())));
            g2.setFont(new Font("宋体", Font.BOLD, 20));
            if(dls[i]>0){
              	 if(dls[i]>cutValue){
                		if(dlss[0]<0){
     					g2.drawString(""+dls[i],lwidth-(int)(fudl*(width-lwidth)/cutValue)+(width-lwidth)*3/5+100, 40+i*40);
     				}else{
     					g2.drawString(""+dls[i],lwidth-(int)(fudl*(width-lwidth)/cutValue)+(width-lwidth)*4/5+100, 40+i*40);
     				}
                	 }else{
                		g2.drawString(""+dls[i],lwidth-(int)((fudl-dls[i])*(width-lwidth)/cutValue), 40+i*40);
                	 }
                 }else{
                	 g2.drawString(""+dls[i],lwidth-(int)(fudl*(width-lwidth)/cutValue), 40+i*40);
            }
		}
        
         //Draw the bottom right border of the picture  
        //set thickness
        g2.setStroke(new BasicStroke(8.0f));
        //set color
        g2.setColor(new Color(Integer.valueOf(objList.get(12).getR()), Integer.valueOf(objList.get(12).getG()), Integer.valueOf(objList.get(12).getB())));  //int x1, int y1, int x2, int y2
        g2.drawLine(width,0,width,high);//Draw the right black line  
        g2.drawLine( 0,high,width,high);//Draw the lower black line  
       String  path =request.getSession().getServletContext().getRealPath("/upload/");
       String  realPath="/upload/";
      try {
    		File dir = new File(path,name+".jpg");         
            ImageIO.write(bi, "JPEG", dir);
            handleDpi(dir, 300, 300);
            g2.dispose();
            bi = null;
            System.gc();           
        } catch (IOException e) {
            e.printStackTrace ();
        }
		proute = realPath+name+".jpg";
      return proute;
	}
	
	/**
	 * Judge the character length according to the input string and add the corresponding space
	 * @param cityName
	 * @return
	 */
    public static String sub_Str(String cityName){
    	String ss=null;
    	int count =0;
    	char[] c = cityName.toCharArray();
    	         for(int i = 0; i < c.length; i ++)
    	         {
    	             String len = Integer.toBinaryString (c [i]);
    	             if(len.length() > 8)
    	                 count ++;
    	         }
    	if(count==2){
    		ss=cityName.substring(0, 1)+"  "+"  "+"  "+cityName.substring(1);
    	}else if(count==3){
    		ss=cityName.substring(0, 1)+"  "+cityName.substring(1,2)+"  "+cityName.substring(2,3);
    	}else if(count==4){
    		ss=cityName.substring(0, 1)+" "+cityName.substring(1,2)+""+cityName.substring(2,3)+" "+cityName.substring(3,4);
    	}else if(count==5){
    		ss=cityName;
    	}else{
    		ss="11111111111";
    	}
    	return ss;
    }


    /**
     * Change picture DPI
     *
     * @param file
     * @param xDensity
     * @param yDensity
     */  
    public static void handleDpi(File file, int xDensity, int yDensity) {  
        try {  
            BufferedImage image = ImageIO.read(file);  
			JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(new FileOutputStream(file));  
            JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);  
            jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);  
            jpegEncoder.setJPEGEncodeParam(jpegEncodeParam);  
            jpegEncodeParam.setQuality(0.75f, false);  
            jpegEncodeParam.setXDensity(xDensity);  
            jpegEncodeParam.setYDensity(yDensity);  
            jpegEncoder.encode(image, jpegEncodeParam);  
            image.flush();  
        } catch (IOException e) {  
            e.printStackTrace ();  
        }  
    }  
}

Summary of the problems encountered in the process:

1. There are positive and negative data, and some judgments need to be made when drawing.

2. Some data are much larger than others and need to be broken.

3. The problem that Graphics2D and BufferedImage are finally closed. If they are not closed, the pictures cannot be accessed while the program is running. My solution is:


Problem solved, please give more pointers.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325612804&siteId=291194637