使用JFreeChart创建基于WEB的图形报表.docx
《使用JFreeChart创建基于WEB的图形报表.docx》由会员分享,可在线阅读,更多相关《使用JFreeChart创建基于WEB的图形报表.docx(33页珍藏版)》请在冰豆网上搜索。
使用JFreeChart创建基于WEB的图形报表
使用JFreeChart创建基于WEB的图形报表
2006-9-29
修订日期
修订人
修订内容
注释
2006-09-29
Watson(郭胜旺)
整体
文章转载请保留初稿者信息
前言
为了创建一个可以在web浏览器上查看的图表,一般有下面几种做法:
第一种就是使用applet利用java本身对图形的支持来显示一个图表;第二种就是直接在web服务器端生成好图表图片文件后发送给浏览器。
第三种不直接生成图片,而是将流直接送达web浏览器。
第一种方式显然对于客户端要求太高,随着现在主流浏览器放弃对JAVA的支持后,这种方式只适合一些局域网的应用,而对于因特网的环境就显得不太适合。
第二种对于图片文件的管理需要考虑。
因此我们下面将介绍一个JAVA的图表引擎JFreeChart用来产生基于WEB的图表。
JFreeChart支持生成的图片和应用系统的交互。
第一章JfeeChart简介,介绍JFreeChart项目情况。
第二章体验JFreeChart,介绍JFreeChart的应用,包括图形和应用交互。
第三章JFeechart实现Linechart。
第四章JFeechart实现Barchart。
第五章JFeechart实现Piechart。
第六章部分API。
第一章JFreeChart简介
JfreeChart是生成图标的开源软件,功能包括:
●piecharts;
●barcharts(regularandstacked,withanoptional3Deffect);
●lineandareacharts;
●scatterplotsandbubblecharts;
●timeseries,high/low/open/closechartsandcandlestickcharts;
●combinationcharts;
●Paretocharts;
●Ganttcharts;
●windplots,meterchartsandsymbolcharts;
●wafermapcharts;
JfreeChart提供的其他特性:
●completesourcecodeisincluded,underthetermsoftheGNULesserGeneralPublicLicence;
●accesstodatafromanysourceviadatasetinterfaces;
●supportformultiplesecondaryaxesanddatasets;
●tooltips,zooming,printing;
●directexporttoPNGandJPEG;
●exporttoPDFviaiTextandSVGviaBatik(bothdescribedintheJFreeChartDeveloperGuide).
●支持servlets,JSP(感谢Cewolf),applets或者JavaApplication;
●完善的Javadoc文档;
第二章体验JFreeChart
本章采用JfreeChart的演示程序说明JfreeChart的基本功能。
2.1环境
截至2006年9月29日,其最新版本为JFreechart-1.0.2.zip;Jcommon-1.0.6.zip.
这个版本里面带了好多例子jfreechart-1.0.2-demo.jar,但是没有源代码,而仅仅包含编译好的类程序。
如果需要源代码和文档则需要付费购买。
当然,通过反编译工具也可以得到源代码。
JFreechart-0.9.20.zip版本是携带源代码的,可惜的是高版本不向下兼容,很多api都改变了,不过还是可以参考这个版本,然后在高版本里面实现自己的需求的。
进入http:
//www.jfree.org,按信息下载到需要的包。
高版本只需要JFreechart-1.0.2.zip;Jcommon-1.0.6.zip.两个包。
而要运行带源代码的JFreechart-0.9.20.zip,则需在项目中把包里lib下的gnujaxp.jar;jcommon-0.9.5.jar;servlet.jar及顶层中的JFreechart-0.9.20.jar加入到类库路径中。
然后Application方式运行研究路径\src\org\jfree\chart\demo下的各个实例。
各图像会显示在UI的Frame中。
2.2运行及开发流程
如果jdk路径配好后,可双击之运行jfreechart-X-demo.jar,或Application方式运行JFreechart-0.9.20.zip中路径\src\org\jfree\chart\demo下的各个实例源代码,可得到各种图形,下面列出几种:
JFreechart的开发流程:
创建一个数据源(dataset)来包含将要在图形中显示的数据;
创建一个JFreeChart对象来代表要显示的图形;
把图形输出:
多种方式的输出。
2.3JFreeChart实现图形和应用交互
很多情况我们不仅仅要求可以在浏览器上显示一个图表,我们更需要客户可以直接在图表上做一下交互的操作,例如获取信息提示,点击图表某个部分进行更详细信息的展示等等。
例如前面生成的简单柱状图,用户需要在看到柱状图后点击某种水果例如是苹果即可看到各个地区苹果产量的情况。
为此就要求该图形具有交互操作的功能。
在HTML中为了让一个图像具有可交互的功能就必须给该图像定义一个Map对象。
下表节选一段具有该功能的HTML代码
series=0&category=100"title="100=7,048"
onclick="javascript:
clickChart('100');returnfalse;">
series=0&category=200"title="200=6,721"
onclick="javascript:
clickChart('200');returnfalse;">
series=0&category=300"title="300=5,929"
onclick="javascript:
clickChart('300');returnfalse;">
series=0&category=400"title="400=5,005"
onclick="javascript:
clickChart('400');returnfalse;">
series=0&category=Diet"title="Diet=7,017"onclick="javascript:
clickChart('Diet');returnfalse;">
由此就产生了一个问题:
如果根据一个图像来生成对应的MAP对象。
我们回头看看刚才的代码,在创建一个图表对象时候有两个参数,我们举柱状图的例子来讲这两个参数就是ChartFactory.createBarChart3D方法中的最后两个参数,这两个参数的类型都是布尔值。
这两个参数意思分别是:
是否创建工具提示(tooltip)以及是否生成URL。
这两个参数分别对应着MAP中一个AREA的title属性以及href属性。
可是我想知道的是怎么来产生这个MAP啊!
哈哈,不要着急,JFreeChart已经帮我们做好生成MAP对象的功能。
为了生成MAP对象就要引入另外一个对象:
ChartRenderingInfo。
因为JFreeChart没有直接的方法利用一个图表对象直接生成MAP数据,它需要一个中间对象来过渡,这个对象就是ChartRenderingInfo。
下图是生成MAP数据的流程图:
如上图所示,ChartUtilities类是整个流程的核心,它周围的对象都是一些例如数据对象或者是文件等。
这个流程简单描述如下:
首先创建一个ChartRenderingInfo对象并在调用ChartUtilities的writeChartAsJPEG时作为最后一个参数传递进去。
调用该方法结束后将产生一个图像文件以及一个填充好MAP数据的ChartRenderingInfo对象,有了这个对象我们还是没有办法获取具体的MAP数据,我们还必须借助于ChartUtilities的writeImageMap方法来将ChartRenderingInfo对象读取出来。
下面一段程序是JavaApplication方式运行,生成一个html文件,运行该html文件可以展示交互效果。
packageorg.jfree.chart.demo;
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
importjava.io.PrintWriter;
importorg.jfree.chart.ChartFactory;
importorg.jfree.chart.ChartRenderingInfo;
importorg.jfree.chart.ChartUtilities;
importorg.jfree.chart.JFreeChart;
importorg.jfree.chart.axis.CategoryAxis;
importorg.jfree.chart.axis.NumberAxis;
importorg.jfree.chart.axis.ValueAxis;
importorg.jfree.chart.entity.StandardEntityCollection;
importorg.jfree.chart.labels.StandardCategoryItemLabelGenerator;
importorg.jfree.chart.plot.CategoryPlot;
importorg.jfree.chart.plot.PlotOrientation;
importorg.jfree.chart.renderer.BarRenderer;
importorg.jfree.chart.urls.StandardCategoryURLGenerator;
importorg.jfree.data.CategoryDataset;
importorg.jfree.data.DatasetUtilities;
publicclassImageMapDemo1{
publicstaticvoidmain(String[]args){
//createachart
double[][]data=newdouble[][]{
{56.0,-12.0,34.0,76.0,56.0,100.0,67.0,45.0},
{37.0,45.0,67.0,25.0,34.0,34.0,100.0,53.0},
{43.0,54.0,34.0,34.0,87.0,64.0,73.0,12.0}
};
CategoryDatasetdataset=DatasetUtilities.createCategoryDataset("Series","Type",data);
JFreeChartchart=null;
booleandrilldown=true;
if(drilldown){
CategoryAxiscategoryAxis=newCategoryAxis("Category");
ValueAxisvalueAxis=newNumberAxis("Value");
BarRendererrenderer=newBarRenderer();
renderer.setItemLabelGenerator(newStandardCategoryItemLabelGenerator());
renderer.setItemURLGenerator(newStandardCategoryURLGenerator("bar_chart_detail.jsp"));
CategoryPlotplot=newCategoryPlot(dataset,categoryAxis,valueAxis,renderer);
plot.setOrientation(PlotOrientation.VERTICAL);
chart=newJFreeChart("BarChart",JFreeChart.DEFAULT_TITLE_FONT,plot,true);
}
else{
chart=ChartFactory.createBarChart(
"VerticalBarChart",//charttitle
"Category",//domainaxislabel
"Value",//rangeaxislabel
dataset,//data
PlotOrientation.VERTICAL,
true,//includelegend
true,
false
);
}
chart.setBackgroundPaint(java.awt.Color.white);
//saveittoanimage
try{
ChartRenderingInfoinfo=newChartRenderingInfo(newStandardEntityCollection());
Filefile1=newFile("barchart100.png");
ChartUtilities.saveChartAsPNG(file1,chart,600,400,info);
//writeanHTMLpageincorporatingtheimagewithanimagemap
Filefile2=newFile("barchart100.html");
OutputStreamout=newBufferedOutputStream(newFileOutputStream(file2));
PrintWriterwriter=newPrintWriter(out);
writer.println("");
writer.println("
JFreeChartImageMapDemo");
writer.println("
");
ChartUtilities.writeImageMap(writer,"chart",info);
writer.println("+"WIDTH=\"600\"HEIGHT=\"400\"BORDER=\"0\"USEMAP=\"#chart\">");
writer.println("");
writer.println("");
writer.close();
}
catch(IOExceptione){
System.out.println(e.toString());
}
}
}
2.4JfreeChart重要类和接口
类名
类的作用以及简单描述
JFreeChart
图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。
JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象
XXXXXDataset
数据集对象,用于提供显示图表所用的数据。
根据不同类型的图表对应着很多类型的数据集对象类
XXXXXPlot
图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis、Renderer以及数据集对象的支持
XXXXXAxis
用于处理图表的两个轴:
纵轴和横轴
XXXXXRenderer
负责如何显示一个图表对象
XXXXXURLGenerator
用于生成Web图表中每个项目的鼠标点击链接
XXXXXToolTipGenerator
用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类
org.jfree.chart.ChartFactory
由它来产生JFreeChart对象
C1.org.jfree.data
类名
接口或类的作用以及简单描述
DefaultCategoryDataset
此接口适用于有一个或多个series和category对应的DataSet。
柱状图使用。
DefaultIntervalCategoryDataset
此接口适用于每个series/category绑定都可以定义一个浮动值(valuerange)的DataSet。
柱状图使用。
DefaultPieDataset
此接口使用于值和键值匹配的DataSet。
饼图使用。
DefaultKeyedValues
此类用List结构存储饼图数据。
Acollectionof(key,value)pairs.
ThisclassprovidesadefaultimplementationoftheKeyedValuesinterface.
XYSeries
曲线图使用。
Dataset
数据集合(datasets)的基本接口。
要求所有的datasets通过允许监听器(listeners)注册和接受任何对于dataset的改变的通知来支持DatasetChangeEvent机制。
此外,所有的datasets都必须从属于一个(并且只有一个)DatasetGroup。
这个对象提供一个读写锁,它提供了在多线程代码中对于datasets的同步处理。
C2.org.jfree.chart
类名
接口或类的作用以及简单描述
ChartFactory
工厂类方法,提供了创建多种图形的方法。
JFreeChart
使用Java2DAPIs实现的一个图形java类。
当前版本支持bar图,line图,pie图和xy图(包含时间series数据)。
JFreeChart结合少数其他对象来实现再一个Java2D图形设备上面绘制图形的目的,这几个对象包括:
alistofTitleobjects,aLegend,aPlotandaDataset(theplotinturnmanagesahorizontalaxisandaverticalaxis).
你可以使用ChartPanel来在GUI中显示一个图形。
ChartFactory类包含一系列静态方法来创建只读模式的图形。
C3.org.jfree.chart.servlet
类名
接口或类的作用以及简单描述
DisplayChart
DisplayChart继承自Httpservlet用于处理显示图象;
ServletUtilities
saveChartAs*;saveChartAs*是把图表按照不同的形式存储为图象;
sendTempFile方法被重载了很多次,用于把文件流发送response;
ChartDeleter
ChartDeleter继承自HttpSessionBindingListener,用于实现当Session关闭时,删除临时目中的图象文件。
2.4JfreeChart常用类图
第三章JFreeChartLineChart
3.1线性图
//createadefaultchartbasedonsomesampledata...
//曲线图标题
Stringtitle="趋势分析";
//曲线图X轴提示
Stringdomain="月份走势";
//曲线图Y轴提示
Stringrange="应收余额";
//曲线图自标题
StringsubtitleStr="2003财年分析";
//创建时间数据源
//每一个TimeSeries在图上是一条曲线
TimeSeriesca=newTimeSeries("用友");
for(inti=1999;i<2005;i++){
for(intmon=0;mon<12;mon++){
//ca.add(newMonth(mon+1,i),newDouble(500+Math.random()*100));
//TimeSeriesDataPair是一个时间点的数值体现
ca.add(
newTimeSeriesDataPair(
newDay(1,mon+1,i),
newDouble(500+Math.random()*100)));
}
}
TimeSeriesibm=newTimeSeries("金碟");
for(inti=1999;i<2005;i++){
for(intmon=0;mon<12;mon++){
//ibm.add(newMonth(mon+1,i),newDouble(400-Math.random()*100));
ibm.add(
newTimeSeriesDataPair(
newDay(1,mon+1,i),
newDouble(400-Math.random()*100)));
}
}
TimeSeriesking=newTimeSeries("东软");
for(inti