JFreeChart基于Java Web的报表组件的使用以及解决乱码

JFreeChart的简介在此就不赘述,主要讲解如何使用JFreeChart创建各种图表,这些图表包括:饼图、柱状图 ( 普通柱状图以及堆栈柱状图 )、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等。以及自定义图表热点事件等。。另外解决乱码问题。

完整源码下载:http://download.csdn.net/detail/jackphang/5265557

参考资料:http://www.ibm.com/developerworks/cn/java/l-jfreechart/

JFreeChart主页:http://www.jfree.org/jfreechart/index.html

JFreeChart下载页面:http://sourceforge.net/projects/jfreechart/

下载后的文件jfreechart-1.0.14.jar,目前是最新的,解压后,在lib目录中找到jfreechart-1.0.14.jar和jcommon-1.0.17.jar这两个jar包,将此复制到你的项目中。值得注意的是,如果JFreeChart不同版本的类结构是不一样的。

在此,笔者主要介绍几种图表,其他的图表可以触类旁通。

1.柱状图

 

如果不对中文做处理,则会有乱码的的情况,主要原因有

1:操作系统不支持JFreeChart框架中的字体,读者可以下载相应的字体库到系统中,或者使用笔者提供设置字体的类ChartFontUtil。
2:软件版本问题,jfreechart-1.0.10有人说没有问题,但jfreechart-1.0.11到14都有问题,我用的最新的jfreechart-1.0.14不做设置是有问题的。
究其原因,是它代码的内部设置的字体有问题.

3:读者可以修改JFreeChart源码中默认的字体、然后重新打包成Jar使用,以此可以一劳永逸,但是笔者没这么干过。

设置乱码工具类

 

package com.pyy.report;

import java.awt.Color;
import java.awt.Font;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.TextTitle;

/**
 * @author jackphang
 * @date 2013-4-16
 * @description 设置JFreeChart字体,解决乱码问题
 */

public class ChartFontUtil {
	/**
	 * 配置柱状图的字体,以防止乱码
	 * 
	 * @param chart
	 *            JFreeChart 对象
	 */
	public static void setBarChartFont(JFreeChart chart) {
		// 配置字体
		CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象
		// 标题
		setTitleFont(chart);
		// 底部
		setBottomFont(chart);
		// X轴
		setXFont(plot.getDomainAxis());
		// Y轴
		setYFont(plot.getRangeAxis());
	}

	/**
	 * 设置线图字体,防止乱码
	 * 
	 * @param chart
	 */
	public static void setXYLineCharFont(JFreeChart chart) {
		XYPlot plot = chart.getXYPlot();// 图形的绘制结构对象
		// 标题
		setTitleFont(chart);
		// 底部
		setBottomFont(chart);
		// X轴
		setXFont(plot.getDomainAxis());
		// Y轴
		setYFont(plot.getRangeAxis());
	}

	/**
	 * 设置饼图的字体,防止乱码
	 * 
	 * @param chart
	 */
	public static void setPieChartFont(JFreeChart chart) {
		PiePlot3D plot = (PiePlot3D) chart.getPlot();
		
		// 标题
		setTitleFont(chart);
		// 底部
		setBottomFont(chart);
		
		Font font=new Font("宋体",Font.PLAIN,12);
		plot.setLabelFont(font);

	}
	
	/**
	 * 设置区域的字体,防止乱码
	 * 
	 * @param chart
	 */
	public static void setAreaChartFont(JFreeChart chart) {
	 	CategoryPlot plot=chart.getCategoryPlot();
		// 标题
		setTitleFont(chart);
		// X轴
		setXFont(plot.getDomainAxis());
		// Y轴
		setYFont(plot.getRangeAxis());
	}
	
	/**
	 * 配置甘特图的字体,以防止乱码
	 * 
	 * @param chart
	 *            JFreeChart 对象
	 */
	public static void setGanTChartFont(JFreeChart chart) {
		// 配置字体
		CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象
		// 标题
		setTitleFont(chart);
		// 底部
		setBottomFont(chart);
		// X轴
		setXFont(plot.getDomainAxis());
		// Y轴
		setYFont(plot.getRangeAxis());
	}

