首页 > 技术文章 > jfreeChart生成折线图和柱状图(转)

jiangyaqiong 2013-11-13 17:15 原文

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

Java代码  收藏代码
  3     import java.awt.Color;  
  4     import java.awt.Font;  
  5     import java.io.File;  
  6     import java.io.FileOutputStream;  
  7     import java.io.IOException;  
  8     import java.util.ArrayList;  
  9     import java.util.HashMap;  
 10     import java.util.List;  
 11     import java.util.Map;  
 12       
 13     import net.bingosoft.common.config.Config;  
 14       
 15     import org.apache.commons.logging.Log;  
 16     import org.apache.commons.logging.LogFactory;  
 17     import org.jfree.chart.ChartFactory;  
 18     import org.jfree.chart.ChartUtilities;  
 19     import org.jfree.chart.JFreeChart;  
 20     import org.jfree.chart.axis.CategoryAxis;  
 21     import org.jfree.chart.axis.CategoryLabelPositions;  
 22     import org.jfree.chart.axis.NumberAxis;  
 23     import org.jfree.chart.axis.ValueAxis;  
 24     import org.jfree.chart.labels.ItemLabelAnchor;  
 25     import org.jfree.chart.labels.ItemLabelPosition;  
 26     import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;  
 27     import org.jfree.chart.labels.StandardCategoryToolTipGenerator;  
 28     import org.jfree.chart.plot.CategoryPlot;  
 29     import org.jfree.chart.plot.PlotOrientation;  
 30     import org.jfree.chart.renderer.category.BarRenderer;  
 31     import org.jfree.chart.renderer.category.LineAndShapeRenderer;  
 32     import org.jfree.chart.title.TextTitle;  
 33     import org.jfree.data.category.CategoryDataset;  
 34     import org.jfree.data.general.DatasetUtilities;  
 35     import org.jfree.data.general.DefaultPieDataset;  
 36     import org.jfree.data.general.PieDataset;  
 37     import org.jfree.ui.TextAnchor;  
 38       
 39     public class CreateChartService {  
 40       
 41         private static Log log = LogFactory.getLog(CreateChartService.class);  
 42           
 43         // 图片的生成路径  
 44         private static final String CHART_PATH = Config.getString("image.filepath");     
 45           
 46         /**   
 47          * 生成折线图   
 48          * 1.解析数据<br> 
 49          * 2.迭代数据,产出图片数据流,并添加到List<br> 
 50          * @throws IOException  
 51          */    
 52         public List createLineAndShapeChart(double[][]data , String[]rowKeys,String[] columnKeys,ChartEntity entity) throws IOException {     
 53             List list = new ArrayList() ;  
 54             byte[] bytes = new byte[]{} ;  
 55             // 解析数据  
 56             Map map = this.parseDataForBarPage(data, rowKeys, columnKeys) ;  
 57             int pageNum = Integer.parseInt(""+map.get("pageNum")) ;  
 58             // 迭代,产生图片数据流  
 59             for(int i=0 ; i<pageNum ; i++){  
 60                 bytes = createSingleLineAndShapeChart((double[][])(map.get("data"+i)),(String[])(map.get("rowKeys"+i)),  
 61                         (String[])(map.get("columnKeys"+i)),entity) ;   
 62                 list.add(bytes) ;  
 63             }  
 64             return list ;  
 65         }     
 66           
 67         /** 
 68          * 生成单个折线图数据流   
 69          * @param data 
 70          * @param rowKeys 
 71          * @param columnKeys 
 72          * @param entity 
 73          * @return 
 74          * @throws IOException 
 75          */   
 76         public byte[] createSingleLineAndShapeChart(double[][]data , String[]rowKeys,String[] columnKeys,ChartEntity entity) throws IOException {     
 77             CategoryDataset dataset = getBarData(data, rowKeys, columnKeys);     
 78             JFreeChart chart = createTimeXYChar(dataset, entity);  
 79             byte[] bytes = this.createImage(chart, entity) ;  
 80             return bytes ;  
 81         }     
 82           
 83           
 84         /** 
 85          * 生成柱状图<br> 
 86          * 1.解析数据<br> 
 87          * 2.迭代数据,产出图片数据流,并添加到List<br> 
 88          * @param data 数据 
 89          * @param rowKeys 行 
 90          * @param columnKeys 列 
 91          * @param entity 图片配置对象 
 92          * @return 包含多个图片数据流的List 
 93          * @throws IOException 
 94          */  
 95         public List createStackedBarChart(double[][]data,String[]rowKeys,String[]columnKeys , ChartEntity entity) throws IOException {  
 96             // 解析数据  
 97             List list = new ArrayList() ;  
 98             byte[] bytes = new byte[]{} ;  
 99             Map map = this.parseDataForBarPage(data, rowKeys, columnKeys) ;  
100             int pageNum = Integer.parseInt(""+map.get("pageNum")) ;  
101             // 迭代数据,产出图片数据流,并添加到List  
102             for(int i=0 ; i<pageNum ; i++){  
103                 bytes = createSingleStackedBarChart((double[][])(map.get("data"+i)),(String[])(map.get("rowKeys"+i)),  
104                         (String[])(map.get("columnKeys"+i)),entity) ;   
105                 list.add(bytes) ;  
106             }  
107             return list ;  
108         }  
109           
110         /** 
111          * 解析生成柱状图分页数据 
112          * @param data 
113          * @param rowKeys 
114          * @param columnKeys 
115          * @return 
116          */  
117         private Map parseDataForBarPage(double[][]data,String[]rowKeys,String[]columnKeys){  
118             Map map = new HashMap() ;  
119               
120             double [][] pageData = null ;  
121             String [] pageColumn = null ;  
122               
123             int sumColumnNum = columnKeys.length ; // 总列数  
124             int indexNum = Config.getInt("image.export.pagesize", 10) ;// 分页的列数  
125             int pageNum = sumColumnNum%indexNum==0 ? sumColumnNum/indexNum : sumColumnNum/indexNum+1 ; // 分页数  
126             int rowNum = rowKeys.length ;  
127               
128     //      log.debug("data.length="+data.length+"sumColumnNum="+sumColumnNum+" indexNum="+indexNum+" pageNum="+pageNum+" rowNum="+rowNum+" ");  
129               
130             // 解析传递过来的数据  
131             for(int i=0 ; i<pageNum ; i++){  
132                 int columnNum = (sumColumnNum-i*indexNum)/indexNum>0 ? indexNum : (sumColumnNum-i*indexNum)%indexNum ;//当前页列数  
133                 pageData = new double[rowNum][columnNum] ;  
134                 // 取数据值  
135                 for(int j=0 ; j<rowNum ; j++){  
136                     pageColumn = new String[columnNum] ;  
137                     for(int k=0 ; k<columnNum ; k ++){  
138                         pageData[j][k] = data[j][k+i*indexNum] ; // 数据  
139                     }  
140                 }  
141                 // 取列值  
142                 for(int j=0 ; j<columnNum ; j++){  
143                     pageColumn[j] = columnKeys[j+i*indexNum] ; //
144                 }  
145                 // 保存数据并返回  
146                 map.put("data"+i, pageData) ;  
147                 map.put("rowKeys"+i, rowKeys) ;  
148                 map.put("columnKeys"+i, pageColumn) ;  
149             }  
150             // 保存分页数  
151             map.put("pageNum", pageNum);  
152             return map ;  
153         }  
154           
155         /** 
156          * 解析生成折线图分页数据 
157          * @param data 
158          * @param rowKeys 
159          * @param columnKeys 
160          * @return 
161          */  
162         private Map parseDataForLinePage(double[][]data,String[]rowKeys,String[]columnKeys){  
163             Map map = new HashMap() ;  
164               
165             double [][] pageData = null ;  
166             String [] pageColumn = null ;  
167               
168             int sumColumnNum = columnKeys.length ; // 总列数  
169             int indexNum = Config.getInt("image.export.pagesize", 10) ;// 分页的列数  
170             int pageNum = sumColumnNum%indexNum==0 ? sumColumnNum/indexNum : sumColumnNum/indexNum+1 ; // 分页数  
171             int rowNum = rowKeys.length ;  
172               
173     //      log.debug("data.length="+data.length+"sumColumnNum="+sumColumnNum+" indexNum="+indexNum+" pageNum="+pageNum+" rowNum="+rowNum+" ");  
174               
175             // 解析传递过来的数据  
176             for(int i=0 ; i<pageNum ; i++){  
177                 int columnNum = (sumColumnNum-i*indexNum)/indexNum>0 ? indexNum : (sumColumnNum-i*indexNum)%indexNum ;//当前页列数  
178                 pageData = new double[rowNum][columnNum] ;  
179                 // 取数据值  
180                 for(int j=0 ; j<rowNum ; j++){  
181                     pageColumn = new String[columnNum] ;  
182                     for(int k=0 ; k<columnNum ; k ++){  
183                         pageData[j][k] = data[j][k+i*indexNum] ; // 数据  
184                     }  
185                 }  
186                 // 取列值  
187                 for(int j=0 ; j<columnNum ; j++){  
188                     pageColumn[j] = columnKeys[j+i*indexNum] ; //
189                 }  
190                 // 保存数据并返回  
191                 map.put("data"+i, pageData) ;  
192                 map.put("rowKeys"+i, rowKeys) ;  
193                 map.put("columnKeys"+i, pageColumn) ;  
194             }  
195             // 保存分页数  
196             map.put("pageNum", pageNum);  
197             return map ;  
198         }  
199           
200         /**   
201          * 生成单个堆栈柱状图   
202          * @return 图片数据流 
203          * @throws IOException  
204          */    
205         public byte[] createSingleStackedBarChart(double[][]data,String[]rowKeys,String[]columnKeys , ChartEntity entity) throws IOException {     
206             CategoryDataset dataset = getBarData(data, rowKeys, columnKeys);     
207             JFreeChart chart = createStackedBarChart(dataset, entity);   
208             byte[] bytes = this.createImage(chart, entity) ;  
209             return bytes ;  
210         }    
211           
212         // 柱状图,折线图 数据集     
213         private CategoryDataset getBarData(double[][] data, String[] rowKeys,     
214                 String[] columnKeys) {     
215             return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);     
216         
217         }     
218         
219         /**   
220          * 判断文件夹是否存在,如果不存在则新建   
221          * @param chartPath   
222          */    
223         private void isChartPathExist(String chartPath) {     
224             File file = new File(chartPath);     
225             if (!file.exists()) {     
226                 file.mkdirs();     
227             }     
228         }     
229         
230         /**   
231          * 折线图   
232          *    
233          * @param chartTitle   
234          * @param x   
235          * @param y   
236          * @param xyDataset   
237          * @param charName   
238          * @return   
239          */    
240         private JFreeChart createTimeXYChar(CategoryDataset xyDataset,ChartEntity entity) {     
241         
242             JFreeChart chart = ChartFactory.createLineChart(  
243                     entity.getTitle(),   
244                     entity.getXname(),   
245                     entity.getYname(),     
246                     xyDataset,   
247                     PlotOrientation.VERTICAL,   
248                     true,   
249                     true,   
250                     false);     
251         
252             chart.setTextAntiAlias(false);     
253             chart.setBackgroundPaint(Color.WHITE);     
254         
255             CategoryPlot categoryplot = (CategoryPlot) chart.getPlot();     
256             // 没有数据时显示  
257             this.configNoData(chart, "没有查询到数据 !") ;  
258               
259             // x轴 // 分类轴网格是否可见     
260             categoryplot.setDomainGridlinesVisible(true);     
261             // y轴 //数据轴网格是否可见     
262             categoryplot.setRangeGridlinesVisible(true);     
263         
264             categoryplot.setRangeGridlinePaint(Color.WHITE);// 虚线色彩     
265         
266             categoryplot.setDomainGridlinePaint(Color.WHITE);// 虚线色彩     
267         
268             categoryplot.setBackgroundPaint(Color.lightGray);     
269         
270               
271             // 配置字体  
272             this.configFont(chart) ;  
273         
274             // x轴设置  
275             CategoryAxis domainAxis = categoryplot.getDomainAxis();     
276               
277             // 设置距离图片左端距离     
278             domainAxis.setLowerMargin(0.0);     
279             // 设置距离图片右端距离     
280             domainAxis.setUpperMargin(0.0);  
281             domainAxis.setTickLabelPaint(Color.BLUE) ;  
282             domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示    
283         
284             NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();     
285             numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());     
286             numberaxis.setAutoRangeIncludesZero(true);     
287         
288             // 获得renderer 注意这里是下嗍造型到lineandshaperenderer!!     
289             LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer) categoryplot.getRenderer();     
290             lineandshaperenderer.setBaseShapesVisible(true); // series 点(即数据点)可见     
291             lineandshaperenderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见     
292         
293             // 显示折点数据     
294             lineandshaperenderer.setBaseItemLabelGenerator(new     
295             StandardCategoryItemLabelGenerator());     
296             lineandshaperenderer.setBaseItemLabelsVisible(true);     
297               
298             return chart ;  
299         }     
300         
301         /**   
302          * 堆栈柱状图   
303          *    
304          * @param dataset   
305          * @param xName   
306          * @param yName   
307          * @param chartTitle   
308          * @param charName   
309          * @return   
310          */    
311         private JFreeChart createStackedBarChart(CategoryDataset dataset, ChartEntity entity) {     
312               
313             JFreeChart chart = ChartFactory.createStackedBarChart3D(  
314                     entity.getTitle(),   
315                     entity.getXname(),   
316                     entity.getYname(),   
317                     dataset,   
318                     PlotOrientation.VERTICAL,   
319                     true,   
320                     false,   
321                     false );  
322               
323             // 没有数据配置  
324             this.configNoData(chart,"没有查询到数据 !") ;  
325               
326             // 配置字体  
327             this.configFont(chart) ;  
328               
329             // 配置 Renderer  
330             this.configBarRenderer(chart) ;  
331               
332             // 其他配置  
333             this.configOtherForBar(chart) ;  
334               
335             return chart ;  
336         }     
337           
338         /** 
339          * 配置字体  
340          * @param chart JFreeChart 对象 
341          */  
342         private void configFont(JFreeChart chart){  
343             // 配置字体  
344             Font xfont = new Font("宋体",Font.PLAIN,12) ;// X轴  
345             Font yfont = new Font("宋体",Font.PLAIN,12) ;// Y轴  
346             Font kfont = new Font("宋体",Font.PLAIN,12) ;// 底部  
347             Font titleFont = new Font("隶书", Font.BOLD , 25) ; // 图片标题  
348             CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象  
349               
350             // 图片标题  
351             chart.setTitle(new TextTitle(chart.getTitle().getText(),titleFont));  
352               
353             // 底部  
354             chart.getLegend().setItemFont(kfont);  
355               
356             // X 轴  
357             CategoryAxis domainAxis = plot.getDomainAxis();     
358             domainAxis.setLabelFont(xfont);// 轴标题  
359             domainAxis.setTickLabelFont(xfont);// 轴数值    
360             domainAxis.setTickLabelPaint(Color.BLUE) ; // 字体颜色  
361             domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示   
362               
363             // Y 轴  
364             ValueAxis rangeAxis = plot.getRangeAxis();     
365             rangeAxis.setLabelFont(yfont);   
366             rangeAxis.setLabelPaint(Color.BLUE) ; // 字体颜色  
367             rangeAxis.setTickLabelFont(yfont);    
368               
369         }  
370           
371         /** 
372          * 配置柱状图 
373          * @param chart 
374          */  
375         private void configBarRenderer(JFreeChart chart){  
376               
377             CategoryPlot categoryplot = (CategoryPlot)chart.getPlot();  
378     //       自定义显示柱子上的总值  
379             ExtendedStackedBarRenderer extendedstackedbarrenderer = new ExtendedStackedBarRenderer();  
380             extendedstackedbarrenderer.setBaseItemLabelsVisible(true);  
381             extendedstackedbarrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());  
382             extendedstackedbarrenderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());  
383             categoryplot.setRenderer(extendedstackedbarrenderer);  
384               
385             BarRenderer barrenderer = (BarRenderer)categoryplot.getRenderer();  
386             barrenderer.setDrawBarOutline(false);  
387             barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());  
388             barrenderer.setBaseItemLabelsVisible(true);  
389             barrenderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER));  
390             barrenderer.setBaseNegativeItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER));  
391               
392             // 柱子显示数值  
393     //        barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}",new DecimalFormat("0.0%")));      
394     //        barrenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());  
395             barrenderer.setItemLabelFont(new Font("Arial Unicode MS",Font.PLAIN,9));    
396             barrenderer.setItemLabelsVisible(true);  
397               
398     //      如果数值没有显示空间,设置显示格式  
399     //      ItemLabelPosition itemLabelPositionFallback=new ItemLabelPosition(  
400     //              ItemLabelAnchor.OUTSIDE12,TextAnchor.BASELINE_LEFT,  
401     //              TextAnchor.HALF_ASCENT_LEFT,0D);  
402     //      barrenderer.setPositiveItemLabelPositionFallback(itemLabelPositionFallback);  
403     //      barrenderer.setNegativeItemLabelPositionFallback(itemLabelPositionFallback);  
404               
405             categoryplot.setRenderer(barrenderer) ;  
406         }  
407           
408         /** 
409          * 配置没有数据时的显示信息 
410          * @param chart 
411          */  
412         private void configNoData(JFreeChart chart,String message){  
413             CategoryPlot categoryplot = (CategoryPlot)chart.getPlot();  
414             // 没有数据时的显示  
415             categoryplot.setNoDataMessage(message) ;  
416             categoryplot.setNoDataMessageFont(new Font("黑体",Font.BOLD,25)) ;  
417         }  
418           
419         /** 
420          * 其他配置 
421          * @param chart 
422          */  
423         private void configOtherForBar(JFreeChart chart){  
424        
425             chart.setTextAntiAlias(false);   // 图例字体清晰    
426         
427             chart.setBackgroundPaint(Color.WHITE); // 背景颜色   
428               
429             CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象  
430             NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();     
431             numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());     
432             numberaxis.setAutoRangeIncludesZero(true);   
433         }  
434       
435         /** 
436          * 创建图片的数据流 
437          * @param chart 
438          * @param entity 图片配置对象 
439          * @return 图片数据流 
440          * @throws IOException 
441          */  
442         private byte[] createImage(JFreeChart chart , ChartEntity entity) throws IOException{  
443             return ChartUtilities.encodeAsPNG(chart.createBufferedImage(entity.getWidth(), entity.getHeight())) ;  
444         }  
445           
446         /** 
447          * 创建图片文件到硬盘 
448          * @param chart 
449          * @param entity 
450          * @throws IOException 
451          */  
452         private void createImageFile(JFreeChart chart , ChartEntity entity) throws IOException{  
453             FileOutputStream fos_jpg = null;     
454             try {     
455                 isChartPathExist(CHART_PATH);     
456                 String chartName = CHART_PATH + entity.getFileName();     
457                 fos_jpg = new FileOutputStream(chartName);     
458                 ChartUtilities.writeChartAsJPEG(fos_jpg, chart, entity.getWidth(), entity.getHeight()) ;  
459             } catch (Exception e) {     
460                 e.printStackTrace();     
461             } finally {     
462                 try {     
463                     fos_jpg.close();     
464                 } catch (Exception e) {     
465                     e.printStackTrace();     
466                 }     
467             }     
468         }  
469     }  

 

推荐阅读