2011年6月1日 星期三

[ Java 文章收集 ] JFreeChart 入門教學 (Part 1)


前言 :
最近因為需要寫一些 GUI 來顯示圖表, 所以就 Survey 了一下 Java 開源的 Chart 相關 library. 有興趣可以參考 這理. 裡面列了一些常見也廣泛被使用有關 Chart 的 library. 而這理要介紹的是 JFreeChart. 而底下是 JFreeChart 這個套件的官方說明 :
A free Java chart library. JFreeChart supports pie charts (2D and 3D), bar charts (horizontal and vertical, regular and stacked), line charts, scatter plots, time series charts, high-low-open-close charts, candlestick plots, Gantt charts, combined plots, thermometers, dials and more. JFreeChart can be used in applications, applets, servlets and JSP. This project is maintained by David Gilbert.

How To Install / Get Started :
這裡我們使用 Eclipse 與 JFreeChart v1.0.13 進行說明. 在開始開發 JFreeChart 之前, 還是有一些前置動作需要進行. 參考如下 :
1. Start Eclipse 3.?. (If you do not have Eclipse installed, visit www.eclipse.org.)
2. Go to File -> New -> Project....
3. Select "Java Project" and click on Next. Enter in a project name and click Finish.
4. Select the project in the Package Explorer view. Go to Project -> Properties.
5. Click on "Java Build Path" on the left-hand side of the dialog box and on the right-hand side and click on the "Libraries" tab.
6. Click on "Add External JARs..." and locate jfreechart-1.0.13.jar and jcommon-1.0.16.jar. Click on OK when done.
7. Select the project in the Package Explorer view. Go to File -> New -> Package. Give the package a name and click on Finish.
8. Select the newly-created package in the Package Explorer view. Go to File -> New -> Class. Give the class a name and click on Finish.
9. You are now ready to start using the JFreeChart library!

接著我們會針對四種常用的圖表 Pie Chart, XY Chart, Bar Chart 與 Time-Series Chart進行介紹.

Pie Chart Demo (圓餅圖) :
底下我們先來看看代碼, 接著針對範例代碼進行說明與額外功能介紹. 這理我們使用一個 JFrame 來展示建立的 Chart 並建立一支線程動態的改變圖表的資料, 所以你會發現圖表一直在變動. 範例代碼如下 :
- PieChart.java : JFrame 容器, 用來顯示建立的圖表.
  1. package john.jfreechart;  
  2.   
  3. import java.awt.event.WindowAdapter;  
  4. import java.awt.event.WindowEvent;  
  5. import java.io.File;  
  6. import javax.swing.JFrame;  
  7. import john.jfreechart.thds.PieChartThd;  
  8. import org.jfree.chart.ChartFactory;  
  9. import org.jfree.chart.ChartPanel;  
  10. import org.jfree.chart.ChartUtilities;  
  11. import org.jfree.chart.JFreeChart;  
  12. import org.jfree.chart.plot.PiePlot3D;  
  13. import org.jfree.data.general.DefaultPieDataset;  
  14. import org.jfree.data.general.PieDataset;  
  15. import org.jfree.util.Rotation;  
  16.   
  17. public class PieChart extends JFrame{  
  18.     public enum EPlatform {  
  19.         Linux("Linux"), Mac("Mac"), Windows("Windows");  
  20.         private String msg;  
  21.         private EPlatform(String m){this.msg = m;};  
  22.         @Override  
  23.         public String toString(){return msg;}  
  24.     }     
  25.     private static final long serialVersionUID = 1L;  
  26.     private DefaultPieDataset result;  
  27.     private PieChartThd dynamicDataThd = null;  
  28.     class AppAdapter extends WindowAdapter {  
  29.         public void windowClosing(WindowEvent event) {  
  30.             if(dynamicDataThd!=null) {  
  31.                 dynamicDataThd.runFlag = false;  
  32.             }  
  33.         }  
  34.     }  
  35.   
  36.     public PieChart(String applicationTitle, String chartTitle) {  
  37.         super(applicationTitle);  
  38.         // This will create the dataset   
  39.         PieDataset dataset = createDataset();  
  40.         // based on the dataset we create the chart  
  41.         JFreeChart chart = createChart(dataset, chartTitle);  
  42.         try {  
  43.             ChartUtilities.saveChartAsJPEG(new File("C:\\chart.jpg"), chart,  
  44.                     500300);  
  45.         } catch (Exception e) {  
  46.             System.out.println("Problem occurred creating chart.");  
  47.         }  
  48.               
  49.         // we put the chart into a panel  
  50.         ChartPanel chartPanel = new ChartPanel(chart);  
  51.         // default size  
  52.         chartPanel.setPreferredSize(new java.awt.Dimension(700300));  
  53.         // add it to our application  
  54.         setContentPane(chartPanel);     
  55.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  56.         // setup dynamic data input  
  57.         dynamicDataThd = new PieChartThd(result);  
  58.         new Thread(dynamicDataThd).start();  
  59.     }  
  60.       
  61.     /** 
  62.      * Creates a sample dataset  
  63.      */  
  64.     private  PieDataset createDataset() {  
  65.         result = new DefaultPieDataset();  
  66.         result.setValue(EPlatform.Linux, 29);  
  67.         result.setValue(EPlatform.Mac, 20);  
  68.         result.setValue(EPlatform.Windows, 51);  
  69.           
  70.         return result;          
  71.     }  
  72.       
  73.     public DefaultPieDataset getDataset(){return result;}  
  74.       
  75.     /** 
  76.      * Creates a pie chart 
  77.      */  
  78.     private JFreeChart createChart(PieDataset dataset, String title) {          
  79.         JFreeChart chart = ChartFactory.createPieChart(  
  80.             title,                  // chart title  
  81.             dataset,                // data  
  82.             true,                   // include legend  
  83.             true,  
  84.             false  
  85.         );     
  86.           
  87.         return chart;          
  88.     }  
  89.       
  90.     /** 
  91.      * Creates a 3D pie chart 
  92.      */  
  93.     private JFreeChart create3DChart(PieDataset dataset, String title) {          
  94.         JFreeChart chart = ChartFactory.createPieChart3D(  
  95.             title,                  // chart title  
  96.             dataset,                // data  
  97.             true,                   // include legend  
  98.             true,  
  99.             false  
  100.         );  
  101.   
  102.         PiePlot3D plot = (PiePlot3D) chart.getPlot();  
  103.         plot.setStartAngle(290);  
  104.         plot.setDirection(Rotation.CLOCKWISE);  
  105.         plot.setForegroundAlpha(0.5f);  
  106.           
  107.         return chart;  
  108.           
  109.     }  
  110.       
  111.     public static void main(String[] args) {  
  112.         PieChart demo = new PieChart("Comparison""Which operating system are you using?");  
  113.         demo.pack();  
  114.         demo.setVisible(true);          
  115.     }  
  116. }  

