一:JFreeChart功能介绍
JFreeChart 目前是最好的java图形解决方案,基本能够解决目前的图形方面的需求,主要包括如下几个方面:
pie charts (2D and 3D) :饼图(平面和立体)
bar charts (regular and stacked, with an optional 3D effect) :柱状图
line and area charts :曲线图
scatter plots and bubble charts
time series, high/low/open/close charts and candle stick charts :时序图
combination charts :复合图
Pareto charts
Gantt charts :甘特图
wind plots, meter charts and symbol charts
wafer map charts
( 态图表,饼图(二维和三维) , 柱状图 ( 水平,垂直),线图,点图,时间变化图,甘特图, 股票行情图,混和图, 温度计图, 刻度图等常用商用图表)
图形可以导出成PNG和JPEG格式,同时还可以与PDF和EXCEL关联
JFreeChart 核心类库介绍:
研究jfreechart源码发现源码的主要由两个大的包组成:org.jfree.chart,org.jfree.data。其中前者主要与图形
本身有关,后者与图形显示的数据有关。具体研究如果大家有兴趣的话可以自己研究 。
核心类主要有:
org.jfree.chart.JFreeChart :图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象
org.jfree.data.category.XXXDataSet: 数据集对象,用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类
org.jfree.chart.plot.XXXPlot :图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis、Renderer以及数据集对象的支持
org.jfree.chart.axis.XXXAxis :用于处理图表的两个轴:纵轴和横轴
org.jfree.chart.render.XXXRender :负责如何显示一个图表对象
org.jfree.chart.urls.XXXURLGenerator: 用于生成Web图表中每个项目的鼠标点击链接
XXXXXToolTipGenerator: 用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类
个人感觉JFreeChart可以满足大部分图片创建的需要,美中不足的是:对字体的设置做的不够好,特别是使用中文的时候字体很不清晰。因为这个原因建议你自己去修改他的源代码,最好使用properties文件去设置字体.还有就是文档要钱所以要多花点时间去看源代码。或多上社区.
以下是一个简单的Jfreechart Web项目:
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!-- for test jfreechar --> <servlet> <servlet-name>ChartServlet</servlet-name> <servlet-class>cn.netjava.jFreeChart.ChartServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ChartServlet</servlet-name> <url-pattern>/servlet/ChartServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>viewChart.jsp</welcome-file> </welcome-file-list> </web-app>
viewChart.jsp 用于显示图
<%@page contentType="text/html" pageEncoding="GBK"%> <title>jFreeChart图表测试</title> <br>请选择要生成的图表类型: <hr> <select id="scType" onchange="loadChartBySelectType(this)"> <option value="1">请选择一种图表</option> <option value="PieChart3D">PieChart3D</option> <option value="PieChart">PieChart</option> <option value="BarChart3D">BarChart3D</option> <option value="LineChart">LineChart</option> <option value="RingChart">RingChart</option> <option value="AreaChart">AreaChart</option> <option value="WaterfallChart">WaterfallChart</option> <option value="Thermometer">Thermometer</option> <option value="MeterChart">MeterChart</option> </select> <hr> 图表: <div id="displayChart" /> <script type="text/javascript"> /**选择jf图表类型时,载入图片*/ function loadChartBySelectType(sua) { var cType=sua.value; if(cType=="1"){ return ; } alert("选中的是: "+cType) var disabledImageZone=document.getElementById("displayChart"); //这样多简单,清理div中己有的东东:) disabledImageZone.innerHTML=""; var image = document.createElement('img'); image.setAttribute('id','imageZone'); //提取服务器上的图片显示下来: image.setAttribute('src',"servlet/ChartServlet?chartType="+cType); disabledImageZone.appendChild(image); } </script>
后台处理类:
package cn.netjava.jFreeChart; import java.awt.BasicStroke; import java.awt.Color; import java.io.IOException; import javax.servlet.*; import javax.servlet.http.*; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.MeterPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.ThermometerPlot; import org.jfree.data.Range; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; import org.jfree.data.general.DefaultValueDataset; /** * 生成jFreeChart图片的Servlet * @author Eric.zhangh * Jan 8, 2011 */ public class ChartServlet extends HttpServlet { /** * 根据客户端请求的图表类型chartType的值,返回对应的图表, */ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 输出图片格式为png格式 response.setHeader("Cache-Control", "no-cache"); response.setContentType("image/png"); //请求的图表类型 String chartType = request.getParameter("chartType"); System.out.println("请求的图表类型是 : " + chartType); // for export Chart: JFreeChart chart = null; if (chartType.equalsIgnoreCase("PieChart3D")) { // 创建pie图的数据集方法 DefaultPieDataset data = ChartTools.getPieDataSet(); chart = ChartFactory.createPieChart3D("这是PieChart3D图:", data, true, false, false); } else if (chartType.equalsIgnoreCase("PieChart")) { // 创建pie图的数据集方法 DefaultPieDataset data = ChartTools.getPieDataSet(); chart = ChartFactory.createPieChart("这是PieChart图:", data, true, false, false); } else if (chartType.equalsIgnoreCase("RingChart")) { // 创建pie图的数据集方法 DefaultPieDataset data = ChartTools.getPieDataSet(); chart = ChartFactory.createRingChart("这是RingChart图:", data, true, false, false); } else if (chartType.equalsIgnoreCase("BarChart3D")) { // 创建bar图的数据集方法 DefaultCategoryDataset data = ChartTools.getCategoryDataset(); // PlotOrientation.HORIZONTAL这个参数说明是水平还是垂直方向VERTICAL chart = ChartFactory.createBarChart3D("这是BarChart3D", "数量", "地点", data, PlotOrientation.VERTICAL, true, false, false); } else if (chartType.equalsIgnoreCase("LineChart")) { // 创建线图 DefaultCategoryDataset data = ChartTools.getCategoryDataset(); chart = ChartFactory.createLineChart("这是LineChart", "数量", "地点", data, PlotOrientation.VERTICAL, true, false, false); } else if (chartType.equalsIgnoreCase("AreaChart")) { // 创建区域形图 DefaultCategoryDataset data = ChartTools.getCategoryDataset(); chart = ChartFactory.createAreaChart("这是AreaChart", "数量", "地点", data, PlotOrientation.VERTICAL, true, false, false); } else if (chartType.equalsIgnoreCase("WaterfallChart")) { // 搞不明白这是什么图:( DefaultCategoryDataset data = ChartTools.getCategoryDataset(); chart = ChartFactory.createWaterfallChart("这是WaterfallChart", "数量", "地点", data, PlotOrientation.VERTICAL, true, false, false); } else if (chartType.equalsIgnoreCase("Thermometer")) { // 整个温度计。。。。。。。。。。 // 数据集,初始值为0 DefaultValueDataset valuedataset = new DefaultValueDataset(0); // 创建漫度计的Plot对象 ThermometerPlot thermometerplot = new ThermometerPlot(valuedataset); chart = new JFreeChart("设备温度", JFreeChart.DEFAULT_TITLE_FONT, thermometerplot, false); thermometerplot.setThermometerStroke(new BasicStroke(2.0F)); // 图表的轮廓颜色 thermometerplot.setThermometerPaint(Color.BLUE); thermometerplot.setOutlinePaint(null); // 图表计数单位 thermometerplot.setUnits(10); // 数值范围 thermometerplot.setRange(-40, 40); thermometerplot.setForegroundAlpha(1f); // 图表的当前值 valuedataset.setValue(20); } else if (chartType.equalsIgnoreCase("MeterChart")) { // 整个仪表盘 // 数据集,初始值为30 DefaultValueDataset valuedataset = new DefaultValueDataset(30); // 创建Plot对象 MeterPlot meterplot = new MeterPlot(valuedataset); chart = new JFreeChart("当前流量速度", JFreeChart.DEFAULT_TITLE_FONT, meterplot, false); // 表盘上显示的数据单位说明 meterplot.setUnits("条/秒)"); // 表盘分害的单位,即30为一格 meterplot.setTickSize(30); // 显示数据范围,0~600 meterplot.setRange(new Range(0, 600)); // 图表的当前值 valuedataset.setValue(100); } if (null != chart) { // 将图片对象输出到客户端 java.io.OutputStream ous = response.getOutputStream(); ChartUtilities.writeChartAsPNG(ous, chart, 500, 300); // 使用这样的代码输出可能会出错! // ChartUtilities.writeChartAsJPEG(ous,100,chart,500,300,null); ous.flush(); ous.close(); System.out.println("******ho ho..*****图片输出完毕....... " + chartType); } } } /** * 生成图片数据集的工具类: * @author Eric.zhangh * Jan 8, 2011 */ class ChartTools { /** * 生成bar图的数据集: * @return:可用于Bar图的数据集 */ public static DefaultCategoryDataset getCategoryDataset() { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for (int series = 0; series < seriesTimes.length; series++) { for (int i = 0; i < seriesNames.length; i++) { nameValueOfTime[series][i] = new java.util.Random() .nextInt(300) + 100; dataset.addValue(nameValueOfTime[series][i], seriesNames[i], seriesTimes[series]); } } return dataset; } /** * 创建用于填充pie图的数据集 * @return DefaultPieDataset对象 */ public static DefaultPieDataset getPieDataSet() { // 用来填充pie图的数据集 DefaultPieDataset dataset = new DefaultPieDataset(); // 饼图分块名字 String[] seriesNames = { "东方路", "南京路", "北京路", "大学路", }; for (int i = 0; i < seriesNames.length; i++) { int value = new java.util.Random().nextInt(1000) + 500; // 设置pie数据集中的数据对 dataset.setValue(seriesNames[i], value); } return dataset; } private ChartTools(){}; /** X轴时间维数据序型(当然也可以为标签维度)* */ private static String[] seriesTimes = { "一月", "二月", "三月", "四月", "五月", "六月","七月" }; /** 柱状标签序列(比如做为地点序列) */ private static String[] seriesNames = { "南京东路", "北京东路", "浦东南路" }; /** 每个时间点上每个地区/类型序列的值 */ private static int[][] nameValueOfTime = new int[seriesTimes.length][seriesNames.length]; }