首页 > 代码库 > JFreeChart在Struts2中实现3D柱状图统计

JFreeChart在Struts2中实现3D柱状图统计

上篇介绍了JFreeChart柱状图在Struts2中的实现,这篇来看一下3D柱状图的实现。

在Struts2中,用JFreeChart实现3D柱状图统计

下面分别用两种方式来实现: 一种是以java应用程序的方式,一种是以web项目程序的方式


需要加入的jar包有:  jcommon-1.0.17.jar 、 jfreechart-1.0.14.jar(前两个是JFreeChart中所带的,在下载的JFreeChart的lib目录下) 、 struts2-jfreechart-plugin-2.3.16.3.jar(这个是Struts2所带的,在下载的Struts2的lib目录下)、struts2所常用的9个核心jar包 。 jar包的版本可以有所不同


上述jar包放入到项目的WebRoot/WEB-INF/lib目录下


1、 以java应用程序的方式运行,在web项目中的src目录下新建包: com.jfreechart.test  , 在该包中新建类 BarChart3DTest.java

BarChart3DTest.java

package com.jfreechart.test;

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Random;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor;

public class BarChart3DTest {
	
	public static void main(String[] args) throws IOException{
		
        //步骤1:创建CategoryDataset对象(准备数据)     
	    CategoryDataset dataset = createDataset();     
        //步骤2:根据Dataset 生成JFreeChart对象,以及做相应的设置     
        JFreeChart jfreeChart = createChart(dataset);     
        //步骤3:将JFreeChart对象输出到文件     
        saveAsFile("F:\\BarChart3D.jpg", jfreeChart, 800, 600);     
		
    }
	
	/**
         * 创建一个dataset,该dataset包含图表要显示的数据
         * @return CategoryDataset
         */
	public static CategoryDataset createDataset() {
		// 图例名称
		String[] line = { "文学类", "科技类", "财经类", "娱乐类"};
		// 类别
		String[] category = { "2008年", "2009年", "2010年", "2012年", "2013年" };
		Random random = new Random(); // 实例化Random对象
		// 实例化DefaultCategoryDataset对象
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		// 使用循环向数据集合中添加数据
		for (int i = 0; i < line.length; i++) {
			for (int j = 0; j < category.length; j++) {
				dataset.addValue(100000 + random.nextInt(100000), line[i],
						category[j]);
			}
		}
		return dataset;
	}
	
    /**    
     * 根据PieDataset创建JFreeChart对象
     * @return JFreeChart    
     */      
    public static JFreeChart createChart(CategoryDataset categoryDataset) {
    	
      //JFreeChart类是一个制图对象类,先用它来创建一个制图对象chart
      //ChartFactory类是制图工厂类,用它来为制图对象chart完成实例化
      //createBarChart3D()是制图工厂的一个方法,用来创建一个3D的柱状图对象
      JFreeChart chart = ChartFactory.createBarChart3D(
    		  
    	    "图书销量统计图",                 //图表标题
            "年份",                        //X轴标题     
            "销售数量(本)",                        //Y轴标题
            categoryDataset,              //数据集
            PlotOrientation.VERTICAL,     //绘制方向
      		true,                         //是否显示图例
      		false,                        //是否采用标准生成器
      		false                         //是否支持超链接
      		);
      
      //通过JFreeChart对象的 setTitle方法,修改统计图表的标题部分(包括修改图表标题内容、字体大小等)
      chart.setTitle(new TextTitle("图书销量统计图", new Font("黑体", Font.ITALIC , 22))); 
      //调用 JFreeChart对象的 getLegend(int index)方法,取得该图表的指定索引的图例对象,通过 LegendTitle对象来修改统计图表的图例  
      LegendTitle legend = chart.getLegend(0); 
      //设置图例的字体和字体大小,即位于下方的字的字体和大小
      legend.setItemFont(new Font("宋体", Font.BOLD, 14));
      // 设置画布背景色
      chart.setBackgroundPaint(new Color(204, 204, 204)); 
      //取得折线图的绘图(plot)对象
      CategoryPlot plot = chart.getCategoryPlot();
      //设置数据区的背景透明度,范围在0.0~1.0间
      plot.setBackgroundAlpha(0.5f);
      // 设置数据区的前景透明度,范围在0.0~1.0间     
      plot.setForegroundAlpha(0.7f);     
      // 设置横轴字体
      plot.getDomainAxis().setLabelFont(new Font("黑体", Font.BOLD, 14));
          // 设置坐标轴标尺值字体
	  plot.getDomainAxis().setTickLabelFont(new Font("宋体", Font.BOLD, 12));
	  // 设置纵轴字体
	  plot.getRangeAxis().setLabelFont(new Font("黑体", Font.BOLD, 14));
	  // 设置绘图区背景色
	  plot.setBackgroundPaint(Color.WHITE);
	  // 设置水平方向背景线颜色
	  plot.setRangeGridlinePaint(Color.BLACK);
	  // 设置是否显示水平方向背景线,默认值为true
	  plot.setRangeGridlinesVisible(true);
	  // 设置垂直方向背景线颜色
	  plot.setDomainGridlinePaint(Color.BLACK);
	  // 设置是否显示垂直方向背景线,默认值为false
	  plot.setDomainGridlinesVisible(false);
	  // 横轴上的label斜显示
	  plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45); 
	  // 没有数据时显示的消息
          plot.setNoDataMessage("没有相关统计数据");
          plot.setNoDataMessageFont(new Font("黑体", Font.CENTER_BASELINE, 16));
          plot.setNoDataMessagePaint(Color.RED);
	
