JFreeChart 使用一 饼图之高级特性

原文链接:http://www.cnblogs.com/jtmjx/archive/2013/04/23/jfreechart_advantage.html

本文主要讲解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();
                                

时间: 2024-10-01 05:25:34

JFreeChart 使用一 饼图之高级特性的相关文章

MapReduce编程实战之“高级特性”

本篇介绍MapReduce的一些高级特性,如计数器.数据集的排序和连接.计数器是一种收集作业统计信息的有效手段,排序是MapReduce的核心技术,MapReduce也能够执行大型数据集间的""连接(join)操作. 计数器 计数器是一种收集作业统计信息的有效手段,用于质量控制或应用级统计.计数器还可用于辅助诊断系统故障.对于大型分布式系统来说,获取计数器比分析日志文件容易的多. 示例一:气温缺失及不规则数据计数器 import java.io.IOException; import

javascript高级特性

01_javascript相关内容02_函数_Arguments对象03_函数_变量的作用域04_函数_特殊函数05_闭包_作用域链&闭包06_闭包_循环中的闭包07_对象_定义普通对象08_对象_定义函数对象09_对象_内建对象10_原型_为函数对象增加属性或方法11_原型_利用函数对象本身重写原型12_继承_函数对象之间的继承13_继承_普通对象之间的继承 javascript高级特性(面向对象): * 面向对象:   * 面向对象和面向过程的区别:     * 面向对象:人就是对象,年龄\

python之高级特性

掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n = 1 while n <= 99: L.append(n) n = n + 2 取list的前一半的元素,也可以通过循环实现. 但是在Python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好. 基于这一思想,我们来介绍Python中非常有用的高级特性,1行代码能实现的功能,决不写5行代码.请始终

Python_高级特性

Python高级特性 author:lxy 切片.迭代.列表生成式.生成器 切片 Python中 代码越少越简单越好, 我们要取一个list中的某一部分的元素的我们可以使用判断+循环实现,在Python提供了专门的方法--切片 slice切片,用来获取list中某一段元素 tuple.str等都看做是一种list只是使用切片获取的片段还是他们原来相应的类型 例1.对list进行切片 >>> n = [1,3,2,5,6,8] >>> n[0:3]           

JSP简明教程(五):高级特性

JSP过滤器 过滤器的作用是给web请求增加额外的逻辑,每个页面可以被多个过滤器进行处理.过滤器需要在web.xml文件中进行定义,语法如下.过滤器的执行顺序与filter-mapping的定义顺序相同. <filter> <filter-name>FilterName</filter-name> <filter-class>TestFilter</filter-name> <init-param> <param-name>

Day-5: Python高级特性

python的理念是:简单.优雅.所以,在Python中集成了许多经常要使用的高级特性,以此来简化代码. 切片: 对于一个list或者tuple,取其中一段的元素,称为切片(Slice). L[start:end]表示取L中从索引号为start到end的元素,其中如果顺着取,则索引号范围为0~len(L)-1:反着取,则索引号范围为-1~-len(L). 迭代: Python中迭代用for...in来完成.对于list或者tuple,就是for name in names之类:而对于dict,就

ActiveMQ中的Destination高级特性(一)

---------------------------------------------------------------------------------------- Destination高级特性----->Composite Destinations 组合队列Composite Destinations : 允许用一个虚拟的destination代表多个destinations,这样就可以通过composite destinations在一个操作中同时向多个queue/topic发

《深入理解Java虚拟机 JVM高级特性...》核心笔记

深入理解Java虚拟机 JVM高级特性与最佳实践(第二版) 核心笔记 JAVA 环境: JAVA虚拟机高级特性: 一:java内存区域与内存异常 一):运行数据区     1:程序计数器(Program Counter Register),也称"PC寄存器" A:用来指示需要执行哪条指令的.(在汇编语言中,CPU在得到指令之后,程序计数器便自动加1或者根据                    转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令.) B:由于在JVM中,多线程

JavaScript【5】高级特性(作用域、闭包、对象)

笔记来自<Node.js开发指南>BYVoid编著 1.作用域 if (true) { var somevar = 'value'; } console.log(somevar); JavaScript的作用域完全是由函数决定的,if.for语句中的花括号不是独立的作用域. 1.1.函数作用域 作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函数作用域.在函数中引用一个变量时,JavaScript会先搜索当前函数作用域,或者称为"局部作用域",