	/**
	 * 设置标题字体
	 * 
	 * @param chart
	 */
	private static void setTitleFont(JFreeChart chart) {
		Font titleFont = new Font("隶书", Font.BOLD, 25); // 图片标题
		// 图片标题
		chart.setTitle(new TextTitle(chart.getTitle().getText(), titleFont));
	}

	/**
	 * 设置底部字体
	 * 
	 * @param chart
	 */
	private static void setBottomFont(JFreeChart chart) {
		Font kfont = new Font("宋体", Font.PLAIN, 12);// 底部
		// 底部
		chart.getLegend().setItemFont(kfont);
	}

	/**
	 * 设置X轴字体
	 * 
	 * @param plot
	 */
	private static void setXFont(Axis domainAxis) {
		// X 轴
		Font xfont = new Font("宋体", Font.PLAIN, 12);// X轴
		domainAxis.setLabelFont(xfont);// 轴标题
		domainAxis.setTickLabelFont(xfont);// 轴数值
		domainAxis.setTickLabelPaint(Color.RED); // 字体颜色
	}

	/**
	 * 设置Y轴字体
	 * 
	 * @param plot
	 */
	private static void setYFont(Axis rangeAxis) {
		// Y 轴
		Font yfont = new Font("宋体", Font.PLAIN, 12);// Y轴
		rangeAxis.setLabelFont(yfont);
		rangeAxis.setLabelPaint(Color.BLUE); // 字体颜色
		rangeAxis.setTickLabelFont(yfont);
	}

}


生成柱状图的类

package com.pyy.report;

import java.io.FileOutputStream;
import java.io.IOException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

/**
 * 柱状图
 * 
 * @author jackphang
 */
public class BarChart {
	public static void main(String[] args) throws IOException {
		CategoryDataset dataset = getDataSet2();
		JFreeChart chart = ChartFactory.createBarChart3D("水果产量柱状图", // 图表标题
				"水果", // 目录轴的显示标签
				"产量", // 数值轴的显示标签
				dataset, // 数据集
				PlotOrientation.VERTICAL, // 图表方向:水平、垂直
				true, // 是否显示图例(对于简单的柱状图必须是 false)
				false, // 是否生成工具
				false // 是否生成 URL 链接
				);
		ChartFontUtil.setBarChartFont(chart);

		FileOutputStream fos_jpg = null;
		try {
			fos_jpg = new FileOutputStream("F:\\bar_chart.jpg");
			ChartUtilities.writeChartAsJPEG(fos_jpg, 1, chart, 400, 300, null);
		} finally {
			try {
				fos_jpg.close();
			} catch (Exception e) {
			}
		}

	}

	/**
	 * 获取一个演示用的简单数据集对象
	 * 
	 * @return
	 */
	private static CategoryDataset getDataSet() {
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		dataset.addValue(100, "", "苹果");
		dataset.addValue(200, "", "梨子");
		dataset.addValue(300, "", "葡萄");
		dataset.addValue(400, "", "香蕉");
		dataset.addValue(500, "", "荔枝");
		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;
	}
}


以上是生成一个简单的柱状图,在你的Web项目中读取生成的图片即可。下面笔者带大家一起编写一个在JSP页面显示并且可以点击的饼图报表。

先看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">
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>chartServlet</servlet-name>
		<servlet-class>com.pyy.servlet.ChartServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>chartServlet</servlet-name>
		<url-pattern>/chartServlet</url-pattern>
	</servlet-mapping>

	<!-- 该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>
		<!--注意这个url-patten与ChartServlet中的访问是一致的 -->
	</servlet-mapping>
</web-app>


接下来是编写生成图表的Servlet。

 

package com.pyy.servlet;

