`
julyboxer
  • 浏览: 220979 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多
JFreeChart项目简介

JFreeChart 是开放源代码站点SourceForge.net上的一个JAVA项目,它主要用来各种各样的图表,这些图表包括:饼图、柱状图(普通柱状图以及堆栈柱状 图)、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等。这些不同式样的图表基本上可以满足目前的要求。为了减少篇幅本文主要介绍前面三种类型的 图表,读者可以触类旁通去开发其他样式的图表。下面几个是JFreeChart产生的这三种类型图表的结果:


图1



图2



图3


上 面的三个图都是表示四个季度的某个产品的销量信息。在继续下面小节之前必须先准备好开发环境,因为是基于WEB浏览器的图表展现,因此需要一个 Servlet引擎或者是J2EE应用服务器(例如WebSphere,Tomcat等)。WEB环境的搭建就不累赘了,读者根据喜好自行安装。 JFreeChart引擎本身需要到SourceForge.net上下载,地址如下:

JFreeChart主页:        http://www.jfree.org/jfreechart/index.htmlJFreeChart下载页面:        http://sourceforge.net/projects/jfreechart/				      

下载的时候需要注意的是必须下载两个文件:JFreeChart以及Jcommon。目前最新配套版本是:JFreeChart 0.9.11 Jcommon 0.8.6

这里有点笔者在开发中遇见的问题需要注意的是:在使用Eclipse开发的时候会报一个莫名其妙的错误,错误可能指向某个类文件的第一行。遇到这样的问题一般是因为没有把Jcommon的jar包设置到项目的类路径中的缘故。具体的原因不祥。

解读JFreeChart的源码结构

在 开始使用JFreeChart之前我们有必要先大概了解一下JFreeChart本身的结构以及它所带一些例子程序,这样有助于我们下一步自行开发。下载 JFreeChart包后已经带有非常丰富的例子,因为JFreeChart这个项目本身的使用文档非常少,因此学习它最好的办法就是学习它所带的例子源 码。在包org.jfree.chart.demo中有几十个文件用于展示JFreeChart所能支持的所有图表的结果。如果你的JDK是比较新的情况 下可能在运行这些例子时会有问题,现象如下:

java.lang.UnsatisfiedLinkError: initDDraw	at sun.awt.windows.Win32OffScreenSurfaceData.initDDraw(Native Method)	at sun.awt.windows.Win32OffScreenSurfaceData.<clinit>(Win32OffScreenSurfaceData.java:141)	at sun.awt.Win32GraphicsDevice.<clinit>(Win32GraphicsDevice.java:58)	at sun.awt.Win32GraphicsEnvironment.makeScreenDevice(Win32GraphicsEnvironment.java:168)	at sun.java2d.SunGraphicsEnvironment.getScreenDevices(SunGraphicsEnvironment.java:240)	at sun.awt.Win32GraphicsEnvironment.getDefaultScreenDevice(Win32GraphicsEnvironment.java:61)	at java.awt.Window.init(Window.java:224)	at java.awt.Window.<init>(Window.java:268)	at java.awt.Frame.<init>(Frame.java:398)	at javax.swing.JFrame.<init>(JFrame.java:198)	at org.jfree.chart.demo.JFreeChartDemo.<init>(JFreeChartDemo.java:148)	at org.jfree.chart.demo.JFreeChartDemo.main(JFreeChartDemo.java:285)Exception in thread "main"

这 个错误是由于新版的Swing大量的使用了微软的DirectDraw的技术来提高画图的性能,而可能你的显卡在这时候会跟你闹点情绪或者显卡本身并不支 持这样的一个技术。难道就没有办法了嘛?要解决这个问题也非常简单,我们可以屏蔽掉DirectDraw,不让Swing使用该技术就可以了。在运行这些 代码时给虚拟机指定参数-Dsun.java2d.noddraw即可。

这时可能你又该纳闷了,不说是基于Web的图表嘛,怎么又扯到 Swing上了?这是因为为了使开发者容易上手,无需配置任何运行环境,所以这些例子都是基于GUI方式的用于展现给开发者如果生成一个图表,我们要学习 的也就是如何利用这个引擎生成图表而不是怎么来显示一个图表。当我们把生成的图表对象Export到一个图像文件即可在Web上发布。

下面我们来介绍JFreeChart中几个核心的对象类:

类名 类的作用以及简单描述
JFreeChart 图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象
XXXXXDataset 数据集对象,用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类
XXXXXPlot 图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis、Renderer以及数据集对象的支持
XXXXXAxis 用于处理图表的两个轴:纵轴和横轴
XXXXXRenderer 负责如何显示一个图表对象
XXXXXURLGenerator 用于生成Web图表中每个项目的鼠标点击链接
XXXXXToolTipGenerator 用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类

基 本上我认为JFreeChart项目本身的类结构的设计并不是很好,首先在创建图表的时候用到了大量的工厂方法,这样做虽然可以简化创建图表对象的代码, 但是对项目本身或者开发人员来讲自行扩展一种新的图表都仍然是一件很麻烦的事情;其次除图表对象本身外其余的类过于复杂,使用者必须去了解每个类型的图表 对象应该对应哪些Axis、Plot、Renderer类,并且必须非常熟悉这些类的构造函数中每个参数的具体含义。这些问题都大大困扰很多初学者。不 过,虽然存在很多问题,但是JFreeChart本身仍不失为一个非常优秀的图表引擎,况且项目本身也在逐渐的发展中。

在非常简略的介绍了JFreeChart本身的代码结构后,下面我们开始动手试验几个常用的图表并把他们放到web上。

使用JFreeChart生成各种样式的图表

限于篇幅的问题我们在这里只实现两种常用的图表,其他类型图表读者可以触类旁通。我们先给出柱状图的实现,饼图的实现再来跟柱状图进行比较。

1 柱状图

package lius.chart.demo;import java.io.*;import org.jfree.data.*;import org.jfree.chart.*;import org.jfree.chart.plot.*;/** * 该类用于演示最简单的柱状图生成 * @author Winter Lau */public class BarChartDemo {	public static void main(String[] args) throws IOException{		CategoryDataset dataset = getDataSet2();		JFreeChart chart = ChartFactory.createBarChart3D(							"水果产量图", // 图表标题							"水果", // 目录轴的显示标签							"产量", // 数值轴的显示标签							dataset, // 数据集							PlotOrientation.VERTICAL, // 图表方向:水平、垂直							true, 	// 是否显示图例(对于简单的柱状图必须是false)							false, 	// 是否生成工具							false 	// 是否生成URL链接							);									FileOutputStream fos_jpg = null;		try {			fos_jpg = new FileOutputStream("D:\\fruit.jpg");			ChartUtilities.writeChartAsJPEG(fos_jpg,100,chart,400,300,null);		} finally {			try {				fos_jpg.close();			} catch (Exception e) {}		}	}	/**	 * 获取一个演示用的简单数据集对象	 * @return	 */	private static CategoryDataset getDataSet() {		DefaultCategoryDataset dataset = new DefaultCategoryDataset();		dataset.addValue(100, null, "苹果");		dataset.addValue(200, null, "梨子");		dataset.addValue(300, null, "葡萄");		dataset.addValue(400, null, "香蕉");		dataset.addValue(500, null, "荔枝");		return dataset;	}	/**	 * 获取一个演示用的组合数据集对象	 * @return	 */	private static CategoryDataset getDataSet2() {		DefaultCategoryDataset dataset = new DefaultCategoryDataset();		dataset.addValue(100, "北京", "苹果");		dataset.addValue(100, "上海", "苹果");		dataset.addValue(100, "广州", "苹果");		dataset.addValue(200, "北京", "梨子");		dataset.addValue(200, "上海", "梨子");		dataset.addValue(200, "广州", "梨子");		dataset.addValue(300, "北京", "葡萄");		dataset.addValue(300, "上海", "葡萄");		dataset.addValue(300, "广州", "葡萄");		dataset.addValue(400, "北京", "香蕉");		dataset.addValue(400, "上海", "香蕉");		dataset.addValue(400, "广州", "香蕉");		dataset.addValue(500, "北京", "荔枝");		dataset.addValue(500, "上海", "荔枝");		dataset.addValue(500, "广州", "荔枝");		return dataset;	}}

程序运行结束后生成的图片文件效果如下图所示:


图4


如果是使用简单的数据即使用getDataSet方法获取数据集时产生的图片文件如下:


图5


2 饼图

对于饼图而言,数据集的获取用的不是同一个数据集类,另外饼图不支持同一个类别的项目中还有子项目这样的数据。我们只给出创建饼图的代码,至于写图表到一个文件则与柱状图一致,无需重复。

package lius.chart.demo;import java.io.*;import org.jfree.data.*;import org.jfree.chart.*;/** * 用于演示饼图的生成 * @author Winter Lau */public class PieChartDemo {	public static void main(String[] args) throws IOException{		DefaultPieDataset data = getDataSet();		JFreeChart chart = ChartFactory.createPie3DChart("水果产量图",  // 图表标题		data, 		true, // 是否显示图例		false,		false		);		//写图表对象到文件,参照柱状图生成源码	}	/**	 * 获取一个演示用的简单数据集对象	 * @return	 */	private static DefaultPieDataset getDataSet() {		DefaultPieDataset dataset = new DefaultPieDataset();		dataset.setValue("苹果",100);		dataset.setValue("梨子",200);		dataset.setValue("葡萄",300);		dataset.setValue("香蕉",400);		dataset.setValue("荔枝",500);		return dataset;	}}

生成的饼图文件效果如下:


图6



将生成的图表移到浏览器上

为了将生成的图表直接传给客户端浏览器,只需要将前面两个例子中的文件流换成是通过HttpServletResponse对象获取到的输出流,详细代码清单如下:

package lius.chart.demo;import java.io.IOException;import javax.servlet.*;import javax.servlet.http.HttpServlet;import org.jfree.data.*;import org.jfree.chart.*;/** * 演示通过servlet直接输出图表 * @author Winter Lau */public class ChartDemoServlet extends HttpServlet {	public void service(ServletRequest req, ServletResponse res)		throws ServletException, IOException 	{		res.setContentType("image/jpeg");		DefaultPieDataset data = getDataSet();		JFreeChart chart = ChartFactory.createPie3DChart("水果产量图",		data,		true,		false,		false		);						ChartUtilities.writeChartAsJPEG(res.getOutputStream(),			100,chart,400,300,null);	}	/**	 * 获取一个演示用的简单数据集对象	 * @return	 */	private static DefaultPieDataset getDataSet() {		DefaultPieDataset dataset = new DefaultPieDataset();		dataset.setValue("苹果",100);		dataset.setValue("梨子",200);		dataset.setValue("葡萄",300);		dataset.setValue("香蕉",400);		dataset.setValue("荔枝",500);		return dataset;	}}


高级主题

很 多情况我们不仅仅要求可以在浏览器上显示一个图表,我们更需要客户可以直接在图表上做一下交互的操作,例如获取信息提示,点击图表某个部分进行更详细信息 的展示等等。例如前面生成的简单柱状图,用户需要在看到柱状图后点击某种水果例如是苹果即可看到各个地区苹果产量的情况。为此就要求该图形具有交互操作的 功能。在HTML中为了让一个图像具有可交互的功能就必须给该图像定义一个Map对象。下表节选一段具有该功能的HTML代码

<MAP NAME="chartMap"><AREA SHAPE="RECT" COORDS="81,15,126,254" href="?series=0&category=100" title="100 = 7,048" 	onclick="javascript:clickChart('100');return false;"><AREA SHAPE="RECT" COORDS="143,27,188,255" href="?series=0&category=200" title="200 = 6,721" 	onclick="javascript: clickChart ('200');return false;"><AREA SHAPE="RECT" COORDS="205,54,250,255" href="?series=0&category=300" title="300 = 5,929" 	onclick="javascript: clickChart ('300');return false;"><AREA SHAPE="RECT" COORDS="267,85,312,255" href="?series=0&category=400" title="400 = 5,005" 	onclick="javascript: clickChart ('400');return false;"><AREA SHAPE="RECT" COORDS="329,17,374,255" href="?series=0&category=Diet" title="Diet = 7,017" onclick="javascript: 	clickChart ('Diet');return false;"></MAP>

由 此就产生了一个问题:如果根据一个图像来生成对应的MAP对象。我们回头看看刚才的代码,在创建一个图表对象时候有两个参数,我们举柱状图的例子来讲这两 个参数就是ChartFactory. createBarChart3D方法中的最后两个参数,这两个参数的类型都是布尔值。这两个参数意思分别是:是否创建工具提示(tooltip)以及是 否生成URL。这两个参数分别对应着MAP中一个AREA的title属性以及href属性。

可是我想知道的是怎么来产生这个MAP 啊!哈哈,不要着急,JFreeChart已经帮我们做好生成MAP对象的功能。为了生成MAP对象就要引入另外一个对象: ChartRenderingInfo。因为JFreeChart没有直接的方法利用一个图表对象直接生成MAP数据,它需要一个中间对象来过渡,这个对 象就是ChartRenderingInfo。下图是生成MAP数据的流程图:


图7

如 上图所示,ChartUtilities类是整个流程的核心,它周围的对象都是一些例如数据对象或者是文件等。这个流程简单描述如下:首先创建一个 ChartRenderingInfo对象并在调用ChartUtilities的writeChartAsJPEG时作为最后一个参数传递进去。调用该 方法结束后将产生一个图像文件以及一个填充好MAP数据的ChartRenderingInfo对象,有了这个对象我们还是没有办法获取具体的MAP数 据,我们还必须借助于ChartUtilities的writeImageMap方法来将ChartRenderingInfo对象读取出来,获取MAP 数据的代码片断如下:

		PrintWriter w = null;		FileOutputStream fos_jpg = null;		FileOutputStream fos_cri = null;		try{			//根据不同类型的图表使用不同类,以下是针对饼图的操作			PiePlot plot = (PiePlot) chart.getPlot();			plot.setURLGenerator(new StandardPieURLGenerator(url));			//设置工具提示		   plot.setToolTipGenerator(new StandardPieToolTipGenerator());			fos_jpg = new FileOutputStream(“d:\\fruit.jpg”); 			ChartUtilities.writeChartAsJPEG(				fos_jpg,				100,				chart,				400,				300,				info);			fos_cri = new FileOutputStream(__d:\\fruit.map__);			w = new PrintWriter(fos_cri);			ChartUtilities.writeImageMap(w, __mapname__, info);			w.flush();		}finally{			try{				w.close();			}catch(Exception e){}				try{				fos_cri.close();			}catch(Exception e){}				try{				fos_jpg.close();			}catch(Exception e){}		}

打 开文件D:\fruit.map,文件的内容就是要写到页面上的MAP数据。把生成的图像文件以及MAP数据文件写到页面上即可完成热点图表的功能。至于 怎么结合两者之间的关系例如图像的useMap属性值必须与MAP对象的名称结合起来,必须根据实际的应用情况进行相应的处理。笔者建议把二者通过标签库 封装起来,图像文件的名称以及MAP对象的名称由标签库统一进行控制,这样可以保证二者的一致性。

 

 

<一>前言:

JFreeChart是开放源代码站点SourceForge.net上的一个JAVA项目。它的功能十分强大,能创建饼图、柱状图(普通柱状图以及堆栈柱状图)、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等,并可生成PNG或JPG图片格式文件。
本人在学习过程中发现,网上很多文章都是讲一些JFreeChart的基本应用,而对JFreeChart生成热点图表这样常用的功能虽有所提及却没有一个完整的例子,所以我就写一个简单示例供大家参考,希望对大家的学习有所帮助。

<二>示例说明:

假设有一个关于程序员北京,上海,广洲三地程序员学历,开发语言,薪金情况的调查。首先要以饼图显示程序员学历的分布情况(index.jsp)。点击饼图的每一部分会以柱状图显示该层次程序员所用开发语言和薪金的情况(barview.jsp)。重点演示怎样在饼图上添加链接。

<三>准备工作:

1.下载最新版本的JFreeChart,当前为jfreechart-1.0.0-rc1
下载地址:http://www.jfree.org/jfreechart/index.html

2.解压文件,将jfreechart-1.0.0-rc1/lib下的jcommon-1.0.0-rc1.jar,jfreechart-1.0.0-rc1.jar复制到WEB应用的lib目录下。

3.在web.xml文件中增加以下内容:

<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>/servletDisplayChart</url-pattern>
</servlet-mapping>

<四>饼图页面代码(index.jsp)


<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="org.jfree.data.general.DefaultPieDataset"%>
<%@ page import="org.jfree.chart.*"%>
<%@ page import="org.jfree.chart.plot.*"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"%>
<%@ page import="org.jfree.chart.labels.StandardPieItemLabelGenerator"%>
<%@ page import="org.jfree.chart.urls.StandardPieURLGenerator"%>
<%@ page import="org.jfree.chart.entity.StandardEntityCollection"%>
<%@ page import="java.io.*"%>
<HTML>
<HEAD>
<META http-equiv=Content-Type content="text/html; charset=GBK">
<TITLE>nacl_zhuang@hotmail.com</TITLE>
</HEAD>
<BODY>
<%

DefaultPieDataset data = new DefaultPieDataset();
data.setValue("高中以下",370);
data.setValue("高中",1530);
data.setValue("大专",5700);
data.setValue("本科",8280);
data.setValue("硕士",4420);
data.setValue("博士",80);

PiePlot3D plot = new PiePlot3D(data);//3D饼图
plot.setURLGenerator(new StandardPieURLGenerator("barview.jsp"));//设定链接
JFreeChart chart = new JFreeChart("",JFreeChart.DEFAULT_TITLE_FONT, plot, true);
chart.setBackgroundPaint(java.awt.Color.white);//可选,设置图片背景色
chart.setTitle("程序员学历情况调查表");//可选,设置图片标题
plot.setToolTipGenerator(new StandardPieItemLabelGenerator());
StandardEntityCollection sec = new StandardEntityCollection();
ChartRenderingInfo info = new ChartRenderingInfo(sec);
PrintWriter w = new PrintWriter(out);//输出MAP信息
//500是图片长度,300是图片高度
String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, info, session);
ChartUtilities.writeImageMap(w, "map0", info, false);

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

%>

<P ALIGN="CENTER">
<img src="<%= graphURL %>" width=500 height=300 border=0 usemap="#map0">
</P>
</BODY>
</HTML>

生成的图片如下


在浏览器中点右键->查看源文件会发现有以下一段HTML代码:

<map id="map0" name="map0">
<area shape="poly" coords="247,61,250,61,250,123,250,123" title="博士 = 80" alt="" href="barview.jsp?category=博士&pieIndex=0"/>
<area shape="poly" coords="148,112,153,102,160,92,170,83,182,76,196,70,212,65,229,62,247,61,250,123,250,123" title="硕士 = 4,420" alt="" href="barview.jsp?category=硕士&pieIndex=0"/>
<area shape="poly" coords="324,167,311,173,297,179,282,182,266,185,250,186,234,185,217,183,202,179,188,173,175,167,
165,159,157,151,151,142,147,132,146,122,148,112,250,123,250,123" title="本科 = 8,280" alt=""
href="barview.jsp?category=本科&pieIndex=0"/>
<area shape="poly" coords="307,72,324,80,338,91,347,103,352,117,352,131,347,144,338,156,324,167,250,123,250,123" title="大专 = 5,700" alt="" href="barview.jsp?category=大专&pieIndex=0"/>
<area shape="poly" coords="261,62,285,65,307,72,250,123,250,123" title="高中
= 1,530" alt="" href="barview.jsp?category=高中&pieIndex=0"/>
<area shape="poly" coords="250,61,261,62,250,123,250,123" title="高中以下 = 370" alt="" href="barview.jsp?category=高中以下&pieIndex=0"/>
</map>


这就是MAP信息,我们在IMG标签中加入usemap="#map0"就可以为饼图的每一部分加入链接。

<五>柱状图页面代码:(barview.jsp)

<HTML>
<HEAD>
<META http-equiv=Content-Type content="text/html; charset=GBK">
<TITLE>nacl_zhuang@hotmail.com</TITLE>
</HEAD>

<body>

<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="org.jfree.chart.ChartFactory,
org.jfree.chart.JFreeChart,
org.jfree.chart.plot.PlotOrientation,
org.jfree.chart.servlet.ServletUtilities,
org.jfree.data.category.*"%>
<%
CategoryDataset dataset;
String category=request.getParameter("category");
category= new String(category.getBytes("ISO8859_1"), "GBK");
if(category.equals("本科")||category.equals("高中")||category.equals("大专"))
{
dataset=getDataSet();
}
else if(category.equals("硕士")||category.equals("博士"))
{
dataset=getDataSet2();
}else
{
dataset=getDataSet3();
}
String title=category+"程序员在各城市薪金情况统计";
JFreeChart chart = ChartFactory.createBarChart3D(title,
"城市",
"薪金",
dataset,
PlotOrientation.VERTICAL,
true,
false,
false);

String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, null, session);
String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename;
%>
<P ALIGN="CENTER">
<img src="<%= graphURL %>" width=500 height=300 border=0 usemap="#<%= filename %>">
</P>
<%!
private static CategoryDataset getDataSet() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(2000, "北京", "VB");
dataset.addValue(1800, "上海", "VB");
dataset.addValue(2200, "广州", "VB");
dataset.addValue(3200, "北京", "JAVA");
dataset.addValue(3500, "上海", "JAVA");
dataset.addValue(3600, "广州", "JAVA");
dataset.addValue(3300, "北京", "DOT NET");
dataset.addValue(3400, "上海", "DOT NET");
dataset.addValue(3700, "广州", "DOT NET");
dataset.addValue(2500, "北京", "DELPHI");
dataset.addValue(2800, "上海", "DELPHI");
dataset.addValue(3200, "广州", "DELPHI");
dataset.addValue(5000, "北京", "VC");
dataset.addValue(3500, "上海", "VC");
dataset.addValue(4600, "广州", "VC");
return dataset;
}
private static CategoryDataset getDataSet2() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(2000, "上海", "VB");
dataset.addValue(3000, "北京", "JAVA");
dataset.addValue(3330, "上海", "JAVA");
dataset.addValue(3500, "广州", "JAVA");
dataset.addValue(3500, "北京", "DOT NET");
dataset.addValue(4000, "上海", "DOT NET");
dataset.addValue(4800, "广州", "DOT NET");
dataset.addValue(2600, "北京", "DELPHI");
dataset.addValue(2200, "上海", "DELPHI");
dataset.addValue(4000, "北京", "VC");
dataset.addValue(4000, "上海", "VC");
dataset.addValue(4200, "广州", "VC");
return dataset;
}
private static CategoryDataset getDataSet3() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(2100, "北京", "VB");
dataset.addValue(2200, "上海", "VB");
dataset.addValue(2100, "广州", "VB");
dataset.addValue(3000, "北京", "JAVA");
dataset.addValue(3200, "上海", "JAVA");
dataset.addValue(3600, "广州", "JAVA");
dataset.addValue(4100, "北京", "DOT NET");
dataset.addValue(4200, "上海", "DOT NET");
dataset.addValue(4160, "广州", "DOT NET");
dataset.addValue(2400, "北京", "DELPHI");
dataset.addValue(2600, "上海", "DELPHI");
dataset.addValue(2500, "广州", "DELPHI");
dataset.addValue(5400, "北京", "VC");
dataset.addValue(5000, "上海", "VC");
dataset.addValue(5500, "广州", "VC");
return dataset;
}
%>
</body>
</html>

生成图片如下:

 

 

用JFreeChart画统计分析柱状图

        我们介绍使用 JFreeChart 生成柱状图,首先从一个最简单的例子开始。
一 最简单的例子

为了降低门槛,让大家心理有个底,先介绍一个简单的不能再简单的例子,图片中的各类属性都采用默认值。 <%@ page contentType="text/html;charset=GBK"%><BR>
<%@ page import="org.jfree.chart.ChartFactory,<BR>
org.jfree.chart.JFreeChart,<BR>
org.jfree.chart.plot.PlotOrientation,<BR>
org.jfree.chart.servlet.ServletUtilities,<BR>
org.jfree.data.DefaultCategoryDataset"%><BR>
<%
<BR>
DefaultCategoryDataset dataset = new DefaultCategoryDataset();<BR>
dataset.addValue(300, "广州", "苹果");<BR>
dataset.addValue(200, "广州", "梨子");<BR>
dataset.addValue(500, "广州", "葡萄");<BR>
dataset.addValue(340, "广州", "芒果");<BR>
dataset.addValue(280, "广州", "荔枝");<BR>
JFreeChart chart = ChartFactory.createBarChart3D("水果销量统计图",
"水果",
"销量",dataset,
PlotOrientation.VERTICAL,
false,
false,
false);<BR>
String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, null, session);<BR>
String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename;<BR>
%>
<IMG height=300 src="<%= graphURL %>" width=500 useMap="#<%= filename %>" border=0>
这个 JSP 程序运行的结果如下图



图 一

二 柱状图高级特性
        上面的程序简单,但生成的柱状图也很简单。更多的时候,我们可能需要不同的效果。org.jfree.chart.ChartFactory 这个工厂类有createBarChart,createStackedBarChart,createBarChart3D, createStackedBarChart3D这几个工厂方法创建不同类型的柱状图。关于这四个方法的 JFreeChart 的 Java Doc API 文档有详细说明,比较重要的是 PlotOrientation.VERTICAL 让平行柱垂直显示,而 PlotOrientation.HORIZONTAL 则让平行柱水平显示。
几个对柱状图影响较大的几个类,它们分别是:
org.jfree.chart.axis.CategoryAxis
org.jfree.chart.axis.ValueAxis
org.jfree.chart.renderer.BarRenderer
org.jfree.chart.renderer.BarRenderer3D
我们还是以实例来说明这几个类,先来假设一个需要统计的数据表:

  北京 上海 广州 成都 深圳
苹果 672 766 223 540 126
梨子 325 521 210 340 106
葡萄 332 256 523 240 526

根据上表数据,首先构造 CategoryDataset, 这里不再使用上面简单例子里面的 DefaultCategoryDataset 类,而是 DatasetUtilities 更有效的构造 CategoryDataset,如下列代码:

double[][] data = new double[][] {{672, 766, 223, 540, 126}, {325, 521, 210, 340, 106}, {332, 256, 523, 240, 526} };
String[] rowKeys = {"苹果","梨子","葡萄"};
String[] columnKeys = {"北京","上海","广州","成都","深圳"};
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);

用上面的 dataset 生成的 3D 柱状图


图 二

org.jfree.chart.axis.CategoryAxis
CategoryAxis domainAxis = plot.getDomainAxis();
//设置 columnKey 是否垂直显示
domainAxis.setVerticalCategoryLabels(true);
//设置距离图片左端距离
domainAxis.setLowerMargin(0.1);
//设置距离图片右端距离
domainAxis.setUpperMargin(0.1);
//设置 columnKey 是否间隔显示
domainAxis.setSkipCategoryLabelsToFit(true);
plot.setDomainAxis(domainAxis);
上面代码产生的效果如下图,注意与图二的区别。


图 三

org.jfree.chart.axis.ValueAxis

ValueAxis rangeAxis = plot.getRangeAxis();
//设置最高的一个柱与图片顶端的距离
rangeAxis.setUpperMargin(0.15);
//设置最低的一个柱与图片底端的距离
//rangeAxis.setLowerMargin(0.15);
plot.setRangeAxis(rangeAxis);

上面代码产生的效果如下图,注意与图二的区别。


图 四

org.jfree.chart.renderer.BarRenderer3D

BarRenderer3D renderer = new BarRenderer3D();
renderer.setBaseOutlinePaint(Color.BLACK);
//设置 Wall 的颜色
renderer.setWallPaint(Color.gray);
//设置每种水果代表的柱的颜色
renderer.setSeriesPaint(0, new Color(0, 0, 255));
renderer.setSeriesPaint(1, new Color(0, 100, 255));
renderer.setSeriesPaint(2, Color.GREEN);
//设置每种水果代表的柱的 Outline 颜色
renderer.setSeriesOutlinePaint(0, Color.BLACK);
renderer.setSeriesOutlinePaint(1, Color.BLACK);
renderer.setSeriesOutlinePaint(2, Color.BLACK);
//设置每个地区所包含的平行柱的之间距离
renderer.setItemMargin(0.1);
//显示每个柱的数值,并修改该数值的字体属性
renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setItemLabelFont(new Font("黑体",Font.PLAIN,12));
renderer.setItemLabelsVisible(true);

上面代码产生的效果如下图,注意与图二的区别。


图 五

补充两个有用的方法
补充 org.jfree.chart.plot.CategoryPlot 的两个方法,这两个方法对所有类型的图表都有作用,因为在前面没有介绍,这里补充一下。


//设置地区、销量的显示位置
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);

上面代码产生的效果如下图,注意与图二的区别。


图 六

三 完整范例
前面都是一些代码片段,现在把这些片段组合成一个完整范例。

<DIV class=code>
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.awt.Color,
java.awt.Font,
org.jfree.chart.ChartFactory,
org.jfree.chart.JFreeChart,
org.jfree.chart.plot.PlotOrientation,
org.jfree.chart.servlet.ServletUtilities,
org.jfree.data.CategoryDataset,
org.jfree.data.DatasetUtilities,
org.jfree.chart.plot.CategoryPlot,
org.jfree.chart.axis.CategoryAxis,
org.jfree.chart.axis.ValueAxis,
org.jfree.chart.renderer.BarRenderer3D,
org.jfree.chart.labels.StandardCategoryItemLabelGenerator,
org.jfree.chart.axis.AxisLocation"%>
<%
double[][] data = new double[][] {
{672, 766, 223, 540, 126},
{325, 521, 210, 340, 106},
{332, 256, 523, 240, 526}
};
String[] rowKeys = {"苹果","梨子","葡萄"};
String[] columnKeys = {"北京","上海","广州","成都","深圳"};
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
JFreeChart chart = ChartFactory.createBarChart3D("水果销量图统计",null,null,dataset,
PlotOrientation.VERTICAL,true,false,false);
chart.setBackgroundPaint(Color.WHITE);
CategoryPlot plot = chart.getCategoryPlot();
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalCategoryLabels(false);
plot.setDomainAxis(domainAxis);
ValueAxis rangeAxis = plot.getRangeAxis();
//设置最高的一个 Item 与图片顶端的距离
rangeAxis.setUpperMargin(0.15);
//设置最低的一个 Item 与图片底端的距离
rangeAxis.setLowerMargin(0.15);
<BR>plot.setRangeAxis(rangeAxis);
BarRenderer3D renderer = new BarRenderer3D();
renderer.setBaseOutlinePaint(Color.BLACK);
//设置 Wall 的颜色<BR>
renderer.setWallPaint(Color.gray);
//设置每种水果代表的柱的颜色
renderer.setSeriesPaint(0, new Color(0, 0, 255));
renderer.setSeriesPaint(1, new Color(0, 100, 255));
renderer.setSeriesPaint(2, Color.GREEN);
//设置每个地区所包含的平行柱的之间距离
renderer.setItemMargin(0.1);
//显示每个柱的数值,并修改该数值的字体属性<BR>
renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setItemLabelsVisible(true);
plot.setRenderer(renderer);
//设置柱的透明度<BR>
plot.setForegroundAlpha(0.6f);
//设置地区、销量的显示位置<BR>
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, null, session);
String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename;
%s>
<img src="<%= graphURL %>" width=500 height=300 border=0 usemap="#<%= filename %>"&gt;
</DIV>
看看程序运行的结果吧:


图 七

三 总结

我只介绍了少量的方法,更多的请参考 JFreeChart 的 Java Doc API 文档和 Sample Code。

分享到:
评论

相关推荐

    Jfreechart

    JFreeChart 是一个流行的 Java 库,用于创建各种类型的图表,包括饼图、折线图、柱状图等。在使用 JFreeChart 进行数据可视化时,可能会遇到乱码的问题,这通常与字体设置不当有关。本文将详细分析 Jfreechart 乱码...

    jfreechart所需jar包.zip

    JFreeChart是一款强大的Java图表库,它允许开发者创建多种类型的2D图表,包括折线图、柱状图、饼图、散点图等。在Java应用程序中,JFreeChart经常被用于数据分析和可视化,尤其在报表系统、数据分析工具或者任何需要...

    jfreechart的一个小总结

    JFreeChart 是一个开源的 Java 图表库,它允许开发者创建各种复杂的图表,如柱状图、饼图、散点图、线形图等。在本文中,我们将深入探讨 JFreeChart 的核心类和它们在创建图表过程中的作用。 1. **JFreeChart 类**...

    jfreechart绘制的风速风向玫瑰图

    jfreechart绘制的风速风向玫瑰图 jfreechart是Java中一个流行的图表库,它提供了许多种类的图表,包括柱状图、折线图、饼图、雷达图等。本文主要介绍如何使用jfreechart绘制风速风向玫瑰图。 首先,了解jfreechart...

    JFreeChart混合图表演示

    JFreeChart是一款强大的Java库,用于创建各种类型的图表,包括柱状图、饼图、线图、散点图等。在“JFreeChart混合图表演示”中,我们重点探讨如何利用JFreeChart来创建一个包含多种图表类型的混合图表,以提供更丰富...

    jfreechart使用的3个jar包

    **JFreeChart 使用详解** JFreeChart 是一个用于 Java 的开源图表库,它提供了一种简单的方法来创建各种复杂的图表,如折线图、柱状图、饼图、散点图以及更专业的图表类型,如甘特图和雷达图。在Java应用中,如果你...

    如何在eclipse中配置JFreeChart

    JFreeChart是一款功能强大的Java图表库,它能够生成多种图表,如柱状图、折线图、饼图、时间序列图等,常用于Java应用程序中。而Eclipse是一个开源的集成开发环境,广泛用于Java语言的开发。在Eclipse中配置...

    jfreeChart pdf文档(原文)

    ### jfreeChart 实际开发运用手册知识点概览 #### 一、引言 **1.1 JFreeChart 是什么?** ##### 1.1.1 概述 JFreeChart 是一个免费的图表库,专为 Java 平台设计。它能够应用于各种 Java 应用程序、Applet、...

    jfreechart的jar包

    **JFreeChart 概述** JFreeChart 是一个开源的 Java 图形库,它为 Java 应用程序提供了丰富的图表功能。这个库被广泛用于创建数据可视化,包括但不限于报表、仪表盘、幻灯片和 Web 应用。JFreeChart 支持多种图表...

    jfreechart,jfreechart-1.0.13,jfreechart-1.0.13,jfreechart

    《JFreeChart:Java 图形绘制的利器》 在Java编程世界中,高效且美观的图形展示是数据可视化的重要组成部分。JFreeChart作为一款强大的开源图表库,为开发者提供了丰富的图表类型和高度自定义的能力,使得Java应用...

    JfreeChart-雷达图与导出

    **JFreeChart库详解** JFreeChart是一款强大的Java图表库,它允许开发者在Java应用程序或网页中创建多种类型的图表,包括雷达图(也称为蜘蛛网图)。本篇将深入探讨如何利用JFreeChart生成雷达图以及相关的数据导出...

    JFreeChart 官方例子 JFReeChart Dome

    "JFreeChart 官方例子 JFreeChart Dome" 提供了一系列官方示例,帮助开发者更好地理解和运用JFreeChart库的各种功能。 "ChangeLog" 文件通常记录了软件的更新历史,其中包括了每次版本升级中添加的新特性、修复的...

    用JFreeChart写的雷达图实例

    在Java编程环境中,JFreeChart是一个非常流行的库,用于创建各种复杂的图表,包括线图、柱状图、饼图以及我们的焦点——雷达图。本文将深入探讨如何利用JFreeChart库来实现一个雷达图实例,这有助于数据可视化,特别...

    jfreechart依赖jar包

    JFreeChart 是一个强大的 Java 图形库,它为开发者提供了丰富的图表类型,包括柱状图、折线图、饼状图等,用于在 Java 应用程序中进行数据可视化。在 Java 后台开发中,数据的图形化表示能够帮助用户更直观地理解...

    jfreechart+cewolf的架包

    **JFreeChart与Cewolf:构建可视化报表的关键组件** 在Java开发中,生成美观且具有交互性的图表对于数据可视化和报表制作至关重要。JFreeChart和Cewolf是两个强大的开源库,它们共同为开发者提供了丰富的图形生成和...

    JFreeChart用户开发指南1.0.6(中文).pdf

    ### JFreeChart用户开发指南1.0.6(中文)知识点总结 #### 一、引言 **JFreeChart**是一款强大的Java图表绘制库,它为开发者提供了丰富的API来创建各种类型的图表,如饼图、柱状图、折线图等。本指南详细介绍了...

    jfreechart的jar包(全+中文教程)

    JFreeChart是一款强大的Java图表库,它为开发者提供了创建各种静态和动态图表的功能。这个压缩包包含JFreeChart所需的所有核心组件,以及相关的依赖库,如jcommon.jar,确保你可以全面地利用JFreeChart的强大功能。 ...

    JFreeChart示例 JAVA_JFreeChart的应用 JFreeChart 教程

    ### JFreeChart应用详解:Java图形解决方案的深度解析 #### JFreeChart概述 JFreeChart是Java领域中领先的开源图表库,由JFree组织在SourceForge.net上维护和发布。它提供了一系列强大的图表生成功能,适用于多种...

Global site tag (gtag.js) - Google Analytics