                //显示每个柱的数值,并修改该数值的字体属性
    		BarRenderer3D renderer = new BarRenderer3D();
    		renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
    		renderer.setBaseItemLabelsVisible(true);
    		//设置外廓线不可见
    		renderer.setDrawBarOutline(false);
    		//设置每个系列直方图中所包含的平行柱的之间距离
    		//renderer.setItemMargin(0.2);
    		//去掉柱子的倒影
    		renderer.setShadowVisible(false);
    		//默认的数字显示在柱子中,通过如下两句可调整数字的显示
    		//注意:此句很关键,若无此句,那数字的显示会被覆盖,给人数字没有显示出来的问题
    		renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
    		renderer.setItemLabelAnchorOffset(10D);
    		//设置每个柱子上的字体
    		//12号黑体加粗,字体为黑色
    		renderer.setItemLabelFont(new Font("黑体",Font.BOLD,10)); 
    		renderer.setItemLabelPaint(Color.black); 
    		
    		//改变图表中每个系列直方图的填充颜色
    		renderer.setSeriesPaint(0, new Color(153, 0, 102));   
    		renderer.setSeriesPaint(1, Color.orange);
    		renderer.setSeriesPaint(2, Color.RED);
    		renderer.setSeriesPaint(3, new Color(0, 0, 204));
    		
    		//提交设计的效果
    		plot.setRenderer(renderer);
      
      return chart;
    }
	
	/**
	 * 保存图表为文件 
	 */
    public static void saveAsFile(String filePath, JFreeChart jfreeChart,      
            int weight, int height) throws IOException { 
        
    	//输出图表到文件,saveCharAsJPEG()方法的参数(File file,JFreeChart chart,int width,int height)
        ChartUtilities.saveChartAsJPEG(new File(filePath), jfreeChart, weight, height);
    }
	

}


以java应用程序的方式,运行上面的 BarChart3DTest.java ,便可以在F盘的根目录下产生了一个名叫BarChart3D.jpg文件,如下图所示:


1、 以web项目程序的方式运行

(1)在web项目中的src目录下新建包: com.jfreechart.action , 在该包中新建类 BarChart3DAction.java

BarChart3DAction.java
package com.jfreechart.action;

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Random;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
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.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor;

import com.jfreechart.commons.FileUtil;
import com.opensymphony.xwork2.ActionContext;

public class BarChart3DAction {
	private JFreeChart chart;

