TNT blog  
          日歷
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345
          統計
          • 隨筆 - 5
          • 文章 - 40
          • 評論 - 7
          • 引用 - 0

          導航

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          home

          搜索

          •  

          最新隨筆

          最新評論

          閱讀排行榜

           

          生成基于瀏覽器的圖表方式比較多。據我所知道的,常用的有三種:

          1、 ????? VML 方式實現。這種方式是通過產生客戶端的代碼,由客戶端根據代碼生成相應的圖表。但這種方式產生的圖表有很多的局限性,如受限于瀏覽器,有些瀏覽器可能并不支持 VML 。另外,沒有封裝完整的圖表開發包。

          2、 ????? 通過 applet 來產生圖表。這種方式也對客戶端要求比較高,必須要有 JRE ,而且通過 applet 生成的圖表在加載過程中會有個 Java Log 動畫。用戶看了可能會感覺不太舒服。

          3、 ????? 通過服務端直接生成圖表的圖片。這種方式對客戶端幾乎沒有什么要求,缺點是加重了服務端的負擔,對服務端要求就相對高了點。

          ?

          經過比較,根據項目自身特點,我們打算采用第三種方式來開發圖表。為了縮短開發周期、節約成本,我們選用了開源的 JFreeChart ( http://www.jfree.org/jfreechart/index.php )

          ?

          jfreechart 是一個免費創建圖表的 java 工具,目前最新版本是 JFreeChart-1.0.0-rc1 。它可以生成各式各樣的圖表。這些圖表包括餅圖、柱狀圖、線形圖、區域圖、甘特圖等等,基本可以滿足各種項目的要求。但在開發過程中我也發現了 JFreeChart 的一些不足,或者說有些稱得上是 BUG 。總體說來, JFreeChart 還是個優秀的開源項目。

          ?

          關于 JFreeChart 生成圖表的文章比較多了,我主要談談使用 JFreeChart 的一些比較棘手問題以及解決方法。同時也會將問題所用到的源碼( JFreeChart-1.0.0-rc1+Struts1.2.4 )從項目中抽象出來一起提供給大家。

          ?

          一、 圖片上熱點鏈接中文亂碼的解決方法

          ?

          這個問題是在我查閱關于 JFreeChart 相關資料時出現頻率最高的一個問題。其實這個亂碼問題不能怪罪于 JFreeChart 。有人甚至就因此認為 JFreeChart 對中文支持不太完善, JFreeChart 可要叫了:我是冤枉的!

          ?

          我們來找出問題產生的原因,這個問題也就不難解決了。

          ?

          首先查看一下出現問題頁面的 Html 源文件,你會發現在源文件的開頭多出了一段 map 代碼,代碼類似于這樣:

          <map id="chart-30928.png" name="chart-30928.png">

          <area shape="poly" coords="179,163,176,154,174,145" title=" 洗衣機 =315(29.86%)" alt=""/>

          …………
          </map>

          ?

          <html>

          <head>

          …………


          這部分 map 代碼其實是 JFreeChart 產生的,是用來產生圖片上的熱點鏈接,這也是問題產生的根源所在。你的 Jsp 頁面通過 <%@ page contentType="text/html; charset=UTF-8" %> 或者 <%@ page contentType="text/html; charset=GBK" %> 來設置 contentType 這無可厚非,但 map 并不是由這個 jsp 頁面產生的。它是 JFreeChart 通過 PrintWriter 產生的。查看一下你生成圖片的 Chart 源碼,其中有 ChartUtilities.writeImageMap(pw, filename, info, false) 這樣的語句。這是用來向頁面寫入 map 代碼的。默認情況下, map 代碼會以服務器默認編碼 (ISO-8859-1) 輸出。這就和你的 Jsp 編碼不一致,從而產生亂碼。

          ?

          原因找到了,問題也就不難解決的。設置 PrintWriter contentType Jsp contentType 保存一致就可以了。代碼如下(筆者的 Web 應用是基于 Struts 框架的):

          //PieMothAciton.java

          ?

          public ActionForward execute(ActionMapping mapping, ActionForm form,

          ?????????????? HttpServletRequest request, HttpServletResponse response)

          ?????????????? throws Exception {??????

          ???????

          ??????? // 設置輸出編碼格式

          ??????? response.setContentType("text/html;charset=UTF-8");

          ??????? PrintWriter out = response.getWriter();

          ???????

          ??????? …………

          ???????

          ??????? String filename = chart.generatePieChart3D(" 月統計比例圖 ",

          ????????????????????? session, out);

          ???????

          ??????? String graphURL = request.getContextPath()

          ????????????????????? + "/servlet/DisplayChart?filename=" + filename;

          ???????

          ??????? request.setAttribute("filename",filename);

          ??????? request.setAttribute("graphURL",graphURL);

          ???????

          ??????? return mapping.findForward(SUCCESS);???????????

          }

          重新部署你的 Web 應用,中文亂碼文件就可以解決了。

          ?

          二、 餅圖顯示百分比

          ?

          在餅圖中 JFreeChart 默認只顯示選項和數值,沒有顯示各項所占比例。由于手頭沒有 1.0 版的 JFreeChart Developer Guide (這可是要錢的,后來想想即使有,也未必能找到關于百分比這方面的說明),再加上 DEMO 中的餅圖都沒有顯示百分比,無法參考。后來在網上找到了一個老版本的例子,其中能顯示百分比。它是通過在 PiePlot 中設置的:

          PiePlot pie;
          pie.setPercentFormatString("#,###0.0#%");

          1.0 版本中根本就找不到 setPercentFormatString 這方法, JFreeChart 各版本之間改動比較大,很難兼容。還好它是開源的,把它的源碼都搜索了一遍,認真讀了一些源碼,終于理出了頭緒。

          ?

          原來在 1.0.0-rc1 版中顯示百分比已經調整到 StandardPieItemLabelGenerator 構造函數中了, StandardPieItemLabelGenerator 有三個構造函數。 StandardPieItemLabelGenerator() 不顯示各項所占比例。另外兩個可以顯示比例。代碼如下:

          ?

          plot.setLabelGenerator(new StandardPieItemLabelGenerator(StandardPieItemLabelGenerator.DEFAULT_TOOLTIP_FORMAT));
          //
          或者采用下面自定義樣式顯示, {0} 表示選項, {1} 表示數值, {2} 表示所占比例

          plot.setLegendLabelGenerator(new StandardPieItemLabelGenerator("{0}: ({1}M, {2})"));

          效果如下圖:

          ?

          默認顯示百分比是取整的,如果要讓百分比保留二位小數,可以用第三個構造函數:

          plot.setLabelGenerator(new StandardPieItemLabelGenerator(“{0}={1}({2})”,

          ???????????????????????????? NumberFormat.getNumberInstance(),

          ???????????????????????????? new DecimalFormat("0.00%")));

          效果如下圖:

          ?

          三、 混合圖表(不同類型的圖混合顯示)

          ?

          我們經常用的是柱狀圖、曲線圖、和餅圖,這三類型圖基本能滿足大部分項目的需求。但有些項目比較特殊,可能需要在一張圖上同時顯示不同類型的圖。這在 JFreeChart 中可以輕松實現。例如我們要做個流量監控的系統,該系統一天中在不同的時間段有不同的閥值(最大值),該閥值表示成階梯線。而實際流量就是個曲線了。當流量在某個時段內超過閥值時就觸發相應的事件(如限流)。要表示閥值和流量的對比關系就需要兩種類型的圖片在同一張圖表上表示,如下圖:

          ?

          首先像創建普通圖表一樣來創建圖片,筆者先創建了一個 XYStep Chart 。然后創建第二圖表的 Renderer ,再分別將第二圖表的 Dataset Renderer 添加進第一圖表的 plot 。實例代碼如下:

          //MultipleChart.java

          ?

          JFreeChart jfreechart = ChartFactory.createXYStepAreaChart(" 監控設置 ",

          ??????? ??????? " 時刻 ",

          ??????? ??????? " 流量 ",

          ??????? ??????? xydataset,

          ??????? ??????? PlotOrientation.VERTICAL,

          ??????? ??????? true,

          ??????? ??????? true,

          ??????? ??????? false);

          ???????

          ??????? XYPlot xyplot = jfreechart.getXYPlot();

          ?

          …………

          ?

          ??????? // 設置第二圖表的 Renderer

          ??????? StandardXYItemRenderer standardxyitemrenderer = new StandardXYItemRenderer();

          ??????? standardxyitemrenderer.setToolTipGenerator(new StandardXYToolTipGenerator("{0}({1}) = {2}",

          ??????? ??????? new SimpleDateFormat("HH:mm"),

          ??????? ??????? new DecimalFormat("#,##0"))); ???????

          ???????

          ??????? // 將第二圖表的 Dataset Renderer 添加進 xyplot

          ??????? xyplot.setDataset(1, lineDataset);

          ??????? xyplot.setRenderer(1,standardxyitemrenderer);? ?

          這樣就創建了曲線和階梯的混合圖表。

          ?

          四、 其它問題

          ?

          1) ? 版本問題。

          JFreeChart 的各版本變動比較大,這在升級版本時是比較頭疼的問題,升級時需要改動你代碼的地方可能比較多。因此盡量采用最新的版本,新版本的文檔可能比較少,但問題要相對少一些,在舊版中就出現過標注數值重疊在一起這樣的問題。好的是 JFreeChart 是開源的,碰到解決不了的問題可以從源碼中找到有參考價值的信息。

          ?

          2) ? 設置背景透明度的 BUG

          不知道這是不是 JFreeChart 的一個 BUG 。利用 chart.setBackgroundImageAlpha(0.5f) 來設置背景透明度, ServletUtilities.saveChartAsPNG 保存圖片。將 chart.setBackgroundImageAlpha(0.5f) 注釋掉再生成圖片,發現兩張圖片是一樣的。也就是說 setBackgroundImageAlpha 方法無效,具體原因筆者還不太清楚,讀者大家可以自己測試看看。

          posted on 2006-06-01 10:34 TNT 閱讀(619) 評論(0)  編輯  收藏 所屬分類: REPORT
           
          Copyright © TNT Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 磐安县| 阜平县| 乾安县| 江陵县| 上栗县| 三台县| 德令哈市| 长治市| 勃利县| 谢通门县| 太仓市| 揭阳市| 酒泉市| 山阳县| 资阳市| 浦北县| 安丘市| 井冈山市| 安溪县| 镶黄旗| 贵溪市| 林州市| 灵璧县| 佛教| 噶尔县| 曲阜市| 永安市| 旺苍县| 清河县| 奉化市| 剑川县| 五原县| 茌平县| 房产| 杭州市| 莱西市| 湖北省| 惠州市| 新丰县| 鲁甸县| 罗平县|