天天看点

jFreeChart初探

正好我最近的一个项目用到她,于是就很粗略的看了一下,现在把他拿出来和大家分享,希望对大家的工作有所 

帮助。 

本文主要是讲解她在jsp上面的应用。例子采用jsp+javabean结构实现 

准备工作:首先我们需要什么?当然是jfreechart的package了,能够在她的官方网站上面找到下载链接 

http://www.jfree.org/jfreechart/,把包下下来,配置到tomcat当中,然后能够开始我们的jfreechart之旅 

了。 

下面我要做的是个饼状统计图,首先建立javabean文档 

文档名:tryitshow.java 

package com.tryit; 

import java.io.*; 

import java.awt.insets; 

import java.awt.font; 

import java.io.printwriter; 

import java.text.simpledateformat; 

import java.util.iterator; 

import java.util.locale; 

import java.text.numberformat; 

import javax.servlet.http.httpsession; 

import org.jfree.data.*; 

import org.jfree.chart.*; 

import org.jfree.chart.axis.*; 

import org.jfree.chart.renderer.verticalbarrenderer; 

import org.jfree.chart.renderer.standardxyitemrenderer; 

import org.jfree.chart.plot.*; 

import org.jfree.chart.entity.*; 

import org.jfree.chart.tooltips.*; 

import org.jfree.chart.urls.*; 

import org.jfree.chart.servlet.*; 

import org.jfree.chart.texttitle; 

import java.net.url; 