	// 必须提供 getChart() 方法,且由该方法返回 JFreeChart 对象
	public JFreeChart getChart() throws Exception {
		//JFreeChart类是一个制图对象类,先用它来创建一个制图对象chart
		//ChartFactory类是制图工厂类,用它来为制图对象chart完成实例化
		//createBarChart3D()是制图工厂的一个方法,用来创建一个3D的柱状图对象
		chart = ChartFactory.createBarChart3D(
	    		  
	    		"图书销量统计图",                 //图表标题
	            "年份",                        //X轴标题     
	            "销售数量(本)",                        //Y轴标题
	            createDataset(),              //数据集
	            PlotOrientation.VERTICAL,     //绘制方向
	      		true,                         //是否显示图例
	      		false,                        //是否采用标准生成器
	      		false                         //是否支持超链接
	      		);
	      
	      //通过JFreeChart对象的 setTitle方法,修改统计图表的标题部分(包括修改图表标题内容、字体大小等)
	      chart.setTitle(new TextTitle("图书销量统计图", new Font("黑体", Font.ITALIC , 22))); 
	      //调用 JFreeChart对象的 getLegend(int index)方法,取得该图表的指定索引的图例对象,通过 LegendTitle对象来修改统计图表的图例  
	      LegendTitle legend = chart.getLegend(0); 
	      //设置图例的字体和字体大小,即位于下方的字的字体和大小
	      legend.setItemFont(new Font("宋体", Font.BOLD, 14));
	      // 设置画布背景色
	      chart.setBackgroundPaint(new Color(204, 204, 204)); 
	      //取得折线图的绘图(plot)对象
	      CategoryPlot plot = chart.getCategoryPlot();
	      //设置数据区的背景透明度,范围在0.0~1.0间
	      plot.setBackgroundAlpha(0.5f);
	      // 设置数据区的前景透明度,范围在0.0~1.0间     
	      plot.setForegroundAlpha(0.7f);     
	      // 设置横轴字体
	      plot.getDomainAxis().setLabelFont(new Font("黑体", Font.BOLD, 14));
	          // 设置坐标轴标尺值字体
		  plot.getDomainAxis().setTickLabelFont(new Font("宋体", Font.BOLD, 12));
		  // 设置纵轴字体
		  plot.getRangeAxis().setLabelFont(new Font("黑体", Font.BOLD, 14));
		  // 设置绘图区背景色
		  plot.setBackgroundPaint(Color.WHITE);
		  // 设置水平方向背景线颜色
		  plot.setRangeGridlinePaint(Color.BLACK);
		  // 设置是否显示水平方向背景线,默认值为true
		  plot.setRangeGridlinesVisible(true);
		  // 设置垂直方向背景线颜色
		  plot.setDomainGridlinePaint(Color.BLACK);
		  // 设置是否显示垂直方向背景线,默认值为false
		  plot.setDomainGridlinesVisible(false);
		  // 横轴上的label斜显示
		  plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45); 
		  // 没有数据时显示的消息
	          plot.setNoDataMessage("没有相关统计数据");
	          plot.setNoDataMessageFont(new Font("黑体", Font.CENTER_BASELINE, 16));
	          plot.setNoDataMessagePaint(Color.RED);
		
	                //显示每个柱的数值,并修改该数值的字体属性
	    		BarRenderer3D renderer = new BarRenderer3D();
	    		renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
	    		renderer.setBaseItemLabelsVisible(true);
	    		//设置外廓线不可见
	    		renderer.setDrawBarOutline(false);
	    		//设置每个系列直方图中所包含的平行柱的之间距离
	    		//renderer.setItemMargin(0.2);
	    		//去掉柱子的倒影
	    		renderer.setShadowVisible(false);
	    		//默认的数字显示在柱子中,通过如下两句可调整数字的显示
	    		//注意:此句很关键,若无此句,那数字的显示会被覆盖,给人数字没有显示出来的问题
	    		renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
	    		renderer.setItemLabelAnchorOffset(10D);
	    		//设置每个柱子上的字体
	    		//12号黑体加粗,字体为黑色
	    		renderer.setItemLabelFont(new Font("黑体",Font.BOLD,10)); 
	    		renderer.setItemLabelPaint(Color.black); 
	    		
	    		//改变图表中每个系列直方图的填充颜色
	    		renderer.setSeriesPaint(0, new Color(153, 0, 102));   
	    		renderer.setSeriesPaint(1, Color.orange);
	    		renderer.setSeriesPaint(2, Color.RED);
	    		renderer.setSeriesPaint(3, new Color(0, 0, 204));
	    		
	    		//提交设计的效果
	    		plot.setRenderer(renderer);
			
			//设置生成的图表的文件名
	        String fileName = "BarChart3DBook.jpg";
	        //设置图像输出的指定路径
	        String filePath = FileUtil.getWebRootPath()+"images\\chart\\"+fileName;
	        //输出图表到文件
	        saveAsFile(filePath, chart, 800, 600);
			
	        //取得request对象
	        Map request = (Map)ActionContext.getContext().get("request");
			//把生成的图表文件的路径filePath放进request对象中
	        request.put("filePath", filePath);
			
