`
smileCat2009
  • 浏览: 21334 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

jfreechart完整使用(3)- CreateChartService.java

阅读更多

CreateChartService.java
完成报表的生成,项目只要柱状图和折线图,所以只生成了2中图形,
类中还有JFreeChart 数据的转换方法,JFreeChart相关的配置方法

 

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.bingosoft.common.config.Config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.ui.TextAnchor;

public class CreateChartService {

	private static Log log = LogFactory.getLog(CreateChartService.class);
	
	// 图片的生成路径
	private static final String CHART_PATH = Config.getString("image.filepath");   
	
	/**  
     * 生成折线图  
     * 1.解析数据<br>
     * 2.迭代数据,产出图片数据流,并添加到List<br>
	 * @throws IOException 
     */  
    public List createLineAndShapeChart(double[][]data , String[]rowKeys,String[] columnKeys,ChartEntity entity) throws IOException {   
    	List list = new ArrayList() ;
    	byte[] bytes = new byte[]{} ;
    	// 解析数据
    	Map map = this.parseDataForBarPage(data, rowKeys, columnKeys) ;
    	int pageNum = Integer.parseInt(""+map.get("pageNum")) ;
    	// 迭代,产生图片数据流
    	for(int i=0 ; i<pageNum ; i++){
    		bytes = createSingleLineAndShapeChart((double[][])(map.get("data"+i)),(String[])(map.get("rowKeys"+i)),
    				(String[])(map.get("columnKeys"+i)),entity) ; 
    		list.add(bytes) ;
    	}
        return list ;
    }   
    
	/**
	 * 生成单个折线图数据流  
	 * @param data
	 * @param rowKeys
	 * @param columnKeys
	 * @param entity
	 * @return
	 * @throws IOException
	 */ 
    public byte[] createSingleLineAndShapeChart(double[][]data , String[]rowKeys,String[] columnKeys,ChartEntity entity) throws IOException {   
        CategoryDataset dataset = getBarData(data, rowKeys, columnKeys);   
        JFreeChart chart = createTimeXYChar(dataset, entity);
        byte[] bytes = this.createImage(chart, entity) ;
        return bytes ;
    }   
    
    
    /**
     * 生成柱状图<br>
     * 1.解析数据<br>
     * 2.迭代数据,产出图片数据流,并添加到List<br>
     * @param data 数据
     * @param rowKeys 行
     * @param columnKeys 列
     * @param entity 图片配置对象
     * @return 包含多个图片数据流的List
     * @throws IOException
     */
    public List createStackedBarChart(double[][]data,String[]rowKeys,String[]columnKeys , ChartEntity entity) throws IOException {
    	// 解析数据
    	List list = new ArrayList() ;
    	byte[] bytes = new byte[]{} ;
    	Map map = this.parseDataForBarPage(data, rowKeys, columnKeys) ;
    	int pageNum = Integer.parseInt(""+map.get("pageNum")) ;
    	// 迭代数据,产出图片数据流,并添加到List
    	for(int i=0 ; i<pageNum ; i++){
    		bytes = createSingleStackedBarChart((double[][])(map.get("data"+i)),(String[])(map.get("rowKeys"+i)),
    				(String[])(map.get("columnKeys"+i)),entity) ; 
    		list.add(bytes) ;
    	}
        return list ;
    }
    
    /**
     * 解析生成柱状图分页数据
     * @param data
     * @param rowKeys
     * @param columnKeys
     * @return
     */
    private Map parseDataForBarPage(double[][]data,String[]rowKeys,String[]columnKeys){
    	Map map = new HashMap() ;
    	
    	double [][] pageData = null ;
    	String [] pageColumn = null ;
    	
    	int sumColumnNum = columnKeys.length ; // 总列数
    	int indexNum = Config.getInt("image.export.pagesize", 10) ;// 分页的列数
    	int pageNum = sumColumnNum%indexNum==0 ? sumColumnNum/indexNum : sumColumnNum/indexNum+1 ; // 分页数
    	int rowNum = rowKeys.length ;
    	
//    	log.debug("data.length="+data.length+"sumColumnNum="+sumColumnNum+" indexNum="+indexNum+" pageNum="+pageNum+" rowNum="+rowNum+" ");
    	
    	// 解析传递过来的数据
    	for(int i=0 ; i<pageNum ; i++){
    		int columnNum = (sumColumnNum-i*indexNum)/indexNum>0 ? indexNum : (sumColumnNum-i*indexNum)%indexNum ;//当前页列数
    		pageData = new double[rowNum][columnNum] ;
    		// 取数据值
    		for(int j=0 ; j<rowNum ; j++){
    			pageColumn = new String[columnNum] ;
    			for(int k=0 ; k<columnNum ; k ++){
    				pageData[j][k] = data[j][k+i*indexNum] ; // 数据
    			}
    		}
    		// 取列值
    		for(int j=0 ; j<columnNum ; j++){
    			pageColumn[j] = columnKeys[j+i*indexNum] ; // 列
    		}
            // 保存数据并返回
    		map.put("data"+i, pageData) ;
    		map.put("rowKeys"+i, rowKeys) ;
    		map.put("columnKeys"+i, pageColumn) ;
    	}
    	// 保存分页数
    	map.put("pageNum", pageNum);
    	return map ;
    }
    
    /**
     * 解析生成折线图分页数据
     * @param data
     * @param rowKeys
     * @param columnKeys
     * @return
     */
    private Map parseDataForLinePage(double[][]data,String[]rowKeys,String[]columnKeys){
    	Map map = new HashMap() ;
    	
    	double [][] pageData = null ;
    	String [] pageColumn = null ;
    	
    	int sumColumnNum = columnKeys.length ; // 总列数
    	int indexNum = Config.getInt("image.export.pagesize", 10) ;// 分页的列数
    	int pageNum = sumColumnNum%indexNum==0 ? sumColumnNum/indexNum : sumColumnNum/indexNum+1 ; // 分页数
    	int rowNum = rowKeys.length ;
    	
//    	log.debug("data.length="+data.length+"sumColumnNum="+sumColumnNum+" indexNum="+indexNum+" pageNum="+pageNum+" rowNum="+rowNum+" ");
    	
    	// 解析传递过来的数据
    	for(int i=0 ; i<pageNum ; i++){
    		int columnNum = (sumColumnNum-i*indexNum)/indexNum>0 ? indexNum : (sumColumnNum-i*indexNum)%indexNum ;//当前页列数
    		pageData = new double[rowNum][columnNum] ;
    		// 取数据值
    		for(int j=0 ; j<rowNum ; j++){
    			pageColumn = new String[columnNum] ;
    			for(int k=0 ; k<columnNum ; k ++){
    				pageData[j][k] = data[j][k+i*indexNum] ; // 数据
    			}
    		}
    		// 取列值
    		for(int j=0 ; j<columnNum ; j++){
    			pageColumn[j] = columnKeys[j+i*indexNum] ; // 列
    		}
            // 保存数据并返回
    		map.put("data"+i, pageData) ;
    		map.put("rowKeys"+i, rowKeys) ;
    		map.put("columnKeys"+i, pageColumn) ;
    	}
    	// 保存分页数
    	map.put("pageNum", pageNum);
    	return map ;
    }
    
    /**  
     * 生成单个堆栈柱状图  
     * @return 图片数据流
     * @throws IOException 
     */  
    public byte[] createSingleStackedBarChart(double[][]data,String[]rowKeys,String[]columnKeys , ChartEntity entity) throws IOException {   
        CategoryDataset dataset = getBarData(data, rowKeys, columnKeys);   
        JFreeChart chart = createStackedBarChart(dataset, entity); 
        byte[] bytes = this.createImage(chart, entity) ;
        return bytes ;
    }  
    
    // 柱状图,折线图 数据集   
    private CategoryDataset getBarData(double[][] data, String[] rowKeys,   
            String[] columnKeys) {   
        return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);   
  
    }   
  
    /**  
     * 判断文件夹是否存在,如果不存在则新建  
     * @param chartPath  
     */  
    private void isChartPathExist(String chartPath) {   
        File file = new File(chartPath);   
        if (!file.exists()) {   
            file.mkdirs();   
        }   
    }   
  
    /**  
     * 折线图  
     *   
     * @param chartTitle  
     * @param x  
     * @param y  
     * @param xyDataset  
     * @param charName  
     * @return  
     */  
    private JFreeChart createTimeXYChar(CategoryDataset xyDataset,ChartEntity entity) {   
  
        JFreeChart chart = ChartFactory.createLineChart(
        		entity.getTitle(), 
        		entity.getXname(), 
        		entity.getYname(),   
                xyDataset, 
                PlotOrientation.VERTICAL, 
                true, 
                true, 
                false);   
  
        chart.setTextAntiAlias(false);   
        chart.setBackgroundPaint(Color.WHITE);   
  
        CategoryPlot categoryplot = (CategoryPlot) chart.getPlot();   
        // 没有数据时显示
        this.configNoData(chart, "没有查询到数据 !") ;
        
        // x轴 // 分类轴网格是否可见   
        categoryplot.setDomainGridlinesVisible(true);   
        // y轴 //数据轴网格是否可见   
        categoryplot.setRangeGridlinesVisible(true);   
  
        categoryplot.setRangeGridlinePaint(Color.WHITE);// 虚线色彩   
  
        categoryplot.setDomainGridlinePaint(Color.WHITE);// 虚线色彩   
  
        categoryplot.setBackgroundPaint(Color.lightGray);   
  
        
        // 配置字体
        this.configFont(chart) ;
  
        // x轴设置
        CategoryAxis domainAxis = categoryplot.getDomainAxis();   
        
        // 设置距离图片左端距离   
        domainAxis.setLowerMargin(0.0);   
        // 设置距离图片右端距离   
        domainAxis.setUpperMargin(0.0);
        domainAxis.setTickLabelPaint(Color.BLUE) ;
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示  
  
        NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();   
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());   
        numberaxis.setAutoRangeIncludesZero(true);   
  
        // 获得renderer 注意这里是下嗍造型到lineandshaperenderer!!   
        LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer) categoryplot.getRenderer();   
        lineandshaperenderer.setBaseShapesVisible(true); // series 点(即数据点)可见   
        lineandshaperenderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见   
  
        // 显示折点数据   
        lineandshaperenderer.setBaseItemLabelGenerator(new   
        StandardCategoryItemLabelGenerator());   
        lineandshaperenderer.setBaseItemLabelsVisible(true);   
        
        return chart ;
    }   
  
    /**  
     * 堆栈柱状图  
     *   
     * @param dataset  
     * @param xName  
     * @param yName  
     * @param chartTitle  
     * @param charName  
     * @return  
     */  
    private JFreeChart createStackedBarChart(CategoryDataset dataset, ChartEntity entity) {   
    	
    	JFreeChart chart = ChartFactory.createStackedBarChart3D(
    			entity.getTitle(), 
    			entity.getXname(), 
    			entity.getYname(), 
        		dataset, 
        		PlotOrientation.VERTICAL, 
        		true, 
        		false, 
        		false );
    	
    	// 没有数据配置
        this.configNoData(chart,"没有查询到数据 !") ;
        
        // 配置字体
        this.configFont(chart) ;
        
        // 配置 Renderer
        this.configBarRenderer(chart) ;
        
        // 其他配置
        this.configOtherForBar(chart) ;
        
        return chart ;
    }   
    
    /**
     * 配置字体 
     * @param chart JFreeChart 对象
     */
    private void configFont(JFreeChart chart){
    	// 配置字体
    	Font xfont = new Font("宋体",Font.PLAIN,12) ;// X轴
    	Font yfont = new Font("宋体",Font.PLAIN,12) ;// Y轴
    	Font kfont = new Font("宋体",Font.PLAIN,12) ;// 底部
    	Font titleFont = new Font("隶书", Font.BOLD , 25) ; // 图片标题
    	CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象
    	
    	// 图片标题
    	chart.setTitle(new TextTitle(chart.getTitle().getText(),titleFont));
    	
    	// 底部
    	chart.getLegend().setItemFont(kfont);
    	
    	// X 轴
    	CategoryAxis domainAxis = plot.getDomainAxis();   
        domainAxis.setLabelFont(xfont);// 轴标题
        domainAxis.setTickLabelFont(xfont);// 轴数值  
        domainAxis.setTickLabelPaint(Color.BLUE) ; // 字体颜色
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示 
        
    	// Y 轴
    	ValueAxis rangeAxis = plot.getRangeAxis();   
        rangeAxis.setLabelFont(yfont); 
        rangeAxis.setLabelPaint(Color.BLUE) ; // 字体颜色
        rangeAxis.setTickLabelFont(yfont);  
        
    }
    
    /**
     * 配置柱状图
     * @param chart
     */
    private void configBarRenderer(JFreeChart chart){
    	
    	CategoryPlot categoryplot = (CategoryPlot)chart.getPlot();
//    	 自定义显示柱子上的总值
        ExtendedStackedBarRenderer extendedstackedbarrenderer = new ExtendedStackedBarRenderer();
        extendedstackedbarrenderer.setBaseItemLabelsVisible(true);
        extendedstackedbarrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        extendedstackedbarrenderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
        categoryplot.setRenderer(extendedstackedbarrenderer);
        
        BarRenderer barrenderer = (BarRenderer)categoryplot.getRenderer();
        barrenderer.setDrawBarOutline(false);
        barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        barrenderer.setBaseItemLabelsVisible(true);
        barrenderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER));
        barrenderer.setBaseNegativeItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER));
        
        // 柱子显示数值
//        barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}",new DecimalFormat("0.0%")));    
//        barrenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        barrenderer.setItemLabelFont(new Font("Arial Unicode MS",Font.PLAIN,9));  
        barrenderer.setItemLabelsVisible(true);
        
//      如果数值没有显示空间,设置显示格式
//      ItemLabelPosition itemLabelPositionFallback=new ItemLabelPosition(
//              ItemLabelAnchor.OUTSIDE12,TextAnchor.BASELINE_LEFT,
//              TextAnchor.HALF_ASCENT_LEFT,0D);
//      barrenderer.setPositiveItemLabelPositionFallback(itemLabelPositionFallback);
//      barrenderer.setNegativeItemLabelPositionFallback(itemLabelPositionFallback);
        
        categoryplot.setRenderer(barrenderer) ;
    }
    
    /**
     * 配置没有数据时的显示信息
     * @param chart
     */
    private void configNoData(JFreeChart chart,String message){
    	CategoryPlot categoryplot = (CategoryPlot)chart.getPlot();
        // 没有数据时的显示
        categoryplot.setNoDataMessage(message) ;
        categoryplot.setNoDataMessageFont(new Font("黑体",Font.BOLD,25)) ;
    }
    
    /**
     * 其他配置
     * @param chart
     */
    private void configOtherForBar(JFreeChart chart){
 
        chart.setTextAntiAlias(false);   // 图例字体清晰  
  
        chart.setBackgroundPaint(Color.WHITE); // 背景颜色 
        
    	CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象
        NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();   
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());   
        numberaxis.setAutoRangeIncludesZero(true); 
    }

    /**
     * 创建图片的数据流
     * @param chart
     * @param entity 图片配置对象
     * @return 图片数据流
     * @throws IOException
     */
    private byte[] createImage(JFreeChart chart , ChartEntity entity) throws IOException{
        return ChartUtilities.encodeAsPNG(chart.createBufferedImage(entity.getWidth(), entity.getHeight())) ;
    }
    
    /**
     * 创建图片文件到硬盘
     * @param chart
     * @param entity
     * @throws IOException
     */
    private void createImageFile(JFreeChart chart , ChartEntity entity) throws IOException{
    	FileOutputStream fos_jpg = null;   
        try {   
            isChartPathExist(CHART_PATH);   
            String chartName = CHART_PATH + entity.getFileName();   
            fos_jpg = new FileOutputStream(chartName);   
            ChartUtilities.writeChartAsJPEG(fos_jpg, chart, entity.getWidth(), entity.getHeight()) ;
        } catch (Exception e) {   
            e.printStackTrace();   
        } finally {   
            try {   
                fos_jpg.close();   
            } catch (Exception e) {   
                e.printStackTrace();   
            }   
        }   
    }
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics