本文主要講解JFreeChart中餅圖的一些特征。內容如下:
l控制顏色和餅圖片區的外廓
lnull值和零值的處理
l餅圖片區的標簽(定制文本,改變分配的比例空間)
l“取出”某個片區
l多個餅圖顯示
l顯示3D效果的餅圖
更多的信息,可以參見PiePlot參考文檔
1、片區顏色
餅圖片區缺省填充的顏色是自動分配的,正如你上面實例看到的。如果你不喜歡這個缺省的顏色,你可以實用setSectionPaint()方法來設置片區顏色。例如:
PiePlot plot = (PiePlot) chart.getPlot(); plot.setSectionPaint("Section A", new Color(200, 255, 255)); plot.setSectionPaint("Section B", new Color(200, 200, 255));
JFreeChart的實例PieChartDemo2.java演示了如何定制顏色。在JFreeChart的代碼中,片區顏色使用三層色屬性機制來定義的。
同時,我們也可以對餅圖中的每一個系列定義填充的顏色,這里我們不做細述,更多的信息請參閱PiePlot類
2、片區的外廓
每一個餅圖片區的外廓默認是一條細灰線勾畫出來的。PiePlot類提供了如下選擇項:
l完全不顯示片區外廓
l通過改變缺省的值來改變全部的片區外廓
l單獨改變部分餅圖的片區外廓
2.1 片區外廓的可見性控制
為了完全關閉片區外廓,使用下面代碼:
PiePlot plot = (PiePlot) chart.getPlot(); plot.setSectionOutlinesVisible(false);
在任何時候,只需要將值設為 true 即可讓外廓顯示出來,調用該方法可以觸發PlotChangeEvent事件
2.2 片區外廓的控制
在片區外廓顯示的時候,我們可以改變餅圖片區的整個外廓顏色或風格或者單個餅圖片區的顏色或風格。
整個外廓顏色或風格的修改需要在基本層里面設置,單個餅圖片區的顏色設置需要在系列層中設置。
在基本層里,如果沒有更高層的顏色設置,則調用已定義的默認設置。我們可以使用PiePot類的方法來改變我們的設置。如下方法:
public void setBaseSectionOutlinePaint(Paint paint); public void setBaseSectionOutlineStroke(Stroke stroke);
有時候在圖表里面,我們會更喜歡設置餅圖里面某個具體的片區的外廓的顏色,或許突出顯示某些片區的細節方面。做到這些,我們可以是使用系列層層設置,通過下面的方法來定義。
public void setSectionOutlinePaint(Comparable key, Paint paint); public void setSectionOutlineStroke(Comparable key, Stroke stroke);
方法的第一個參數是dataset的片區關鍵值。如果我們將該值設為null,則系統將使用基本層的設置。
3 空值、零值、負值的處理
PieDataset可能會包含一些餅圖不可能顯示的數值,比如null、零值或者負值。對於這些數據PiePlot類有專門的處理機制來處理。如果是零值,並且該值有意義,PiePlot類默認將一個標簽放置在餅圖片區顯示的位置,並且在圖表的圖例中添加一個分類。如果零值可以忽略,我們可以使用下面代碼設置一個標志,不顯示該數據:
PiePlot plot = (PiePlot) chart.getPlot(); plot.setIgnoreZeroValues(true);
類似的null值也是如此處理,nul值代表dataset丟失或者不知來源的值。缺省的處理與零值相同,如果忽略null值,則代碼如下:
PiePlot plot = (PiePlot) chart.getPlot(); plot.setIgnoreNullValues(true);
在餅圖中處理負值是非常不明知的,所以在JFreeChart中負值總是被忽略的。
4 片區和圖例標簽
片區標簽使用的文本,即可以在圖表上顯示,也可以在圖表的圖例上顯示,並且完全可以定制。標簽是自動默認產生的,但我們可以使用下面方法來改變:
public void setLabelGenerator(PieSectionLabelGenerator generator); public void setLegendLabelGenerator(PieSectionLabelGenerator generator);
StandPieSectionLabelGenerator類專門用來生成圖例的一個實現類,提供靈活處理定制標簽的功能(如果你不喜歡用這個類,可以定義自己的類,只要實現接口PieSectionLabelGenerator即可)。Dataset顯示出的標簽值由Javade信息格式類來進行格式化——表5.1所示格式化的變量值。
名稱 |
描述 |
{0} |
片區關鍵值(字符串) |
{1} |
片區值 |
{2} |
百分比的片區值 |
表4.1 StandardPieSectionLabelGenerator substitutions
下面舉例說,假如我們有一個PieData包含下面的值
片區標識 |
片區值 |
S1 |
3.0 |
S2 |
5.0 |
S3 |
Null |
S4 |
2.0 |
表 5.2 一個dataset實例
下面是格式化字符串產生的標簽值內容:
格式化字符串 |
片區 |
產生的標簽值 |
{0} |
0 |
S1 |
{0} has value {1} |
1 |
S2 has value 5.0 |
{0}({2} percent) |
0 |
S1(30 percent) |
{0} = {1} |
2 |
S3 = null |
類PieChartDemo2.java使用了定制標簽的方法。
5 “取出”某個片區
PiePlot類支持將某個片區“取出“顯示。即某個片區偏離圖表中心,以突出顯示。如類所顯示。
片區偏離的數值是圖表半徑的一個百分值來表示。例如0.3(30 persent)代碼偏離的值是半徑的長度×0.3.代碼如下:
PiePlot pieplot = (PiePlot) jfreechart.getPlot();
pieplot.setExplodePercent("Two", 0.5);
6 3D餅圖
JFreeChart具有一個實現3D效果的餅圖類PiePlot3D,如圖5.5所示, (PieChart3DDemo1.java)。PiePlot3D是PiePlot的子類,因此在我們創建自己的餅圖時,使用PiePlot3D替換掉原來的PiePlot即可。
創建3D效果的餅圖時,使用ChartFactory的 createPieChart3D()方法,而不是createPieChart()方法。
對於該類有一些限制,如下:
l不支持”取出”片區功能。
l不支持軸項轉動——如果支持,3D效果圖可能會變型。
3D的實例主要是類PieChart3DDemo1-3.java。講解類中沒有列出其他兩個。因為功能雷同於非3D效果。
7 多餅圖
我們可是使用類MultiplePiePlot在一個圖表上顯示多個餅圖。餅圖的數據使用CatoryDataset。如圖5.6所示。每個獨立的餅圖由一個專門的圖表多次創建而成。
創建的每一個餅圖的PieDataset是由系統提供的CategoryDataset按照行或者列拆分出來的
多餅圖圖表
8、一個簡單的PieChart實例
代碼如下:
private static JFreeChart createChart(PieDataset piedataset) { JFreeChart jfreechart = ChartFactory.createPieChart("PieChart Demo 2", piedataset, true, true, false); PiePlot pieplot = (PiePlot) jfreechart.getPlot(); pieplot.setSectionPaint("One", new Color(160, 160, 255)); pieplot.setSectionPaint("Two", new Color(128, 128, 223)); pieplot.setSectionPaint("Three", new Color(96, 96, 191)); pieplot.setSectionPaint("Four", new Color(64, 64, 159)); pieplot.setSectionPaint("Five", new Color(32, 32, 127)); pieplot.setSectionPaint("Six", new Color(0, 0, 111)); pieplot.setNoDataMessage("No data available"); pieplot.setExplodePercent("Two", 0.5); pieplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} ({2} percent)")); pieplot.setLabelBackgroundPaint(new Color(220, 220, 220)); pieplot.setLegendLabelToolTipGenerator(new StandardPieSectionLabelGenerator("Tooltip for legend item {0}")); return jfreechart; }
運行結果:
關鍵代碼說明
lsetSectionPaint("One", new Color(160, 160, 255)):設置某個片區的填充顏色。第一個參數為片區的標識,第二個參數為色值。
lsetNoDataMessage("No data available"):設置dataset為null時顯示的提示信息。
lsetLabelGenerator(new StandardPieSectionLabelGenerator("{0}({2} percent)")):設置標簽顯示的格式。
lsetLabelBackgroundPaint(new Color(220, 220, 220)):設置標簽的背景顏色。
lsetLegendLabelToolTipGenerator(new StandardPieSectionLabelGenerator("Tooltip for legend item {0}")):設置鼠標滑過圖表是顯示鼠標當前片區的提示信息。
lpieplot.setExplodePercent("Two", 0.5):將第2個片區取出顯示。后面一個參數是取出的距離,是一個比例數。
9 自定義標簽生成器實例
自定義標簽生成器必須實現接口PieSectionLabelGenerator。
該實例實現了自定義的標簽生成,並將“TWO”標簽不顯示。代碼如下:
private static JFreeChart createChart(PieDataset piedataset) { JFreeChart jfreechart = ChartFactory.createPieChart("Pie Chart Demo 8", piedataset, false, true, false); PiePlot pieplot = (PiePlot) jfreechart.getPlot(); pieplot.setLabelGenerator(new CustomLabelGenerator()); return jfreechart; } //自定義標簽生成器 static class CustomLabelGenerator implements PieSectionLabelGenerator { public String generateSectionLabel(PieDataset piedataset, Comparable comparable) { String string = null; if (piedataset != null && !comparable.equals("Two")) string = comparable.toString(); return string; } public AttributedString generateAttributedSectionLabel( PieDataset piedataset, Comparable comparable) { Object object = null; String string = comparable.toString(); String string_0_ = (string + " : " + String.valueOf(piedataset .getValue(comparable))); AttributedString attributedstring = new AttributedString(string_0_); attributedstring.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 0, string.length() - 1); return attributedstring; } }
效果圖:
10 3D效果餅圖實例
代碼:
private static JFreeChart createChart(PieDataset piedataset) { JFreeChart jfreechart = ChartFactory.createPieChart3D( "Pie Chart 3D Demo 1", piedataset, true, true, false); PiePlot3D pieplot3d = (PiePlot3D) jfreechart.getPlot(); //設置旋轉角度 pieplot3d.setStartAngle(180.0); //設置旋轉方向,Rotation.CLOCKWISE)為順時針。 pieplot3d.setDirection(Rotation.CLOCKWISE); //設置圖表透明圖0.0~1.0范圍。0.0為完全透明,1.0為完全不透明。 pieplot3d.setForegroundAlpha(0.5F); pieplot3d.setNoDataMessage("No data to display"); return jfreechart; }
效果圖:
11 多餅圖實例
使用CategoryDataset數據集,在一個圖表上產生多個餅圖。
創建多餅圖的CategoryDataset數據集代碼
private static CategoryDataset createDataset() { double[][] ds = { { 3.0, 4.0, 3.0, 5.0 }, { 5.0, 7.0, 6.0, 8.0 }, { 5.0, 7.0, Double.NaN, 3.0 }, { 1.0, 2.0, 3.0, 4.0 }, { 2.0, 3.0, 2.0, 3.0 } }; CategoryDataset categorydataset = DatasetUtilities .createCategoryDataset("Region ", "Sales/Q", ds); return categorydataset; }
使用多餅圖CategoryDataset數據集生成多餅圖的代碼
private static JFreeChart createChart(CategoryDataset categorydataset) { //創建多餅圖圖表 JFreeChart jfreechart = ChartFactory.createMultiplePieChart( "Multiple Pie Chart", categorydataset, TableOrder.BY_ROW, true, true, false); //多餅圖Plot對象 MultiplePiePlot multiplepieplot = (MultiplePiePlot) jfreechart.getPlot(); //獲得單個餅圖圖表 JFreeChart jfreechart_0_ = multiplepieplot.getPieChart(); PiePlot pieplot = (PiePlot) jfreechart_0_.getPlot(); pieplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}")); pieplot.setLabelFont(new Font("SansSerif", 0, 8)); pieplot.setInteriorGap(0.3); return jfreechart; }
效果圖:
12 餅圖的其他常用設置實例
對DataSet進行排序,改變片區的位置:
dataset.sortByKeys(SortOrder.ASCENDING);通過片區的關鍵值進行升序排序。
dataset.sortByValues(SortOrder.DESCENDING);通過片區的值進行降序排序
對Null值和零值處理
pieplot.setIgnoreNullValues(true):設置餅圖忽略null值,即是null值將不顯示。 pieplot.setIgnoreZeroValues(false);設置餅圖不忽略零值。即圖表中顯示出零值。
使餅圖和標簽開始旋轉:使用Rotator對象,旋轉餅圖
pieplot.setCircular(true);//設置餅圖為圓形 //標簽格式 pieplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} = {2}", NumberFormat.getNumberInstance(), NumberFormat.getPercentInstance())); pieplot.setNoDataMessage("No data available"); //ChartPanel是JPanel的子類,此方法可以生成一個JPanel ChartPanel chartpanel = new ChartPanel(jfreechart); chartpanel.setPreferredSize(new Dimension(500, 270)); //該方法可以使餅圖開始旋轉 Rotator rotator = new Rotator(pieplot); rotator.start();