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.