|
不知道 JFreeChart 項目組出于什么目的,他們提供的 sample code 里面的例子給人感覺就是亂,同樣的結果可以用不同方式、使用不的方法。再加上網(wǎng)上流傳的 JFreeChart 舊的使用方法,使剛接觸 JFreeChart 的朋友進到 JFreeChart 中不花一些時間很難理出一個頭緒來。 前面已經(jīng)介紹過 JFreeChart 生成餅狀圖,可能由于上面提到的原因,有些朋友來信和留言希望介紹 JFreeChart 如何生成柱狀圖。抄襲別人一句話:Help others as well as to help myself。這次我們介紹使用 JFreeChart 生成柱狀圖,首先從一個最簡單的例子開始。
一 最簡單的例子為了降低門檻,讓大家心理有個底,先介紹一個簡單的不能再簡單的例子,圖片中的各類屬性都采用默認值。
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="org.jfree.chart.ChartFactory, org.jfree.chart.JFreeChart, org.jfree.chart.plot.PlotOrientation, org.jfree.chart.servlet.ServletUtilities, org.jfree.data.DefaultCategoryDataset"%> <% DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(300, "廣州", "蘋果"); dataset.addValue(200, "廣州", "梨子"); dataset.addValue(500, "廣州", "葡萄"); dataset.addValue(340, "廣州", "芒果"); dataset.addValue(280, "廣州", "荔枝"); JFreeChart chart = ChartFactory.createBarChart3D("水果銷量統(tǒng)計圖", "水果", "銷量", dataset, PlotOrientation.VERTICAL, false, false, false); String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, null, session); String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename; %> <img src="<%= graphURL %>" width=500 height=300 border=0 usemap="#<%= filename %>"> 這個 JSP 程序運行的結果如下圖
二 柱狀圖高級特性上面的程序簡單,但生成的柱狀圖也很簡單。更多的時候,我們可能需要不同的效果。 org.jfree.chart.ChartFactory 這個工廠類有 createBarChart, createStackedBarChart, createBarChart3D, createStackedBarChart3D 這幾個工廠方法創(chuàng)建不同類型的柱狀圖。關于這四個方法的 JFreeChart 的 Java Doc API 文檔有詳細說明,比較重要的是 PlotOrientation.VERTICAL 讓平行柱垂直顯示,而 PlotOrientation.HORIZONTAL 則讓平行柱水平顯示。 幾個對柱狀圖影響較大的幾個類,它們分別是: 我們還是以實例來說明這幾個類,先來假設一個需要統(tǒng)計的數(shù)據(jù)表:
根據(jù)上表數(shù)據(jù),首先構造 CategoryDataset, 這里不再使用上面簡單例子里面的 DefaultCategoryDataset 類,而是 DatasetUtilities 更有效的構造 CategoryDataset,如下列代碼:
double[][] data = new double[][] {{672, 766, 223, 540, 126}, {325, 521, 210, 340, 106}, {332, 256, 523, 240, 526}};
String[] rowKeys = {"蘋果","梨子","葡萄"}; String[] columnKeys = {"北京","上海","廣州","成都","深圳"}; CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data); 用上面的 dataset 生成的 3D 柱狀圖
org.jfree.chart.axis.CategoryAxis
CategoryAxis domainAxis = plot.getDomainAxis();
//設置 columnKey 是否垂直顯示 domainAxis.setVerticalCategoryLabels(true); //設置距離圖片左端距離 domainAxis.setLowerMargin(0.1); //設置距離圖片右端距離 domainAxis.setUpperMargin(0.1); //設置 columnKey 是否間隔顯示 domainAxis.setSkipCategoryLabelsToFit(true); plot.setDomainAxis(domainAxis); 上面代碼產(chǎn)生的效果如下圖,注意與圖二的區(qū)別。
org.jfree.chart.axis.ValueAxis
ValueAxis rangeAxis = plot.getRangeAxis();
//設置最高的一個柱與圖片頂端的距離 rangeAxis.setUpperMargin(0.15); //設置最低的一個柱與圖片底端的距離 //rangeAxis.setLowerMargin(0.15); plot.setRangeAxis(rangeAxis); 上面代碼產(chǎn)生的效果如下圖,注意與圖二的區(qū)別。
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); //設置每個地區(qū)所包含的平行柱的之間距離 renderer.setItemMargin(0.1); //顯示每個柱的數(shù)值,并修改該數(shù)值的字體屬性 renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setItemLabelFont(new Font("黑體",Font.PLAIN,12)); renderer.setItemLabelsVisible(true); 上面代碼產(chǎn)生的效果如下圖,注意與圖二的區(qū)別。
補充兩個有用的方法 補充 org.jfree.chart.plot.CategoryPlot 的兩個方法,這兩個方法對所有類型的圖表都有作用,因為在前面沒有介紹,這里補充一下。
//設置地區(qū)、銷量的顯示位置
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT); plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT); 上面代碼產(chǎn)生的效果如下圖,注意與圖二的區(qū)別。
三 完整范例 前面都是一些代碼片段,現(xiàn)在把這些片段組合成一個完整范例。
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.awt.Color, java.awt.Font, org.jfree.chart.ChartFactory, org.jfree.chart.JFreeChart, org.jfree.chart.plot.PlotOrientation, org.jfree.chart.servlet.ServletUtilities, org.jfree.data.CategoryDataset, org.jfree.data.DatasetUtilities, org.jfree.chart.plot.CategoryPlot, org.jfree.chart.axis.CategoryAxis, org.jfree.chart.axis.ValueAxis, org.jfree.chart.renderer.BarRenderer3D, org.jfree.chart.labels.StandardCategoryItemLabelGenerator, org.jfree.chart.axis.AxisLocation"%> <% double[][] data = new double[][] {{672, 766, 223, 540, 126},{325, 521, 210, 340, 106},{332, 256, 523, 240, 526}}; String[] rowKeys = {"蘋果","梨子","葡萄"}; String[] columnKeys = {"北京","上海","廣州","成都","深圳"}; CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data); JFreeChart chart = ChartFactory.createBarChart3D("水果銷量圖統(tǒng)計", null, null, dataset, PlotOrientation.VERTICAL, true,false,false); chart.setBackgroundPaint(Color.WHITE); CategoryPlot plot = chart.getCategoryPlot(); CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setVerticalCategoryLabels(false); plot.setDomainAxis(domainAxis); ValueAxis rangeAxis = plot.getRangeAxis(); //設置最高的一個 Item 與圖片頂端的距離 rangeAxis.setUpperMargin(0.15); //設置最低的一個 Item 與圖片底端的距離 rangeAxis.setLowerMargin(0.15); plot.setRangeAxis(rangeAxis); 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); //設置每個地區(qū)所包含的平行柱的之間距離 renderer.setItemMargin(0.1); //顯示每個柱的數(shù)值,并修改該數(shù)值的字體屬性 renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setItemLabelsVisible(true); plot.setRenderer(renderer); //設置柱的透明度 plot.setForegroundAlpha(0.6f); //設置地區(qū)、銷量的顯示位置 plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT); plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT); String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, null, session); String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename; %s> <img src="<%= graphURL %>" width=500 height=300 border=0 usemap="#<%= filename %>"> 看看程序運行的結果吧:
三 總結我只介紹了少量的方法,更多的請參考 JFreeChart 的 Java Doc API 文檔和 Sample Code。文中的有些關于圖表的術語不知道該如何正確的表達,如果你有任何關于本文的想法,可以與我聯(lián)系 wayne@sentom.net. |
|
|