<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java學習

    java,spring,structs,hibernate,jsf,ireport,jfreechart,jasperreport,tomcat,jboss -----本博客已經搬家了,新的地址是 http://www.javaly.cn 如果有對文章有任何疑問或者有任何不懂的地方,歡迎到www.javaly.cn (Java樂園)指出,我會盡力幫助解決。一起進步

     

    使用 JFreeChart來創建基于web的圖表

    WWW的發展使得基于因特網的應用程序不再局限于靜態或者簡單的動態內容提供。傳統的一些以軟件包形式發布應用程序例如報表系統 等都在逐漸搬到因特網上。但是這兩者之間有著天壤之別,雖然對于數據獲取、業務處理等方面基本類似,但是最大的差別在于用戶界面。為了能在web瀏覽器上 顯示要求用戶界面使用HTML以及圖片的方式來展現數據,而傳統的一些利用操作系統本身的控件來開發的用戶界面無法適應琳瑯滿目的客戶端,因此在這里也變 得無能為力。回到本文的題目上來,為了創建一個可以在web瀏覽器上查看到圖表一般有兩種做法:第一種就是使用applet利用java本身對圖形的支持 來顯示一個圖表;第二種就是直接在web服務器端生成好圖表圖片文件后發送給瀏覽器。第一種方式顯然對于客戶端要求太高,隨著現在主流瀏覽器放棄對 JAVA的支持后,這種方式只適合一些局域網的應用,而對于因特網的環境就顯得不太適合。因此我們下面將介紹一個JAVA的圖表引擎JFreeChart 用來產生基于WEB的圖表。

    JFreeChart項目簡介

    JFreeChart是開放源代碼站點SourceForge.net上的一個JAVA項目,它主要用來各種各樣的圖表,這些圖表包括:餅圖、柱狀圖(普 通柱狀圖以及堆棧柱狀圖)、線圖、區域圖、分布圖、混合圖、甘特圖以及一些儀表盤等等。這些不同式樣的圖表基本上可以滿足目前的要求。為了減少篇幅本文主 要介紹前面三種類型的圖表,讀者可以觸類旁通去開發其他樣式的圖表。下面幾個是JFreeChart產生的這三種類型圖表的結果:


    圖1


    圖2


    圖3

    上 面的三個圖都是表示四個季度的某個產品的銷量信息。在繼續下面小節之前必須先準備好開發環境,因為是基于WEB瀏覽器的圖表展現,因此需要一個 Servlet引擎或者是J2EE應用服務器(例如WebSphere,Tomcat等)。WEB環境的搭建就不累贅了,讀者根據喜好自行安裝。 JFreeChart引擎本身需要到SourceForge.net上下載,地址如下:

    JFreeChart主頁:
    http://www.jfree.org/jfreechart/index.html
    JFreeChart下載頁面:
    http://sourceforge.net/projects/jfreechart/


    下載的時候需要注意的是必須下載兩個文件:JFreeChart以及Jcommon。目前最新配套版本是:JFreeChart 0.9.11 Jcommon 0.8.6

    這里有點筆者在開發中遇見的問題需要注意的是:在使用Eclipse開發的時候會報一個莫名其妙的錯誤,錯誤可能指向某個類文件的第一行。遇到這樣的問題一般是因為沒有把Jcommon的jar包設置到項目的類路徑中的緣故。具體的原因不祥。





    回頁首


    解讀JFreeChart的源碼結構

    在 開始使用JFreeChart之前我們有必要先大概了解一下JFreeChart本身的結構以及它所帶一些例子程序,這樣有助于我們下一步自行開發。下載 JFreeChart包后已經帶有非常豐富的例子,因為JFreeChart這個項目本身的使用文檔非常少,因此學習它最好的辦法就是學習它所帶的例子源 碼。在包org.jfree.chart.demo中有幾十個文件用于展示JFreeChart所能支持的所有圖表的結果。如果你的JDK是比較新的情況 下可能在運行這些例子時會有問題,現象如下:

    java.lang.UnsatisfiedLinkError: initDDraw
    at sun.awt.windows.Win32OffScreenSurfaceData.initDDraw(Native Method)
    at sun.awt.windows.Win32OffScreenSurfaceData.<clinit>(Win32OffScreenSurfaceData.java:141)
    at sun.awt.Win32GraphicsDevice.<clinit>(Win32GraphicsDevice.java:58)
    at sun.awt.Win32GraphicsEnvironment.makeScreenDevice(Win32GraphicsEnvironment.java:168)
    at sun.java2d.SunGraphicsEnvironment.getScreenDevices(SunGraphicsEnvironment.java:240)
    at sun.awt.Win32GraphicsEnvironment.getDefaultScreenDevice(Win32GraphicsEnvironment.java:61)
    at java.awt.Window.init(Window.java:224)
    at java.awt.Window.<init>(Window.java:268)
    at java.awt.Frame.<init>(Frame.java:398)
    at javax.swing.JFrame.<init>(JFrame.java:198)
    at org.jfree.chart.demo.JFreeChartDemo.<init>(JFreeChartDemo.java:148)
    at org.jfree.chart.demo.JFreeChartDemo.main(JFreeChartDemo.java:285)
    Exception in thread "main"

    這個錯誤是由于新版的Swing大量的使用了微軟的 DirectDraw的技術來提高畫圖的性能,而可能你的顯卡在這時候會跟你鬧點情緒或者顯卡本身并不支持這樣的一個技術。難道就沒有辦法了嘛?要解決這 個問題也非常簡單,我們可以屏蔽掉DirectDraw,不讓Swing使用該技術就可以了。在運行這些代碼時給虛擬機指定參數- Dsun.java2d.noddraw即可。

    這時可能你又該納悶了,不說是基于Web的圖表嘛,怎么又扯到Swing上了?這是因為為了使開發者容易上手,無需配置任 何運行環境,所以這些例子都是基于GUI方式的用于展現給開發者如果生成一個圖表,我們要學習的也就是如何利用這個引擎生成圖表而不是怎么來顯示一個圖 表。當我們把生成的圖表對象Export到一個圖像文件即可在Web上發布。

    下面我們來介紹JFreeChart中幾個核心的對象類:

    類名 類的作用以及簡單描述
    JFreeChart 圖表對象,任何類型的圖表的最終表現形式都是在該對象進行一些屬性的定制。JFreeChart引擎本身提供了一個工廠類用于創建不同類型的圖表對象
    XXXXXDataset 數據集對象,用于提供顯示圖表所用的數據。根據不同類型的圖表對應著很多類型的數據集對象類
    XXXXXPlot 圖表區域對象,基本上這個對象決定著什么樣式的圖表,創建該對象的時候需要Axis、Renderer以及數據集對象的支持
    XXXXXAxis 用于處理圖表的兩個軸:縱軸和橫軸
    XXXXXRenderer 負責如何顯示一個圖表對象
    XXXXXURLGenerator 用于生成Web圖表中每個項目的鼠標點擊鏈接
    XXXXXToolTipGenerator 用于生成圖象的幫助提示,不同類型圖表對應不同類型的工具提示類

    基 本上我認為JFreeChart項目本身的類結構的設計并不是很好,首先在創建圖表的時候用到了大量的工廠方法,這樣做雖然可以簡化創建圖表對象的代碼, 但是對項目本身或者開發人員來講自行擴展一種新的圖表都仍然是一件很麻煩的事情;其次除圖表對象本身外其余的類過于復雜,使用者必須去了解每個類型的圖表 對象應該對應哪些Axis、Plot、Renderer類,并且必須非常熟悉這些類的構造函數中每個參數的具體含義。這些問題都大大困擾很多初學者。不 過,雖然存在很多問題,但是JFreeChart本身仍不失為一個非常優秀的圖表引擎,況且項目本身也在逐漸的發展中。

    在非常簡略的介紹了JFreeChart本身的代碼結構后,下面我們開始動手試驗幾個常用的圖表并把他們放到web上。





    回頁首


    使用JFreeChart生成各種樣式的圖表

    限于篇幅的問題我們在這里只實現兩種常用的圖表,其他類型圖表讀者可以觸類旁通。我們先給出柱狀圖的實現,餅圖的實現再來跟柱狀圖進行比較。

    1 柱狀圖

    package lius.chart.demo;
    import java.io.*;
    import org.jfree.data.*;
    import org.jfree.chart.*;
    import org.jfree.chart.plot.*;
    /**
    * 該類用于演示最簡單的柱狀圖生成
    * @author Winter Lau
    */
    public class BarChartDemo {
    public static void main(String[] args) throws IOException{
    CategoryDataset dataset = getDataSet2();
    JFreeChart chart = ChartFactory.createBarChart3D(
    "水果產量圖", // 圖表標題
    "水果", // 目錄軸的顯示標簽
    "產量", // 數值軸的顯示標簽
    dataset, // 數據集
    PlotOrientation.VERTICAL, // 圖表方向:水平、垂直
    true, // 是否顯示圖例(對于簡單的柱狀圖必須是false)
    false, // 是否生成工具
    false // 是否生成URL鏈接
    );

    FileOutputStream fos_jpg = null;
    try {
    fos_jpg = new FileOutputStream("D:\\fruit.jpg");
    ChartUtilities.writeChartAsJPEG(fos_jpg,100,chart,400,300,null);
    } finally {
    try {
    fos_jpg.close();
    } catch (Exception e) {}
    }
    }
    /**
    * 獲取一個演示用的簡單數據集對象
    * @return
    */
    private static CategoryDataset getDataSet() {
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    dataset.addValue(100, null, "蘋果");
    dataset.addValue(200, null, "梨子");
    dataset.addValue(300, null, "葡萄");
    dataset.addValue(400, null, "香蕉");
    dataset.addValue(500, null, "荔枝");
    return dataset;
    }
    /**
    * 獲取一個演示用的組合數據集對象
    * @return
    */
    private static CategoryDataset getDataSet2() {
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    dataset.addValue(100, "北京", "蘋果");
    dataset.addValue(100, "上海", "蘋果");
    dataset.addValue(100, "廣州", "蘋果");
    dataset.addValue(200, "北京", "梨子");
    dataset.addValue(200, "上海", "梨子");
    dataset.addValue(200, "廣州", "梨子");
    dataset.addValue(300, "北京", "葡萄");
    dataset.addValue(300, "上海", "葡萄");
    dataset.addValue(300, "廣州", "葡萄");
    dataset.addValue(400, "北京", "香蕉");
    dataset.addValue(400, "上海", "香蕉");
    dataset.addValue(400, "廣州", "香蕉");
    dataset.addValue(500, "北京", "荔枝");
    dataset.addValue(500, "上海", "荔枝");
    dataset.addValue(500, "廣州", "荔枝");
    return dataset;
    }
    }

    程序運行結束后生成的圖片文件效果如下圖所示:


    圖4

    如果是使用簡單的數據即使用getDataSet方法獲取數據集時產生的圖片文件如下:


    圖5

    2 餅圖

    對于餅圖而言,數據集的獲取用的不是同一個數據集類,另外餅圖不支持同一個類別的項目中還有子項目這樣的數據。我們只給出創建餅圖的代碼,至于寫圖表到一個文件則與柱狀圖一致,無需重復。

    package lius.chart.demo;
    import java.io.*;
    import org.jfree.data.*;
    import org.jfree.chart.*;
    /**
    * 用于演示餅圖的生成
    * @author Winter Lau
    */
    public class PieChartDemo {
    public static void main(String[] args) throws IOException{
    DefaultPieDataset data = getDataSet();
    JFreeChart chart = ChartFactory.createPie3DChart("水果產量圖", // 圖表標題
    data,
    true, // 是否顯示圖例
    false,
    false
    );
    //寫圖表對象到文件,參照柱狀圖生成源碼
    }
    /**
    * 獲取一個演示用的簡單數據集對象
    * @return
    */
    private static DefaultPieDataset getDataSet() {
    DefaultPieDataset dataset = new DefaultPieDataset();
    dataset.setValue("蘋果",100);
    dataset.setValue("梨子",200);
    dataset.setValue("葡萄",300);
    dataset.setValue("香蕉",400);
    dataset.setValue("荔枝",500);
    return dataset;
    }
    }

    生成的餅圖文件效果如下:


    圖6





    回頁首


    將生成的圖表移到瀏覽器上

    為了將生成的圖表直接傳給客戶端瀏覽器,只需要將前面兩個例子中的文件流換成是通過HttpServletResponse對象獲取到的輸出流,詳細代碼清單如下:

    package lius.chart.demo;
    import java.io.IOException;
    import javax.servlet.*;
    import javax.servlet.http.HttpServlet;
    import org.jfree.data.*;
    import org.jfree.chart.*;
    /**
    * 演示通過servlet直接輸出圖表
    * @author Winter Lau
    */
    public class ChartDemoServlet extends HttpServlet {
    public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException
    {
    res.setContentType("image/jpeg");
    DefaultPieDataset data = getDataSet();
    JFreeChart chart = ChartFactory.createPie3DChart("水果產量圖",
    data,
    true,
    false,
    false
    );

    ChartUtilities.writeChartAsJPEG(res.getOutputStream(),
    100,chart,400,300,null);
    }
    /**
    * 獲取一個演示用的簡單數據集對象
    * @return
    */
    private static DefaultPieDataset getDataSet() {
    DefaultPieDataset dataset = new DefaultPieDataset();
    dataset.setValue("蘋果",100);
    dataset.setValue("梨子",200);
    dataset.setValue("葡萄",300);
    dataset.setValue("香蕉",400);
    dataset.setValue("荔枝",500);
    return dataset;
    }
    }





    回頁首


    高級主題

    很 多情況我們不僅僅要求可以在瀏覽器上顯示一個圖表,我們更需要客戶可以直接在圖表上做一下交互的操作,例如獲取信息提示,點擊圖表某個部分進行更詳細信息 的展示等等。例如前面生成的簡單柱狀圖,用戶需要在看到柱狀圖后點擊某種水果例如是蘋果即可看到各個地區蘋果產量的情況。為此就要求該圖形具有交互操作的 功能。在HTML中為了讓一個圖像具有可交互的功能就必須給該圖像定義一個Map對象。下表節選一段具有該功能的HTML代碼

    <MAP NAME="chartMap">
    <AREA SHAPE="RECT" COORDS="81,15,126,254" href="?series=0&category=100" title="100 = 7,048"
    onclick="javascript:clickChart('100');return false;">
    <AREA SHAPE="RECT" COORDS="143,27,188,255" href="?series=0&category=200" title="200 = 6,721"
    onclick="javascript: clickChart ('200');return false;">
    <AREA SHAPE="RECT" COORDS="205,54,250,255" href="?series=0&category=300" title="300 = 5,929"
    onclick="javascript: clickChart ('300');return false;">
    <AREA SHAPE="RECT" COORDS="267,85,312,255" href="?series=0&category=400" title="400 = 5,005"
    onclick="javascript: clickChart ('400');return false;">
    <AREA SHAPE="RECT" COORDS="329,17,374,255" href="?series=0&category=Diet" title="Diet = 7,017" onclick="javascript:
    clickChart ('Diet');return false;">
    </MAP>

    由此就產生了一個問題:如果根據一個圖像來生成對應的 MAP對象。我們回頭看看剛才的代碼,在創建一個圖表對象時候有兩個參數,我們舉柱狀圖的例子來講這兩個參數就是ChartFactory. createBarChart3D方法中的最后兩個參數,這兩個參數的類型都是布爾值。這兩個參數意思分別是:是否創建工具提示(tooltip)以及是 否生成URL。這兩個參數分別對應著MAP中一個AREA的title屬性以及href屬性。

    可是我想知道的是怎么來產生這個MAP啊!哈哈,不要著急,JFreeChart已經幫我們做好生成MAP對象的功能。為 了生成MAP對象就要引入另外一個對象:ChartRenderingInfo。因為JFreeChart沒有直接的方法利用一個圖表對象直接生成MAP 數據,它需要一個中間對象來過渡,這個對象就是ChartRenderingInfo。下圖是生成MAP數據的流程圖:


    圖7

    如 上圖所示,ChartUtilities類是整個流程的核心,它周圍的對象都是一些例如數據對象或者是文件等。這個流程簡單描述如下:首先創建一個 ChartRenderingInfo對象并在調用ChartUtilities的writeChartAsJPEG時作為最后一個參數傳遞進去。調用該 方法結束后將產生一個圖像文件以及一個填充好MAP數據的ChartRenderingInfo對象,有了這個對象我們還是沒有辦法獲取具體的MAP數 據,我們還必須借助于ChartUtilities的writeImageMap方法來將ChartRenderingInfo對象讀取出來,獲取MAP 數據的代碼片斷如下:

    		PrintWriter w = null;
    FileOutputStream fos_jpg = null;
    FileOutputStream fos_cri = null;
    try{
    //根據不同類型的圖表使用不同類,以下是針對餅圖的操作
    PiePlot plot = (PiePlot) chart.getPlot();
    plot.setURLGenerator(new StandardPieURLGenerator(url));
    //設置工具提示
    plot.setToolTipGenerator(new StandardPieToolTipGenerator());
    fos_jpg = new FileOutputStream(“d:\\fruit.jpg”);
    ChartUtilities.writeChartAsJPEG(
    fos_jpg,
    100,
    chart,
    400,
    300,
    info);
    fos_cri = new FileOutputStream(__d:\\fruit.map__);
    w = new PrintWriter(fos_cri);
    ChartUtilities.writeImageMap(w, __mapname__, info);
    w.flush();
    }finally{
    try{
    w.close();
    }catch(Exception e){}
    try{
    fos_cri.close();
    }catch(Exception e){}
    try{
    fos_jpg.close();
    }catch(Exception e){}
    }

    打開文件D:\fruit.map,文件的內容就是要 寫到頁面上的MAP數據。把生成的圖像文件以及MAP數據文件寫到頁面上即可完成熱點圖表的功能。至于怎么結合兩者之間的關系例如圖像的useMap屬性 值必須與MAP對象的名稱結合起來,必須根據實際的應用情況進行相應的處理。筆者建議把二者通過標簽庫封裝起來,圖像文件的名稱以及MAP對象的名稱由標 簽庫統一進行控制,這樣可以保證二者的一致性。

    posted on 2008-07-16 16:11 找個美女做老婆 閱讀(251) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     

    導航

    統計

    公告

    本blog已經搬到新家了, 新家:www.javaly.cn
     http://www.javaly.cn

    常用鏈接

    留言簿(6)

    隨筆檔案

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 一级做a免费视频观看网站| 国产亚洲欧美在线观看| 中文在线免费观看| 亚洲精品无码专区久久同性男| 免费一看一级毛片全播放| 国产精品亚洲片在线va| 97人妻无码一区二区精品免费| 久久久久久亚洲AV无码专区| 日韩精品无码专区免费播放| 亚洲福利视频网站| 成人免费午夜无码视频| 亚洲妇女熟BBW| 国产高清视频在线免费观看| 国产精品日本亚洲777| 亚洲视频在线一区二区| 成在线人免费无码高潮喷水| 久久国产亚洲精品麻豆| 色猫咪免费人成网站在线观看| 午夜亚洲AV日韩AV无码大全| 中文字幕在线观看免费视频| 国产99在线|亚洲| 国产无遮挡又黄又爽免费视频| 粉色视频成年免费人15次| 亚洲日本乱码在线观看| 四虎影视成人永久免费观看视频| 亚洲欧洲精品久久| 成年女人毛片免费播放人| 羞羞网站免费观看| 亚洲AV中文无码乱人伦下载| 免费99精品国产自在现线| 老子影院午夜伦不卡亚洲| 亚洲精品国偷自产在线| av无码免费一区二区三区| 黄色免费网址大全| 亚洲av女电影网| 免费高清小黄站在线观看| 少妇性饥渴无码A区免费| 国产成人精品日本亚洲网址| 国产精品亚洲综合专区片高清久久久| 最好免费观看高清在线| 亚洲愉拍一区二区三区|