- AbstDataThd.java : 提供或變動 Data 的線程的父類別
  1. package john.jfreechart.thds;  
  2.   
  3. import java.util.Random;  
  4.   
  5. public abstract class AbstDataThd implements Runnable{  
  6.     protected int sleepPeriod = 1000// 每隔 sleepPeriod 變更一次 Data  
  7.     protected int showTimes = 20;  // 總共變更 showTimes 次 Data  
  8.     protected Random rdm;  
  9.     public boolean runFlag = true// 如果 runFlag 為 false, 則停止變更 Data.  
  10. }  

- PieChartThd.java : 動態的變更圖表 Data 的線程
  1. package john.jfreechart.thds;  
  2.   
  3. import john.jfreechart.PieChart;  
  4. import java.util.Random;  
  5. import javax.swing.JOptionPane;  
  6. import org.jfree.data.general.DefaultPieDataset;  
  7.   
  8. public class PieChartThd extends AbstDataThd{  
  9.     private DefaultPieDataset ds;     
  10.       
  11.     public PieChartThd(DefaultPieDataset dataset){  
  12.         this.ds = dataset;  
  13.     }  
  14.   
  15.     @Override  
  16.     public void run() {       
  17.         try{  
  18.             int count = showTimes;  
  19.             rdm = new Random();  
  20.             while(runFlag && count>0){  
  21.                 Thread.sleep(sleepPeriod);  
  22.                 int ls = rdm.nextInt(20) + 20;  
  23.                 int ms = rdm.nextInt(20) + 20;  
  24.                 ds.setValue(PieChart.EPlatform.Linux, ls);  
  25.                 ds.setValue(PieChart.EPlatform.Mac, ms);  
  26.                 int ws = 100 - ls - ms;  
  27.                 ds.setValue(PieChart.EPlatform.Windows, ws);  
  28.                 count--;  
  29.             }  
  30.             JOptionPane.showConfirmDialog(null"Completed demo!""Msg", JOptionPane.CLOSED_OPTION, JOptionPane.INFORMATION_MESSAGE);  
  31.         }catch(Exception e){e.printStackTrace();}  
  32.     }  
  33. }  

執行結果 :


- 使用說明
在開始使用 JFreeChart 之前, 必須知道所有的圖表都必須要有資料來源, 這理的圓餅圖的資料使用類別是 DefaultPieDataset :
  1. DefaultPieDataset pieDataset = new DefaultPieDataset();  
知道使用的資料類別後, 接下來便是填入我們的數據 :
  1. PieDataset.setValue(’A”, new Integer(75));  
  2. ...  
