JFreeChart 可用于生成各式各样的统计图表,只要开发人员提供符合 JFreeChart 所需格式的数据,JFreeChart 即可自动生成相应的统计图表,这些统计图表既可以直接输出成图片文件,也可被导出成 PDF 文档。
JFreeChart 的安装和使用
为了使用 JFreeChart 来生成统计图表,必须下载和安装 JFreeChart 项目。下载和安装 JfreeChart 的步骤比较简单:登录 http://www.jfree.org/jfreechart/download.html 即可下载 JFreeChart 的最新版,然后将 JFreeChart 所需的核心 JAR 包、第三方 JAR(位于 lib 路径下)复制到应用的 CLASSPATH 路径下即可;如果是 Web 应用则需要使用 JFreeChart 图表,将这些 JAR 文件复制到 Web 应用的 WEB-INF/lib 路径下。如果编译和运行中需要使用 JFreeChart 项目,则还应将 lib 路径下的 jfreechart-1.0.13.jar 文件添加到系统的 CLASSPATH 环境变量里;如果使用 Ant,或其他 IDE 工具,则无需添加环境变量。
JFreeChart 是一个非常优秀的图表工具,而且简单、易用,我们只需提供满足 JFreeChart 要求的数据,即可使用 ChartFactory 创建一个 JFreeChart 图表,该图表既可以输出成图片文件,也可以导出成各种格式的文档。
现在将以生成一张饼图为例,示范如何使用 JFreeChart 生成统计图。下面是生成饼状图的 Java 代码:
清单 1. PieChartDemo.java
上面代码先提供一个方法,该方法返回 Dataset 对象,这个 Dataset 就是创建统计图表的底层数据,然后调用 ChartFactory 的 createPieChart 方法来生成一个 JFreeChart 对象,这个对象就是统计图表,该图表可以直接输出到图片文件中,也可导出成各种格式的文件。
上面示例是导出了一个 JPG 格式的图片文件,编译、运行上面程序,将生成一个 book.jpg 文件,使用 ACDSee 浏览该图片,将看到如图 1 所示的饼图。
图 1. 使用 JFreeChart 生成的饼图
从图 1 中可以看出,JFreeChart 统计图可以分成 3 个部分:
- 图表标题部分。
- 实际统计图部分。
- 图表图例部分。
结合上面代码部分可以看出,修改统计图表的标题部分(包括修改图表标题内容、字体大小等)都是通过 JFreeChart 对象的 setTitle 方法实现的,修改统计图表的图例则通过 LegendTitle 对象来完成。一个统计图可以包含多个图例,当调用 JFreeChart 对象的 getLegend(int index)方法时,就可以取得该图表的指定索引的图例对象,一旦取得了指定图例,就可以修改图例的文本内容、字体大小等。
在上面程序中,我们调用了 ChartFactory 的 createPieChart 方法,该方法用于创建一个平面的饼图;如果将该方法修改为 createPieChart3D,则用于创建一个 3D 饼图,创建 3D 饼图时,我们将前景色修改为 0.5 的透明度,将看到生成如图 2 所示的 3D 饼图。
图 2. 使用 JFreeChart 生成的 3D 饼图
JFreeChart 开发步骤
通过上面的开发过程,我们不难发现通过 JFreeChart 开发统计图表是非常简单的,按如下步骤即可非常方便地开发出各种统计图表。
(1)提供一个 Dateset 实例,该实例里包含了创建统计图表的数据。
JFreeChart 使用 DataSet 来封装统计数据,程序首先应将需要显示的统计数据转换为 DataSet。不同的统计图表所使用的 Dataset 实例不一样,例如,饼图使用 PieDataset 实例作为饼图数据;而柱状图则采用 CategoryDataset 作为柱状图数据。
(2)使用 ChartFactory 的多个工厂方法 createXxxChart 来创建统计图表,统计图表就是一个 JFreeChart 对象。
(3)得到了 JFreeChart 对象后,可以调用 setTitle 来修改统计图表的标题;或者调用 getLegend 方法来获得指定索引的图表图例,取得图例对象后即可修改图表的图例。
(4)通过 JFreeChart 对象的 getPlot 方法,即可获得图表的 Plot 对象,该对象对应于统计图表的实际图表部分,可以调用 Plot 对象的方法来修改图表中的各种显示内容。
按上面的 4 个步骤进行,即可快速开发出各种简单的 JFreeChart 图表。
在上面步骤中,共涉及到 JFreeChart 的如下核心 API:
- XxxDataset:这是一个数据集对象,封装系统中需要显示的统计数据,用于提供显示图表所用的数据。对于不同类型的统计图表,也需要使用不同的 Dataset 对象。
- ChartFactory:该对象是一个图表工厂类,通过调用该工厂类的不同方法,即可生成不同的统计图表。
- JFreeChart:代表内存中的统计图表对象,JFreeChart 由如下 3 个部分组成:TextTitle(标题)、LegendTitle(图例标题)和 XxxPlot(实际统计图)。这个统计图表既可输出成图片文件,也可转换成内存中图片,直接在 Java 程序中显示出来。
- ChartUtilities:该类包含了系列输出统计图表的工具方法,包括输出各种格式的(如 JPG 和 PNG 等)的图表,包括直接输出到文件和普通输出流等。除此之外,该类还包含了创建 HTML 热点的方法(具体参看后面内容)。
- XxxPlot:实际统计图表对象,这个对象决定了实际图表的显示样式,创建该对象时需要 Axis、Renderer 及数据集对象的支持。
实际统计图表是根据 XxxPlot 对象生成的,为了生成 XxxPlot 对象,还需要额外的 Axis、Renderer 的支持;除此之外,如果希望在网页上生成带交互功能的热点图,还需要用到 XxxURLGenerator 和 XxxToolTipGenerator 等 API。即 JFreeChart 还包含如下常用的核心 API:
- XxxAxis:用于处理图表的两个轴:纵轴和横轴。
- XxxRenderer:负责如何显示一个图表对象。
- XxxURLGenerator:用于生成 Web 图表中每个项目的超级链接。
- XxxToolTipGenerator:用于生成图表的帮助提示,不同类型图表对应不同类型的工具提示类。
为 Struts 2 应用安装 JFreeChart 插件
为了在 Struts 2 中使用 JFreeChart 统计图表,Struts 2 提供了 JFreeChart 插件支持。借助于 JFreeChart 插件的支持,Struts 2 可以非常方便地使用 JFreeChart 统计图表。
借助于 JFreeChart 插件的支持,Struts 2 允许我们只需在 Action 中返回一个 JFreeChart 实例,而无需处理导出 JFreeChart 实例,在页面显示统计图表等细节。只要我们为 Action 指定一个类型为 chart 的 Result,该 Result 将自动生成一个 JFreeChart 图表来显示 Action 的处理结果。
与 Struts 2 的其他插件类似,安装 JFreeChart 插件非常容易,只需将 Struts 2 的 JFreeChart 插件复制到 Web 应用的 WEB-INF/lib 路径下即可。
查看 struts2-jfreechart-plugin-2.1.6.jar 文件中的 struts-plugin.xml 文件时,发现该配置文件中代码如下:
此处的 jfreechart-default 包已经继承了 struts-default,因此让我们配置 Action 所在包继承 jfreechart-default 即可。
除了要将上面的 struts2-jfreechart-plugin-2.1.6.jar 文件复制到 Web 应用的 WEB-INF/lib 路径下之外,当然还需要将 JFreeChart 的二进制类库文件复制到 Web 应用的 WEB-INF/lib 路径下。经过上面步骤,即完成了 Struts 2 和 JFreeChart 的整合。
在 Struts 2 应用中使用 JFreeChart
Struts 2.1 的改进
JFreeChart 插件要求用户的 Action 中 JFreeChart 类型的属性名只能是 chart(必须提供 getChart() 方法,且该方法返回 JFreeChart 对象),这种硬编码方式提供的统计图表大大降低了 Action 的灵活性。Struts 2.1 改进了这个地方,开发者允许使用任何方法返回一个 JFreeChart 对象。假如开发者提供了 getAbc() 方法返回一个 JFreeChart 对象,那需要开发者配置 Action 时配置一个名为 value 的参数。也就是增加如下配置:
将 JFreeChart 与 Struts 2 整合后,可以对 JFreeChart 统计图表的开发有一定的简化作用。下面就以一个简单的饼状图为例,介绍如何在 Struts 2 中使用 JFreeChart 统计图表。
创建 Action 类
如果仅仅使用 Struts 2 官方提供的 JFreeChart 插件,那么 Struts 2 的 JFreeChart 插件对开发 JFreeChart 并没有提供太多的简便,我们依然需要手动创建 JFreeChart 实例。如果需要的 Action 中的统计图表能被 Struts 2 处理,则要求该 JFreeChart 类型的属性名为 chart ——也就是要求该 Action 内必须有一个 getChart() 方法,该方法返回一个 JFreeChart 对象。
下面是该 Action 的实现类代码:
清单 2. ChartAction.java
上面 Action 类继承了 ActionSupport 类,因此无需提供 execute 方法——这是因为 ActionSupport 类已经提供了一个 execute() 方法,该方法返回一个 success 字符串作为逻辑视图,该 Action 直接使用 ActionSupport 的 execute 方法作为系统的处理逻辑。
从上面代码中不难发现,上面的 Action 有如下两个非常不灵活的地方:
- 需要手动创建 JFreeChart 实例,与创建普通 JFreeChart 图表没有太大的区别。
- Action 的统计图表属性名必须是 chart(必须提供 getChart() 方法,且该方法返回 JFreeChart 对象),这种硬编码方式提供的属性大大降低了 Action 的灵活性。
配置 Action
配置 JFreeChart 的 Action 非常简单,只需要为该 Action 指定一个类型为 chart 的 Result,该 Result 将使用 JFreeChart 统计图表来作为视图组件。配置类型为 chart 的 Result 时,可以指定两个参数:width 和 height,这两个参数分别指定统计图的宽和高。
因为前面已经定义了名为 jfreechart-default 的包,该包扩展了 Struts 2 系统的 struts-default 包,在 struts-default 包里增加了一个名为 chart 的 Result 类型。因此我们应该让 Struts 2 应用中自定义包继承 jfreechart-default 包即可。
下面是本示例应用的 struts-config.xml 文件:
清单 3. struts-config.xml
上面配置文件配置了一个名为 bookChart 的 Action,该 Action 将产生一个类型为 chart 的 Result。在浏览器中直接向 bookChart.action 发送请求,将看到如图 3 所示的统计图。
图 3. 整合 Struts 2 和 JFreeChart 生成统计图
从上面的程序中不难看出,Struts 2 的 JFreeChart 插件所完成的事情就是负责将 Action 里的 JFreeChart 实例提取出来,并输出到 HttpServletResponse 中。
分析 Struts 2 官方提供的 JFreeChart 插件不难发现,它的主要作用就是在页面中显示 Action 中的 JFreeChart 对象。因此 JFreeChart 插件所完成的工作非常有限,即使我们在 Struts 2 中整合了 JFreeChart 框架,我们依然需要自己手动创建 JFreeChart 实例,这是非常烦琐的事情。最理想的状况是我们只提供需要显示的数据,而 Struts 2 对 JFreeChart 进行封装,自动生成 JFreeChart 图表,并将其显示在 HTML 页面上。
下面我们将来介绍改进后的 JFreeChart 插件
改进 JFreeChart 插件
前面提到 Struts 2 的 JFreeChart 插件存在一些不够方便的地方,主要是 Struts 2 的 Action 还必须手动创建 JFreeChart 对象,这就显得比较繁琐了。
对于常见的饼图、柱状图,我们可以对 JFreeChart 插件进行适当改进,由 JFreeChart 插件来根据 Dataset 创建 JFreeChart 对象,这样就可以让 Struts 2 Action 开发者更加简便。
JFreeChart 插件的关键就是实现了一个名为“chart”的 Result Type,为了简化 JFreeChart 插件,我们改进这个名为“chart”的 Result Type,下面是改进过的 Result Type 类:
清单 4. CrazyChartResult.java
上面程序中粗体字代码就负责根据 Action 中 Dataset 来创建 JFreeChart 对象,从上面源代码中可以看出,这个 JFreeChart 插件只支持创建饼图和柱状图两种;如果开发者希望使用其他其他统计图,则依然需要手动创建 JFreeChart 对象。
提供了上面 CrazyChartResult 类之后,接下来为新的 Struts 2 插件提供 struts-plugin.xml 文件,这个文件的配置非常简单,只要将名为 chart 的 Result Type 改为使用 CrazyChartResult 类即可。下面是扩展后的 JFreeChart 插件中配置文件的代码:
从上面粗体字代码可以看出,此时的 JFreeChart 插件中名为“chart”的 Result Type 已经改为使用 CrazyChartResult 了,这就允许 Struts 2 中 Action 只要提供 Dataset 即可。
将这些资源打包成 JAR 文件,即可放在项目中正常使用了。扩展后的 JFreeChart 插件可下载本文的 struts2-crazytjfreechart-plugin-2.1.6.jar 附件。
使用改进后 JFreeChart 插件
提供了改进后的 JFreeChart 插件之后,接下来开发者开发的 Action 就会简单多了,下面的 Action 只有一个 getDataset() 方法,该方法返回创建 JFreeChart 的 Dataset 对象,不再需要手动创建 JFreeChart 对象——这个工作由扩展后的 JFreeChart 插件完成。
还是前面那个创建饼图的示例程序,但此时的 Action 就简单多了,下面是该 Action 类的代码:
清单 5. ChartAction.java
上面的 Action 类已经简化多了,该 Action 只需提供一个 Dataset 即可,剩下的事情都交给 JFreeChart 插件来完成。
当然,开发者还应该告诉 JFreeChart 需要创建怎样的统计图、统计图的标题等必要信息,因此配置该 Action 时需要更多的参数,下面是该 Action 的配置代码:
清单 6. struts.xml
上面配置文件中粗体字代码指定了创建统计图的类型(饼图)、统计图的标题,提供了这些必要信息之后,JFreeChart 插件即可根据 Action 提供的 Dataset、配置文件中提供的统计图标题、统计图类型自动生成统计图。在浏览器中直接向 bookChart.action 发送请求,将看到如图 3 所示的统计图。
图 4. 使用改进后的 JFreeChart 插件
从图 4 可以看出,改进后的 JFreeChart 插件可以根据 Action 提供的 Dataset 来生成统计图,但需要指出的是:采用这种方式生成的统计图显然无法设置太多的自定义属性——这是因为 JFreeChart 插件负责根据 Dataset 来创建 JFreeChart,而 JFreeChart 插件显然没法根据具体项目进行定制。
由此可见,改进后的 JFreeChart 插件用起来更方便;如果开发者需要获得对 JFreeChart 全部的控制,则依然可以在 Action 中手动创建 JFreeChart,从而弥补灵活性不足的缺点。
小结
JFreeChart 是一个非常优秀的统计图表工具,对于实际企业开发具有非常重要的作用。Struts 2 作为一个强大前端 MVC 框架,已经提供了对 JFreeChart 的封装,不过这种封装对于实际开发来说显得还不够简洁。本文主要从简洁、易用的角度对 Struts 2 的 JFreeChart 做了进一步改进,使得实际项目中可以更方便使用 JFreeChart 来生成统计图表。