import java.awt.Rectangle;
import java.awt.Shape;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.imagemap.ImageMapUtilities;
import org.jfree.chart.imagemap.StandardToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.StandardURLTagFragmentGenerator;
import org.jfree.chart.imagemap.ToolTipTagFragmentGenerator;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.general.DefaultPieDataset;

import com.pyy.report.ChartFontUtil;
import com.pyy.report.ChartMapUtil;

/**
 * @author jackphang
 * @date 2013-4-16
 * @description
 */
public class ChartServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2356456574687594944L;

	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		Shape shape = new Rectangle(20, 10);
		ChartEntity entity = new ChartEntity(shape);
		StandardEntityCollection coll = new StandardEntityCollection();
		coll.add(entity);
		// 在鼠标移动到图片时显示提示信息是用Map实现的,这些Map是用该类生成的。
		ChartRenderingInfo info = new ChartRenderingInfo(coll);
		PrintWriter pw = response.getWriter();// 输出MAP信息
		// 生成提示信息的类
		ToolTipTagFragmentGenerator toolTip = new StandardToolTipTagFragmentGenerator();
		JFreeChart chart = createChart(response);
		/**
		 * 生成图片的文件名
		 * 注意,这个savesaveChartAsPNG方法的第四个参数,info,如果没有这个参数的话,是不能将图片的map存入的,
		 * 也就是说生成的图片没有热点。。
		 * */
		String fileName = ServletUtilities.saveChartAsPNG(chart, 500, 500,
				info, request.getSession());
		/*
		 * 这里的参数chartMap,意思是:把map信息写入request中key值为chartMap的map中。
		 * 取出的时候,在页面上用getAttribute("chartMap")
		 */
		ChartUtilities.writeImageMap(pw, "chartMap", info, false);
		StandardURLTagFragmentGenerator url = new StandardURLTagFragmentGenerator();
		url.generateURLFragment("index.do");
		// 获得"map"
		String chartMap = ImageMapUtilities.getImageMap("chartMap", info,
				toolTip, url);
		System.out.println(chartMap);
		chartMap = ChartMapUtil.getChartMap(chartMap);
		System.out.println(chartMap);
		// 存储map信息,页面读取该Map
		request.setAttribute("myChartMap", chartMap);

		request.setAttribute("fileName", fileName);
		// response.setBufferSize(1024*100);
		// pw.flush();
		// 获取图片的路径
		String graphURL = request.getContextPath()
				+ "/servlet/DisplayChart?filename=" + fileName; // 将路径放到request对象中
		// 注意这里的"/servlet/DisplayChart?filename="
		// 是jfreechart的虚拟的存储路径。一定要与在web.xml中配置的servlet一致
		request.setAttribute("graphURL", graphURL);
		// 页面转发到index.jsp
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}

	/**
	 * 创建图表
	 * 
	 * @param resp
	 * @return
	 * @throws IOException
	 */
	private JFreeChart createChart(HttpServletResponse resp) throws IOException {
		DefaultPieDataset dataSet = getDataSet();
		JFreeChart chart = ChartFactory.createPieChart3D("水果产量饼图", dataSet,
				true, true, true);
		ChartFontUtil.setPieChartFont(chart);
		return chart;
	}

	private DefaultPieDataset getDataSet() {
		DefaultPieDataset dataSet = new DefaultPieDataset();
		dataSet.setValue("荔枝", 100);
		dataSet.setValue("西瓜", 150);
		dataSet.setValue("苹果", 300);
		dataSet.setValue("荔枝", 200);
		dataSet.setValue("香蕉", 400);
		dataSet.setValue("蜜桃", 200);
		dataSet.setValue("西瓜", 100);
		dataSet.setValue("香蕉", 100);
		dataSet.setValue("苹果", 100);
		return dataSet;
	}

}


ChartServlet类所依赖的工具类

package com.pyy.report;

import java.io.StringReader;
import java.util.List;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;

/**
 * @author jackphang
 * @date 2013-4-16
 * @description
 */
public class ChartMapUtil {

