最近,公司一项目要出很多的图表。由于项目是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代码,代码类似于这样:
<
map
id
="chart-30928.png"
name
="chart-30928.png"
>
< area shape ="poly" coords ="179,163,176,154,174,145" title ="洗衣机=315(29.86%)" alt ="" /> ………… </ map > < html > < head > …………
原因找到了,问题也就不难解决的。设置PrintWriter的contentType与Jsp的contentType保存一致就可以了。代码如下(笔者的Web应用是基于Struts框架的):
//
PieMothAciton.java
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //设置输出编码格式 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); ………… String filename = chart.generatePieChart3D("月统计比例图", session, out); String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename; request.setAttribute("filename",filename); request.setAttribute("graphURL",graphURL); return mapping.findForward(SUCCESS); }
二、 饼图显示百分比 在饼图中JFreeChart默认只显示选项和数值,没有显示各项所占比例。由于手头没有1.0版的JFreeChart Developer Guide(这可是要钱的,后来想想即使有,也未必能找到关于百分比这方面的说明),再加上DEMO中的饼图都没有显示百分比,无法参考。后来在网上找到了一个老版本的例子,其中能显示百分比。它是通过在PiePlot中设置的:
PiePlot pie;
pie.setPercentFormatString( " #,###0.0#% " ); 但1.0版本中根本就找不到setPercentFormatString这方法,JFreeChart各版本之间改动比较大,很难兼容。还好它是开源的,把它的源码都搜索了一遍,认真读了一些源码,终于理出了头绪。 原来在1.0.0-rc1版中显示百分比已经调整到StandardPieItemLabelGenerator构造函数中了,StandardPieItemLabelGenerator有三个构造函数。StandardPieItemLabelGenerator()不显示各项所占比例。另外两个可以显示比例。代码如下:
plot.setLabelGenerator(
new
StandardPieItemLabelGenerator(StandardPieItemLabelGenerator.DEFAULT_TOOLTIP_FORMAT));
// 或者采用下面自定义样式显示,{0}表示选项,{1}表示数值,{2}表示所占比例 plot.setLegendLabelGenerator( new StandardPieItemLabelGenerator( " {0}: ({1}M, {2}) " )); 效果如下图: 默认显示百分比是取整的,如果要让百分比保留二位小数,可以用第三个构造函数:
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 以上是笔者在项目开发中总结出来的,希望大家多提宝贵意见! |
使用JfreeChart开发图表经验总结(含源码)
最新推荐文章于 2012-04-01 18:24:32 发布