JFreeChart 学习笔记

目录

  • 目录
    • JfreeChart 的核心对象
      • 制图对象
      • 制图工厂对象
      • 数据集合对象
      • 绘图区对象
        • PiePlot 类
        • CategoryPlot 类
        • XYPlot 类
      • 坐标轴对象
        • CategoryAxis 类
        • ValueAxis 类
        • NumberAxis 类
        • DateAxis 类
      • 图片渲染对象
    • JFreeChart 的应用
      • 如何获取图片
      • 创建数据集合与JFreeChart 实例
      • 图表相关属性的设置
      • JFreeChart 内置JDBC 的使用
      • 中文乱码的解决方案
    • JFreeChart 案列集锦
      • 绘制饼状图
      • 生成柱状图
      • 绘制折线图
      • 生成区域图表
      • 生成时序图
      • 利用柱状图显示某网站的访问量
      • 外插个地址 swing JFreeChart 和HighCharts 报表
      • 利用饼图显示不同编程语言的市场占用率
      • 利用折线图显示气温变化情况
      • 利用区域图对比分析员工业绩
      • 利用时序图分析商品月销售收益

JfreeChart 的核心对象

制图对象

JFreeChart类是一个制图对象,它代表着一种制图类型。如:创建一个柱形图,首先需要创建一个柱形图的制图对象JFreeChart;创建一个饼形图,需要创建个饼形图的制图对象JFreeChart,在制图过程中,只有在创建制图对象JFreeChart后,才可以生成实际的图片。

在JFreeChart类中,可以设置所生成图片的边界、字体、背景、透明度等属性,其常用方法及说明如表1所示。

方法 说明
public void setAntiAlias(boolean flag) 设置字体模糊边界
public void setBackgroudImage(Image image) 设置背景图片
public void setBackgroundImageAlignment(int alignment) 设置背景图片对齐方式,其参数常量定义在org.jfree.ui.Align类中
public void setBackgroundImageAlpha(float alpha) 设置背景图片透明度
public void setBackgroundPaint(Paint paint) 设置背景颜色
public void setBorderPaint(Paint paint) 设置边界线条颜色
public void setBorderVisible(boolean visible) 设置边界线条是否可见

制图工厂对象

在生成图形报表时,制图对象JFreeChart是必不可少的对象,它可以直接通过new关键字进行实例化,也可以通过制图工厂ChartFacroty类进行实例化。当使用new关键字进行实例化时,需要设置大量的属性信息,因为JFreeChart组件提供图表的种类很多,对于每一种图表都进行特殊的设置,非常繁琐。所以在使用过程中,一般都使用制图工厂ChartFacroty类进行创建。

制图工厂ChartFacroty是一个抽象类,它不能被实例化,但此类之中提供创建各种制图对象的方法,如创建柱形图对象、区域图对象、饼形图对象、折线图对象等方法,这些方法都是静态的方法,可直接创建JFreeChart对象,并且是属于某一种具体的图表类型的JFreeChart对象,其使用非常方便,它的常用方法及说明如表1所示。

表1 ChartFactory 类常用方法及其说明

图表类型 方法 说明
柱形图 public static JFreeChart createBarChart() 创建一个常规的柱形图对象
public static JFreeChart createBarChart3D() 创建一个3D效果的柱形图对象
饼形图 public static JFreeChart createPieChart() 创建一个常规的饼形图对象
public static JFreeChart createPieChart3D() 创建一个3D 效果的饼形图对象
区域图 public static JFreeChart createAreaChart() 创建一个常规的区域图对象
折线图 public static JFreeChart createLineChart() 创建一个常规的折线图对象
public static JFreeChart createLineChart3D() 创建一个3D 效果的折线图对象
时序图 public static JFeeChart createTimeSeriesChart() 创建一个常规的时序图对象

除表1中所列的方法外,ChartFacroty类还有很多创建各种类型制图对象的方法,在此不一一进行罗列。在ChartFacroty类中,对于同种类型的制图对象提供一个或多个方法,如表20.1中的所示的常规制图对象与3D效果的制图对象的方法。可见,制图工厂ChartFacroty类为创建制图对象提供了多个灵活的方法。
ChartFacroty类可以理解为是一个生产制图对象JFreeChart的工厂,当需要用到某一种类型的制图对象时,通过此工厂进行获取。

例如:

JFreeChart chart=ChartFactory.createPieChart3D(
                      "饼形图",        //图表的标题
                      initPieData() , //饼形图的数据集对象
                      true ,  //是否显示图列
                      true ,  //是否显示提示文
                      false);  //是否生成超链接

上述代码通过ChartFactory类的createPieChart3D()方法,创建了一个3D效果的饼形图JFreeChart对象。

数据集合对象

在JFreeChart组件的图形报表技术应用中,绘制一个图表需要一定的数据,JFreeChart组件通过提供的数据进行计算并绘制出图表信息。由于在数据的分析计算中并不是单一的数值,所以绘制图表要为JFreeChart组件提供数据集合。

数据集合对象是用于装载绘制图表所需要的数据集。在JFreeChart组件中,针对不同图表类型提供了不同的数据集合对象,它们所具有的作用也是不同的。本节内容将以常用的数据集合对象为例,来讲解JFreeChart中的数据集合对象,在学习JFreeChart数据集合对象前,先来了解一下常用数据集合对象之间的关系,其类图如图1所示。

JFreeChart 学习笔记_第1张图片

Dataset接口是数据集合的核心对象,从图1可以看出,所有数据集合对象都直接或间接的实现了此接口。图中类名以Abstract开头的类均为抽象,它们并不能实例化,但为其子类提供公共属性与方法,其中DefaultCategoryDataset类、DefaultPieDataset类、XYSeriesCollection类与TimeSeriesCollection类为经常用到的数据集合对象,其说明如表1所示。

表1 常用数据集合对象 及说明

数据集合对象 说明
DefaultCategoryDataset类 默认的类别数据集合对象,可用于创建柱形图、区域图数据集合等
DefaultPieDataset类 默认的饼形图数据集合对象,可用于创建饼形图数据集合
XYSeriesCollection类 描述坐标轴序列类型的数据集合,可用于创建折线图等数据集合
TimeSeriesCollection类 描述时间序列的数据集合,可用于创建时序图等数据集合

数据集合是数据集的封装对象,在JFreeChart组件的使用中,绘制每一种图形都需要用到数据集合对象。图1中只介绍了常用的数据集合关系,除了这些数据集合外,JFreeChart还针对不同图表各类提供了同的数据集合,由于篇幅原因,并进行一一介绍,其使用方法请参阅JFreeChart组件的API文档。

例如:

DefaultCategoryDataset dataset=new DefaultCategoryDataset(); //创建数据集合dataSet.addValue(100,"长春","土豆");  //向数据集合中添加数据

上述代码创建一个DefaultCategoryDataset类型的数据集合,并调用addValue()方法向数据集合中添加一个数据。

绘图区对象

通过数据集合所生成数据图表,可以通过绘图区对象进行属性设置,例如背景色、透明度等样式。绘图区对象是JFreeChart组件中的一个重要对象,它由Plot类定义,使用过程中可以通过此类进行设置绘图区属性及样式,其常用方法及说明如表1所示。

表1 Plot 类常用方法及说明