	/**
	 * 获得自定义ChartMap数据
	 * 
	 * @param chartMap
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String getChartMap(String chartMap) {
		StringBuilder builder = new StringBuilder();
		StringReader reader = new StringReader(chartMap);
		InputSource source = new InputSource(reader);
		SAXBuilder build = new SAXBuilder();
		try {
			Document doc = build.build(source);
			Element element = doc.getRootElement();
			List<Element> list = element.getChildren();
			builder.append("<map id=\"myChartMap\" name=\"MyChartMap\">");
			int size = list.size();
			for (int j = 0; j < size; j++) {
				builder.append(" <area shape=\"poly\"");
				Element e = list.get(j);
				Attribute coordsAttr = e.getAttribute("coords");
				builder.append("coords=\"").append(coordsAttr.getValue())
						.append("\" ");
				Attribute titleAttr = e.getAttribute("title");
				String titleValue = titleAttr.getValue();
				builder.append("title=\"").append(titleValue.split("\\:")[0])
						.append("\" ");
				Attribute hrefAttr = e.getAttribute("href");
				String hrefValue = hrefAttr.getValue();
				builder.append("href=\"").append("myUrl.do?")
						.append(hrefValue.split("\\?")[1]).append("\" ");
				builder.append("/>");
			}
			builder.append("</map>");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return builder.toString();
	}

}


index.jsp页面

 

${myChartMap } 
 <!-- usemap中的myChartMap是指${myChartMap}生成后的<map id="myChartMap" name="MyChartMap"> 的name值 -->
 <img src="${graphURL}" border="0" ismap="ismap" usemap="#myChartMap"/><br><br>

 

${myChartMap}生成的代码:

 
<map id="myChartMap" name="MyChartMap">
 <area shape="poly"coords="131,267,128,250,128,232,128,214,131,197,134,180,140,164,146,149,154,134,163,121,174,109,185,99,197,91,209,84,222,79,236,76,250,75,250,232,250,232" title="蜜桃" href="myUrl.do?category=%E8%9C%9C%E6%A1%83&pieIndex=0" />
 <area shape="poly"coords="197,374,185,365,173,355,163,343,154,330,146,316,140,301,135,284,131,267,250,232,250,232" title="香蕉" href="myUrl.do?category=%E9%A6%99%E8%95%89&pieIndex=0" />
 <area shape="poly"coords="302,374,290,381,276,386,263,388,250,389,236,388,223,386,209,381,197,374,250,232,250,232" title="苹果" href="myUrl.do?category=%E8%8B%B9%E6%9E%9C&pieIndex=0" />
 <area shape="poly"coords="368,267,364,284,359,301,353,316,345,330,336,343,326,355,314,365,302,374,250,232,250,232" title="西瓜" href="myUrl.do?category=%E8%A5%BF%E7%93%9C&pieIndex=0" />
 <area shape="poly"coords="250,75,263,76,277,79,290,84,302,91,314,99,325,109,336,121,345,134,353,149,359,164,365,180,368,197,371,214,371,232,371,250,368,267,250,232,250,232" title="荔枝" href="myUrl.do?category=%E8%8D%94%E6%9E%9D&pieIndex=0" />
 </map> 

 

 


图表效果

 

每个区域都会显示热点、而且可以点击url跳转到指定的Servlet。具体实现、读者可以根据ChartMapUtil类自行修改,值得注意的是,生成的ChartMap数据必须符合一定的规范。另外,如果读者是使用OverLIBToolTipTagFragmentGenerator该类创建的热点,则需要加入overlib.js ,查看OverLIBToolTipTagFragmentGenerator源码:return " onMouseOver=\"return overlib('" + ImageMapUtilities.javascriptEscape(toolTipText) + "');\" onMouseOut=\"return nd();\"";  它是使用了外置的js,overlib.js。百度下载overlib.js放入你项目即可。

百度搜索下载即可。

完整源码下载:http://download.csdn.net/detail/jackphang/5265557

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值