JFreeChart是一個開源的JAVA項目,它主要用來開發各種各樣的圖表,這些圖表包括:餅圖、柱狀圖(普通柱狀圖以及堆棧柱狀圖)、線圖、區域圖、分布圖、混合圖、甘特圖以及一些儀表盤等等。在這些不同式樣的圖表上可以滿足目前商業系統的要求。JFreeChart是一種基于JAVA語言的圖表開發技術。JFreeChart可用于Servlet、JSP、Applet、Java Appication環境中,通過JDBC可動態顯示任何數據庫數據,結合Itext可以輸出至PDF文件。
JFreeChart主要是由三個類構成:
A)org.jfree.chart.servlet.ChartDeleter繼承自HttpSessionBindingListener,用于實現當Session 關閉時,刪除臨時目中的圖象文件。
B)org.jfree.chart.servlet.DisplayChart繼承自Httpservlet 用于處理顯示圖象。
C)org.jfree.chart.servlet.ServletUtilities有一系列方法,例如,saveChartAs*;saveChartAs*是把圖表按照不同的形式存儲為圖象;sendTempFile方法被重載了很多次,用于把文件流發送response。
下面以柱狀圖和餅圖為例,介紹圖形創建方法。
1 柱狀圖
org.jfree.chart.ChartFactory這個工廠類有createBarChart、createStackedBarChart、createBarChart3D、createStackedBarChart3D,這幾個工廠方法創建不同類型的柱狀圖,比較重要的是 PlotOrientation.VERTICAL 讓平行柱垂直顯示,而 PlotOrientation.HORIZONTAL 則讓平行柱水平顯示。對柱狀圖影響較大的幾個類包括:org.jfree.chart.axis.CategoryAxis、org.jfree.chart.axis.ValueAxis、org.jfree.chart.renderer.BarRenderer、org.jfree.chart.renderer. BarRenderer3D。
具體實現步驟:
1)創建用于圖形生成所要的數據集對象。
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
其中:rowKeys表示X軸數據,columnKeys表示Y軸數據,data表示填充柱狀圖所要的實際數據(來自于數據庫)。
2)創建圖形對象。
JFreeChart chart = ChartFactory.createBarChart3D("標題", null,null,dataset,PlotOrientation.VERTICAL,,true,false,false);
createBarChart3D方法是ChartFactory工廠類里的一個方法,用于3D柱狀圖的生成,該類繼承自JFreeChart。其中的八個參數分別代表:圖形的標題、X軸標題、Y軸標題、dataset就是CategoryDataset類的實例對象、顯示標題、啟用熱鍵、啟用超鍵接。
3)設置圖形顯示的屬性。
a ) ValueAxis類,設置柱到圖上下邊的距離。實現方法是:
ValueAxis rangeAxis = plot.getRangeAxis();
設置最高的一個柱與圖片頂端的距離:
rangeAxis.setUpperMargin(0.15)
設置最低的一個柱與圖片底端的距離:
rangeAxis.setLowerMargin(0.15)
b)org.jfree.chart.renderer.BarRenderer3D類,設置圖形上顯示的數值。實現方法如下:
BarRenderer3D renderer = new BarRenderer3D();
renderer.setBaseOutlinePaint(Color.BLACK);
設置 Wall 的顏色:
renderer.setWallPaint(Color.gray);
設置每個柱的顏色:
renderer.setSeriesPaint(0, new Color(0, 0, 255));
renderer.setSeriesPaint(1, new Color(0, 100, 255));
renderer.setSeriesPaint(2, Color.GREEN);
設置每個柱的 Outline 顏色
renderer.setSeriesOutlinePaint(0, Color.BLACK);
renderer.setSeriesOutlinePaint(1, Color.BLACK);
renderer.setSeriesOutlinePaint(2, Color.BLACK);
設置每個地區所包含的平行柱之間的距離
renderer.setItemMargin(0.1);
顯示每個柱的數值,并修改該數值的字體屬性
renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setItemLabelFont(new Font("黑體",Font.PLAIN,12));
renderer.setItemLabelsVisible(true);
為圖形加入超連接
renderer.setItemURLGenerator(new StandardCategoryURLGenerator());
renderer.setToolTipGenerator(new StandardCategoryToolTipGenerator());
2 餅圖
org.jfree.chart.plot包,包含創建餅形圖的所有方法和屬性。
筆者根據業務需求創建了setURLGenerator(PieURLGenerator generator)方法,在圖片上建立連接,就是圖片不同部分連接不同的資源。
setSectionLabelType(int type)方法:
指定 section 標簽的類型,共有 7 種類型。如果不指定,默認是 NAME_LABELS,其中類型分別是:
PiePlot.NO_LABELS
PiePlot.NAME_LABELS
PiePlot.VALUE_LABELS
PiePlot.PERCENT_LABELS 、PiePlot.NAME_AND_VALUE_LABELS、PiePlot. NAME_AND_PERCENT_LABELS、PiePlot.VALUE_AND_PERCENT_LABELS。
setDefaultOutlinePaint(java.awt.Paint paint)方法,指定 section 輪廓線的顏色,如果不指定,默認值為NULL。
setDefaultOutlineStroke(java.awt.Stroke stroke)方法,指定 section 輪廓線的厚度。
setRadius(double percent) 和 setExplodePercent(int section, double percent)方法,抽離 section,就是把某一section從餅形圖剝離出來,需要兩個方法一起使用。
setStartAngle(double angle)方法,設置第一個section開始位置,默認從12點鐘方向開始。
setPaint(int section, java.awt.Paint paint)方法指定section的顏色。
setDirection(int direction)方法指定section順序,默認是順時針方向。順時針:PiePlot.CLOCKWISE;逆時針:PiePlot.ANTICLOCKWISE。
具體實現步驟:
1)創建用于圖形生成所要的數據集對象。
首先實例化類DefaultPieDataset dataset = new DefaultPieDataset()。然后利用DefaultPieDataset類提供的setValue(value1,value2)方法,把從數據庫里提取的數據存入DefaultPieDataset對象。其中value1是數據名稱、value2是數據值。
2)創建圖形對象。
首先實例化JFreeChart chart = ChartFactory.createPieChart3D(title, dataset, true, true, false)createPieChart3D方法是用于餅圖生成的主要方法。其中title代表圖形的標題、dataset就是DefaultPieDataset對象的實例。
3)設置圖形顯示的屬性。
String filename = ServletUtilities.saveChartAsPNG(jFreeChart, 700, 450, info, session);
ChartUtilities.writeImageMap(pw, filename, info);
pw.flush()
saveChartAsPNG方法在ServletUtilities工廠類定義完成。主要用于把圖形對象JFreeChart以圖片的形式保存。其中的jFreeChart就是JFreeChart對象的實例。該方法返回一個文件名。
writeImageMap(pw, filename, info)方法用于把保存的圖片文件以字節流的形式寫入用戶界面。
其中pw是java.io包的PrintWriter類的實例對象,該對象創建一個圖形輸出流。Filename是輸出圖片的文件名。該文件名來自ServletUtilities.saveChartAsPNG方法創建。
參數info用于圖形信息的顯示。
用ChartRenderingInfo info=new ChartRenderingInfo(new StandardEntityCollection())創建。
最后輸出完成圖形,調用pw.flush()方法關閉IO流。------------------------------------------------------------------------------------------
限于篇幅的問題我們在這里只實現兩種常用的圖表,其他類型圖表讀者可以觸類旁通。我們先給出柱狀圖的實現,餅圖的實現再來跟柱狀圖進行比較。
|
程序運行結束后生成的圖片文件效果如下圖所示:
圖4

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

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