方法 说明
public void setBackgroundImage(Image image) 设置数据区的背景图片
public void setBackgroundImageAlignment(int alignment) 设置数据区的背景图片对齐方式(参数常量在org.jfree.ui.Align类中定义)
public void setBackgroundAlpha(float alpha) 设置数据区的背景透明度,范围在0.0~1.0间
public void setForegroundAlpha(float alpha) 设置数据区的前景透明度,范围在0.0~1.0间
public void setDataAreaRatio(double ratio) 设置数据区占整个图表区的百分比
public void setOutLinePaint(Paint paint) 设置数据区的边界线条颜色
public void setNoDataMessage(String message) 设置没有数据时显示的消息

JFreeChart所能生成的图形报表是多种多样的,仅仅一个Plot类并不能满足绘图区样式的设置,在对不同类型图形的设置中,可以通过Plot的子类进行实现,其常用子类的类图如图1所示。

JFreeChart 学习笔记_第2张图片

PiePlot 类

PiePlot类是Plot类的子类,主要用于描述PieDataset数据集合类型的图表,通常使用此类来绘制一个饼形图,其常用方法及说明如表2所示。

表2 PiePlot 类常用方法及说明

方法 说明
public void setDataset(PieDataset dataset) 设置绘制图表所需要的数据集合
public void setDataset(PieDataset dataset) 设置绘制图表所需要的数据集合
public void setCircular(boolean flag) 设置饼形图是否一定是正圆
public void setStartAngle(double angle) 设置饼形图的初始角度
public void setDirection(Rotation direction) 设置饼形图的旋转方向
public void setExplodePercent(int section,double percent) 设置抽取图表的部分及距离
public void setLabelFont(Font font) 设置分类标签字体(3D效果下无效)
public void setLabelPaint(Paint paint) 设置分类标签字体颜色(3D效果下无效)

CategoryPlot 类

CategoryPlot类主要用于描述CategoryDataset数据集合类型的图表,是Plot类的子类,它支持折线图、区域图等,其常用方法及说明如表3所示。

表3 CategoryPlot 类常用方法及说明

方法 说明
public void setDataset(PieDataset dataset) 设置绘制图表所需要的数据集合
public void setColumnRenderingOrder(SortOrder order) 设置数据分类的排序方式
public void setAxisOffset(Spacer offset) 设置坐标轴到数据区的间距
public void setOrientation(PlotOrientation orientation) 设置数据区的方向(横向或纵向)
public void setDomainAxis(CategoryAxis axis) 设置数据区的分类轴
public void setRangeAxis(ValueAxis axis) 设置数据区的数据轴
public void addAnnotation(CategoryAnnotation annotation) 设置数据区的注释

XYPlot 类

XYPlot类是Plot类的子类,主要用于描述XYDataset数据集合类型的图表,此类可以具有0或多个数据集合,并且每一个数据集合可以也一个渲染对象相关联,其常用方法及说明如表4所示。

表4 XYPlot 类常用方法及说明

方法 说明
public ValueAxis getDomainAxis 返回X轴
public ValueAxis getRangeAxis() 返回Y轴
public void setDomainAxis(ValueAxis axis) 设置X轴
public void setRangeAxis(ValueAxis axis) 设置Y轴

坐标轴对象

在JFreeChart组件中,涉及到坐标轴类型的图表,其样式与属性由坐标轴对象Axis类进行控制,此类是坐标轴对象的父类,其常用方法及说明如表1所示。

表1 Axis 类常用方法及说明

方法 说明
public void setVisible(boolean flag) 设置坐标轴是否可见
public void setAxisLinePaint(Paint paint) 设置坐标轴线条颜色,此设置在3D效果下无效
public void setAxisLineVisible(boolean visible) 设置坐标轴线条是否可见
public void setLabel(String label) 设置坐标轴标题
public void setLabelFont(Font font) 设置坐标轴标题字体
public void setLabelPaint(Paint paint) 设置坐标轴标题颜色
public void setLabelAngle(double angle) 设置坐标轴标题旋转角度

JFreeChart组件针对不同类型的图表对象,提供了不同类型的坐标轴对象,由Axis类的子类进行扩展,其常用子类的类图如图1所示。

JFreeChart 学习笔记_第3张图片

CategoryAxis 类

CategoryAxis类是Axis类的子类,主要用于对分类轴的相关属性进行设置,其常用方法及说明如表2所示。

表2 CategoryAxis类常用方法及说明

方法 说明
public void setCategoryMargin(double margin) 设置分类轴边距
public void setLowerMargin(double margin) 设置分类轴下边距或左边距
public void setUpperMargin(double margin) 设置分类轴上边距或右边距
public void setVerticalCategoryLabels(boolean flag) 设置分类轴标题是否旋转到垂直
public void setMaxCategoryLabelWidthRatio(float ratio) 设置分类轴分类标签的最大宽度

ValueAxis 类

ValueAxis类是Axis类的子类,主要用于对数据轴的相关属性进行设置,它还是NumberAxis类与DateAxis类的父类,其常用方法及说明如表3所示。

表3 ValueAxis 类常用方法及说明

方法 说明
public void setAutoRange(boolean auto) 设置数据轴数据范围是否为自动
public void setFixedAutoRange(double length) 设置数据轴固定数据范围
public void setInverted(boolean flag) 设置数据轴是否反向
public void setLowerMargin(double margin) 设置分类轴下边距或左边距
public void setUpperMargin(double margin) 设置分类轴上边距或右边距
public void setLowerBound(double min) 设置数据轴上的显示最小值
public void setUpperBound(double max) 设置数据轴上的显示最大值

NumberAxis 类

NumberAxis类主要用于对数值类型数据轴的相关属性进行设置,是ValueAxis类的子类,其常用方法及说明如表4所示。

表4 CategoryPlot 类常用方法及说明

方法 说明
public void setAutoRangeIncludesZero(boolean flag) 设置是否强制在自动选择的数据范围中包含0
public void setAutoRangeStickyZero(boolean flag) 设置是否强制在整个数据轴中包含0,即使0不在数据范围中
public void setNumberFormatOverride(NumberFormat formatter) 设置数据轴数据标签的显示格式

DateAxis 类

DateAxis类主要用于对日期轴的相关属性进行设置,是ValueAxis类的子类,其常用方法及说明如表5所示。

表5 CategoryPlot 类常用方法及说明

方法 说明
public void setMaximumDate(Date maximumDate) 设置日期轴上的最小日期
Public void setMinimumDate(Date minimumDate) 设置日期轴上的最大日期
public void setDateFormatOverride(DateFormat formatter) 设置日期轴日期标签的显示格式
public void setTickUnit(DateTickUnit unit) 设置日期轴的日期标签

图片渲染对象

图片渲染对象用于渲染和显示图表,它在图表的显示效果方面起着很大的作用。在JFreeChart组件中,渲染对象定义为AbstractRenderer类,此类是所有渲染对象的父类,但它是一个抽象类,其常用方法及说明如表1所示。

JFreeChart 学习笔记_第4张图片

在图片渲染对象中,JFreeChart组件同样对AbstractRenderer类进行了扩展,在使用过程中可根据实际需要,选择合适的AbstractRenderer类的子类对象。

JFreeChart 的应用

如何获取图片

JFreeChart组件能够生成.jpeg、.png格式的图片,其输出方式可以直接存储在硬盘之中,也可以交给JFreeChart组件进行管理。在Web项目的应用中,所生成的图形报表一般均为动态图表,如果对每次生成的图表都进行直接存储,将会产生大量的垃圾文件,时间长久将要做一定清理工作。因此,由JFreeChart组件管理所生成的图片是一个不错的选择,它不仅可以提供图片的路径,而且在查看图片后,JFreeChart组件自动做出清理工作。

