2011年1月16日 星期日

JSP 教學 - JFreeChart 製作及中文亂碼問題

JFreeChart 唯一個能運用 JAVA 程式來繪製出各種多樣化的報表圖型,如圓餅圖,長條圖等

此為它的官網,http://www.jfree.org/jfreechart/ 先將壓縮檔下載下來後解壓縮

我是下載 jfreechart-1.0.13 版的,解壓縮後在目錄下的 lib 目錄中的所有JAR複製到WEB專案

路徑下的 /WEB-INF/lib 中,其實只要兩個就夠用啦 jcommon-1.0.16.jar jfreechart-1.0.13.jar


佈置完成後先可以用個 JSP 來測試一下,在 JSP  中寫入 img 標籤

<img src='/vote/showJFreeChart' alt='投票統計'/>  //vote為我的 WEB 專案的名稱
接著可以建置一個 Servlet 來動態產生圖形  showJFreeChart.java

以下來介紹一下最常見的圓餅圖:



package fsc.controller;

import java.awt.Font;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
public class showJFreeChart extends HttpServlet {

    public showJFreeChart() {
        super();
        // TODO Auto-generated constructor stub
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        response.setContentType("image/png");  //設定輸出的型態為圖片且為 .png 檔
        java.io.OutputStream out = response.getOutputStream();  //取得回應的輸出串流 實為 ServletOutputStream
  
        // 圓餅圖
        DefaultPieDataset dataset = new DefaultPieDataset();  //建立圓餅圖的資料集
        dataset.setValue("Java", 50);   //設定項目
        dataset.setValue("C 語言", 30);
        dataset.setValue("C#", 20);
        String title = new String("程式語言排行");
        //title 為標題, dataset 為資料, true 為是否加上說明列, false 為是否加上 Tool chip, false 為是否加上URL位置
        JFreeChart chart = ChartFactory.createPieChart(title, dataset, true, false, false);  
        try{
            ChartUtilities.writeChartAsPNG(out, chart, 400, 300);  //輸出 PNG 圖檔
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
}

以上為一個圓餅圖的範例,注意幾點的是 DefaultPieDataset 為圓餅圖所使用的資料集

ChartUtilities 有很多的繪製圖黨方法,例如 writeChartAsJPEG 為輸出 JPEG 圖檔

相信以上的作法 應該會出現圓餅圖,但會發生中文的亂碼問題,因為 JFreeChart 並不支援中文,所以需要額外寫點程式

//建立文字型態
    Font font = new Font("細明體", Font.BOLD, 12);  

    //取得 PiePlot, 此為圓餅圖中的資料形式
    PiePlot plot = (PiePlot)chart.getPlot();  

    //設定標籤文字
    plot.setLabelFont(font); 

    //設定標題, 用 TextTitle 
    chart.setTitle(new TextTitle(chart.getTitle().getText(),font)); 

    //設定說明列
    chart.getLegend().setItemFont(font);  //設定說明列

接下來在介紹一下長條圖的製作
//DefaultCategoryDataset 為長條圖的資料集
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    //所有的參予資料
    String man1 = "銷售員 1", man2 = "銷售員  2", man3 = "銷售員  3";
    //X軸
    String mon1 = "四月", mon2 = "五月", mon3 = "六月", mon4 = "七月";
    
    //銷售員 1  
    dataset.addValue(500, man1, mon1); //500.0為銷售額
    dataset.addValue(600, man1, mon2);
    dataset.addValue(300, man1, mon3);
    dataset.addValue(450, man1, mon4);
    //銷售員 2 
    dataset.addValue(300, man2, mon1);
    dataset.addValue(400, man2, mon2);
    dataset.addValue(700, man2, mon3);
    dataset.addValue(500, man2, mon4);
    //銷售員 3 
    dataset.addValue(450, man3, mon1);
    dataset.addValue(600, man3, mon2);
    dataset.addValue(700, man3, mon3);
    dataset.addValue(100, man3, mon4);
    // PlotOrientation.VERTICAL 代表長條圖會與X軸垂直
    JFreeChart chart = ChartFactory.createBarChart("銷售員業績",
         "月份", "銷售額", 
         dataset, PlotOrientation.VERTICAL, 
         true, false, false);
    
    Font font = new Font("細明體", Font.BOLD, 12); //設定字型樣式
    CategoryPlot plot = chart.getCategoryPlot();  //取得長條圖的資料形式, 透過 getCategoryPlot
    chart.setTitle(new TextTitle(chart.getTitle().getText(),font));  //設定標題
    chart.getLegend().setItemFont(font);  //設定說明列
    CategoryAxis domainAxis = plot.getDomainAxis();  //X軸 
    domainAxis.setLabelFont(font);   //設定X軸的標題
    domainAxis.setTickLabelFont(font);   //設定X軸的數據
    ValueAxis rangeAxis = plot.getRangeAxis();   //Y軸   
    rangeAxis.setLabelFont(font);  //設定Y軸的標題   
    rangeAxis.setTickLabelFont(font);   //設定Y軸的數據

    try{
        ChartUtilities.writeChartAsPNG(out, chart, 400, 300);
    }catch(Exception e){
        System.out.println(e.getMessage());
    }

沒有留言:

張貼留言