Graphics2D生成柱状图

项目一个需求,展示横向柱状图,自己动手封装了一个生成柱状图的工具类,效果图如下:


下面上代码:

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:    柱状图工具类   
 * @Description:    根据设置各个参数,生成柱状图
 * @author:  wangyun
 * @date: 2018-5-4     下午3:00:20
 */
public class PlotUtils {
	/**
	 * 生成图片
	 * @param names 城市名称
	 * @param dls  对应数值
	 * @param objList  RGB 值
	 * @param dl  平均值
	 * @param cutValue   分割线最大值
	 * @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;
		//图片宽度
		int width = 1000;
		//左侧标题栏宽度
	        int lwidth = 200;
		//图片高度
		int high =  (names.length+1)*40;
		//求出负数最大值
		double dlss [] =new double[dls.length];
		//解释:主要是为了防止指向同一个地址
		for (int i = 0; i < dls.length; i++) {
			dlss[i]=dls[i];
		}
		Arrays.sort(dlss);//从小到大
		double fudl =0.00 ;
		if(dlss[0]<0){
			fudl =dlss[0];
			cutValue=-dlss[0]*5;
		}else{
			cutValue=dlss[dlss.length-1]+dl;
		}
		 // 得到图片缓存区             宽度   高度   图片类别
        BufferedImage bi = new BufferedImage(width, high, BufferedImage.TYPE_INT_RGB);
        // 得到它的绘制环境(这张图片的笔)
        Graphics2D g2 = (Graphics2D)bi.getGraphics();
        // 设置左侧画布颜色
        g2.setColor(new Color(Integer.valueOf(objList.get(0).getR()), Integer.valueOf(objList.get(0).getG()), Integer.valueOf(objList.get(0).getB())));
        // 填充整张图片(其实就是设置背景颜色)int x, int y, int width, int height
        g2.fillRect(0, 0, lwidth, high);
        //设置左侧标题框
        int k=0;
        for (int i = 0; i < names.length; i++) {
        	 // 设置字体
            g2.setFont(new Font("宋体", Font.BOLD, 26));
            //设置城市名称字体颜色
            g2.setColor(new Color(Integer.valueOf(objList.get(1).getR()), Integer.valueOf(objList.get(1).getG()), Integer.valueOf(objList.get(1).getB())));
            // 抗锯齿
            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);  
    		//序号颜色
    		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);
    		}
		}
        

        //设置右侧画布颜色
        g2.setColor(new Color(Integer.valueOf(objList.get(5).getR()), Integer.valueOf(objList.get(5).getG()), Integer.valueOf(objList.get(5).getB())));
        // 填充整张图片(其实就是设置背景颜色)int x, int y, int width, int height
        g2.fillRect(lwidth, 0, width, high);
        
        //设置分割线颜色
        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);
		}
      //设置分割线数字颜色
        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);//设置分割线数值
        }
        
        //设置柱体
        int p = 0;
        for (int i = 0; i < dls.length; i++) {//int x, int y, int width, int height,  int arcWidth, int arcHeight
        	      //设置柱体颜色
        		  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){
           			   //绘制平均线 
           		        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);
           		        //绘制平均线数值
           		        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++;
           		  }
        		  } 		 
		}
        
        
        //设置柱体数值
        for (int i = 0; i < dls.length; i++) {
        	 // 设置字体
        	  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);
            }
		}
        
         //绘制图片右下边框线  
        //设置粗度
        g2.setStroke(new BasicStroke(8.0f));
        //设置颜色
        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);//绘制右黑色线  
        g2.drawLine( 0,high,width,high);//绘制下黑色线  
       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;
	}
	
	/**
	 * 根据输入的字符串判断字符长度,添加相应空格
	 * @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;
    }


    /** 
     * 改变图片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();  
        }  
    }  
}

过程遇到的问题总结:

1.数据有正负,画图时需要做一些判断。

2.有些数据比其他数据要大很多,需要做折断。

3.Graphics2D和BufferedImage最后关闭的问题,如果不关闭,在程序运行是不可以访问图片,我的解决办法是:


问题解决,不足之处请多多指点。


猜你喜欢

转载自blog.csdn.net/qq_37236241/article/details/80223866