JFreeChart组件提供了一个Servlet文件用于获取生成的图片,此Servlet文件存在于JFreeChart组件包中,所以在使用过程中,需要将其配置到Web.xml文件中,其配置方法如下:


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     <servlet>
         <servlet-name>DisplayChartservlet-name>
         <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
     <servlet-mapping>
            <servlet-name>DisplayChartservlet-name>
            <url-pattern>/servlet/DisplayCharturl-pattern>
      servlet-mapping>   
web-app> 

ServletUtilities类的saveChartAsJPEG()方法进行生成,它返回一个.jpeg格式的图片名称。

public static String saveChartAsJPEG(JFreeChart chart ,int width,int height ,HttpSession session )throws IOException 

参数的说明:

chart :制图对象JFreeChartford
width:所生成图片的宽度
height:所生成图片的高度
session”HttpSession对象

通过此方法生成图片后,调用已注册的JFreeChart提供的Servlet类DisplayChart,即可获取到图片的相对路径。
例如:在Jsp页面中获取图片。

<%
         String fileName = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(), 450, 300, session);
      String graphURL = request.getContextPath() + "/DisplayChart?filename=" + fileName;
%>

上述代码生成了一个宽为450、高为300的图片,其文件名fileName,它的路径为graphURL,通过此路径即可对所生成的图片进行访问。

创建数据集合与JFreeChart 实例

通过DefaultCategoryDataset数据集合对象创建柱形图制图对象,其关键代码如下:

import java.awt.Font;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

public class CharUtil {
    //创建数据集合 
    public static CategoryDataset createDataSet(){
        DefaultCategoryDataset dataSet=new DefaultCategoryDataset();  //实例化DefaultCategoryDataset对象
        dataSet.addValue(500, "JAVA图书", "J2SE类"); //向数据集合中添加数据
        dataSet.addValue(100, "JAVA图书", "JAVAME类");
        dataSet.addValue(900, "JAVA图书", "J2EE类");
        return dataSet;
    }
    //创建JFreeChart 对象 
    public static JFreeChart createChart (){
        StandardChartTheme standardChartTheme=new StandardChartTheme("CN"); //创建主题样式
        standardChartTheme.setExtraLargeFont(new Font("隶书",Font.BOLD,20)); //设置标题字体
        standardChartTheme.setRegularFont(new Font("宋体",Font.PLAIN,15)); //设置图例的字体
        standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));          //设置轴向的字体
        ChartFactory.setChartTheme(standardChartTheme);    //设置主题样式
       //通过ChartFactory 创建JFreeChart 
         JFreeChart chart = ChartFactory.createBarChart3D(
                 "JAVA图书销量统计",                    //图表标题
                 "JAVA图书",                           //横轴标题
                 "销量(本)",                        //纵轴标题
                 createDataSet(),                       //数据集合 
                 PlotOrientation.VERTICAL,      //图表方向
                 false,                               //是否显示图例标识
                 false,                               //是否显示tooltips
                 false);                              //是否支持超链接
     return chart;
    }
}

ChartUtil类是一个自定义的制图工具类,其中createDataSet()方法用于创建柱形图所需要的数据集合,它返回CategoryDataset对象。CreateChart()用于创建制图对象JFreeChart,在此方法中通过ChartFactory对象的createBarChart3D()方法创建一个3D效果的柱形图对象,并将其返回。

DisplayChart进行获取图片,实例中在index.jsp页面中输出图片,其关键代码如下:

<%@ page language="java" contentType="text/html" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities,com.lyq.util.ChartUtil"%>

<html>
  <head>
    <title>Java图书销量统计title>
  head>
  <body>
    <%
               String fileName = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),450,300,session);
               String graphURL = request.getContextPath() + "/DisplayChart?filename=" + fileName;
    %>
    <img src="<%=graphURL%>" border="1">
  body>
html>

ServletUtilities类的saveChartAsJPEG()方法进行生成,它返回一个.jpeg格式的图片名称。
在输出图片之前,首先要生成JFreeChart组件所绘制的图片,此操作通过调用ServletUtilities类的saveChartAsJPEG()方法进行生成,它返回一个.jpeg格式的图片名称。

在获取此图片名称后,通过代码“request.getContextPath() + “/DisplayChart?filename=” + fileName”即可获取到图片的路径.

图表相关属性的设置

通常情况下,为了使所生成图片美观、大方,需要对所生成的图片进行一定的设置,如制图对象设置、绘图区设置、坐标轴设置及图片渲染等。


import java.awt.Font;
import java.awt.Image;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.VerticalAlignment;
/**
 * 自定义绘图工具类
 * @author Li Yong Qiang
 */
public class ChartUtil {

/*实例中首先创建数据集合对象DefaultCategoryDataset,并添加四个季度的销量数据,其关键代码如下:*/
    /**
     * 创建数据集合
     * @return CategoryDataset对象
     */
    public static CategoryDataset createDataSet() {
        //实例化DefaultCategoryDataset对象
        DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
        //添加第一季度数据
        dataSet.addValue(6000, "第一季度", "J2SE类");
        dataSet.addValue(3000, "第一季度", "J2ME类");
        dataSet.addValue(12000, "第一季度", "J2EE类");
        //添加第二季度数据
        dataSet.addValue(8000, "第二季度", "J2SE类");
        dataSet.addValue(4000, "第二季度", "J2ME类");
        dataSet.addValue(6000, "第二季度", "J2EE类");
        //添加第三季度数据
        dataSet.addValue(5000, "第三季度", "J2SE类");
        dataSet.addValue(4000, "第三季度", "J2ME类");
        dataSet.addValue(8000, "第三季度", "J2EE类");
        //添加第四季度数据
        dataSet.addValue(8000, "第四季度", "J2SE类");
        dataSet.addValue(2000, "第四季度", "J2ME类");
        dataSet.addValue(9000, "第四季度", "J2EE类");
        return dataSet;
    }
/*   createDataSet()方法定义在ChartUtil类中,它是一个自定义的制图工具类。在此类中,还包含创建制图对象的方法createChart(),用于柱形图对象,其关键代码如下:                       */
    /**
     * 创建JFreeChart对象
     * @return JFreeChart对象
     */

