前段时间公司要做报表开发,顺便研究了下JFreechart的简单使用,个人觉得JFreechart生成的图片效果很差,如:图像、字体模糊,缺乏动态效果,比flash相差很远。不过作为学习,跟大家交流下JFreechart的开发过程。
遇到问题:
windows下图片中文显示乱码--这个主要是由于没有给中文设置字体造成的
某些linux下图片中文显示乱码--这个主要是由于该linux系统缺乏中文字体,向linux的字体目录下导入中文字体即可(具体方法网上很多)
这两种问题本人已测试通过。
本例使用struts2框架,导入jfreechart-1.0.13.jar和struts2-jfreechart-plugin-2.2.1.1.jar
1.带热点饼图的Action
com.milton.hot.FirstChart
package com.milton.hot; import java.awt.Color; import java.awt.Font; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; 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.StandardEntityCollection; import org.jfree.chart.labels.StandardPieToolTipGenerator; import org.jfree.chart.plot.PiePlot; import org.jfree.chart.servlet.ServletUtilities; import org.jfree.chart.title.LegendTitle; import org.jfree.chart.title.TextTitle; import org.jfree.chart.urls.StandardPieURLGenerator; import org.jfree.data.general.DefaultPieDataset; import com.opensymphony.xwork2.ActionSupport; /** * * 带热点的饼图 * @author Milton * */ public class FirstChart extends ActionSupport { private String mapMessage; private String src; /** * 生成饼图 */ public String execute() throws Exception { //设置数据 DefaultPieDataset data = new DefaultPieDataset(); data.setValue("三星I9000", 10000); data.setValue("HTC G7", 20000); data.setValue("HTC G2", 15000); data.setValue("诺基亚5230", 16000); data.setValue("摩托罗拉ME525", 50000); //生成JFreeChart对象 JFreeChart chart = ChartFactory .createPieChart3D("手机销量统计图", data, true, true, true); chart.setTitle(new TextTitle("手机销量统计图", new Font("隶书", Font.BOLD, 25))); //建一个图例 LegendTitle legendTitle = chart.getLegend(0); //设置图例字体 legendTitle.setItemFont(new Font("宋体",Font.BOLD,14)); PiePlot plot = (PiePlot) chart.getPlot(); //根据key指定各个数据饼图的颜色 plot.setSectionPaint("三星I9000", Color.RED); plot.setSectionPaint("HTC G7", Color.BLUE); plot.setSectionPaint("HTC G2", Color.GREEN); plot.setSectionPaint("诺基亚5230", Color.ORANGE); plot.setSectionPaint("摩托罗拉ME525", Color.GRAY); //设置plot字体 plot.setLabelFont(new Font("宋体",Font.BOLD,18)); //设置背景透明度(0~1) plot.setBackgroundAlpha(0.1f); //设置热点 plot.setNoDataMessage("No data available"); plot.setURLGenerator(new StandardPieURLGenerator("second.jsp", "type")); plot.setToolTipGenerator(new StandardPieToolTipGenerator()); StandardEntityCollection sec = new StandardEntityCollection(); //生成RenderingInfo实例,info参数就是图片的热点信息 ChartRenderingInfo info = new ChartRenderingInfo(sec); HttpServletRequest request = ServletActionContext.getRequest(); String filename = ServletUtilities.saveChartAsJPEG(chart, 750, 300, info, request.getSession()); mapMessage = ChartUtilities.getImageMap("map0", info); src = request.getContextPath()+"/DisplayChart?filename=" + filename; return "first"; } public void setMapMessage(String mapMessage) { this.mapMessage = mapMessage; } public void setSrc(String src) { this.src = src; } public String getMapMessage() { return mapMessage; } public String getSrc() { return src; } }
2.热点链接进去后的柱状图的Action
com.milton.hot.SecondChart
package com.milton.hot; import java.awt.Color; import java.awt.Font; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer3D; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.DefaultCategoryDataset; import com.opensymphony.xwork2.ActionSupport; public class SecondChart extends ActionSupport { private JFreeChart chart; /** * 生成柱状图 */ public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); String type = new String(request.getParameter("type").getBytes("ISO_8859_1"), "UTF-8"); if(type.equals("Java")) { //根据类型做不同处理 } //中文必须设置字体,否则页面显示小方块 Font xfont = new Font("宋体", Font.PLAIN, 20);// X轴 Font yfont = new Font("宋体", Font.PLAIN, 12);// Y轴 Font kfont = new Font("宋体", Font.PLAIN, 12);// 底部 Font titleFont = new Font("隶书", Font.BOLD, 25); // 图片标题 DefaultCategoryDataset data = new DefaultCategoryDataset(); data.addValue(15000, "", "第一季度"); data.addValue(10000, "", "第二季度"); data.addValue(20000, "", "第三季度"); data.addValue(5000, "", "第四季度"); chart = ChartFactory.createBarChart3D( type+"季度销量统计图",//图表标题 "季度",//横轴显示标签 "销量",//纵轴显示标签 data,//数据集 PlotOrientation.VERTICAL,//设置图表方向 (水平、垂直) false,//是否显示图例(对于简单的柱状图必须是false) false,//是否生成工具 true//是否生成URL链接 ); //设置标题 chart.setTitle(new TextTitle(type+"季度销量统计图", titleFont)); //设置图表部分 CategoryPlot plot = (CategoryPlot) chart.getPlot(); plot.setForegroundAlpha(0.5f); CategoryAxis categoryAxis = plot.getDomainAxis();//取得横轴 categoryAxis.setTickLabelFont(xfont);//设置横轴分类标签字体 categoryAxis.setLabelFont(xfont);//设置横轴显示标签的字体 categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);//分类标签以45度倾斜 NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();//取得纵轴 numberAxis.setTickLabelFont(yfont);//设置纵轴分类标签字体 numberAxis.setLabelFont(yfont);//设置纵轴显示标签字体 //渲染柱子 BarRenderer3D render = (BarRenderer3D) plot.getRenderer(); render.setSeriesPaint(0, Color.blue);//设置柱子颜色 render.setSeriesPaint(1, Color.BLUE); render.setSeriesPaint(2, Color.RED); render.setSeriesPaint(3, Color.GREEN); render.setItemMargin(0.5);//设置柱子间隔 render.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); render.setBaseItemLabelsVisible(true);//显示每个柱子的数值 plot.setRenderer(render); return SUCCESS; } public JFreeChart getChart() { return chart; } public void setChart(JFreeChart chart) { this.chart = chart; } }
3.web.xml配置
<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>/DisplayChart</url-pattern> </servlet-mapping>
4.struts.xml配置
<action name="firstChart" class="com.milton.hot.FirstChart"> <result name="first">/first.jsp</result> </action> <action name="secondChart" class="com.milton.hot.SecondChart"> <result type="chart"> <param name="width">500</param> <param name="height">500</param> <param name="imageType">jpg</param> </result> </action>
5.first.jsp的<body>中添加如下代码
<p align="center"> <s:property value="mapMessage" escape="false"/> <img src="<s:property value='src'/>" border=0 usemap="#map0"> </p>
6.second.jsp(热点链接进入后的柱状图页面)
<body> <!-- 得到饼图热点类型 --> <% String type = request.getParameter("type"); String str = new String(type.getBytes("ISO_8859_1"), "utf-8"); %> <%=str%> <p align="center"><img src="<%=request.getContextPath()%>/secondChart.action?type=<%=str%>"> </p> </body>
7.部署在web服务器后运行
8.浏览器输入http://10.0.0.46:8080/JFreeChart/firstChart.action后即可看到first.jsp中带热点的饼图
9.点击热点区域即可看到对应的柱状图