![]() ![]() |
![]()
|
為了將生成的圖表直接傳給客戶端瀏覽器,只需要將前面兩個例子中的文件流換成是通過HttpServletResponse對象獲取到的輸出流,詳細代碼清單如下:
|
很多情況我們不僅僅要求可以在瀏覽器上顯示一個圖表,我們更需要客戶可以直接在圖表上做一下交互的操作,例如獲取信息提示,點擊圖表某個部分進行更詳細信 息的展示等等。例如前面生成的簡單柱狀圖,用戶需要在看到柱狀圖后點擊某種水果例如是蘋果即可看到各個地區蘋果產量的情況。為此就要求該圖形具有交互操作 的功能。在HTML中為了讓一個圖像具有可交互的功能就必須給該圖像定義一個Map對象。下表節選一段具有該功能的HTML代碼
|
由此就產生了一個問題:如果 根據一個圖像來生成對應的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 數據的代碼片斷如下:
|
打開文件D:" fruit.map,文件的內容就是要寫到頁面上的MAP數據。把生成的圖像文件以及MAP數據文件寫到頁面上即可完成熱點圖表的功能。至于怎么結合兩者 之間的關系例如圖像的useMap屬性值必須與MAP對象的名稱結合起來,必須根據實際的應用情況進行相應的處理。筆者建議把二者通過標簽庫封裝起來,圖 像文件的名稱以及MAP對象的名稱由標簽庫統一進行控制,這樣可以保證二者的一致性。
posted @ 2007-10-31 17:09 小眼睛大智慧 閱讀(214) | 評論 (0) | 編輯 收藏