一、JFreeChart的介绍
JFreeChart开发包是一个开源的Java图形开发包,它从柱形图,饼形图,到雷达图,蜡烛图等等无所不包,可以运用在c/s,b/s架构中。
优点:目前最好的java图表解决方案,功能强大,基本涵盖了各种图表;java实现,扩展性强,API较完善,支持多种输出方式。
缺点:类及接口较多,需花较长时间研究;如果以文件或响应流输出则缺少交互功能,为实现交互功能需借助Frame或Applet等,各有一定弊端。
总结:使用JFreeChart技术能够按需求定制各种图表,通过某种方式也能够实现多样的人机交互功能,JFreeChart是一个以java为基础的,值得深入研究的开源图表技术。
二、JFreeChart最新版本下载地址:
http://www.jfree.org/jfreechart/index.html
三、API文档:
在线API参考文档:
http://www.jfree.org/jfreechart/api/javadoc/index.html
四、JFreeChart的基本使用
不论创建的是什么图,JFreeChart都遵循以下的这个使用步骤:
1、建立Dataset。所有的数据都存放在Dataset中的。(创建一个数据源(dataset)来包含将要在图形中显示的数据)
2、建立JFreeChart。将dataset中的数据导入到JFreeChart中。(创建一个 JFreeChart 对象来代表要显示的图形 )
3、设置JFreeChart的显示属性。这一步可以省略,使用默认的JFreeChart显示属性。
3、渲染图表。即生成图片。
4、页面图片显示。
重要的类和接口:
org.jfree.data.general.Dataset 所有数据源类都要实现的接口
org.jfree.chart.ChartFactory 由它来产生 JFreeChart 对象
org.jfree.chart.JFreeChart 所有对图形的调整都是通过它噢!!
org.jfree.chart.plot.Plot 通过JFreeChart 对象获得它,然后再通过它对图形外部部分(例:坐标轴)调整
注意:它有很多子类,一般都下涉及到它的子类!
org.jfree.chart.renderer.AbstractRenderer 通过JFreeChart 对象获得它,然后再通过它对图形内部部分(例:折线的类型)调整。同样,针对不同类型的报表图,它有着不同的子类实现!
org.jfree.chart.axis
这个包包含所有轴有关的类和接口:
a.CategoryPlot 和 XYPlot 操作两个轴(默认),我们叫他们domain轴和range轴。这些专用名词是建立这些地图可视化地把domain轴的值映射到value轴上的概念之上。
效果上,domain轴作为x轴,range作为y轴,但我们更热衷与专用名词
b.轴类提供的默认设置基本适合大多数程序的需要,但是,有很多通过JFreeChartAPI改变属性来定制轴的特性。一定要通过读API来熟悉可以定制的选项。
c.JFreeChart的一个更强大的功能是同一个Chart可以提供多个domain轴和多个value轴
轴类是可克隆和可串行化的。
org.jfree.chart.entity
这个包包括展现Chart中实体的类
org.jfree.chart.event
这个包包括跟改变Chart属性相关的发送和接收事件有关的类和接口。默认,库中的类自动把他们注册给其他类,所以他们会自动接收事件并相应地起作用。更大程度上,你只需要简单地依赖默认的行为。
org.jfree.chart.imagemap
这个包包括创建HTML图像映射的类和接口,图像能用ChartUtilities创建,典型例子是来自servlet。
org.jfree.chart.labels
这个包包括为个别数据产生标签的类和接口,有两种标签类型:
a.item labels --作为chart一部分的小文字标签
b.tooltips -- 当鼠标滑到数据项时展示的文字
org.jfree.chart.needle
这个包包括在圆形图中画指针的类和接口
org.jfree.chart.plot
这个包包括:
a.Plot基类
b.一系列Plot的子类
c.各种支持的类和接口
这是一个很重要的包,因为Plot类在JFreeChart中控制和展示数据中起着关键作用
org.jfree.chart.renderer
这个包包括用来扩展渲染器的类和接口,渲染器是一个负责在CategoryPlot或XYPlot上画出个性化的数据项。
渲染器或通过修改现有属性或扩充一个新的渲染器来提供一定程度上Chart外表改变。
org.jfree.chart.servlet
这个包包括Servlet的辅助类
org.jfree.chart.title
这个包包括作为Chart标题或子标题的类,JFreeChart操作一个标题和多个子标题,当画chart的时候,标题和子标题会占用一块空间来画他们自己,这样画图空间就少了,所以尽管对子标题的数目没有限制,但你经可能的少用子标题。
org.jfree.chart.ui
这个包包括改变Chart属性的用户界面类,这个包是可选的,他们用在示例程序中,如果你的程序用不到他们,你不需要把他包括进你的应用程序。
org.jfree.chart.urls
这个包支持在HTML图片上添加URL
org.jfree.data
这个包包括为JFreeChart提供数据集的类和接口。在设计JFreeChart的一个原则就是数据和展示完全分开,所以,在数据集的类里面你找不到任何与展示有关的属性和方法。
org.jfree.data.statistics
这个包包括展示数据统计的类和接口
org.jfree.data.time
这个包包括展示基于时间的数据的类和接口。
TimeSeriesCollection应该是最重要的类,他用来存储一个或多个TimeSeries对象,并提过一个对XYDataset接口的扩展,这样他被允许作为XYPlot的一个数据集。
TimePeriodValuesCollection这个类执行相似的功能,但是可以用更通用的时间段。
org.jfree.data.xml
这个包包括支持从XML文件读取数据集的类和接口。
五、实例
(把下载的jfreechart包lib下面的jfreechart和jcommon两个jar同时部署到classespath下)
在web应用中的例子:
package com.hodmct.jfreechart; import java.awt.Color; import java.awt.Font; import java.io.IOException; import java.io.PrintWriter; import java.text.NumberFormat; import java.text.SimpleDateFormat; import javax.servlet.http.HttpSession; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.entity.StandardEntityCollection; import org.jfree.chart.labels.StandardXYToolTipGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.servlet.ServletUtilities; import org.jfree.chart.title.TextTitle; import org.jfree.data.time.Day; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.xy.XYDataset; import org.jfree.ui.RectangleInsets; /** * 曲线图的绘制 */ public class LineXYChart { /** * 返回生成图片的文件名 * @param session * @param pw * @return 生成图片的文件名 */ public String getLineXYChart(HttpSession session, PrintWriter pw) { XYDataset dataset = this.createDateSet();//建立数据集 String fileName = null; //建立JFreeChart JFreeChart chart = ChartFactory.createTimeSeriesChart( "JFreeChart时间曲线序列图", // title "Date", // x-axis label "Price", // y-axis label dataset, // data true, // create legend? true, // generate tooltips? false // generate URLs? ); //设置JFreeChart的显示属性,对图形外部部分进行调整 chart.setBackgroundPaint(Color.red);//设置曲线图背景色 //设置字体大小,形状 Font font = new Font("宋体", Font.BOLD, 16); TextTitle title = new TextTitle("JFreeChart时间曲线序列图", font); chart.setTitle(title); //副标题 TextTitle subtitle = new TextTitle("副标题", new Font("黑体", Font.BOLD, 12)); chart.addSubtitle(subtitle); chart.setTitle(title); //标题 //设置图示标题字符 //TimeSeries s1 = new TimeSeries("历史曲线", Day.class);该中文字符 LegendTitle legengTitle = chart.getLegend(); legengTitle.setItemFont(font); XYPlot plot = (XYPlot) chart.getPlot();//获取图形的画布 plot.setBackgroundPaint(Color.lightGray);//设置网格背景色 plot.setDomainGridlinePaint(Color.green);//设置网格竖线(Domain轴)颜色 plot.setRangeGridlinePaint(Color.white);//设置网格横线颜色 plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));//设置曲线图与xy轴的距离 plot.setDomainCrosshairVisible(true); plot.setRangeCrosshairVisible(true); XYItemRenderer r = plot.getRenderer(); if (r instanceof XYLineAndShapeRenderer) { XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r; renderer.setBaseShapesVisible(true); renderer.setBaseShapesFilled(true); renderer.setShapesVisible(true);//设置曲线是否显示数据点 } //设置Y轴 NumberAxis numAxis = (NumberAxis) plot.getRangeAxis(); NumberFormat numFormater = NumberFormat.getNumberInstance(); numFormater.setMinimumFractionDigits(2); numAxis.setNumberFormatOverride(numFormater); //设置提示信息 StandardXYToolTipGenerator tipGenerator = new StandardXYToolTipGenerator( "历史信息{1} 16:00,{2})", new SimpleDateFormat("MM-dd"),numFormater); r.setToolTipGenerator(tipGenerator); //设置X轴(日期轴) DateAxis axis = (DateAxis) plot.getDomainAxis(); axis.setDateFormatOverride(new SimpleDateFormat("MM-dd")); ChartRenderingInfo info = new ChartRenderingInfo( new StandardEntityCollection()); try { fileName = ServletUtilities.saveChartAsPNG(chart, 500, 300, info, session);//生成图片 // Write the image map to the PrintWriter ChartUtilities.writeImageMap(pw, fileName, info, false); } catch (IOException e) { e.printStackTrace(); } pw.flush(); return fileName;//返回生成图片的文件名 } /** * 建立生成图形所需的数据集 * @return 返回数据集 */ private XYDataset createDateSet() { TimeSeriesCollection dataset = new TimeSeriesCollection();//时间曲线数据集合 TimeSeries s1 = new TimeSeries("历史曲线", Day.class);//创建时间数据源,每一个//TimeSeries在图上是一条曲线 //s1.add(new Day(day,month,year),value),添加数据点信息 s1.add(new Day(1, 2, 2006), 123.51); s1.add(new Day(2, 2, 2006), 122.1); s1.add(new Day(3, 2, 2006), 120.86); s1.add(new Day(4, 2, 2006), 122.50); s1.add(new Day(5, 2, 2006), 123.12); s1.add(new Day(6, 2, 2006), 123.9); s1.add(new Day(7, 2, 2006), 124.47); s1.add(new Day(8, 2, 2006), 124.08); s1.add(new Day(9, 2, 2006), 123.55); s1.add(new Day(10, 2, 2006), 122.53); dataset.addSeries(s1); dataset.setDomainIsPointsInTime(true); return dataset; } }
在jsp文件中显示图片:
首先在Web应用程序部署文件web.xml中添加以下代码:
<!-- 图片显示,使用专用的servlet来进行显示,它会完成路径的搜索及映射 -->
<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>/servlet/DisplayChart</url-pattern> </servlet-mapping>
然后在jsp中显示图片
完整的jsp文件:
<!--文件名称:timeLine.jsp-->
<%@ page contentType="text/html;charset=gb2312" pageEncoding="GB2312"%> <%@ page import="com.hodmct.jfreechart.LineXYChart"%> <%@ page import = "java.io.PrintWriter" %> <% LineXYChart xyChart=new LineXYChart(); String fileName=xyChart.getLineXYChart(session,new PrintWriter(out)); String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + fileName; %> <html> </head> <title> JFreeChart使用例子</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body> <img src="<%= graphURL %>" width=500 height=300 border=0 usemap="<%= fileName %>"> </body> </html>
jfreechart绘制柱状图:
package com.hodmct.jfreechart; import java.io.File; import java.io.IOException; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.StandardChartTheme; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.category.DefaultCategoryDataset; /* * 绘制柱状图 * */ public class BarChart3DDemo { public static void main(String[] args) { try { // 设置主题 ChartFactory.setChartTheme(new StandardChartTheme( "绘制柱状图")); // 构造数据 DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(100, "JAVA", "1"); dataset.addValue(200, "js", "1"); dataset.addValue(200, "C++", "2"); dataset.addValue(300, "C", "3"); dataset.addValue(400, "HTML", "4"); dataset.addValue(400, "CSS", "5"); /* * public static JFreeChart createBarChart3D( java.lang.String * title, 设置图表的标题 java.lang.String categoryAxisLabel, 设置分类轴的标示 * java.lang.String valueAxisLabel, 设置值轴的标示 CategoryDataset dataset, * 设置数据 PlotOrientation orientation, 设置图表的方向 boolean legend, * 设置是否显示图例 boolean tooltips,设置是否生成热点工具 boolean urls) 设置是否显示url */ JFreeChart chart = ChartFactory.createBarChart3D("编程语言统计", "语言", "学习人数", dataset, PlotOrientation.VERTICAL, true, false, false); // 保存图表 ChartUtilities.saveChartAsPNG(new File("E:/chart/BarChart3D.png"), chart, 800, 500); //显示 ChartFrame frame = new ChartFrame("绘制柱状图", chart); frame.pack(); frame.setVisible(true); } catch (IOException e) { e.printStackTrace(); } } }
jfreechart绘制条线图:
package com.hodmct.jfreechart; import java.awt.Color; import java.awt.Font; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.AxisSpace; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardXYItemLabelGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.data.time.Month; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.ui.RectangleInsets; import org.jfree.ui.TextAnchor; public class try123 { public static void main(String[] args) { // 首先构造数据 TimeSeries timeSeries = new TimeSeries("BMI", Month.class); // 时间曲线数据集合 TimeSeriesCollection lineDataset = new TimeSeriesCollection(); // 构造数据集合 timeSeries.add(new Month(1, 2009), 45); timeSeries.add(new Month(2, 2009), 46); timeSeries.add(new Month(3, 2009), 1); timeSeries.add(new Month(4, 2009), 500); timeSeries.add(new Month(5, 2009), 43); timeSeries.add(new Month(6, 2009), 324); timeSeries.add(new Month(7, 2009), 632); timeSeries.add(new Month(8, 2009), 34); timeSeries.add(new Month(9, 2009), 12); timeSeries.add(new Month(10, 2009), 543); timeSeries.add(new Month(11, 2009), 32); timeSeries.add(new Month(12, 2009), 225); lineDataset.addSeries(timeSeries); JFreeChart chart = ChartFactory.createTimeSeriesChart("", "date", "bmi", lineDataset, true, true, true); // 增加标题 chart.setTitle(new TextTitle("XXXBMI指数", new Font("隶书", Font.ITALIC, 15))); chart.setAntiAlias(true); XYPlot plot = (XYPlot) chart.getPlot(); plot.setAxisOffset(new RectangleInsets(10, 10, 10, 10));// 图片区与坐标轴的距离 plot.setOutlinePaint(Color.PINK); plot.setInsets(new RectangleInsets(15, 15, 15, 15));// 坐标轴与最外延的距离 // plot.setOrientation(PlotOrientation.HORIZONTAL);//图形的方向,包括坐标轴。 AxisSpace as = new AxisSpace(); as.setLeft(25); as.setRight(25); plot.setFixedRangeAxisSpace(as); chart.setPadding(new RectangleInsets(5, 5, 5, 5)); chart.setNotify(true); // 设置曲线是否显示数据点 XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) plot .getRenderer(); xylineandshaperenderer.setBaseShapesVisible(true); // 设置曲线显示各数据点的值 XYItemRenderer xyitem = plot.getRenderer(); xyitem.setBaseItemLabelsVisible(true); xyitem.setBasePositiveItemLabelPosition(new ItemLabelPosition( ItemLabelAnchor.INSIDE10, TextAnchor.BASELINE_LEFT)); xyitem.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator()); xyitem.setBaseItemLabelFont(new Font("Dialog", 1, 14)); plot.setRenderer(xyitem); // 显示 ChartFrame frame = new ChartFrame("条线图", chart); frame.pack(); frame.setVisible(true); } }
jfreechart绘制饼状图:
package com.hodmct.jfreechart; import java.awt.Font; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.JFreeChart; import org.jfree.chart.StandardChartTheme; import org.jfree.data.general.DefaultPieDataset; public class jFreeChartDemo3 { public static void main(String[] args) { StandardChartTheme sct = new StandardChartTheme("CN"); sct.setExtraLargeFont(new Font("隶书", Font.BOLD, 20)); sct.setRegularFont(new Font("隶书", Font.BOLD, 20)); sct.setLargeFont(new Font("隶书", Font.BOLD, 20)); DefaultPieDataset dataset = new DefaultPieDataset(); dataset.setValue("苹果", 100); dataset.setValue("梨子", 200); dataset.setValue("葡萄", 300); dataset.setValue("香蕉", 400); dataset.setValue("荔枝", 500); ChartFactory.setChartTheme(sct); JFreeChart jfreechart = ChartFactory.createPieChart3D("水果产量图", dataset, true, true, true); ChartFrame frame = new ChartFrame("饼状图", jfreechart); frame.setVisible(true); frame.pack(); } }