    public static JFreeChart createChart() {
        //通过ChartFactory创建JFreeChart
        JFreeChart chart = ChartFactory.createBarChart3D(
                "JAVA图书销量统计",           //图表标题
                "JAVA图书",                   //横轴标题
                "销量(本)",                //纵轴标题
                createDataSet(),            //数据集合 
                PlotOrientation.VERTICAL,   //图表方向
                true,                       //是否显示图例标识
                false,                      //是否显示tooltips
                false);                     //是否支持超链接
        //背景图片
        Image image = null;
        try {
            //创建背景图片
            image = ImageIO.read(ChartUtil.class.getResource("test.JPG"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //设置标题字体
        chart.getTitle().setFont(new Font("隶书",Font.BOLD,25));
        //设置图例类别字体
        chart.getLegend().setItemFont(new Font("宋体",Font.PLAIN,12));
        chart.setBorderVisible(true);   //设置显示边框
        //实例化TextTitle对象
        TextTitle subTitle = new TextTitle("2009年Java类图书全国销量统计(J2SE、J2ME、J2EE)");
        //设置居中显示
        subTitle.setVerticalAlignment(VerticalAlignment.BOTTOM);
        chart.addSubtitle(subTitle);    //添加子标题
        //获取绘图区对象
        CategoryPlot plot = chart.getCategoryPlot();
        plot.setForegroundAlpha(0.8F);  //设置绘图区前景色透明度
        plot.setBackgroundAlpha(0.5F);  //设置绘图区背景色透明度
        plot.setBackgroundImage(image); //设置绘图区背景图片
        //获取坐标轴对象
        CategoryAxis categoryAxis = plot.getDomainAxis();
        //设置坐标轴标题字体
        categoryAxis.setLabelFont(new Font("宋体",Font.PLAIN,12));
        //设置坐标轴标尺值字体
        categoryAxis.setTickLabelFont(new Font("宋体",Font.PLAIN,12));
        //设置坐标轴标题旋转角度
        categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
        //获取数据轴对象
        ValueAxis valueAxis = plot.getRangeAxis();
        //设置数据轴字体
        valueAxis.setLabelFont(new Font("宋体",Font.PLAIN,12));
        //获取图片渲染对象
        BarRenderer3D renderer = new BarRenderer3D();
        renderer.setItemMargin(0.32);   //设置柱子间的间距
        plot.setRenderer(renderer);     //设置图片渲染对象
        return chart;
    }
}

制图对象、绘图区对象、坐标轴对象、图片渲染对象等属性进行设置,并添加了一个子标题。实例中通过index.jsp页面

在此方法中,首先创建了一个3D效果的柱形图对象,在创建之后分别对制图对象、绘图区对象、坐标轴对象、图片渲染对象等属性进行设置,并添加了一个子标题。

JFreeChart 内置JDBC 的使用

在实际开发过程中,数据集合中的数据大部分来自于数据库,所以在制图前,需要进行数据库操作来获取数据。JFreeChart组件对这一过程进行了封装,通过自定义的SQL语句就可获取到已封装好的数据集合对象。

常用的JDBC数据集合对象有三种,分别为:JDBCCategoryDataSet(JDBC填充类别数据集合)、JDBCPieDataSet(JDBC填充饼形图数据集合)、JDBCXYDataset(JDBC填充坐标轴数据集合)。它们的使用方法都非常简单,如创建JDBCPieDataSet对象的方法如下:

public JDBCPieDataset(String url,String driverName,String user,String password )throws SQLException, ClassNotFoundException

参数说明:

url: 数据库连接的url ;
driverName :数据库的驱动类.
user : 数据库连接用户名
password : 数据库连接密码.

创建了JDBCPieDataset 对象后,可以通过executeQuery()方法查询数据库,其入口参数为String类型的SQL语句,执行此方法后,将返回拥有数据的数据集合对象。

数据集合与制图对象的创建定义在ChartUtil类中,它是一个自定义制图工具类,用于创建数据集合及制图对象,其关键代码如下:

import java.awt.Font;

import java.text.NumberFormat;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.data.general.PieDataset;
import org.jfree.data.jdbc.JDBCPieDataset;

public class ChartUtil {
    //查询数据库并初始化数据集合
    public static PieDataset initPieData() {
          String driverName = "com.mysql.jdbc.Driver";                    // 数据库驱动
          String url = "jdbc:mysql://localhost:3306/db_database20";     // 数据库连接url
          String user = "root";                                           // 数据库用户名
          String password = "wy136416";                                           // 数据库密码
          JDBCPieDataset dataset = null;                                          //数据集合
          try {
                dataset = new JDBCPieDataset(url, driverName, user, password); // 通过JDBC创建数据集合
                String query = "select category,val from tb_shop";  // SQL语句
                dataset.executeQuery(query);                             // 查询并向数据集合中添加数据
                dataset.close();                                             //关闭数据库连接
          } catch (Exception e) {
                e.printStackTrace();
          } 
          return dataset;
    }
    //创建饼形图实例
    public static JFreeChart createChart() {
          // 创建3D饼型图表
          JFreeChart chart = ChartFactory.createPieChart3D(
                      "XX商城月销量统计",     // 图表的标题
                      initPieData(),             // 饼形图的数据集对象
                      true,                       // 是否显示图例
                      true,                       // 是否显示提示文本
                      false);                     // 是否生成超链接
          chart.getTitle().setFont(new Font("隶书",Font.BOLD,25));         //设置标题字体
          chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //设置图例类别字体
          PiePlot plot = (PiePlot) chart.getPlot();                                      // 获得绘图区对象
          plot.setForegroundAlpha(0.5f);                                                // 设置前景透明度
          plot.setLabelFont(new Font("宋体",Font.PLAIN,12));         // 设置分类标签的字体
          plot.setCircular(true);     // 设置饼形为正圆
          // 设置分类标签的格式
          plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}={2}",
                      NumberFormat.getNumberInstance(),
                      NumberFormat.getPercentInstance()));
          return chart;
    }
}

initPieData()方法用于创建数据集合对象,在此方法中,使用JDBCPieDataset类通过JDBC查询数据库获取数据集合对象。
createChart()方法用于创建饼形图制图对象,在创建制图对象后,并对其相关属性进行了设置。

PiePlot类的setLabelGenerator()方法用于设置分类标签的格式,其参数为StandardPieSectionLabelGenerator对象,此对象的入口参数”{0}={2}”用于指定类别名称及所占有的百分比,{0}代表类别名称,{2 }代表百分比。

编写了ChartUtil类后,通过index.jsp页面查看图片,其关键代码如下:

<%@ page language="java" contentType="text/html" pageEncoding="GBK"%>
<%@page  import="org.jfree.chart.servlet.ServletUtilities,com.lyq.util.ChartUtil"%>

<html>
  <head>
        <title>商城月销量统计title>
   head>
   <body>
   <% 

   String fileName=ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),500,session);
   String graphURL =request.getContextPath()+"/DisplayChart?filename="+fileName;

   %>
   <div align="center">
           <img src="<%=graphURL%>" border="1">
    div>
    body>
    html>

中文乱码的解决方案

由于JFreeChart组件的版本、操作平台、JDK的设置等因素,在使用JFreeChart组件时,可能出出现中文乱码的现象。遇到此问题时,可通过设置乱码文字的字体进行解决,在此笔者提供两种解决此问题的方法。

l 设置主题样式
在制图前,创建主题样式并指定样式中的字体,通过ChartFactory的setChartTheme()方法设置主题样式,在指定制图样式后,ChartFactory对象创建的制图对象将按此样式进行显示,图表中的文字将按指定的字体进行显示。
例如:

StandardChartTheme standardChartTheme = new StandardChartTheme("CN");       //创建主题样式     
standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));          //设置标题字体
standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));             //设置图例的字体
standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));               //设置轴向的字体
ChartFactory.setChartTheme(standardChartTheme);                              //应用主题样式

通过上述代码设置主题样式后,再通过ChartFactory创建JFreeChart的对象,可以解决中文乱码问题。
l 指定乱码文字的字体
此方法通过指定制图对象中的中文字体解决中文乱码问题,在图中任何用到中文的地方,都要对字体进行设置,此操作将涉及到JFreeChart对象、Plot对象、坐标轴对象的属性设置。
例如:

JFreeChart chart = null;
            ……                 // 省略部分代码
chart.getTitle().setFont(new Font("隶书",Font.BOLD,25));              // 设置标题字体
chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15));   // 设置图例类别字体
PiePlot plot = (PiePlot) chart.getPlot();                                           // 获得绘图区对象
plot.setLabelFont(new Font("宋体",Font.PLAIN,12));                     // 设置分类标签的字体

不同的制图对象类型,其相关字体的设置可能存在差异。

JFreeChart 案列集锦

绘制饼状图

在一些网站中,有时会应用到饼图来进行数据统计及分析,比如统计不同行业的市场占有率情况,利用饼图可以更直观的查看统计结果。