			return chart;
	}

	/**
	 * 保存图表为文件 
	 */
        public static void saveAsFile(String filePath, JFreeChart jfreeChart,      
            int weight, int height) throws IOException { 
        
    	//输出图表到文件,saveCharAsJPEG()方法的参数(File file,JFreeChart chart,int width,int height)
        ChartUtilities.saveChartAsJPEG(new File(filePath), jfreeChart, weight, height);
    }
    
       /**
        * 创建一个dataset,该dataset包含图表要显示的数据
        * @return CategoryDataset
        */
	public static CategoryDataset createDataset() {
		// 图例名称
		String[] line = { "文学类", "科技类", "财经类", "娱乐类"};
		// 类别
		String[] category = { "2008年", "2009年", "2010年", "2012年", "2013年" };
		Random random = new Random(); // 实例化Random对象
		// 实例化DefaultCategoryDataset对象
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		// 使用循环向数据集合中添加数据
		for (int i = 0; i < line.length; i++) {
			for (int j = 0; j < category.length; j++) {
				dataset.addValue(100000 + random.nextInt(100000), line[i],
						category[j]);
			}
		}
		return dataset;
	}
	
	//在struts.xml中的对应<action>里,应该写的是  method="barChart3D" 和  <result type="chart">
	public String barChart3D() {
		return "success";
	}
	
}

(2)在web项目中的src目录下新建struts.xml文件

struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	 <!-- 配置 Struts 2 应用中的常量 --> 
	 <constant name="struts.i18n.encoding" value=http://www.mamicode.com/"UTF-8"/> >

(3)修改在web项目中的WebRoot/WEB-INF/目录下的web.xml

web.xml
[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="3.0"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
  7.   
  8.   <!-- 设置struts 2过滤器 -->  
  9.   <filter>  
  10.       <filter-name>struts 2</filter-name>  
  11.       <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  12.   </filter>  
  13.   <filter-mapping>  
  14.       <filter-name>struts 2</filter-name>  
  15.       <url-pattern>/*</url-pattern>  
  16.   </filter-mapping>  
  17.     
  18.   <!-- 设置欢迎页面 -->  
  19.   <welcome-file-list>  
  20.     <welcome-file>index.jsp</welcome-file>  
  21.   </welcome-file-list>  
  22.     
  23.   <!-- session超时定义,单位为分钟 -->  
  24.   <session-config>  
  25.     <session-timeout>30</session-timeout>  
  26.   </session-config>  
  27.     
  28. </web-app>  

(4)在web项目中的src目录下新建包: com.jfreechart.commons , 在该包中新建类 FileUtil.java

FileUtil.java
[java] view plaincopyprint?
  1. <span style="font-weight: normal;"><span style="font-size:12px;">package com.jfreechart.commons;  
  2.   
  3. import javax.servlet.ServletContext;  
  4.   
  5. import org.apache.struts2.ServletActionContext;  
  6.   
  7. import com.opensymphony.xwork2.ActionContext;  
  8.   
  9. public class FileUtil {  
  10.   
  11.     /** 
  12.      * 获得web项目根目录 
  13.      */  
  14.     public static String getWebRootPath() throws Exception {  
  15.         ActionContext actionContext = ActionContext.getContext();  
  16.         ServletContext servletContext = (ServletContext)actionContext.get(ServletActionContext.SERVLET_CONTEXT);  
  17.         String rootPath = servletContext.getRealPath("/");  
  18.         return rootPath;  
  19.     }  
  20. }  

(5)修改在web项目中的WebRoot/目录下新建index.jsp、BarChart3D.jsp

index.jsp
[java] view plaincopyprint?
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href=http://www.mamicode.com/"<%=basePath%>">  
  11.     <title>首页</title>  
  12.   </head>  
  13.   <body>  
  14.       <a href=http://www.mamicode.com/"barChart3D.action">查看3D柱状图</a><br />  
  15.   </body>  
  16. </html>  
BarChart3D.jsp
[java] view plaincopyprint?
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="s" uri="/struts-tags"%>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href=http://www.mamicode.com/"<%=basePath%>">  
  11.     <title>3D柱状图</title>  
  12.   </head>  
  13.     
  14.   <body>  
  15.       <img src=http://www.mamicode.com/"<s:property value=http://www.mamicode.com/"#request.filePath" />" />  
  16.   </body>  
  17. </html>  

完成以上步骤后,把项目部署到服务器,在浏览器中访问该项目的index.jsp文件,点击“查看3D柱状图”的链接,即可跳转到BarChart3D.jsp页面,柱状图图表就显示在BarChart3D.jsp页面上了,图表的效果如上图一致。另外,上述所用的方法是 把图表先生成一个jpg文件,存放在服务器上的该web项目的相关目录下,然后在前台的jsp页面中引用该文件在项目中的的文件路径,即可把图表显示到前台页面中

JFreeChart在Struts2中实现3D柱状图统计