收集好數據後, 接下來便是建立美觀的圖表了, 在 JFreeChart 透過工廠方法來提供我們需要的圖表類別, 而工廠類別是 ChartFactory. 因為我們要建立的是 3D Pie Chart, 所以我們呼叫方法 createPieChart3D() 並返回一個 JFreeChart 的實例 :
  1. JFreeChart chart = ChartFactory.createPieChart3D(  
  2.             title,                  // chart title  
  3.             dataset,                // data  
  4.             true,                   // include legend  
  5.             true,  
  6.             false  
  7.         );  
最後如果我們需要將產出的報表導出到檔案, 可以透過類別 ChartUtilities 來幫我們達成 :
  1. ChartUtilities.saveChartAsJPEG(new File(”C:\\chart.jpg”), chart, 500300);  
講到這裡我們就只差最後一步, 那怎麼把圖表秀在 JFrame 上呢? 答案是透過類別 ChartPanel, 該類別繼承自 javax.swing.JPanel, 所以我們就可以很方便的將之安插在我們建立的 JFrame 上 :
  1. // we put the chart into a panel  
  2. ChartPanel chartPanel = new ChartPanel(chart);  
  3. // default size  
  4. chartPanel.setPreferredSize(new java.awt.Dimension(700300));  
  5. // add it to our application  
  6. setContentPane(chartPanel);  

XY Chart Demo :
有了以上的基礎, 接下來的圖表範例將著重於圖表的建立. 接著我們來看 XY Chart 的範例說明.
- XY Chart 建立代碼 :
  1. ...  
  2. // Create a simple XY chart  
  3. XYSeries series = new XYSeries("XYGraph");  
  4. series.add(11);  
  5. series.add(12);  
  6. series.add(21);  
  7. series.add(39);  
  8. series.add(410);  
  9. // Add the series to your data set  
  10. XYSeriesCollection dataset = new XYSeriesCollection();  
  11. dataset.addSeries(series);  
  12. // Generate the graph  
  13. JFreeChart chart = ChartFactory.createXYAreaChart(  
  14.     "XY Chart"// Title  
  15.     "x-axis"// x-axis Label  
  16.     "y-axis"// y-axis Label  
  17.     dataset, // Dataset  
  18.     PlotOrientation.VERTICAL, // Plot Orientation  
  19.     true// Show Legend  
  20.     true// Use tooltips  
  21.     false // Configure chart to generate URLs?  
  22. );  
  23. ...  

執行結果 :

- 使用說明
一樣我們需要容器來儲存數據, 這裡是透過 XYSeries 與 XYSeriesCollection. 這邊你可能會好奇為啥要分兩個類別來存放數據, 主要是因再在這一類的圖表 XYSeries 可能不只一個, 你可能會有多個 (多條線), 然後透過 XYSeriesCollection 儲存 :
  1. XYSeries series = new XYSeries("XYGraph");  
  2. // Add the series to your data set  
  3. XYSeriesCollection dataset = new XYSeriesCollection();  
  4. dataset.addSeries(series);  
最後便是建立我們的圖表, 這裡是透過方法 createXYAreaChart() ,
  1. // Generate the graph  
  2. JFreeChart chart = ChartFactory.createXYLineChart(  
  3.     "XY Chart"// Title  
  4.     "x-axis"// x-axis Label  
  5.     "y-axis"// y-axis Label  
  6.     dataset, // Dataset  
  7.     PlotOrientation.VERTICAL, // Plot Orientation  
  8.     true// Show Legend  
  9.     true// Use tooltips  
  10.     false // Configure chart to generate URLs?  
  11. );  
如果要建立只有線條的話可以使用方法 createXYLineChart(). 建立圖表如下(這裡使用兩個XYSeries) :


另外如果你想把線條的點拿掉, 則可以把下面兩行給注解掉 :
  1. JFreeChart chart =  ChartFactory.createXYLineChart(  
  2.         "XY Line Chart"// Title  
  3.         "Minutes"// x-axis Label  
  4.         "Voltage"// y-axis Label  
  5.         dataset, // Dataset  
  6.         PlotOrientation.VERTICAL, // Plot Orientation  
  7.         true// Show Legend  
  8.         true// Use tooltips  
  9.         false // Configure chart to generate URLs?  
  10. );  
  11. XYLineAndShapeRenderer render = new XYLineAndShapeRenderer(true,true); // 註解我  
  12. ((XYPlot)chart.getPlot()).setRenderer(render); // 註解我  

補充說明 :
[ Java 文章收集 ] JFreeChart 入門教學 (Part 2)
延續 Part 1 的教學, 繼續介紹 Bar Chart, Time-Series...
This message was edited 8 times. Last update was at 01/06/2011 17:28:32

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...