JFreeChart 使用一 饼图之高级特性
本文主要讲解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();