JFreeChart在Struts2中折線圖統計的實現

光華小丸子發表於2014-11-08

前段時間學習了一下JFreeChart,現在來整理一下自己所作的例項。

下面分別用兩種方式來實現: 一種是以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  , 在該包中新建類 LineChartTest.java

LineChartTest.java

package com.jfreechart.test;

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

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
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;

public class LineChartTest {

	public static void main(String[] args) throws IOException{

        //步驟1:建立CategoryDataset物件(準備資料)     
	    CategoryDataset dataset = createDataset();     
        //步驟2:根據Dataset 生成JFreeChart物件,以及做相應的設定     
        JFreeChart jfreeChart = createChart(dataset);     
        //步驟3:將JFreeChart物件輸出到檔案     
        saveAsFile("F:\\LineChart.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完成例項化
	  //createLineChart()是製圖工廠的一個方法,用來建立一個常規的折線圖物件
      JFreeChart chart = ChartFactory.createLineChart(

    		"圖書銷量統計圖",                 //圖表標題
            "年份",                        //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(192, 228, 106)); 
      //取得折線圖的繪圖(plot)物件
      CategoryPlot plot = chart.getCategoryPlot();
      //設定資料區的背景透明度,範圍在0.0~1.0間
      plot.setBackgroundAlpha(0.5f);
      // 設定資料區的前景透明度,範圍在0.0~1.0間     
      plot.setForegroundAlpha(0.5f);     
      // 設定橫軸字型
      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(true);
	  // 沒有資料時顯示的訊息
      plot.setNoDataMessage("沒有相關統計資料");
      plot.setNoDataMessageFont(new Font("黑體", Font.CENTER_BASELINE, 16));
      plot.setNoDataMessagePaint(Color.RED);

		// 獲取折線物件
		LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
				.getRenderer();

		//設定折點處以某種形狀凸出
		renderer.setShapesVisible(true);
		renderer.setDrawOutlines(true);
		renderer.setUseFillPaint(true);
		renderer.setFillPaint(java.awt.Color.WHITE);

		//設定顯示折點處的資料值
		//renderer.setBaseItemLabelGenerator (new StandardCategoryItemLabelGenerator ());
		//renderer.setItemLabelFont (new Font ("黑體", Font.PLAIN, 12));
		//renderer.setItemLabelsVisible (true);

        BasicStroke realLine = new BasicStroke(2.0f); // 設定實線
		float dashes[] = { 8.0f }; // 定義虛線陣列
		BasicStroke brokenLine = new BasicStroke(2.0f, // 線條粗細
				BasicStroke.CAP_SQUARE, // 端點風格
				BasicStroke.JOIN_MITER, // 折點風格
				8.f, // 折點處理辦法
				dashes, // 虛線陣列
				0.0f); // 虛線偏移量
		// 利用虛線繪製
		renderer.setSeriesStroke(0, brokenLine);
		// 利用虛線繪製
		renderer.setSeriesStroke(1, brokenLine);
		// 利用實線繪製
		renderer.setSeriesStroke(2, realLine);
		// 利用實線繪製
		renderer.setSeriesStroke(3, realLine);

		//設定折線的顏色
		renderer.setSeriesPaint(0, Color.BLACK);
		renderer.setSeriesPaint(1, Color.RED);
		renderer.setSeriesPaint(2, Color.BLUE);
		renderer.setSeriesPaint(3, Color.MAGENTA);

      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應用程式的方式,執行上面的 LineChartTest.java ,便可以在F盤的根目錄下產生了一個名叫LineChart.jpg檔案,如下圖所示:

2、 以web專案程式的方式執行

(1)在web專案中的src目錄下新建包: com.jfreechart.action , 在該包中新建類LineChartAction.java

LineChartAction.java
package com.jfreechart.action;

import java.awt.BasicStroke;
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.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
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 com.jfreechart.commons.FileUtil;
import com.opensymphony.xwork2.ActionContext;

public class LineChartAction {
	private JFreeChart chart;

	// 必須提供 getChart() 方法,且由該方法返回 JFreeChart 物件
	public JFreeChart getChart() throws Exception {
		  //JFreeChart類是一個製圖物件類,先用它來建立一個製圖物件chart
	      //ChartFactory類是製圖工廠類,用它來為製圖物件chart完成例項化
		  //createLineChart()是製圖工廠的一個方法,用來建立一個常規的折線圖物件
		  chart = ChartFactory.createLineChart(

	    		"圖書銷量統計圖",                 //圖表標題
	            "年份",                        //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(192, 228, 106)); 
	      //取得折線圖的繪圖(plot)物件
	      CategoryPlot plot = chart.getCategoryPlot();
	      //設定資料區的背景透明度,範圍在0.0~1.0間
	      plot.setBackgroundAlpha(0.5f);
	      // 設定資料區的前景透明度,範圍在0.0~1.0間     
	      plot.setForegroundAlpha(0.5f);     
	      // 設定橫軸字型
	      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(true);
		  // 沒有資料時顯示的訊息
	      plot.setNoDataMessage("沒有相關統計資料");
	      plot.setNoDataMessageFont(new Font("黑體", Font.CENTER_BASELINE, 16));
	      plot.setNoDataMessagePaint(Color.RED);

			// 獲取折線物件
			LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
					.getRenderer();

			//設定折點處以某種形狀凸出
			renderer.setShapesVisible(true);
			renderer.setDrawOutlines(true);
			renderer.setUseFillPaint(true);
			renderer.setFillPaint(java.awt.Color.WHITE);

			//設定顯示折點處的資料值
			//renderer.setBaseItemLabelGenerator (new StandardCategoryItemLabelGenerator ());
			//renderer.setItemLabelFont (new Font ("黑體", Font.PLAIN, 12));
			//renderer.setItemLabelsVisible (true);

	        BasicStroke realLine = new BasicStroke(2.0f); // 設定實線
			float dashes[] = { 8.0f }; // 定義虛線陣列
			BasicStroke brokenLine = new BasicStroke(2.0f, // 線條粗細
					BasicStroke.CAP_SQUARE, // 端點風格
					BasicStroke.JOIN_MITER, // 折點風格
					8.f, // 折點處理辦法
					dashes, // 虛線陣列
					0.0f); // 虛線偏移量
			// 利用虛線繪製
			renderer.setSeriesStroke(0, brokenLine);
			// 利用虛線繪製
			renderer.setSeriesStroke(1, brokenLine);
			// 利用實線繪製
			renderer.setSeriesStroke(2, realLine);
			// 利用實線繪製
			renderer.setSeriesStroke(3, realLine);

			//設定折線的顏色
			renderer.setSeriesPaint(0, Color.BLACK);
			renderer.setSeriesPaint(1, Color.RED);
			renderer.setSeriesPaint(2, Color.BLUE);
			renderer.setSeriesPaint(3, Color.MAGENTA);

        //設定生成的圖表的檔名
        String fileName = "LineChartBook.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="pieChart" 和  <result type="chart">
	public String lineChart() {
		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="UTF-8"/>   

     <!-- 配置本應用中的包,繼承 jfreechart-default 包 -->   
     <package name="chart" extends="jfreechart-default">   
                  <!-- 定義一個名為 lineChart 的 Action -->   
         <action name="lineChart" class="com.jfreechart.action.LineChartAction" method="lineChart">   
             <result type="chart">  
                     /LineChart.jsp  
                 <!-- 定義 JFreeChart 報表的大小 -->   
                 <param name="width">800</param>   
                 <param name="height">500</param>   
             </result>   
         </action>                                                                             </package>   
</struts>

(3)修改在web專案中的WebRoot/WEB-INF/目錄下的web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="3.0"   
    xmlns="http://java.sun.com/xml/ns/javaee"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  

  <!-- 設定struts 2過濾器 -->  
  <filter>  
      <filter-name>struts 2</filter-name>  
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  </filter>  
  <filter-mapping>  
      <filter-name>struts 2</filter-name>  
      <url-pattern>/*</url-pattern>  
  </filter-mapping>  

  <!-- 設定歡迎頁面 -->  
  <welcome-file-list>  
    <welcome-file>index.jsp</welcome-file>  
  </welcome-file-list>  

  <!-- session超時定義,單位為分鐘 -->  
  <session-config>  
    <session-timeout>30</session-timeout>  
  </session-config>  

</web-app>

(4)在web專案中的src目錄下新建包: com.jfreechart.commons , 在該包中新建類 FileUtil.java

FileUtil.java

package com.jfreechart.commons;  

import javax.servlet.ServletContext;  

import org.apache.struts2.ServletActionContext;  

import com.opensymphony.xwork2.ActionContext;  

public class FileUtil {  

    /** 
     * 獲得web專案根目錄 
     */  
    public static String getWebRootPath() throws Exception {  
        ActionContext actionContext = ActionContext.getContext();  
        ServletContext servletContext = (ServletContext)actionContext.get(ServletActionContext.SERVLET_CONTEXT);  
        String rootPath = servletContext.getRealPath("/");  
        return rootPath;  
    }  
}

(5)修改在web專案中的WebRoot/目錄下新建index.jsp、LineChart.jsp

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
    <title>首頁</title>  
  </head>  
  <body>  
      <a href="lineChart.action">檢視折線圖</a><br />  
  </body>  
</html>

LineChart.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%@ taglib prefix="s" uri="/struts-tags"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
    <title>折線圖</title>  
  </head>  

  <body>  
      <img src="<s:property value="#request.filePath" />" />  
  </body>  
</html>

完成以上步驟後,把專案部署到伺服器,在瀏覽器中訪問該專案的index.jsp檔案,點選“檢視折線圖”的連結,即可跳轉到LineChart.jsp頁面,折線圖圖表就顯示在LineChart.jsp頁面上了,圖表的效果如上圖一致。另外,上述所用的方法是 把圖表先生成一個jpg檔案,存放在伺服器上的該web專案的相關目錄下,然後在前臺的jsp頁面中引用該檔案在專案中的的檔案路徑,即可把圖表顯示到前臺頁面中。

相關文章