实现过程如下:
创建用于绘制饼状图的类ChartUtil。首先在该类中编写createDateSet()方法,该方法用于创建饼图的数据集合对象,并在集合中添加5个不同的数据,关键代码如下:

private static PieDataset createDataset(){
          DefaultPieDataset dataset = new DefaultPieDataset();                        //创建饼图的数据集合
          dataset.setValue("One", new Double(43.200000000000003D));           //向数据集合中添加数据
          dataset.setValue("Two", new Double(10.0D));
          dataset.setValue("Three", new Double(20.5D));
          dataset.setValue("Four", new Double(14.5D));
          dataset.setValue("Five", new Double(11.0D));
          return dataset;                                                                 //返回数据集合
}

(2)创建createChart()方法,用于绘制饼状图。关键代码如下:

public static JFreeChart createChart(){ 
          JFreeChart jfreeChart = ChartFactory.createPieChart("饼状图", createDataset(), true, true, false); //创建JFreeChart对象
          TextTitle localTextTitle = jfreeChart.getTitle();             //获取标题
          localTextTitle.setFont(new Font("宋体",0,15));           //标题字体样式
          PiePlot localPiePlot = (PiePlot)jfreeChart.getPlot();       //获取绘图区对象
          localPiePlot.setLabelFont(new Font("宋体", 0, 12));     //设置分类标签的字体
          localPiePlot.setCircular(false);                             //设置饼图是否一定是正圆
          return jfreeChart; 
}

(3)创建index.jsp页,显示生成的饼状图。关键代码如下:

  <body> 
    <%  //通过saveAsJPEG()方法生成饼状图的JPEG图像,并返回一个临时图像名称
               String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),400,300,session);
               String chartUrl = path+"/DisplayChart?filename="+filename;//获取生成图像的相对路径
     %>
     <img alt="" src="<%=chartUrl %>">
  body>

生成柱状图

JFreeChart是一个很简单易用而且功能很强大的报表工具,它可以生成很多统计图,比如柱状图、饼图、折线图等等。下面以粮食价格分析为例,给读者介绍JFreeChart柱状图的使用

实现过程如下:

(1)创建ChartUtil类,在该类中编写生成柱状图的数据集合对象的方法createDataSet(),关键代码如下:

private static CategoryDataset createDataset(){
             DefaultCategoryDataset dataset = new DefaultCategoryDataset();//创建柱状图数据集合对象
             dataset.setValue(4.4D, "", "大米");//填充数据
             dataset.setValue(2.0D, "", "玉米");//填充数据
             dataset.setValue(5.8D, "", "小麦");//填充数据
             dataset.setValue(1.0D, "", "高粱");//填充数据
             dataset.setValue(5.8D, "", "黄豆");//填充数据
             return dataset;
}

(2)编写生成柱状图的方法createChart(),关键代码如下:

    public static JFreeChart createChart(){
            StandardChartTheme standardChartTheme = new StandardChartTheme("CN");  //创建主题样式
            standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));    //设置标题字体
            standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));        //设置图例的字体
            standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));          //设置轴向的字体
            ChartFactory.setChartTheme(standardChartTheme);                                 //设置主题样式
            JFreeChart chart = ChartFactory.createBarChart(
                         "粮食价格对比图",        //标题
                         "粮食",                          //横轴标题
                         "价格(每公斤)",         //纵轴标题
                         createDataset(),               //数据集合
                         PlotOrientation.VERTICAL, //图表方向
                         false,                      //是否显示图例标识
                         false,                      //是否显示toolTips
                         false);                      //是否生成超链接
            return chart;
       }

完整源码
index.jsp


<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.ChartUtil"  %> 
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>生成柱状图title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),400,300,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

web.xml


<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jspwelcome-file>
  welcome-file-list>
  <servlet>
    <servlet-name>DisplayChartservlet-name>
    <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
  servlet>
  <servlet-mapping>
    <servlet-name>DisplayChartservlet-name>
    <url-pattern>/DisplayCharturl-pattern>
  servlet-mapping>
web-app>

绘制折线图

下面将介绍如何应用JFreeChart组件绘制折线图。

实现过程如下:
(1)创建ChartUtil类,编写生成折线图数据集合对象的方法createChart(),在该方法中,首先需要应用org.jfree.data.xy.XYSeries创建表示折线的3个对象,分别用于表示3个不同城市的折线图,然后在将这几个折线对象添加到数据集合中。关键代码如下:

    public static JFreeChart createChart(){
            StandardChartTheme standardChartTheme = new StandardChartTheme("CN");  //创建主题样式
            standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));    //设置标题字体
            standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));        //设置图例的字体
            standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));          //设置轴向的字体
            ChartFactory.setChartTheme(standardChartTheme);                                 //设置主题样式
            JFreeChart chart = ChartFactory.createXYLineChart(
                         "房价走势对比图",                //标题
                         "年份",                                 //横轴标题
                         "价格(每平米)",                //纵轴标题
                         createDataset(),                      //数据集合
                         PlotOrientation.VERTICAL,    //图表方向
                         true,                              //是否显示图例标识
                         true,                              //是否显示toolTips
                         false);                             //是否生成超链接
             XYPlot localXYPlot = (XYPlot)chart.getPlot();    //获取折线数据区的Plot对象
             //获取折线数据区的数据点对象
             XYLineAndShapeRenderer localXYLineAndShapeRenderer = (XYLineAndShapeRenderer)localXYPlot.getRenderer();
             localXYLineAndShapeRenderer.setBaseShapesVisible(true);        //设置连接点为可见状态
             NumberAxis xAxis=(NumberAxis)localXYPlot.getDomainAxis();       //获取X轴
             xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());  //设置X轴数据为整型
             NumberAxis yAxis = (NumberAxis)localXYPlot.getRangeAxis();       //获取Y轴
             yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());  //设置Y轴的数据为整型
             return chart;
       }

生成区域图表

(1)创建ChartUtil类,编写生成区域图表数据集合对象的方法createChart()。区域图表的数据集合同样式CategoryDataset,所以在此处应用CateGoryDataset创建区域图表的数据结合对象。关键代码如下:

 private static CategoryDataset createDataset(){
             DefaultCategoryDataset dataset = new DefaultCategoryDataset();
             dataset.addValue(12.2D, "苹果", "3月份");
             dataset.addValue(11.1D, "苹果", "4月份");
             dataset.addValue(13.6D, "苹果", "5月份");
             dataset.addValue(8.3D, "苹果",  "6月份");
             dataset.addValue(9.6D, "苹果",  "7月份");
             dataset.addValue(9.2D, "香蕉", "3月份");
             dataset.addValue(8.4D, "香蕉", "4月份");
             dataset.addValue(7.6D, "香蕉", "5月份");
             dataset.addValue(7.9D, "香蕉",  "6月份");
             dataset.addValue(5.5D, "香蕉",  "7月份");
             dataset.addValue(7.6D, "西瓜", "3月份");
             dataset.addValue(7.8D, "香蕉", "4月份");
             dataset.addValue(7.0D, "香蕉", "5月份");
             dataset.addValue(5.5D, "香蕉",  "6月份");
             dataset.addValue(1.5D, "香蕉",  "7月份");
             return dataset;
       }

