JFreeChart基于Java Web的报表组件的使用以及解决乱码
2013-04-16 21:47
489 查看
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使用,以此可以一劳永逸,但是笔者没这么干过。
设置乱码工具类
生成柱状图的类
以上是生成一个简单的柱状图,在你的Web项目中读取生成的图片即可。下面笔者带大家一起编写一个在JSP页面显示并且可以点击的饼图报表。
先看web.xml的配置
接下来是编写生成图表的Servlet。
ChartServlet类所依赖的工具类
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
完整源码下载: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
相关文章推荐
- JSP,mysql,tomcat下(基于struts2)中文及其乱码问题的解决 5大配置点 使用UTF-8编码
- 如何建立基于SSAS的Reporting Services报表,以及参数(parameters)使用
- 老南瓜:如何建立基于SSAS的Reporting Services报表,以及参数(parameters)使用
- 解决jfreechart中文乱码,以及字体模糊,设置主题问题
- android客户端通过Get方式提交参数给服务器,使用URL和HttpURLConnection实现,以及乱码问题解决
- 报表组件 JFreeChart (jfreechart-1.0.19) 的使用
- 老南瓜:如何建立基于SSAS的Reporting Services报表,以及参数(parameters)使用
- jpgraph的使用以及标题和图例中文乱码的源码解决方法
- PHP在使用PHPExcel组件导出xls文件乱码的解决
- 使用PowerDesigner 进行表结构设计--快捷导入sql脚本,以及解决中文乱码
- 解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)——ubuntu环境设置默认是utf-8,文件编码可使用Encodersoft批量转换
- 基于jsp:included的使用与jsp:param乱码的解决方法
- 使用GZIP解压缩数据,以及解决中文乱码
- VS2010 使用RDLC报表 布置在XP系统中 汉字全成了乱码 的解决方法
- Java Web中使用JSPSmartUpload控件实现文件的上传和下载(解决了中文乱码问题)(JSP页面采用GBK编码)
- shell中使用curl时,数据为乱码的解决方法,以及一些参数的解释
- 关于python 自带csv库的使用心得 附带操作实例以及excel下乱码的解决
- spring boot新手教程之使用FastJson解析JSON数据以及解决返回中文乱码问题
- java如何发送邮件以及使用Velocity模板解决模板文件中文乱码的问题
- [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件