JFreeChart是一个开源的JAVA项目,它主要用来开发各种各样的图表,这些图表包括:饼图、柱状图(普通柱状图以及堆栈柱状图)、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等。在这些不同式样的图表上可以满足目前商业系统的要求。JFreeChart是一种基于JAVA语言的图表开发技术。JFreeChart可用于Servlet、JSP、Applet、Java Appication环境中,通过JDBC可动态显示任何数据库数据,结合Itext可以输出至PDF文件。
JFreeChart主要是由三个类构成:
A)org.jfree.chart.servlet.ChartDeleter继承自
HttpSessionBindingListener,用于实现当Session 关闭时,删除临时目中的图象文件。
B)org.jfree.chart.servlet.DisplayChart继承自Httpservlet 用于处理显示图象。
C)org.jfree.chart.servlet.ServletUtilities有一系列方法,例如,saveChartAs*;saveChartAs*是把图表按照不同的形式存储为图象;sendTempFile方法被重载了很多次,用于把文件流发送response。
下面以柱状图和饼图为例,介绍图形创建方法。
1 柱状图
org.jfree.chart.ChartFactory这个工厂类有createBarChart、
createStackedBarChart、createBarChart3D、createStackedBarChart3D,这几个工厂方法创建不同类型的柱状图,比较重要的是 PlotOrientation.VERTICAL 让平行柱垂直显示,而 PlotOrientation.HORIZONTAL 则让平行柱水平显示。对柱状图影响较大的几个类包括:org.jfree.chart.axis.CategoryAxis、
org.jfree.chart.axis.ValueAxis、org.jfree.chart.renderer.BarRenderer、org.jfree.chart.renderer. BarRenderer3D。
具体实现步骤:
1)创建用于图形生成所要的数据集对象。 CategoryDataset dataset =
DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
其中:rowKeys表示X轴数据,columnKeys表示Y轴数据,data表示填充柱状图所要的实际数据(来自于数据库)。
2)创建图形对象。
JFreeChart chart = ChartFactory.createBarChart3D(\"标题\,null,dataset,PlotOrientation.VERTICAL,,true,false,false);
createBarChart3D方法是ChartFactory工厂类里的一个方法,用于3D柱状图的生成,该类继承自JFreeChart。其中的八个参数分别代表:图形的标题、X轴标题、Y轴标题、dataset就是CategoryDataset类的实例对象、显示标题、启用热键、启用超键接。
3)设置图形显示的属性。
a ) ValueAxis类,设置柱到图上下边的距离。实现方法是: ValueAxis rangeAxis = plot.getRangeAxis(); 设置最高的一个柱与图片顶端的距离: rangeAxis.setUpperMargin(0.15) 设置最低的一个柱与图片底端的距离: rangeAxis.setLowerMargin(0.15)
b)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(\"黑体\renderer.setItemLabelsVisible(true); 为图形加入超连接
renderer.setItemURLGenerator(new StandardCategoryURLGenerator()); renderer.setToolTipGenerator(new StandardCategoryToolTipGenerator());
2 饼图
org.jfree.chart.plot包,包含创建饼形图的所有方法和属性。 笔者根据业务需求创建了setURLGenerator(PieURLGenerator generator)方法,在图片上建立连接,就是图片不同部分连接不同的资源。
setSectionLabelType(int type)方法:
指定 section 标签的类型,共有 7 种类型。如果不指定,默认是 NAME_LABELS,其中类型分别是:
PiePlot.NO_LABELS PiePlot.NAME_LABELS PiePlot.VALUE_LABELS
PiePlot.PERCENT_LABELS 、PiePlot.NAME_AND_VALUE_LABELS、PiePlot. NAME_AND_PERCENT_LABELS、PiePlot.VALUE_AND_PERCENT_LABELS。
setDefaultOutlinePaint(java.awt.Paint paint)方法,指定 section 轮廓线的颜色,如果不指定,默认值为NULL。
setDefaultOutlineStroke(java.awt.Stroke stroke)方法,指定 section 轮廓线的厚度。
setRadius(double percent) 和 setExplodePercent(int section, double percent)方法,抽离 section,就是把某一section从饼形图剥离出来,需要两个方法一起使用。
setStartAngle(double angle)方法,设置第一个section开始位置,默认从12点钟方向开始。
setPaint(int section, java.awt.Paint paint)方法指定section的颜色。 setDirection(int direction)方法指定section顺序,默认是顺时针方向。顺时针:PiePlot.CLOCKWISE;逆时针:PiePlot.ANTICLOCKWISE。
具体实现步骤:
1)创建用于图形生成所要的数据集对象。
首先实例化类DefaultPieDataset dataset = new DefaultPieDataset()。然后利用DefaultPieDataset类提供的setValue(value1,value2)方法,把从数据库里提取的数据存入DefaultPieDataset对象。其中value1是数据名称、value2是数据值。
2)创建图形对象。
首先实例化JFreeChart chart = ChartFactory.createPieChart3D(title, dataset, true, true, false)createPieChart3D方法是用于饼图生成的主要方法。其中title代表图形的标题、dataset就是DefaultPieDataset对象的实例。
3)设置图形显示的属性。
String filename = ServletUtilities.saveChartAsPNG(jFreeChart, 700,
450, info, session);
ChartUtilities.writeImageMap(pw, filename, info);
pw.flush()
saveChartAsPNG方法在ServletUtilities工厂类定义完成。主要用于把图形对象JFreeChart以图片的形式保存。其中的jFreeChart就是JFreeChart对
象的实例。该方法返回一个文件名。
writeImageMap(pw, filename, info)方法用于把保存的图片文件以字节
流的形式写入用户界面。
其中pw是java.io包的PrintWriter类的实例对象,该对象创建一个图形
输出流。Filename是输出图片的文件名。该文件名来自
ServletUtilities.saveChartAsPNG方法创建。
参数info用于图形信息的显示。
用ChartRenderingInfo info=new ChartRenderingInfo(new StandardEntityCollection())创建。
最后输出完成图形,调用pw.flush()方法关闭IO流。
------------------------------------------------------------------------------------------
使用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 { CategoryDataset dataset = getDataSet2(); JFreeChart chart = ChartFactory.createBarChart3D( public static void main(String[] args) throws IOException{ \"水果产量图\图表标题 \"水果\目录轴的显示标签 \"产量\数值轴的显示标签 集 dataset, // 数据PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); FileOutputStream fos_jpg = null; try { fos_jpg = new FileOutputStream(\"D:\\\\fruit.jpg\"); l); } finally { try { fos_jpg.close(); ChartUtilities.writeChartAsJPEG(fos_jpg,100,chart,400,300,nul} catch (Exception e) {} } /** } * 获取一个演示用的简单数据集对象 * @return */ private static CategoryDataset getDataSet() { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); } /** * 获取一个演示用的组合数据集对象 * @return */ private static CategoryDataset getDataSet2() { DefaultCategoryDataset dataset = new dataset.addValue(100, null, \"苹果\"); dataset.addValue(200, null, \"梨子\"); dataset.addValue(300, null, \"葡萄\"); dataset.addValue(400, null, \"香蕉\"); dataset.addValue(500, null, \"荔枝\"); return dataset; 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(\"苹果\dataset.setValue(\"梨子\dataset.setValue(\"葡萄\dataset.setValue(\"香蕉\dataset.setValue(\"荔枝\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) { res.setContentType(\"image/jpeg\"); DefaultPieDataset data = getDataSet(); JFreeChart chart = ChartFactory.createPie3DChart(\"水果throws ServletException, IOException 产量图\ ChartUtilities.writeChartAsJPEG(res.getOutputStream(), } /** * 获取一个演示用的简单数据集对象 * @return 100,chart,400,300,null); data, true, false, false ); }
*/ private static DefaultPieDataset getDataSet() { } DefaultPieDataset dataset = new DefaultPieDataset(); dataset.setValue(\"苹果\dataset.setValue(\"梨子\dataset.setValue(\"葡萄\dataset.setValue(\"香蕉\dataset.setValue(\"荔枝\return dataset; 高级主题
很多情况我们不仅仅要求可以在浏览器上显示一个图表,我们更需要客户可以直接在图表上做一下交互的操作,例如获取信息提示,点击图表某个部分进行更详细信 息的展示等等。例如前面生成的简单柱状图,用户需要在看到柱状图后点击某种水果例如是苹果即可看到各个地区苹果产量的情况。为此就要求该图形具有交互操作 的功能。在HTML中为了让一个图像具有可交互的功能就必须给该图像定义一个Map对象。下表节选一段具有该功能的HTML代码