(2)编写生成区域图表的方法createChart(),关键代码如下:

  public static JFreeChart createChart(){
            StandardChartTheme standardChartTheme = new StandardChartTheme("CN");  //创建主题样式
            standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));    //设置标题字体
            standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));        //设置图例的字体
            standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));          //设置轴向的字体
            ChartFactory.setChartTheme(standardChartTheme);                                 //设置主题样式
            JFreeChart chart = ChartFactory.createAreaChart(
                         "水果价格区域图",                //标题
                         "水果",                                 //横轴标题
                         "价格(每公斤)",                //纵轴标题
                         createDataset(),                      //数据集合
                         PlotOrientation.VERTICAL,    //图表方向
                         true,                              //是否显示图例标识
                         true,                       //是否显示toolTips
                         false);                      //是否生成超链接
            CategoryPlot plot = (CategoryPlot)chart.getPlot();                      //获取数据区的图表对象
            plot.setDomainGridlinesVisible(true);                                                //设置显示网格
            plot.setForegroundAlpha(0.6f);                                                        //设置图表透明度
            NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis();            //获取Y轴
            numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());//设置Y轴数据为整型
            ChartUtilities.applyCurrentTheme(chart);                                   //使用当前设置的主题样式
            return chart;
       }

web.xml


<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jspwelcome-file>
  welcome-file-list>
  <servlet>
    <servlet-name>DisplayChartservlet-name>
    <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
  servlet>
  <servlet-mapping>
    <servlet-name>DisplayChartservlet-name>
    <url-pattern>/DisplayCharturl-pattern>
  servlet-mapping>
web-app>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.ChartUtil"  %>  
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>生成区域图title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),400,300,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

生成时序图

时序图主要用于绘制数据与日期、时间联系非常紧密的图表。常用于金融和财经类的图表绘制,如股市的走势图、货币变动趋势图等等。

实现过程如下:
(1)创建TimeSeriesUtil类,编写创建时序图表数据集合的方法getDataset()方法。时序图表的数据集合为TimeSeriesCollection类型,其数据为org.jfree.data.time.TimeSeries对象类型,通过TimeSeriesCollection类的实例对象的addSeries(TimeSeries timeseries)方法向数据集合中添加TimeSeries类型的数据。关键代码如下:

private static XYDataset getDataset(){
            TimeSeriesCollection dataset = new TimeSeriesCollection(); //创建时序图表的数据集合
            TimeSeries timeSeriesA = new TimeSeries("A股");//A股数据对象
            TimeSeries timeSeriesB = new TimeSeries("B股");//B股数据对象
            TimeSeries timeSeriesC = new TimeSeries("C股");//C股数据对象
            for(int i=1;i<=12;i++){//循环一年的月份
                  timeSeriesA.add(new Month(i,2010),new Random().nextDouble()*9);//向A股对象中添加随机数据
                  timeSeriesB.add(new Month(i,2010),new Random().nextDouble()*8); //向B股对象中添加随机数据
                  timeSeriesC.add(new Month(i,2010),new Random().nextDouble()*6); //向C股对象中添加塑胶数据
            }
            dataset.addSeries(timeSeriesA);//将数据对象添加至数据集合
            dataset.addSeries(timeSeriesB); //将数据对象添加至数据集合
            dataset.addSeries(timeSeriesC); //将数据对象添加至数据集合
            return dataset;
      }

(2)编写生成时序图表的方法getTimeSeriesChart(),应用CharFactory的createTimeSeriesChart()方法创建时序图对象。关键代码如下:

 public static JFreeChart getTimeSeriesChart(){
            StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
            standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 24));    // 设置标题字体
            standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 14)); // 设置图例的字体
            standardChartTheme.setLargeFont(new Font("宋体", Font.BOLD, 18));           // 设置轴向的字体
            ChartFactory.setChartTheme(standardChartTheme);                                 // 设置主题样式
            JFreeChart timeChart = ChartFactory.createTimeSeriesChart(
                        "股票价格走势", 
                        "月份", 
                        "每股价格", 
                        getDataset(),
                        true, 
                        true, 
                        false);
            //timeChart.setBackgroundPaint(Color.MAGENTA);                   // 设置背景色
            XYPlot plot = timeChart.getXYPlot();
            DateFormat format = new SimpleDateFormat("MM月份");        // 创建日期格式对象
            DateAxis domainAxis = new DateAxis("2010年统计月份");       // 创建时间轴对象
            DateTickUnit dtu = new DateTickUnit(DateTickUnit.DAY, 29, format);
            domainAxis.setTickUnit(dtu);                // 设置横轴上的时间刻度的显示格式
            domainAxis.setLowerMargin(0.0);       // 设置图表空白
            domainAxis.setUpperMargin(0.0);         // 设置图表空白
            plot.setDomainAxis(domainAxis);           // 为绘图属性添加横轴对象
            return timeChart;
      }

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.*"  %>   
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>生成时序图title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(TimeSeriesUtil.getTimeSeriesChart(),700,400,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

web.xml


<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jspwelcome-file>
  welcome-file-list>
  <servlet>
    <servlet-name>DisplayChartservlet-name>
    <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
  servlet>
  <servlet-mapping>
    <servlet-name>DisplayChartservlet-name>
    <url-pattern>/DisplayCharturl-pattern>
  servlet-mapping>
web-app>

利用柱状图显示某网站的访问量

在开发软件的过程中,经常需要进行数据统计及分析,并将分析结果通过柱形图的方式展示出来,使分析结果更直观。本程序实现了对网站每天各个时间段不同模块访问量的统计功能.

实现过程如下:
(3)创建名称为ChartUtil的类,用于绘制图表及初始化图表所用到的数据。首先编写生成柱状图数据集合的方法getDataset(). 编写createChart()方法,用于创建JFreeChart对象绘制柱形图表。程序中通过绘图工厂ChartFactory进行创建,,其关键代码如下:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.io.IOException;
import java.util.*;
public class ChartUtil {

    private static CategoryDataset getDataset(){
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for(int i=1;i<=6;i++){
            dataset.addValue(new Random().nextInt(200), "新闻模块", (i+8)+":00");
            dataset.addValue(new Random().nextInt(200), "论坛模块", (i+8)+":00");
            dataset.addValue(new Random().nextInt(200), "下载模块", (i+8)+":00");
            dataset.addValue(new Random().nextInt(200), "博客模块", (i+8)+":00");
        }
        return dataset;
    }
    public static JFreeChart createChart(){
          // 创建制图的主题样式
        StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
        // 设置轴向的字体
        standardChartTheme.setLargeFont(new Font("黑体", Font.BOLD, 16));
        // 设置图例的字体
        standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 16));
        // 设置标题字体
        standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 24));
        ChartFactory.setChartTheme(standardChartTheme);//设置制图工厂使用主题
        // 创建效果图
        JFreeChart chart = ChartFactory.createBarChart(
                                   "某网站的访问量", // 图表标题
                                   "", // 坐标标题
                                   "访问量", // 坐标标题
                                   getDataset(), // 绘制数据
                                   PlotOrientation.VERTICAL, // 直方图的方向,竖向
                                   true, // 定义图表是否包含图例
                                   true, // 定义图表是否包含提示
                                   false); // 定义图表是否包含URL
        // 定义图框颜色
        chart.setBackgroundPaint(new Color(168, 219, 219));
        // 获得图表对象引用,自行设置绘制属性
        CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(new Color(219, 219, 127)); // 设置绘图区域背景色
        plot.setDomainGridlinePaint(Color.BLACK); // 设置垂直方向标准线的颜色
        plot.setDomainGridlinesVisible(false); // 设置垂直方向标准线是否显示,false为默认值
        plot.setRangeGridlinePaint(Color.RED); // 设置水平方向标准线的颜色
        plot.setRangeGridlinesVisible(true); // 设置水平方向标准线是否显示,true为默认值

        // 设置横轴标题文字的旋转方向
        CategoryAxis domainAxis = (CategoryAxis) plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
                CategoryLabelPositions.createDownRotationLabelPositions(Math.PI /  // 文字顺时针旋转
                16.0) );// 文字旋转弧度,接受双精度参数
        // 结束自定义图表绘制的相关属性
        ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());

        return chart;
    }
}