p lic class tryitshow 

    p lic static string generatepiechart(string infostr, string titles,httpsession session, printwriter pw) 

        { 

            string filename = null; 

            font font; 

            try { 

                    //  建立piedataset 

            defaultpiedataset data = new defaultpiedataset(); 

            string ss[]=infostr.split(","); 

            for (int n=0;n<ss.length;n++) 

            { 

                string sspart[]=ss[n].split("#"); 

                int tt=integer.parseint(sspart[1]); 

                string mm=sspart[0]; 

                data.setval(mm,tt); 

            } 

                //  生成chart物件 

            pieplot plot = new pieplot(data); 

            plot.setinsets(new insets(0, 5, 5, 5)); 

            plot.settooltipgenerator(new standardpietooltipgenerator()); 

            font=new font("黑体",font.center_baseline,20);//这个地方是配置统计图标题的字体和大小 

            jfreechart chart = new jfreechart("",jfreechart.default_title_font, plot, tr); 

            texttitle tt=new texttitle(titles); 

            tt.setfont(font); 

            chart.setbackgroundpaint(java.awt.color.white);//统计图片的底色 

            chart.settitle(tt); 

            //  把生成的文档写入到临时的目录中 

            chartrenderinginfo info = new chartrenderinginfo(new standardentitycollection()); 

            filename = servletutilities.savechartaspng(chart, 500, 300, info, session); 

//选择存储成png格式的文档,当然您也能够使用savechartasjpeg的方法生成jpg图片 

            //  把image map 写入到 printwriter 

            chartutilities.writeimagemap(pw, filename, info); 

            pw.flush(); 

            catch (exception ex) { 

            system.out.println("error:"+ex.getmessage()); 

            return filename; 

    } 

接着是jsp文档 

<%@ page contenttype="text/html;charset=gb2312"%> 

<%@ page import = "com.tryit.tryitshow" %> 

<%@ page import = "java.io.printwriter" %> 

<%@ page import = "java.text.simpledateformat" %> 

<%@ page import = "java.text.parseexception" %> 

<%@ page import = "java.util.arraylist" %> 

<%@ page import = "java.util.date" %> 

<%@ page import = "java.util.iterator" %> 

<%@ page import = "java.util.locale" %> 

<!doctype html p lic "-//w3c//dtd html 4.0 transitional//en"> 

<html> 

<head> 

<title> new document </title> 

<meta name="generator" content="editplus"> 

<meta name="author" content=""> 

<meta name="keywords" content=""> 

<meta name="description" content=""> 

</head> 

<% 

string filename = tryitshow.generatepiechart("本科#100,专科#200","人才学历信息统计",session, new printwriter(out)); 

    string graphurl = reqst.getcontextpath() + "/servlet/displaychart?filename=" + filename; 

    %> 

<body> 

<img src="<%= graphurl %>" width=500 height=300 border=0 usemap="#<%= filename %>"> 

</body> 

</html> 

ok,大功告成,当然,您能够采用其他方式,比如您能够把dataset的数据配置在xml文档中,从xml文档读取 

统计数据中添加百分比等等,还能够选择生成柱状图、折线图等。 

jfreechart更有很多其他的用法,希望大家能够多多交流。 

web.xml文档的配置 

<web-app> 

  <servlet> 

    <servlet-name>displaychart</servlet-name> 

    <servlet-class>org.jfree.chart.servlet.displaychart</servlet-class> 

  </servlet> 

   <servlet-mapping> 

        <servlet-name>displaychart</servlet-name> 

        <url-pattern>/servlet/displaychart</url-pattern> 

    </servlet-mapping> 

</web-app> 

import java.awt.Insets; 

import java.awt.Image; 

import java.io.PrintWriter; 

import java.text.SimpleDateFormat; 

import java.util.Date; 

import java.util.ArrayList; 

import java.util.Iterator; 

import java.util.Locale; 

import java.text.NumberFormat; 

import javax.servlet.http.HttpSession; 

import org.jfree.chart.renderer.VerticalBarRenderer; 

import org.jfree.chart.renderer.StandardXYItemRenderer; 

import java.awt.Font; 

/** 

* <p>Title: </p> 

* <p>Description: </p> 

* <p>Copyright: Copyright (c) 2003</p> 

* <p>Company: </p> 

* @author jagie 

* @version 1.0 

*/ 

p lic class GSPieChart { 

  p lic static void main(String[] args) { 

    Long[] testData = { 

        new Long(10), new Long(20), new Long(30), new Long(40)}; 

    generatePieChart(testData, "", null, new PrintWriter(System.out), 580, 250); 

  } 

  /** 

   * 生成图像文件 

   * @param datas Long[]数组 

   * @param targetUrl 点饼形图上的扇形,定向到的url 

   * @param session httpsession 

   * @param pw PrintWriter 

   * @param w 生成的图的宽度 

   * @param h 生成的图的高度 

   * @return 生成的图像文件的路径 

   */ 

  p lic static String generatePieChart(Long[] datas, String targetUrl, 

                                        HttpSession session, PrintWriter pw, 

                                        int w, int h) { 

    String filename = null; 

    try { 

      DefaultPieDataset data = new DefaultPieDataset(); 

      data.setVal("正常纳税人", datas[0]); 

      data.setVal("异常纳税人", datas[1]); 

      data.setVal("数据不全纳税人", datas[2]); 

      data.setVal("未处理纳税人", datas[3]); 

      //  Create the chart object 

      Pie3DPlot plot = new Pie3DPlot(data); 

      plot.setInsets(new Insets(0, 5, 5, 5)); 

      plot.setForegroundAlpha(0.6f); 

      plot.setSectionLabelType(plot.NO_LABELS); 

      plot.setURLGenerator(new StandardPieURLGenerator(targetUrl, "type")); 

      plot.setToolTipGenerator(new StandardPieToolTipGenerator()); 

      JFreeChart chart = new JFreeChart( 

"数据处理结果统计图", JFreeChart.DEFAULT_TITLE_FONT, plot, tr); 

      chart.setTitle(new TextTitle( 

"数据处理结果统计图", new Font("黑体", Font.BOLD, 15))); 

      StandardLegend sl = (StandardLegend) chart.getLegend(); 

      sl.setItemFont(new Font("黑体", Font.TRTYPE_FONT, 12)); 

      chart.setBackgroundPaint(new java.awt.Color(254, 254, 141)); 

      //因为jfreechart把生成的png文件保存在系统的临时文件夹中,你需要在适当的  

      //时候调用session.removeAttribute("JFreeChart_Deleter"),这样可以保证png文 

      //件被删除掉 

      ChartRenderingInfo info = new ChartRenderingInfo(new 

          StandardEntityCollection()); 

      filename = ServletUtilities.saveChartAsPNG(chart, w, h, info, session); 

      //  Write the image map to the PrintWriter 

      ChartUtilities.writeImageMap(pw, filename, info); 

      pw.flush(); 

    catch (Exception e) { 

      System.out.println("Exception - " + e.toString()); 

      e.printStackTrace(System.out); 

      filename = "p lic_error_500x300.png"; 

    return filename; 

.........java代码................. 

//以下部分为图象输出 

String targetUrl="../servlet/gov.gwssi.tax.nspg. 

controlservlet.GSMainControlServlet?id="+sid; 

Long[] datas={normals,new Long(totalAbnormal), 

dataLacks,notProcesses}; 

String filename=GSPieChart.generatePieChart 

(datas,targetUrl,session,new PrintWriter(out),580,250); 

String graphURL = reqst.getContextPath() + 

"/servlet/DisplayChart?filename=" + filename; 

%> 

JFreeChart Hacking 

来自于http://www.itep .net/ 

<本文允许任意转载,请注明出处!最后一块骨头.2005-05-16> 

JFreeChart 是什么?我就不再重复介绍了,网上文章大把... 

官方主页:http://www.jfree.org/jfreechart/index.html 

<--本文以jfreechart-1.0.0-pre2版本为基准--> 

那么为什么要Hacking JFreeChart呢? 

罪状一:中文Label显示模糊; 

罪状二:无简体中文LocalizationBundle.properties文件; 

罪状三:向下兼容性不好,官方说jdk1.2+,其实是jdk1.4+; 

                兼容问题A:另存菜单输出PNG文件只能运行于jdk1.4+; 

                兼容问题B:另存菜单不能输出JPEG格式图片; 

                兼容问题C:jdk1.3-环境下中文ToolTips不能正常显示; 

如果一定要加一条罪状的话:目前开源免费的chart项目无出其右; 

十分感谢JFreeChart开发者的辛苦努力!虽然它现在还不完美。 

Ok,下面为Hacking做一些准备工作... 

1.下载jfreechart-1.0.0-pre2.zip解压; 

2.将\解压目录\source\下的源码加入任意project并配置jdk&lib; 

3.安装一个有批量文件查询/替换功能的工具,比如UtralEdit; 

Hacking Begin 

1.解决中文Label显示模糊问题 

  原因分析:JFreeChart默认字体对中文的支持不完善; 

  解决步骤:搜索\解压目录\source\下含有"new Font("的文件; 

           发现JFreeChart默认字体为 

           "foo" 

           "Serif" 

           "Dialog" 

           "SansSerif" 

           "Bitstream Vera Sans" 

           批量替换他们为任意中文字体(推荐"黑体"); 

           当然你也可以把字体写入properties文件, 

           但这里介绍的是最简单的方法; 

           然后重新编译你修改过的文件,Ok,搞定! 

2.无简体中文LocalizationBundle.properties文件 

  org\jfree\chart\LocalizationBundle.properties 

  主要用来显示右键功能菜单的文字,下面我们来汉化: 

  注意:LocalizationBundle.properties的编码不是Unicode, 

       简体中文要用GBK编码。 

  获得GBK编码的方法是: 

  cd ***\j2sdk1.*.*\bin 

  native2ascii -encoding GBK 1.txt 2.txt 

  注:1.txt放中文文本,2.txt输出GBK编码。 

# org.jfree.chart.ChartPanel ResourceBundle properties file 

# Changes (from 31-Aug-2003) 

# -------------------------- 

# 31-Aug-2003 : Initial version (AL); 

# 16-May-2005 : Add GBK version (FinalBone); 

# 16-May-2005 : Add JPG_Image_Files (FinalBone); 

#---------------EN---------------# 

#Auto_Range=Auto Range 

#All_Axes=Both Axes 

#Chart_Properties=Chart Properties 

#Copy=Copy 

#Print...=Print... 

#Save_as...=Save as... 

#Properties...=Properties... 

#PNG_Image_Files=PNG Image Files 

#JPG_Image_Files=JPG Image Files 

#Domain_Axis=Domain Axis 

#Range_Axis=Range Axis 

#Zoom_In=Zoom In 

#Zoom_Out=Zoom Out 

#---------------GBK---------------# 

Auto_Range=\自\动\调\整 

All_Axes=\所\有\坐\标\轴 

Chart_Properties=\图\表\属\性 

Copy=\复\制 

Print...=\打\印... 

Save_as...=\另\存\为... 

Properties...=\属\性... 

PNG_Image_Files=PNG\图\像 

JPG_Image_Files=JPG\图\像 

Domain_Axis=\域\坐\标\轴 

Range_Axis=\值\坐\标\轴 

Zoom_In=\放\大 

Zoom_Out=\缩\小 

另外还有两个同名文件,希望大家有时间也汉化一下。 

org\jfree\chart\ui\LocalizationBundle.properties 

org\jfree\chart\plot\LocalizationBundle.properties 

3.兼容性问题 

   a.PNG输出问题 b.无JPEG输出菜单 

    原因分析:javax.imageio.ImageIO这个类只有jdk1.4+才有。 

    解决步骤:1.打开org.jfree.chart.ChartPanel, 

               查看doSaveAs()方法,了解其结构; 

             2.改写doSaveAs()方法,重新编译; 

             3.如果运行环境是jdk1.3- 

               打开org.jfree.chart.encoders.SunPNGEncoderAdapter 

               注释掉javax.imageio.ImageIO,重新编译。 

    /** 

     * Updated by FinalBone 2005-5-16 PNG --> JPEG 

     * 

     * Opens a file chooser and gives the user an opportunity 

     * to save the chart in JPEG format. 

     * @throws IOException if there is an I/O error. 

     */ 

    p lic void doSaveAs() throws IOException { 

        JFileChooser fileChooser = new JFileChooser(); 

        ExtensionFileFilter filter = new ExtensionFileFilter( 

            localizationResources.getString("JPG_Image_Files"), ".jpg" 

        ); 

        fileChooser.addChoosableFileFilter(filter); 

        int option = fileChooser.showSaveDialog(this); 

        if (option == JFileChooser.APPROVE_OPTION) { 

            String filename = fileChooser.getSelectedFile().getPath(); 

            if (isEnforceFileExtensions()) { 

                if (!filename.endsWith(".jpg")) { 

                    filename = filename + ".jpg"; 

                } 

            ChartUtilities.saveChartAsJPEG( 

                new File(filename), this.chart, getWidth(), getHeight() 

            ); 

        } 

  c.中文ToolTips不能正常显示(显示为小方框) 

    原因分析:相关字体找不到。 

    解决步骤:1.打开org.jfree.chart.block.LabelBlock 

               查看其构造函数p lic LabelBlock(String label); 

             2.修改构造函数的字体定义,重新编译。 

     * Creates a new label block. 

     * @param label  the label. 

    p lic LabelBlock(String label) { 

         /** 

          * Updated by FinalBone 2005-05-16 

          * "Bitstream Vera Sans" --> "黑体" 

          * For Chinese-Simplified ToolTips 

          * JDK 1.3- Environment 

          */ 

        this(label, new Font("黑体", Font.PLAIN, 11)); 

Hacking End 

这时的 JFreeChart 才是真正jdk1.2+兼容,完美支持中文。 

希望下一版本的 JFreeChart 的字体定义写入properties文件, 

并且不同路经下的properties文件最好不要重名。