使用JfreeChart开发图表经验总结(含源码) 最近,公司一项目要出很多的图表。由于项目是B/S架构的,所以生成的图表也要考虑能在浏览器上动态显示。 生成基于浏览器的图表方式比较多。据我所知道的,常用的有三种: jfreechart是一个免费创建图表的java工具,目前最新版本是JFreeChart-1.0.0-rc1。它可以生成各式各样的图表。这些图表包括饼图、柱状图、线形图、区域图、甘特图等等,基本可以满足各种项目的要求。但在开发过程中我也发现了JFreeChart的一些不足,或者说有些称得上是BUG。总体说来,JFreeChart还是个优秀的开源项目。 关于JFreeChart生成图表的文章比较多了,我主要谈谈使用JFreeChart的一些比较棘手问题以及解决方法。同时也会将问题所用到的源码(JFreeChart-1.0.0-rc1+Struts1.2.4)从项目中抽象出来一起提供给大家。 一、 图片上热点链接中文乱码的解决方法 这个问题是在我查阅关于JFreeChart相关资料时出现频率最高的一个问题。其实这个乱码问题不能怪罪于JFreeChart。有人甚至就因此认为JFreeChart对中文支持不太完善,JFreeChart可要叫了:我是冤枉的! 我们来找出问题产生的原因,这个问题也就不难解决了。 首先查看一下出现问题页面的Html源文件,你会发现在源文件的开头多出了一段map代码,代码类似于这样: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
原因找到了,问题也就不难解决的。设置PrintWriter的contentType与Jsp的contentType保存一致就可以了。代码如下(笔者的Web应用是基于Struts框架的): ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
二、 饼图显示百分比 在饼图中JFreeChart默认只显示选项和数值,没有显示各项所占比例。由于手头没有1.0版的JFreeChart Developer Guide(这可是要钱的,后来想想即使有,也未必能找到关于百分比这方面的说明),再加上DEMO中的饼图都没有显示百分比,无法参考。后来在网上找到了一个老版本的例子,其中能显示百分比。它是通过在PiePlot中设置的: ![]() ![]() ![]() 但1.0版本中根本就找不到setPercentFormatString这方法,JFreeChart各版本之间改动比较大,很难兼容。还好它是开源的,把它的源码都搜索了一遍,认真读了一些源码,终于理出了头绪。 原来在1.0.0-rc1版中显示百分比已经调整到StandardPieItemLabelGenerator构造函数中了,StandardPieItemLabelGenerator有三个构造函数。StandardPieItemLabelGenerator()不显示各项所占比例。另外两个可以显示比例。代码如下: ![]() ![]() ![]() ![]() 效果如下图: 默认显示百分比是取整的,如果要让百分比保留二位小数,可以用第三个构造函数: plot.setLabelGenerator(new StandardPieItemLabelGenerator(“{0}={1}({2})”,
NumberFormat.getNumberInstance(), new DecimalFormat("0.00%"))); 效果如下图:
我们经常用的是柱状图、曲线图、和饼图,这三类型图基本能满足大部分项目的需求。但有些项目比较特殊,可能需要在一张图上同时显示不同类型的图。这在JFreeChart中可以轻松实现。例如我们要做个流量监控的系统,该系统一天中在不同的时间段有不同的阀值(最大值),该阀值表示成阶梯线。而实际流量就是个曲线了。当流量在某个时段内超过阀值时就触发相应的事件(如限流)。要表示阀值和流量的对比关系就需要两种类型的图片在同一张图表上表示,如下图:
//MultipleChart.java
JFreeChart jfreechart = ChartFactory.createXYStepAreaChart("监控设置", "时刻", "流量", xydataset, PlotOrientation.VERTICAL, true, true, false); XYPlot xyplot = jfreechart.getXYPlot(); ………… //设置第二图表的Renderer StandardXYItemRenderer standardxyitemrenderer = new StandardXYItemRenderer(); standardxyitemrenderer.setToolTipGenerator(new StandardXYToolTipGenerator("{0}({1}) = {2}", new SimpleDateFormat("HH:mm"), new DecimalFormat("#,##0"))); //将第二图表的Dataset、Renderer添加进xyplot xyplot.setDataset(1, lineDataset); xyplot.setRenderer(1,standardxyitemrenderer);
四、 其它问题 1) 版本问题。 2) 设置背景透明度的BUG 以上是笔者在项目开发中总结出来的,希望大家多提宝贵意见! Feedback很不错~我前一段时间将JfreeChart用在SWT框架的程序里,用了一种比较笨的方法,使用了一个AWT-SWT的桥,是SWT-Designer里面自带的一个工具类,感觉有些傻傻的。
不错的文章。
如果在结尾部分,加上一些比较基础的文章的连接更好。 这样大家如果对jfreechar不了解的话,可以先看看那些基础的文章。 写的不错,我们的项目中也正在使用jfreechart生成图表,不过我们采用的是applet的方式,主要是考虑到服务器负载的问题。另外,我们的项目中并没有直接使用jfreechart,而是按照我们的需要重新封装了一套接口。这样,起码在业务层可以保证代码的稳定
# re: [原创]使用JfreeChart开发图表经验总结(含源码) 回复2006-10-26 10:37 by thinkbase.net确认两张图片是一样的吗? 因为 IE 不支持透明的 PNG 图片的显示, 所以我猜想可能不是 JFreeChart 的 bug, 你用别的浏览器试试看
能不能把你的有关map部分的演示源代码发给我,map部分一直没有测试成功。谢谢
wuxufeng@ivo.com.cn 现有就这个问题了,我在jsp或者 用javabean调用都可以实现链接 ,但是在action中就没有办法把map的资料传到页面
下面是我action的代码 public ActionForward list(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); DefaultPieDataset data = new DefaultPieDataset(); data.setValue("高中以下", 370); data.setValue("高中", 1530); data.setValue("大专", 5700); data.setValue("本科", 8280); data.setValue("硕士", 4420); data.setValue("博士", 80); JFreeChart chart = ChartFactory.createPieChart3D("月统计比例图", data, true, true, true); PiePlot3D plot = (PiePlot3D)chart.getPlot(); plot.setURLGenerator(new StandardPieURLGenerator("barview.jsp")); chart.setBackgroundPaint(java.awt.Color.white); plot.setToolTipGenerator(new StandardPieToolTipGenerator()); StandardEntityCollection sec = new StandardEntityCollection(); ChartRenderingInfo info = new ChartRenderingInfo(sec); String filename = ServletUtilities.saveChartAsJPEG(chart, 500, 300, info, session); //FileOutputStream fos_jpg = new FileOutputStream("d:\\fruit.jpg"); //ChartUtilities.writeChartAsJPEG(out,100, chart, 500, 300, info); ChartUtilities.writeImageMap(out, "map0", info, false); String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename; request.setAttribute("filename", filename); request.setAttribute("graphURL", graphURL); return actionMapping.findForward("list"); } @thinkbase.net
IE支持PNG显示,我这里显示没有任何问题。本文原来是个Word文档,我导成HTML的,发现里面附图PNG的要比JPG的要清晰,就把PNG帖了上来。 @风人园
本文结尾有源码提供下载:http://dev2dev./bbs/servlet/D2DServlet/download/121-28066-168127-1963/JFeeChartProject_src.rar。 是基于Struts的,对应action产生map可以参考一演示源码。 再请问一个问题,除了 pie可以,其他的可以吗?
我用的是jfreechart 1.01,我通过设定 plot.setURLGenerator(new StandardPieURLGenerator("barview.do?from=xxx")); 可以实现链接,但是,其他的图好像没有这个方法,只有piePlot才有这个方法 @风人园
应该都有,可能方法名称不叫setURLGenerator,仔细研究一下源码。 可以到这里http://homepage./richard_c_atkinson/jfreechart/下载个war参考一下,不过版本有点老 |
|
来自: nbtymm > 《Java开源项目》