创建index.jsp页,显示生成的柱状图。关键代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.ChartUtil"  %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>利用柱状图显示网站的访问量title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),700,300,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

外插个地址 swing +JFreeChart 和HighCharts 报表

Swing+JFreeChart

代码地址

HighCharts地址

HighCharts 菜鸟地址

JFreeChart 易百教程

利用饼图显示不同编程语言的市场占用率

学习了饼图的绘制方法之后,下面介绍一下如何利用JFreeChart组件生成的饼图显示不同编程语言的市场占有率情况.

实现过程如下:
(1)创建ChartUtil类,在该类中编写生成饼图数据集合的方法getDataset(),关键代码如下:

   private static PieDataset getDataset(){
            DefaultPieDataset dataset = new DefaultPieDataset();//创建饼图数据集合
            dataset.setValue("Java", 30);  //添加数据
            dataset.setValue("C#", 25);            //添加数据
            dataset.setValue("C++", 20); //添加数据
            dataset.setValue("PHP", 15); //添加数据
            dataset.setValue("C语言", 10); //添加数据
            return dataset;
      }

(2)编写生成饼图的方法createChart(),关键代码如下:

public static JFreeChart createChart(){
      StandardChartTheme standardChartTheme = new StandardChartTheme("CN");       // 创建制图的主题样式
      standardChartTheme.setLargeFont(new Font("黑体", Font.BOLD, 16));                // 设置轴向的字体
      standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 16));               // 设置图例的字体
      standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 24));         // 设置标题字体
      ChartFactory.setChartTheme(standardChartTheme);                                       //设置制图工厂使用主题
     JFreeChart chart = ChartFactory.createPieChart(
                                   "不同编程语言的市场占有率",     // 图表标题
                                   getDataset(),                         // 绘制数据
                                   true,                                   // 定义图表是否包含图例
                                   true,                                     // 定义图表是否包含提示
                                   false);                                  // 定义图表是否包含URL
         PiePlot plot = (PiePlot)chart.getPlot(); 
         plot.setLabelGenerator(
                     new StandardPieSectionLabelGenerator("{0}{2}",
                     NumberFormat.getNumberInstance(), 
                     NumberFormat.getPercentInstance()));//设置分类标签的格式,更改数字的显示格式为百分比
         plot.setBackgroundAlpha(0.8f);       //设置背景透明度
         plot.setForegroundAlpha(0.4f);       //设置前景透明度
    return chart;
}

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.ChartUtil"  %>  
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>利用饼图显示不同语言市场占有率title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),500,300,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

web.xml


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>DisplayChartservlet-name>
        <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>DisplayChartservlet-name>
        <url-pattern>/DisplayCharturl-pattern>
    servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>

利用折线图显示气温变化情况

使用折线图可以更清晰的查看统计结果的变化情况。本程序将通过折线图显示3月份到11月份之间的不同城市的气温变化情况。

实现过程如下:
(1)创建ChartUtil类,编写用于生成折线图表数据集合的方法getDataset(),关键代码如下:
private static CategoryDataset getDataset(){
DefaultCategoryDataset dataset = new DefaultCategoryDataset();//创建数据集合
Number[]temperature1 = {-6,2,10,20,29,33,26,19,-1};//不同月份的温度值数组
Number[]temperature2 = {-15,-2,6,18,26,29,32,15,-5};
Number[]temperature3 = {-20,-10,1,14,20,25,29,12,-10};
for(int i=3;i<=11;i++){
dataset.addValue(temperature1[i-3], “北京”, i+”月”);//添加数据
dataset.addValue(temperature2[i-3], “长春”, i+”月”);//添加数据
dataset.addValue(temperature3[i-3], “哈尔滨”, i+”月”);//添加数据
}
return dataset;
}
(2)编写绘制折线图表的方法createChart(),关键代码如下:
public static JFreeChart createChart(){
StandardChartTheme standardChartTheme = new StandardChartTheme(“CN”); // 创建制图的主题样式
standardChartTheme.setLargeFont(new Font(“黑体”, Font.BOLD, 16)); // 设置轴向的字体
standardChartTheme.setRegularFont(new Font(“宋体”, Font.BOLD, 16)); // 设置图例的字体
standardChartTheme.setExtraLargeFont(new Font(“隶书”, Font.BOLD, 24)); // 设置标题字体
ChartFactory.setChartTheme(standardChartTheme); // 设置制图工厂使用主题
JFreeChart chart = ChartFactory.createLineChart(
“气温变化情况”, // 图表标题
“月份”,
“温度”,
getDataset(), // 绘制数据
PlotOrientation.VERTICAL, // 图表方向
true, // 定义图表是否包含图例
true, // 定义图表是否包含提示
false); // 定义图表是否包含URL
return chart;
}

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"  %>
<%@ page import="com.lh.util.ChartUtil"  %>  
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>利用折线图显示气温变化title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body> 
    <%
        String filename = ServletUtilities.saveChartAsJPEG(ChartUtil.createChart(),500,300,session);
        String chartUrl = path+"/DisplayChart?filename="+filename;
     %>
     <img alt="" src="<%=chartUrl %>">
  body>
html>

web.xml


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>DisplayChartservlet-name>
        <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>DisplayChartservlet-name>
        <url-pattern>/DisplayCharturl-pattern>
    servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>

利用区域图对比分析员工业绩

区域图的表现形式是多样的,它可以用于描述数据的变化程度、部分与整体的关系、数据对比等。本程序通过员工的销售数据绘制区域图.

实现过程如下:
(1)创建名称为AreaChartUtil的类,它是绘制区域图的工具类,主要用于创建JFreeChart对象。此类提供两个方法,其中createDataset()方法用于创建绘制区域图所需要的数据集合,它使用Random类随机生成员工的销售数据,其关键代码如下:

public static CategoryDataset createDataset() {
      DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();//数据集合DefaultCategoryDataset对象
      Random random = new Random();              //创建Random对象
      //向数据集合加入6个月的数据
      for (int i = 1; i < 7; i++) {
            defaultcategorydataset.addValue(random.nextInt(10000) + 2000, "小王", i + "月份");
            defaultcategorydataset.addValue(random.nextInt(10000) + 2000, "小李", i + "月份");
            defaultcategorydataset.addValue(random.nextInt(10000) + 2000, "小刘", i + "月份");
      }
      return defaultcategorydataset;
}

(2)编写createChart ()方法,用于获取JFreeChart对象,此方法首先设置了区域图的主体样式,然后通过主体样式创建JfreeChart对象,并设置相应的属性值将其返回,其关键代码如下:

public static JFreeChart createChart() {
      JFreeChart jfreechart = null;                               //JFreeChart对象
      StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
      standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 24)); // 设置标题字体
      standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 15)); // 设置图例的字体
      standardChartTheme.setLargeFont(new Font("宋体", Font.BOLD, 15)); // 设置轴向的字体
      ChartFactory.setChartTheme(standardChartTheme);// 设置主题样式
      jfreechart=ChartFactory.createAreaChart(
                  "员工业绩",                                  // 图表标题
                  "部门员工",                                  // 横轴标题
                  "销售额",                              // 纵轴标题
                  createDataset(),                             //制图的数据集
                  PlotOrientation.VERTICAL,                    //定义区域图的方向为纵向
                  true,                                      // 是否显示图例标识
                  true,                                      // 是否显示tooltips
                  false);                                    // 是否支持超链接
      //获取categoryplot对象
      CategoryPlot categoryplot = (CategoryPlot)jfreechart.getPlot();
      categoryplot.setForegroundAlpha(0.5F);                     // 设置前景透明度为50%
      categoryplot.setDomainGridlinesVisible(true);                            //显示网格
      //创建子标题
      TextTitle textTile = new TextTitle("XX公司2009年上半年 销售部员工销售业绩");
      textTile.setVerticalAlignment(VerticalAlignment.BOTTOM);  //居中显示
      jfreechart.addSubtitle(textTile);                                         //将子标题放入jfreechart中
      //获取NumberAxis对象
      NumberAxis numberaxis = (NumberAxis)categoryplot.getRangeAxis();
      numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
      ChartUtilities.applyCurrentTheme(jfreechart);
      return jfreechart;
}
(3)创建AreaChartServlet类,它是一个Servlet。此类中,通过ServletUtilities类的saveChartAsJPEG()方法生成图表的访问路径,然后将其转发到result.jsp页面做出显示,其关键代码如下:
String w = request.getParameter("w");//图形的宽度

String h = request.getParameter("h");//图形的高度

if (w == null || w.isEmpty()) {

      w = "600";         //宽度默认值

}

if (h == null || h.isEmpty()) {

      h = "300";          //高度默认值

}

JFreeChart chart = AreaChartUtil.createChart();

// 初始化图表并获取文件名

String fileName = ServletUtilities.saveChartAsJPEG(chart, Integer.parseInt(w), Integer.parseInt(h), request.getSession());

// 生成图表的访问路径

String imageUrl = request.getContextPath()+ "/servlet/DisplayChart?filename=" + fileName;

request.setAttribute("imageUrl", imageUrl);

request.getRequestDispatcher("result.jsp").forward(request, response); // 转发请求到结果页面

(4)创建显示图表信息的jsp页面result.jsp,其关键代码如下:

<div align="center">

      <img src="${imageUrl}" border="1">

div>

web.xml


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>AreaChartServletservlet-name>
        <servlet-class>com.lyq.servlet.AreaChartServletservlet-class>
    servlet>
    <servlet>
        <servlet-name>DisplayChartservlet-name>
        <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>DisplayChartservlet-name>
        <url-pattern>/servlet/DisplayCharturl-pattern>
    servlet-mapping>

    <servlet-mapping>
        <servlet-name>AreaChartServletservlet-name>
        <url-pattern>/AreaChartServleturl-pattern>
    servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>

index.jsp

<%@ page language="java" pageEncoding="GBK"%>


<html>
  <head>
    <title>My JSP 'index.jsp' starting pagetitle>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body>
    <jsp:forward page="AreaChartServlet">jsp:forward>
  body>
html>

result.jsp

<%@ page language="java" pageEncoding="GBK"%>

<html>
  <head>
    <title>员工业绩title>
    <link rel="stylesheet" type="text/css" href="images/css.css">
  head>

  <body>
    <table align="center" border="0" width="826" height="688">
        <tr>
            <td background="images/bg.jpg">
                <img src="${imageUrl}" border="1" class="t1">
            td>
        tr>
    table>
  body>
html>

利用时序图分析商品月销售收益

下面介绍如何使用时序图分析商品月销售收益,程序中生成图表的数据是随机生成的,所以每次刷新页面,这个区域图都会改变。

实现过程如下:
(1)创建名称为TimeSeriesUtil的类,它是绘制时序图的工具类,专门用于构建绘制时序图所需的数据集合及创建JfreeChart对象。此类提供两个方法,其中createDataset ()方法用于创建时序图的数据集合,其关键代码如下:

public static XYDataset createDataset() {
      TimeSeries timeseries = new TimeSeries("Random Data");
      Day day = new Day(1, 1, 2009);
      double d = 3000D;
      // 添加一年365天的数据
      for (int i = 0; i < 365; i++) { 
            d = d + (Math.random() - 0.5) * 200;
            timeseries.add(day, d);
            day = (Day) day.next();
      }
      return new TimeSeriesCollection(timeseries); //返回数据集合对象
}

(3)createChart ()方法用于获取制图对象JFreeChart,此方法首先设置了时序图的主体样式,然后创建 JfreeChart对象,设置子标题及绘制属性等,并返回JFreeChart对象,其关键代码如下:

public static JFreeChart createChart() {
      StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
      standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 24));    // 设置标题字体
      standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 14)); // 设置图例的字体
      standardChartTheme.setLargeFont(new Font("宋体", Font.BOLD, 18));   // 设置轴向的字体
      ChartFactory.setChartTheme(standardChartTheme);                                // 设置主题样式
      JFreeChart jfreechart = ChartFactory.createTimeSeriesChart(
                  "时序图分析商品月销售收益", "2009 年销售情况", "销售额", createDataset(), false, false,false);
      jfreechart.setBackgroundPaint(Color.ORANGE);                 // 设置背景色
      XYPlot xyplot = jfreechart.getXYPlot();                             // 获取图表的绘制属性
      DateFormat format = new SimpleDateFormat("MM月份"); // 创建日期格式对象
      DateAxis domainAxis = new DateAxis("2009年统计月份");      // 创建时间轴对象
      DateTickUnit dtu = new DateTickUnit(DateTickUnit.DAY, 29, format);
      domainAxis.setTickUnit(dtu);                                           // 设置横轴上的时间刻度的显示格式
      domainAxis.setLowerMargin(0.0);                                           // 设置图表空白
      domainAxis.setUpperMargin(0.0);                                           // 设置图表空白
      xyplot.setDomainAxis(domainAxis);                                        // 为绘图属性添加横轴对象
      return jfreechart;
}

(3)编写处理页面请求的Servlet,名称为TimeSeriesServlet。此类中,通过接收width、height参数,设置生成图片的宽度及高度,并生成时序图的访问路径,将其转发到result.jsp进行显示。

index.jsp

<%@ page language="java" pageEncoding="GBK"%>


<html>
  <head>
    <title>My JSP 'index.jsp' starting pagetitle>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
  head>

  <body>
    <jsp:forward page="TimeSeriesServlet">jsp:forward>
  body>
html>

result.jsp

<%@ page language="java" pageEncoding="GBK"%>

<html>
  <head>
    <title>商品销售收益title>
    <link rel="stylesheet" type="text/css" href="images/css.css">
  head>

  <body>
    <table align="center" border="0" width="748" height="620">
        <tr>
            <td background="images/bg.jpg" align="center" valign="top">
                <img src="${imageUrl}" border="1" class="t1">          
            td>
        tr>
    table>
  body>
html>

web.xml


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>TimeSeriesServletservlet-name>
        <servlet-class>com.lyq.servlet.TimeSeriesServletservlet-class>
    servlet>
    <servlet>
        <servlet-name>DisplayChartservlet-name>
        <servlet-class>org.jfree.chart.servlet.DisplayChartservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>DisplayChartservlet-name>
        <url-pattern>/servlet/DisplayCharturl-pattern>
    servlet-mapping>
    <servlet-mapping>
        <servlet-name>TimeSeriesServletservlet-name>
        <url-pattern>/TimeSeriesServleturl-pattern>
    servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>

你可能感兴趣的:(JfreeChart,学习笔记)